diff --git a/source/v8/CNAME b/source/v8/CNAME
new file mode 100644
index 0000000..e873526
--- /dev/null
+++ b/source/v8/CNAME
@@ -0,0 +1 @@
+www.pixijselementals.com
\ No newline at end of file
diff --git a/source/v8/android-chrome-192x192.png b/source/v8/android-chrome-192x192.png
new file mode 100644
index 0000000..589a731
Binary files /dev/null and b/source/v8/android-chrome-192x192.png differ
diff --git a/source/v8/android-chrome-512x512.png b/source/v8/android-chrome-512x512.png
new file mode 100644
index 0000000..9c1fb25
Binary files /dev/null and b/source/v8/android-chrome-512x512.png differ
diff --git a/source/v8/apple-touch-icon.png b/source/v8/apple-touch-icon.png
new file mode 100644
index 0000000..452c2e2
Binary files /dev/null and b/source/v8/apple-touch-icon.png differ
diff --git a/source/v8/favicon-16x16.png b/source/v8/favicon-16x16.png
new file mode 100644
index 0000000..f6aeb19
Binary files /dev/null and b/source/v8/favicon-16x16.png differ
diff --git a/source/v8/favicon-32x32.png b/source/v8/favicon-32x32.png
new file mode 100644
index 0000000..84bdf7f
Binary files /dev/null and b/source/v8/favicon-32x32.png differ
diff --git a/source/v8/favicon.ico b/source/v8/favicon.ico
new file mode 100644
index 0000000..cd36b8a
Binary files /dev/null and b/source/v8/favicon.ico differ
diff --git a/source/v8/fonts/slate.eot b/source/v8/fonts/slate.eot
new file mode 100644
index 0000000..13c4839
Binary files /dev/null and b/source/v8/fonts/slate.eot differ
diff --git a/source/v8/fonts/slate.svg b/source/v8/fonts/slate.svg
new file mode 100644
index 0000000..671eae4
--- /dev/null
+++ b/source/v8/fonts/slate.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/source/v8/fonts/slate.ttf b/source/v8/fonts/slate.ttf
new file mode 100644
index 0000000..ace9a46
Binary files /dev/null and b/source/v8/fonts/slate.ttf differ
diff --git a/source/v8/fonts/slate.woff b/source/v8/fonts/slate.woff
new file mode 100644
index 0000000..1e72e0e
Binary files /dev/null and b/source/v8/fonts/slate.woff differ
diff --git a/source/v8/fonts/slate.woff2 b/source/v8/fonts/slate.woff2
new file mode 100644
index 0000000..7c585a7
Binary files /dev/null and b/source/v8/fonts/slate.woff2 differ
diff --git a/source/v8/images/logo.png b/source/v8/images/logo.png
new file mode 100644
index 0000000..dfad9d9
Binary files /dev/null and b/source/v8/images/logo.png differ
diff --git a/source/v8/images/navbar.png b/source/v8/images/navbar.png
new file mode 100644
index 0000000..df38e90
Binary files /dev/null and b/source/v8/images/navbar.png differ
diff --git a/source/v8/includes/_00-WIP.md b/source/v8/includes/_00-WIP.md
new file mode 100644
index 0000000..5c840c1
--- /dev/null
+++ b/source/v8/includes/_00-WIP.md
@@ -0,0 +1,3 @@
+# Coming Soon
+
+👀
\ No newline at end of file
diff --git a/source/v8/index.html.md b/source/v8/index.html.md
new file mode 100644
index 0000000..f214e8a
--- /dev/null
+++ b/source/v8/index.html.md
@@ -0,0 +1,19 @@
+---
+title: PixiJS Elementals v8
+
+language_tabs:
+
+toc_footers:
+ -
+
+includes:
+ - 00-WIP
+
+
+search: true
+
+code_clipboard: true
+---
+
+
+
diff --git a/source/v8/javascripts/all.js b/source/v8/javascripts/all.js
new file mode 100644
index 0000000..daf4f01
--- /dev/null
+++ b/source/v8/javascripts/all.js
@@ -0,0 +1,2 @@
+//= require ./all_nosearch
+//= require ./app/_search
diff --git a/source/v8/javascripts/all_nosearch.js b/source/v8/javascripts/all_nosearch.js
new file mode 100644
index 0000000..402730e
--- /dev/null
+++ b/source/v8/javascripts/all_nosearch.js
@@ -0,0 +1,27 @@
+//= require ./lib/_energize
+//= require ./app/_copy
+//= require ./app/_toc
+//= require ./app/_lang
+
+function adjustLanguageSelectorWidth() {
+ const elem = $('.dark-box > .lang-selector');
+ elem.width(elem.parent().width());
+}
+
+$(function() {
+ loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10);
+ setupLanguages($('body').data('languages'));
+ $('.content').imagesLoaded( function() {
+ window.recacheHeights();
+ window.refreshToc();
+ });
+
+ $(window).resize(function() {
+ adjustLanguageSelectorWidth();
+ });
+ adjustLanguageSelectorWidth();
+});
+
+window.onpopstate = function() {
+ activateLanguage(getLanguageFromQueryString());
+};
diff --git a/source/v8/javascripts/app/_copy.js b/source/v8/javascripts/app/_copy.js
new file mode 100644
index 0000000..2cdadf9
--- /dev/null
+++ b/source/v8/javascripts/app/_copy.js
@@ -0,0 +1,15 @@
+function copyToClipboard(container) {
+ const el = document.createElement('textarea');
+ el.value = container.textContent.replace(/\n$/, '');
+ document.body.appendChild(el);
+ el.select();
+ document.execCommand('copy');
+ document.body.removeChild(el);
+}
+
+function setupCodeCopy() {
+ $('pre.highlight').prepend('
');
+ $('.copy-clipboard').on('click', function() {
+ copyToClipboard(this.parentNode.children[1]);
+ });
+}
diff --git a/source/v8/javascripts/app/_lang.js b/source/v8/javascripts/app/_lang.js
new file mode 100644
index 0000000..c1bd6b2
--- /dev/null
+++ b/source/v8/javascripts/app/_lang.js
@@ -0,0 +1,171 @@
+//= require ../lib/_jquery
+
+/*
+Copyright 2008-2013 Concur Technologies, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may
+not use this file except in compliance with the License. You may obtain
+a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations
+under the License.
+*/
+;(function () {
+ 'use strict';
+
+ var languages = [];
+
+ window.setupLanguages = setupLanguages;
+ window.activateLanguage = activateLanguage;
+ window.getLanguageFromQueryString = getLanguageFromQueryString;
+
+ function activateLanguage(language) {
+ if (!language) return;
+ if (language === "") return;
+
+ $(".lang-selector a").removeClass('active');
+ $(".lang-selector a[data-language-name='" + language + "']").addClass('active');
+ for (var i=0; i < languages.length; i++) {
+ $(".highlight.tab-" + languages[i]).hide();
+ $(".lang-specific." + languages[i]).hide();
+ }
+ $(".highlight.tab-" + language).show();
+ $(".lang-specific." + language).show();
+
+ window.recacheHeights();
+
+ // scroll to the new location of the position
+ if ($(window.location.hash).get(0)) {
+ $(window.location.hash).get(0).scrollIntoView(true);
+ }
+ }
+
+ // parseURL and stringifyURL are from https://github.com/sindresorhus/query-string
+ // MIT licensed
+ // https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license
+ function parseURL(str) {
+ if (typeof str !== 'string') {
+ return {};
+ }
+
+ str = str.trim().replace(/^(\?|#|&)/, '');
+
+ if (!str) {
+ return {};
+ }
+
+ return str.split('&').reduce(function (ret, param) {
+ var parts = param.replace(/\+/g, ' ').split('=');
+ var key = parts[0];
+ var val = parts[1];
+
+ key = decodeURIComponent(key);
+ // missing `=` should be `null`:
+ // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
+ val = val === undefined ? null : decodeURIComponent(val);
+
+ if (!ret.hasOwnProperty(key)) {
+ ret[key] = val;
+ } else if (Array.isArray(ret[key])) {
+ ret[key].push(val);
+ } else {
+ ret[key] = [ret[key], val];
+ }
+
+ return ret;
+ }, {});
+ };
+
+ function stringifyURL(obj) {
+ return obj ? Object.keys(obj).sort().map(function (key) {
+ var val = obj[key];
+
+ if (Array.isArray(val)) {
+ return val.sort().map(function (val2) {
+ return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
+ }).join('&');
+ }
+
+ return encodeURIComponent(key) + '=' + encodeURIComponent(val);
+ }).join('&') : '';
+ };
+
+ // gets the language set in the query string
+ function getLanguageFromQueryString() {
+ if (location.search.length >= 1) {
+ var language = parseURL(location.search).language;
+ if (language) {
+ return language;
+ } else if (jQuery.inArray(location.search.substr(1), languages) != -1) {
+ return location.search.substr(1);
+ }
+ }
+
+ return false;
+ }
+
+ // returns a new query string with the new language in it
+ function generateNewQueryString(language) {
+ var url = parseURL(location.search);
+ if (url.language) {
+ url.language = language;
+ return stringifyURL(url);
+ }
+ return language;
+ }
+
+ // if a button is clicked, add the state to the history
+ function pushURL(language) {
+ if (!history) { return; }
+ var hash = window.location.hash;
+ if (hash) {
+ hash = hash.replace(/^#+/, '');
+ }
+ history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash);
+
+ // save language as next default
+ if (localStorage) {
+ localStorage.setItem("language", language);
+ }
+ }
+
+ function setupLanguages(l) {
+ var defaultLanguage = null;
+ if (localStorage) {
+ defaultLanguage = localStorage.getItem("language");
+ }
+
+ languages = l;
+
+ var presetLanguage = getLanguageFromQueryString();
+ if (presetLanguage && languages.includes(presetLanguage)) {
+ // the language is in the URL, so use that language!
+ activateLanguage(presetLanguage);
+
+ if (localStorage) {
+ localStorage.setItem("language", presetLanguage);
+ }
+ } else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) {
+ // the language was the last selected one saved in localstorage, so use that language!
+ activateLanguage(defaultLanguage);
+ } else {
+ // no language selected, so use the default
+ activateLanguage(languages[0]);
+ }
+ }
+
+ // if we click on a language tab, activate that language
+ $(function() {
+ $(".lang-selector a").on("click", function() {
+ var language = $(this).data("language-name");
+ pushURL(language);
+ activateLanguage(language);
+ return false;
+ });
+ });
+})();
diff --git a/source/v8/javascripts/app/_search.js b/source/v8/javascripts/app/_search.js
new file mode 100644
index 0000000..622aea6
--- /dev/null
+++ b/source/v8/javascripts/app/_search.js
@@ -0,0 +1,102 @@
+//= require ../lib/_lunr
+//= require ../lib/_jquery
+//= require ../lib/_jquery.highlight
+;(function () {
+ 'use strict';
+
+ var content, searchResults;
+ var highlightOpts = { element: 'span', className: 'search-highlight' };
+ var searchDelay = 0;
+ var timeoutHandle = 0;
+ var index;
+
+ function populate() {
+ index = lunr(function(){
+
+ this.ref('id');
+ this.field('title', { boost: 10 });
+ this.field('body');
+ this.pipeline.add(lunr.trimmer, lunr.stopWordFilter);
+ var lunrConfig = this;
+
+ $('h1, h2').each(function() {
+ var title = $(this);
+ var body = title.nextUntil('h1, h2');
+ lunrConfig.add({
+ id: title.prop('id'),
+ title: title.text(),
+ body: body.text()
+ });
+ });
+
+ });
+ determineSearchDelay();
+ }
+
+ $(populate);
+ $(bind);
+
+ function determineSearchDelay() {
+ if (index.tokenSet.toArray().length>5000) {
+ searchDelay = 300;
+ }
+ }
+
+ function bind() {
+ content = $('.content');
+ searchResults = $('.search-results');
+
+ $('#input-search').on('keyup',function(e) {
+ var wait = function() {
+ return function(executingFunction, waitTime){
+ clearTimeout(timeoutHandle);
+ timeoutHandle = setTimeout(executingFunction, waitTime);
+ };
+ }();
+ wait(function(){
+ search(e);
+ }, searchDelay);
+ });
+ }
+
+ function search(event) {
+
+ var searchInput = $('#input-search')[0];
+
+ unhighlight();
+ searchResults.addClass('visible');
+
+ // ESC clears the field
+ if (event.keyCode === 27) searchInput.value = '';
+
+ if (searchInput.value) {
+ var results = index.search(searchInput.value).filter(function(r) {
+ return r.score > 0.0001;
+ });
+
+ if (results.length) {
+ searchResults.empty();
+ $.each(results, function (index, result) {
+ var elem = document.getElementById(result.ref);
+ searchResults.append("" + $(elem).text() + "");
+ });
+ highlight.call(searchInput);
+ } else {
+ searchResults.html('');
+ $('.search-results li').text('No Results Found for "' + searchInput.value + '"');
+ }
+ } else {
+ unhighlight();
+ searchResults.removeClass('visible');
+ }
+ }
+
+ function highlight() {
+ if (this.value) content.highlight(this.value, highlightOpts);
+ }
+
+ function unhighlight() {
+ content.unhighlight(highlightOpts);
+ }
+})();
+
diff --git a/source/v8/javascripts/app/_toc.js b/source/v8/javascripts/app/_toc.js
new file mode 100644
index 0000000..350280e
--- /dev/null
+++ b/source/v8/javascripts/app/_toc.js
@@ -0,0 +1,122 @@
+//= require ../lib/_jquery
+//= require ../lib/_imagesloaded.min
+;(function () {
+ 'use strict';
+
+ var htmlPattern = /<[^>]*>/g;
+ var loaded = false;
+
+ var debounce = function(func, waitTime) {
+ var timeout = false;
+ return function() {
+ if (timeout === false) {
+ setTimeout(function() {
+ func();
+ timeout = false;
+ }, waitTime);
+ timeout = true;
+ }
+ };
+ };
+
+ var closeToc = function() {
+ $(".toc-wrapper").removeClass('open');
+ $("#nav-button").removeClass('open');
+ };
+
+ function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) {
+ var headerHeights = {};
+ var pageHeight = 0;
+ var windowHeight = 0;
+ var originalTitle = document.title;
+
+ var recacheHeights = function() {
+ headerHeights = {};
+ pageHeight = $(document).height();
+ windowHeight = $(window).height();
+
+ $toc.find(tocLinkSelector).each(function() {
+ var targetId = $(this).attr('href');
+ if (targetId[0] === "#") {
+ headerHeights[targetId] = $("#" + $.escapeSelector(targetId.substring(1))).offset().top;
+ }
+ });
+ };
+
+ var refreshToc = function() {
+ var currentTop = $(document).scrollTop() + scrollOffset;
+
+ if (currentTop + windowHeight >= pageHeight) {
+ // at bottom of page, so just select last header by making currentTop very large
+ // this fixes the problem where the last header won't ever show as active if its content
+ // is shorter than the window height
+ currentTop = pageHeight + 1000;
+ }
+
+ var best = null;
+ for (var name in headerHeights) {
+ if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) {
+ best = name;
+ }
+ }
+
+ // Catch the initial load case
+ if (currentTop == scrollOffset && !loaded) {
+ best = window.location.hash;
+ loaded = true;
+ }
+
+ var $best = $toc.find("[href='" + best + "']").first();
+ if (!$best.hasClass("active")) {
+ // .active is applied to the ToC link we're currently on, and its parent s selected by tocListSelector
+ // .active-expanded is applied to the ToC links that are parents of this one
+ $toc.find(".active").removeClass("active");
+ $toc.find(".active-parent").removeClass("active-parent");
+ $best.addClass("active");
+ $best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent');
+ $best.siblings(tocListSelector).addClass("active");
+ $toc.find(tocListSelector).filter(":not(.active)").slideUp(150);
+ $toc.find(tocListSelector).filter(".active").slideDown(150);
+ if (window.history.replaceState) {
+ window.history.replaceState(null, "", best);
+ }
+ var thisTitle = $best.data("title");
+ if (thisTitle !== undefined && thisTitle.length > 0) {
+ document.title = thisTitle.replace(htmlPattern, "") + " – " + originalTitle;
+ } else {
+ document.title = originalTitle;
+ }
+ }
+ };
+
+ var makeToc = function() {
+ recacheHeights();
+ refreshToc();
+
+ $("#nav-button").click(function() {
+ $(".toc-wrapper").toggleClass('open');
+ $("#nav-button").toggleClass('open');
+ return false;
+ });
+ $(".page-wrapper").click(closeToc);
+ $(".toc-link").click(closeToc);
+
+ // reload immediately after scrolling on toc click
+ $toc.find(tocLinkSelector).click(function() {
+ setTimeout(function() {
+ refreshToc();
+ }, 0);
+ });
+
+ $(window).scroll(debounce(refreshToc, 200));
+ $(window).resize(debounce(recacheHeights, 200));
+ };
+
+ makeToc();
+
+ window.recacheHeights = recacheHeights;
+ window.refreshToc = refreshToc;
+ }
+
+ window.loadToc = loadToc;
+})();
diff --git a/source/v8/javascripts/lib/_energize.js b/source/v8/javascripts/lib/_energize.js
new file mode 100644
index 0000000..c6eb95e
--- /dev/null
+++ b/source/v8/javascripts/lib/_energize.js
@@ -0,0 +1,169 @@
+/**
+ * energize.js v0.1.0
+ *
+ * Speeds up click events on mobile devices.
+ * https://github.com/davidcalhoun/energize.js
+ */
+
+(function() { // Sandbox
+ /**
+ * Don't add to non-touch devices, which don't need to be sped up
+ */
+ if(!('ontouchstart' in window)) return;
+
+ var lastClick = {},
+ isThresholdReached, touchstart, touchmove, touchend,
+ click, closest;
+
+ /**
+ * isThresholdReached
+ *
+ * Compare touchstart with touchend xy coordinates,
+ * and only fire simulated click event if the coordinates
+ * are nearby. (don't want clicking to be confused with a swipe)
+ */
+ isThresholdReached = function(startXY, xy) {
+ return Math.abs(startXY[0] - xy[0]) > 5 || Math.abs(startXY[1] - xy[1]) > 5;
+ };
+
+ /**
+ * touchstart
+ *
+ * Save xy coordinates when the user starts touching the screen
+ */
+ touchstart = function(e) {
+ this.startXY = [e.touches[0].clientX, e.touches[0].clientY];
+ this.threshold = false;
+ };
+
+ /**
+ * touchmove
+ *
+ * Check if the user is scrolling past the threshold.
+ * Have to check here because touchend will not always fire
+ * on some tested devices (Kindle Fire?)
+ */
+ touchmove = function(e) {
+ // NOOP if the threshold has already been reached
+ if(this.threshold) return false;
+
+ this.threshold = isThresholdReached(this.startXY, [e.touches[0].clientX, e.touches[0].clientY]);
+ };
+
+ /**
+ * touchend
+ *
+ * If the user didn't scroll past the threshold between
+ * touchstart and touchend, fire a simulated click.
+ *
+ * (This will fire before a native click)
+ */
+ touchend = function(e) {
+ // Don't fire a click if the user scrolled past the threshold
+ if(this.threshold || isThresholdReached(this.startXY, [e.changedTouches[0].clientX, e.changedTouches[0].clientY])) {
+ return;
+ }
+
+ /**
+ * Create and fire a click event on the target element
+ * https://developer.mozilla.org/en/DOM/event.initMouseEvent
+ */
+ var touch = e.changedTouches[0],
+ evt = document.createEvent('MouseEvents');
+ evt.initMouseEvent('click', true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
+ evt.simulated = true; // distinguish from a normal (nonsimulated) click
+ e.target.dispatchEvent(evt);
+ };
+
+ /**
+ * click
+ *
+ * Because we've already fired a click event in touchend,
+ * we need to listed for all native click events here
+ * and suppress them as necessary.
+ */
+ click = function(e) {
+ /**
+ * Prevent ghost clicks by only allowing clicks we created
+ * in the click event we fired (look for e.simulated)
+ */
+ var time = Date.now(),
+ timeDiff = time - lastClick.time,
+ x = e.clientX,
+ y = e.clientY,
+ xyDiff = [Math.abs(lastClick.x - x), Math.abs(lastClick.y - y)],
+ target = closest(e.target, 'A') || e.target, // needed for standalone apps
+ nodeName = target.nodeName,
+ isLink = nodeName === 'A',
+ standAlone = window.navigator.standalone && isLink && e.target.getAttribute("href");
+
+ lastClick.time = time;
+ lastClick.x = x;
+ lastClick.y = y;
+
+ /**
+ * Unfortunately Android sometimes fires click events without touch events (seen on Kindle Fire),
+ * so we have to add more logic to determine the time of the last click. Not perfect...
+ *
+ * Older, simpler check: if((!e.simulated) || standAlone)
+ */
+ if((!e.simulated && (timeDiff < 500 || (timeDiff < 1500 && xyDiff[0] < 50 && xyDiff[1] < 50))) || standAlone) {
+ e.preventDefault();
+ e.stopPropagation();
+ if(!standAlone) return false;
+ }
+
+ /**
+ * Special logic for standalone web apps
+ * See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window
+ */
+ if(standAlone) {
+ window.location = target.getAttribute("href");
+ }
+
+ /**
+ * Add an energize-focus class to the targeted link (mimics :focus behavior)
+ * TODO: test and/or remove? Does this work?
+ */
+ if(!target || !target.classList) return;
+ target.classList.add("energize-focus");
+ window.setTimeout(function(){
+ target.classList.remove("energize-focus");
+ }, 150);
+ };
+
+ /**
+ * closest
+ * @param {HTMLElement} node current node to start searching from.
+ * @param {string} tagName the (uppercase) name of the tag you're looking for.
+ *
+ * Find the closest ancestor tag of a given node.
+ *
+ * Starts at node and goes up the DOM tree looking for a
+ * matching nodeName, continuing until hitting document.body
+ */
+ closest = function(node, tagName){
+ var curNode = node;
+
+ while(curNode !== document.body) { // go up the dom until we find the tag we're after
+ if(!curNode || curNode.nodeName === tagName) { return curNode; } // found
+ curNode = curNode.parentNode; // not found, so keep going up
+ }
+
+ return null; // not found
+ };
+
+ /**
+ * Add all delegated event listeners
+ *
+ * All the events we care about bubble up to document,
+ * so we can take advantage of event delegation.
+ *
+ * Note: no need to wait for DOMContentLoaded here
+ */
+ document.addEventListener('touchstart', touchstart, false);
+ document.addEventListener('touchmove', touchmove, false);
+ document.addEventListener('touchend', touchend, false);
+ document.addEventListener('click', click, true); // TODO: why does this use capture?
+
+})();
\ No newline at end of file
diff --git a/source/v8/javascripts/lib/_imagesloaded.min.js b/source/v8/javascripts/lib/_imagesloaded.min.js
new file mode 100644
index 0000000..65a0e86
--- /dev/null
+++ b/source/v8/javascripts/lib/_imagesloaded.min.js
@@ -0,0 +1,7 @@
+/*!
+ * imagesLoaded PACKAGED v4.1.4
+ * JavaScript is all like "You images are done yet or what?"
+ * MIT License
+ */
+
+!function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o (default options)
+ * $('#content').highlight('lorem');
+ *
+ * // search for and highlight more terms at once
+ * // so you can save some time on traversing DOM
+ * $('#content').highlight(['lorem', 'ipsum']);
+ * $('#content').highlight('lorem ipsum');
+ *
+ * // search only for entire word 'lorem'
+ * $('#content').highlight('lorem', { wordsOnly: true });
+ *
+ * // don't ignore case during search of term 'lorem'
+ * $('#content').highlight('lorem', { caseSensitive: true });
+ *
+ * // wrap every occurrance of term 'ipsum' in content
+ * // with
+ * $('#content').highlight('ipsum', { element: 'em', className: 'important' });
+ *
+ * // remove default highlight
+ * $('#content').unhighlight();
+ *
+ * // remove custom highlight
+ * $('#content').unhighlight({ element: 'em', className: 'important' });
+ *
+ *
+ * Copyright (c) 2009 Bartek Szopka
+ *
+ * Licensed under MIT license.
+ *
+ */
+
+jQuery.extend({
+ highlight: function (node, re, nodeName, className) {
+ if (node.nodeType === 3) {
+ var match = node.data.match(re);
+ if (match) {
+ var highlight = document.createElement(nodeName || 'span');
+ highlight.className = className || 'highlight';
+ var wordNode = node.splitText(match.index);
+ wordNode.splitText(match[0].length);
+ var wordClone = wordNode.cloneNode(true);
+ highlight.appendChild(wordClone);
+ wordNode.parentNode.replaceChild(highlight, wordNode);
+ return 1; //skip added node in parent
+ }
+ } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
+ !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
+ !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
+ for (var i = 0; i < node.childNodes.length; i++) {
+ i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
+ }
+ }
+ return 0;
+ }
+});
+
+jQuery.fn.unhighlight = function (options) {
+ var settings = { className: 'highlight', element: 'span' };
+ jQuery.extend(settings, options);
+
+ return this.find(settings.element + "." + settings.className).each(function () {
+ var parent = this.parentNode;
+ parent.replaceChild(this.firstChild, this);
+ parent.normalize();
+ }).end();
+};
+
+jQuery.fn.highlight = function (words, options) {
+ var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
+ jQuery.extend(settings, options);
+
+ if (words.constructor === String) {
+ words = [words];
+ }
+ words = jQuery.grep(words, function(word, i){
+ return word != '';
+ });
+ words = jQuery.map(words, function(word, i) {
+ return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+ });
+ if (words.length == 0) { return this; };
+
+ var flag = settings.caseSensitive ? "" : "i";
+ var pattern = "(" + words.join("|") + ")";
+ if (settings.wordsOnly) {
+ pattern = "\\b" + pattern + "\\b";
+ }
+ var re = new RegExp(pattern, flag);
+
+ return this.each(function () {
+ jQuery.highlight(this, re, settings.element, settings.className);
+ });
+};
+
diff --git a/source/v8/javascripts/lib/_jquery.js b/source/v8/javascripts/lib/_jquery.js
new file mode 100644
index 0000000..fc6c299
--- /dev/null
+++ b/source/v8/javascripts/lib/_jquery.js
@@ -0,0 +1,10881 @@
+/*!
+ * jQuery JavaScript Library v3.6.0
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright OpenJS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2021-03-02T17:08Z
+ */
+( function( global, factory ) {
+
+ "use strict";
+
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
+
+ // For CommonJS and CommonJS-like environments where a proper `window`
+ // is present, execute the factory and get jQuery.
+ // For environments that do not have a `window` with a `document`
+ // (such as Node.js), expose a factory as module.exports.
+ // This accentuates the need for the creation of a real `window`.
+ // e.g. var jQuery = require("jquery")(window);
+ // See ticket #14549 for more info.
+ module.exports = global.document ?
+ factory( global, true ) :
+ function( w ) {
+ if ( !w.document ) {
+ throw new Error( "jQuery requires a window with a document" );
+ }
+ return factory( w );
+ };
+ } else {
+ factory( global );
+ }
+
+// Pass this if window is not defined yet
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+"use strict";
+
+var arr = [];
+
+var getProto = Object.getPrototypeOf;
+
+var slice = arr.slice;
+
+var flat = arr.flat ? function( array ) {
+ return arr.flat.call( array );
+} : function( array ) {
+ return arr.concat.apply( [], array );
+};
+
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var fnToString = hasOwn.toString;
+
+var ObjectFunctionString = fnToString.call( Object );
+
+var support = {};
+
+var isFunction = function isFunction( obj ) {
+
+ // Support: Chrome <=57, Firefox <=52
+ // In some browsers, typeof returns "function" for HTML