Skip to content

Instantly share code, notes, and snippets.

@mthh
Last active November 2, 2018 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mthh/3f70594e37c0c7ba0cc8a874d5d10e3b to your computer and use it in GitHub Desktop.
Save mthh/3f70594e37c0c7ba0cc8a874d5d10e3b to your computer and use it in GitHub Desktop.
d3 graph
license: MIT
.sey-container {
display: none;
position: absolute;
box-shadow: 1px 2px 6px;
background-color: #fff;
color: #333;
transition: left 0.1s ease-in-out;
z-index: 1;
}
.sey-list {
padding: 0;
margin: 0;
list-style-type: none;
}
.sey-show {
display: block;
}
.sey-hide {
display: none;
}
.sey-empty {
cursor: default;
padding: 7px;
}
.sey-item {
cursor: pointer;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
padding: 7px;
}
.sey-item:hover {
background-color: #444;
color: #fff;
}
.sey-selected {
background-color: #333;
color: #fff;
}
.sey-char-highlight {
font-weight: bold;
}
.sey-category-id {
background-color: #eee;
color: #aaa;
text-align: right;
text-transform: capitalize;
font-style: italic;
font-size: 12px;
box-shadow: 1px 0px 1px;
padding: 7px;
}
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.horsey = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var _hashSum = require('hash-sum');
var _hashSum2 = _interopRequireDefault(_hashSum);
var _sell = require('sell');
var _sell2 = _interopRequireDefault(_sell);
var _sektor = require('sektor');
var _sektor2 = _interopRequireDefault(_sektor);
var _emitter = require('contra/emitter');
var _emitter2 = _interopRequireDefault(_emitter);
var _bullseye = require('bullseye');
var _bullseye2 = _interopRequireDefault(_bullseye);
var _crossvent = require('crossvent');
var _crossvent2 = _interopRequireDefault(_crossvent);
var _fuzzysearch = require('fuzzysearch');
var _fuzzysearch2 = _interopRequireDefault(_fuzzysearch);
var _debounce = require('lodash/debounce');
var _debounce2 = _interopRequireDefault(_debounce);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var KEY_BACKSPACE = 8;
var KEY_ENTER = 13;
var KEY_ESC = 27;
var KEY_UP = 38;
var KEY_DOWN = 40;
var KEY_TAB = 9;
var doc = document;
var docElement = doc.documentElement;
function horsey(el) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var setAppends = options.setAppends;
var _set = options.set;
var filter = options.filter;
var source = options.source;
var _options$cache = options.cache;
var cache = _options$cache === undefined ? {} : _options$cache;
var predictNextSearch = options.predictNextSearch;
var renderItem = options.renderItem;
var renderCategory = options.renderCategory;
var blankSearch = options.blankSearch;
var appendTo = options.appendTo;
var anchor = options.anchor;
var debounce = options.debounce;
var caching = options.cache !== false;
if (!source) {
return;
}
var userGetText = options.getText;
var userGetValue = options.getValue;
var getText = typeof userGetText === 'string' ? function (d) {
return d[userGetText];
} : typeof userGetText === 'function' ? userGetText : function (d) {
return d.toString();
};
var getValue = typeof userGetValue === 'string' ? function (d) {
return d[userGetValue];
} : typeof userGetValue === 'function' ? userGetValue : function (d) {
return d;
};
var previousSuggestions = [];
var previousSelection = null;
var limit = Number(options.limit) || Infinity;
var completer = autocomplete(el, {
source: sourceFunction,
limit: limit,
getText: getText,
getValue: getValue,
setAppends: setAppends,
predictNextSearch: predictNextSearch,
renderItem: renderItem,
renderCategory: renderCategory,
appendTo: appendTo,
anchor: anchor,
noMatches: noMatches,
noMatchesText: options.noMatches,
blankSearch: blankSearch,
debounce: debounce,
set: function set(s) {
if (setAppends !== true) {
el.value = '';
}
previousSelection = s;
(_set || completer.defaultSetter)(getText(s), s);
completer.emit('afterSet');
},
filter: filter
});
return completer;
function noMatches(data) {
if (!options.noMatches) {
return false;
}
return data.query.length;
}
function sourceFunction(data, done) {
var query = data.query;
var limit = data.limit;
if (!options.blankSearch && query.length === 0) {
done(null, [], true);return;
}
if (completer) {
completer.emit('beforeUpdate');
}
var hash = (0, _hashSum2.default)(query); // fast, case insensitive, prevents collisions
if (caching) {
var entry = cache[hash];
if (entry) {
var start = entry.created.getTime();
var duration = cache.duration || 60 * 60 * 24;
var diff = duration * 1000;
var fresh = new Date(start + diff) > new Date();
if (fresh) {
done(null, entry.items.slice());return;
}
}
}
var sourceData = {
previousSuggestions: previousSuggestions.slice(),
previousSelection: previousSelection,
input: query,
renderItem: renderItem,
renderCategory: renderCategory,
limit: limit
};
if (typeof options.source === 'function') {
options.source(sourceData, sourced);
} else {
sourced(null, options.source);
}
function sourced(err, result) {
if (err) {
console.log('Autocomplete source error.', err, el);
done(err, []);
}
var items = Array.isArray(result) ? result : [];
if (caching) {
cache[hash] = { created: new Date(), items: items };
}
previousSuggestions = items;
done(null, items.slice());
}
}
}
function autocomplete(el) {
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var o = options;
var parent = o.appendTo || doc.body;
var getText = o.getText;
var getValue = o.getValue;
var form = o.form;
var source = o.source;
var noMatches = o.noMatches;
var noMatchesText = o.noMatchesText;
var _o$highlighter = o.highlighter;
var highlighter = _o$highlighter === undefined ? true : _o$highlighter;
var _o$highlightCompleteW = o.highlightCompleteWords;
var highlightCompleteWords = _o$highlightCompleteW === undefined ? true : _o$highlightCompleteW;
var _o$renderItem = o.renderItem;
var renderItem = _o$renderItem === undefined ? defaultItemRenderer : _o$renderItem;
var _o$renderCategory = o.renderCategory;
var renderCategory = _o$renderCategory === undefined ? defaultCategoryRenderer : _o$renderCategory;
var setAppends = o.setAppends;
var limit = typeof o.limit === 'number' ? o.limit : Infinity;
var userFilter = o.filter || defaultFilter;
var userSet = o.set || defaultSetter;
var categories = tag('div', 'sey-categories');
var container = tag('div', 'sey-container');
var deferredFiltering = defer(filtering);
var state = { counter: 0, query: null };
var categoryMap = Object.create(null);
var selection = null;
var eye = void 0;
var attachment = el;
var noneMatch = void 0;
var textInput = void 0;
var anyInput = void 0;
var ranchorleft = void 0;
var ranchorright = void 0;
var lastPrefix = '';
var debounceTime = o.debounce || 300;
var debouncedLoading = (0, _debounce2.default)(loading, debounceTime);
if (o.autoHideOnBlur === void 0) {
o.autoHideOnBlur = true;
}
if (o.autoHideOnClick === void 0) {
o.autoHideOnClick = true;
}
if (o.autoShowOnUpDown === void 0) {
o.autoShowOnUpDown = el.tagName === 'INPUT';
}
if (o.anchor) {
ranchorleft = new RegExp('^' + o.anchor);
ranchorright = new RegExp(o.anchor + '$');
}
var hasItems = false;
var api = (0, _emitter2.default)({
anchor: o.anchor,
clear: clear,
show: show,
hide: hide,
toggle: toggle,
destroy: destroy,
refreshPosition: refreshPosition,
appendText: appendText,
appendHTML: appendHTML,
filterAnchoredText: filterAnchoredText,
filterAnchoredHTML: filterAnchoredHTML,
defaultAppendText: appendText,
defaultFilter: defaultFilter,
defaultItemRenderer: defaultItemRenderer,
defaultCategoryRenderer: defaultCategoryRenderer,
defaultSetter: defaultSetter,
retarget: retarget,
attachment: attachment,
source: []
});
retarget(el);
container.appendChild(categories);
if (noMatches && noMatchesText) {
noneMatch = tag('div', 'sey-empty sey-hide');
text(noneMatch, noMatchesText);
container.appendChild(noneMatch);
}
parent.appendChild(container);
el.setAttribute('autocomplete', 'off');
if (Array.isArray(source)) {
loaded(source, false);
}
return api;
function retarget(el) {
inputEvents(true);
attachment = api.attachment = el;
textInput = attachment.tagName === 'INPUT' || attachment.tagName === 'TEXTAREA';
anyInput = textInput || isEditable(attachment);
inputEvents();
}
function refreshPosition() {
if (eye) {
eye.refresh();
}
}
function loading(forceShow) {
if (typeof source !== 'function') {
return;
}
_crossvent2.default.remove(attachment, 'focus', loading);
var query = readInput();
if (query === state.query) {
return;
}
hasItems = false;
state.query = query;
var counter = ++state.counter;
source({ query: query, limit: limit }, sourced);
function sourced(err, result, blankQuery) {
if (state.counter !== counter) {
return;
}
loaded(result, forceShow);
if (err || blankQuery) {
hasItems = false;
}
}
}
function loaded(categories, forceShow) {
clear();
hasItems = true;
api.source = [];
categories.forEach(function (cat) {
return cat.list.forEach(function (suggestion) {
return add(suggestion, cat);
});
});
if (forceShow) {
show();
}
filtering();
}
function clear() {
unselect();
while (categories.lastChild) {
categories.removeChild(categories.lastChild);
}
categoryMap = Object.create(null);
hasItems = false;
}
function readInput() {
return (textInput ? el.value : el.innerHTML).trim();
}
function getCategory(data) {
if (!data.id) {
data.id = 'default';
}
if (!categoryMap[data.id]) {
categoryMap[data.id] = createCategory();
}
return categoryMap[data.id];
function createCategory() {
var category = tag('div', 'sey-category');
var ul = tag('ul', 'sey-list');
renderCategory(category, data);
category.appendChild(ul);
categories.appendChild(category);
return { data: data, ul: ul };
}
}
function add(suggestion, categoryData) {
var cat = getCategory(categoryData);
var li = tag('li', 'sey-item');
renderItem(li, suggestion);
if (highlighter) {
breakupForHighlighter(li);
}
_crossvent2.default.add(li, 'mouseenter', hoverSuggestion);
_crossvent2.default.add(li, 'click', clickedSuggestion);
_crossvent2.default.add(li, 'horsey-filter', filterItem);
_crossvent2.default.add(li, 'horsey-hide', hideItem);
cat.ul.appendChild(li);
api.source.push(suggestion);
return li;
function hoverSuggestion() {
select(li);
}
function clickedSuggestion() {
var input = getText(suggestion);
set(suggestion);
hide();
attachment.focus();
lastPrefix = o.predictNextSearch && o.predictNextSearch({
input: input,
source: api.source.slice(),
selection: suggestion
}) || '';
if (lastPrefix) {
el.value = lastPrefix;
el.select();
show();
filtering();
}
}
function filterItem() {
var value = readInput();
if (filter(value, suggestion)) {
li.className = li.className.replace(/ sey-hide/g, '');
} else {
_crossvent2.default.fabricate(li, 'horsey-hide');
}
}
function hideItem() {
if (!hidden(li)) {
li.className += ' sey-hide';
if (selection === li) {
unselect();
}
}
}
}
function breakupForHighlighter(el) {
getTextChildren(el).forEach(function (el) {
var parent = el.parentElement;
var text = el.textContent || el.nodeValue || '';
if (text.length === 0) {
return;
}
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = text[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var char = _step.value;
parent.insertBefore(spanFor(char), el);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
parent.removeChild(el);
function spanFor(char) {
var span = doc.createElement('span');
span.className = 'sey-char';
span.textContent = span.innerText = char;
return span;
}
});
}
function highlight(el, needle) {
var rword = /[\s,._\[\]{}()-]/g;
var words = needle.split(rword).filter(function (w) {
return w.length;
});
var elems = [].concat(_toConsumableArray(el.querySelectorAll('.sey-char')));
var chars = void 0;
var startIndex = 0;
balance();
if (highlightCompleteWords) {
whole();
}
fuzzy();
clearRemainder();
function balance() {
chars = elems.map(function (el) {
return el.innerText || el.textContent;
});
}
function whole() {
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = words[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var word = _step2.value;
var tempIndex = startIndex;
retry: while (tempIndex !== -1) {
var init = true;
var prevIndex = tempIndex;
var _iteratorNormalCompletion3 = true;
var _didIteratorError3 = false;
var _iteratorError3 = undefined;
try {
for (var _iterator3 = word[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
var char = _step3.value;
var i = chars.indexOf(char, prevIndex + 1);
var fail = i === -1 || !init && prevIndex + 1 !== i;
if (init) {
init = false;
tempIndex = i;
}
if (fail) {
continue retry;
}
prevIndex = i;
}
} catch (err) {
_didIteratorError3 = true;
_iteratorError3 = err;
} finally {
try {
if (!_iteratorNormalCompletion3 && _iterator3.return) {
_iterator3.return();
}
} finally {
if (_didIteratorError3) {
throw _iteratorError3;
}
}
}
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = elems.splice(tempIndex, 1 + prevIndex - tempIndex)[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var _el = _step4.value;
on(_el);
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
balance();
needle = needle.replace(word, '');
break;
}
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
function fuzzy() {
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
for (var _iterator5 = needle[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var input = _step5.value;
while (elems.length) {
var _el2 = elems.shift();
if ((_el2.innerText || _el2.textContent) === input) {
on(_el2);
break;
} else {
off(_el2);
}
}
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
}
function clearRemainder() {
while (elems.length) {
off(elems.shift());
}
}
function on(ch) {
ch.classList.add('sey-char-highlight');
}
function off(ch) {
ch.classList.remove('sey-char-highlight');
}
}
function getTextChildren(el) {
var texts = [];
var walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
var node = void 0;
while (node = walker.nextNode()) {
texts.push(node);
}
return texts;
}
function set(value) {
if (o.anchor) {
return (isText() ? api.appendText : api.appendHTML)(getValue(value));
}
userSet(value);
}
function filter(value, suggestion) {
if (o.anchor) {
var il = (isText() ? api.filterAnchoredText : api.filterAnchoredHTML)(value, suggestion);
return il ? userFilter(il.input, il.suggestion) : false;
}
return userFilter(value, suggestion);
}
function isText() {
return isInput(attachment);
}
function visible() {
return container.className.indexOf('sey-show') !== -1;
}
function hidden(li) {
return li.className.indexOf('sey-hide') !== -1;
}
function show() {
eye.refresh();
if (!visible()) {
container.className += ' sey-show';
_crossvent2.default.fabricate(attachment, 'horsey-show');
}
}
function toggler(e) {
var left = e.which === 1 && !e.metaKey && !e.ctrlKey;
if (left === false) {
return; // we only care about honest to god left-clicks
}
toggle();
}
function toggle() {
if (!visible()) {
show();
} else {
hide();
}
}
function select(li) {
unselect();
if (li) {
selection = li;
selection.className += ' sey-selected';
}
}
function unselect() {
if (selection) {
selection.className = selection.className.replace(/ sey-selected/g, '');
selection = null;
}
}
function move(up, moves) {
var total = api.source.length;
if (total === 0) {
return;
}
if (moves > total) {
unselect();
return;
}
var cat = findCategory(selection) || categories.firstChild;
var first = up ? 'lastChild' : 'firstChild';
var last = up ? 'firstChild' : 'lastChild';
var next = up ? 'previousSibling' : 'nextSibling';
var prev = up ? 'nextSibling' : 'previousSibling';
var li = findNext();
select(li);
if (hidden(li)) {
move(up, moves ? moves + 1 : 1);
}
function findCategory(el) {
while (el) {
if (_sektor2.default.matchesSelector(el.parentElement, '.sey-category')) {
return el.parentElement;
}
el = el.parentElement;
}
return null;
}
function findNext() {
if (selection) {
if (selection[next]) {
return selection[next];
}
if (cat[next] && findList(cat[next])[first]) {
return findList(cat[next])[first];
}
}
return findList(categories[first])[first];
}
}
function hide() {
eye.sleep();
container.className = container.className.replace(/ sey-show/g, '');
unselect();
_crossvent2.default.fabricate(attachment, 'horsey-hide');
if (el.value === lastPrefix) {
el.value = '';
}
}
function keydown(e) {
var shown = visible();
var which = e.which || e.keyCode;
if (which === KEY_DOWN) {
if (anyInput && o.autoShowOnUpDown) {
show();
}
if (shown) {
move();
stop(e);
}
} else if (which === KEY_UP) {
if (anyInput && o.autoShowOnUpDown) {
show();
}
if (shown) {
move(true);
stop(e);
}
} else if (which === KEY_BACKSPACE) {
if (anyInput && o.autoShowOnUpDown) {
show();
}
} else if (shown) {
if (which === KEY_ENTER) {
if (selection) {
_crossvent2.default.fabricate(selection, 'click');
} else {
hide();
}
stop(e);
} else if (which === KEY_ESC) {
hide();
stop(e);
}
}
}
function stop(e) {
e.stopPropagation();
e.preventDefault();
}
function showNoResults() {
if (noneMatch) {
noneMatch.classList.remove('sey-hide');
}
}
function hideNoResults() {
if (noneMatch) {
noneMatch.classList.add('sey-hide');
}
}
function filtering() {
if (!visible()) {
return;
}
debouncedLoading(true);
_crossvent2.default.fabricate(attachment, 'horsey-filter');
var value = readInput();
if (!o.blankSearch && !value) {
hide();return;
}
var nomatch = noMatches({ query: value });
var count = walkCategories();
if (count === 0 && nomatch && hasItems) {
showNoResults();
} else {
hideNoResults();
}
if (!selection) {
move();
}
if (!selection && !nomatch) {
hide();
}
function walkCategories() {
var category = categories.firstChild;
var count = 0;
while (category) {
var list = findList(category);
var partial = walkCategory(list);
if (partial === 0) {
category.classList.add('sey-hide');
} else {
category.classList.remove('sey-hide');
}
count += partial;
category = category.nextSibling;
}
return count;
}
function walkCategory(ul) {
var li = ul.firstChild;
var count = 0;
while (li) {
if (count >= limit) {
_crossvent2.default.fabricate(li, 'horsey-hide');
} else {
_crossvent2.default.fabricate(li, 'horsey-filter');
if (li.className.indexOf('sey-hide') === -1) {
count++;
if (highlighter) {
highlight(li, value);
}
}
}
li = li.nextSibling;
}
return count;
}
}
function deferredFilteringNoEnter(e) {
var which = e.which || e.keyCode;
if (which === KEY_ENTER) {
return;
}
deferredFiltering();
}
function deferredShow(e) {
var which = e.which || e.keyCode;
if (which === KEY_ENTER || which === KEY_TAB) {
return;
}
setTimeout(show, 0);
}
function autocompleteEventTarget(e) {
var target = e.target;
if (target === attachment) {
return true;
}
while (target) {
if (target === container || target === attachment) {
return true;
}
target = target.parentNode;
}
}
function hideOnBlur(e) {
var which = e.which || e.keyCode;
if (which === KEY_TAB) {
hide();
}
}
function hideOnClick(e) {
if (autocompleteEventTarget(e)) {
return;
}
hide();
}
function inputEvents(remove) {
var op = remove ? 'remove' : 'add';
if (eye) {
eye.destroy();
eye = null;
}
if (!remove) {
eye = (0, _bullseye2.default)(container, attachment, {
caret: anyInput && attachment.tagName !== 'INPUT',
context: o.appendTo
});
if (!visible()) {
eye.sleep();
}
}
if (remove || anyInput && doc.activeElement !== attachment) {
_crossvent2.default[op](attachment, 'focus', loading);
} else {
loading();
}
if (anyInput) {
_crossvent2.default[op](attachment, 'keypress', deferredShow);
_crossvent2.default[op](attachment, 'keypress', deferredFiltering);
_crossvent2.default[op](attachment, 'keydown', deferredFilteringNoEnter);
_crossvent2.default[op](attachment, 'paste', deferredFiltering);
_crossvent2.default[op](attachment, 'keydown', keydown);
if (o.autoHideOnBlur) {
_crossvent2.default[op](attachment, 'keydown', hideOnBlur);
}
} else {
_crossvent2.default[op](attachment, 'click', toggler);
_crossvent2.default[op](docElement, 'keydown', keydown);
}
if (o.autoHideOnClick) {
_crossvent2.default[op](doc, 'click', hideOnClick);
}
if (form) {
_crossvent2.default[op](form, 'submit', hide);
}
}
function destroy() {
inputEvents(true);
if (parent.contains(container)) {
parent.removeChild(container);
}
}
function defaultSetter(value) {
if (textInput) {
if (setAppends === true) {
el.value += ' ' + value;
} else {
el.value = value;
}
} else {
if (setAppends === true) {
el.innerHTML += ' ' + value;
} else {
el.innerHTML = value;
}
}
}
function defaultItemRenderer(li, suggestion) {
text(li, getText(suggestion));
}
function defaultCategoryRenderer(div, data) {
if (data.id !== 'default') {
var id = tag('div', 'sey-category-id');
div.appendChild(id);
text(id, data.id);
}
}
function defaultFilter(q, suggestion) {
var needle = q.toLowerCase();
var text = getText(suggestion) || '';
if ((0, _fuzzysearch2.default)(needle, text.toLowerCase())) {
return true;
}
var value = getValue(suggestion) || '';
if (typeof value !== 'string') {
return false;
}
return (0, _fuzzysearch2.default)(needle, value.toLowerCase());
}
function loopbackToAnchor(text, p) {
var result = '';
var anchored = false;
var start = p.start;
while (anchored === false && start >= 0) {
result = text.substr(start - 1, p.start - start + 1);
anchored = ranchorleft.test(result);
start--;
}
return {
text: anchored ? result : null,
start: start
};
}
function filterAnchoredText(q, suggestion) {
var position = (0, _sell2.default)(el);
var input = loopbackToAnchor(q, position).text;
if (input) {
return { input: input, suggestion: suggestion };
}
}
function appendText(value) {
var current = el.value;
var position = (0, _sell2.default)(el);
var input = loopbackToAnchor(current, position);
var left = current.substr(0, input.start);
var right = current.substr(input.start + input.text.length + (position.end - position.start));
var before = left + value + ' ';
el.value = before + right;
(0, _sell2.default)(el, { start: before.length, end: before.length });
}
function filterAnchoredHTML() {
throw new Error('Anchoring in editable elements is disabled by default.');
}
function appendHTML() {
throw new Error('Anchoring in editable elements is disabled by default.');
}
function findList(category) {
return (0, _sektor2.default)('.sey-list', category)[0];
}
}
function isInput(el) {
return el.tagName === 'INPUT' || el.tagName === 'TEXTAREA';
}
function tag(type, className) {
var el = doc.createElement(type);
el.className = className;
return el;
}
function defer(fn) {
return function () {
setTimeout(fn, 0);
};
}
function text(el, value) {
el.innerText = el.textContent = value;
}
function isEditable(el) {
var value = el.getAttribute('contentEditable');
if (value === 'false') {
return false;
}
if (value === 'true') {
return true;
}
if (el.parentElement) {
return isEditable(el.parentElement);
}
return false;
}
module.exports = horsey;
},{"bullseye":3,"contra/emitter":7,"crossvent":8,"fuzzysearch":11,"hash-sum":12,"lodash/debounce":13,"sektor":20,"sell":29}],2:[function(require,module,exports){
module.exports = function atoa (a, n) { return Array.prototype.slice.call(a, n); }
},{}],3:[function(require,module,exports){
'use strict';
var crossvent = require('crossvent');
var throttle = require('./throttle');
var tailormade = require('./tailormade');
function bullseye (el, target, options) {
var o = options;
var domTarget = target && target.tagName;
if (!domTarget && arguments.length === 2) {
o = target;
}
if (!domTarget) {
target = el;
}
if (!o) { o = {}; }
var destroyed = false;
var throttledWrite = throttle(write, 30);
var tailorOptions = { update: o.autoupdateToCaret !== false && update };
var tailor = o.caret && tailormade(target, tailorOptions);
write();
if (o.tracking !== false) {
crossvent.add(window, 'resize', throttledWrite);
}
return {
read: readNull,
refresh: write,
destroy: destroy,
sleep: sleep
};
function sleep () {
tailorOptions.sleeping = true;
}
function readNull () { return read(); }
function read (readings) {
var bounds = target.getBoundingClientRect();
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
if (tailor) {
readings = tailor.read();
return {
x: (readings.absolute ? 0 : bounds.left) + readings.x,
y: (readings.absolute ? 0 : bounds.top) + scrollTop + readings.y + 20
};
}
return {
x: bounds.left,
y: bounds.top + scrollTop
};
}
function update (readings) {
write(readings);
}
function write (readings) {
if (destroyed) {
throw new Error('Bullseye can\'t refresh after being destroyed. Create another instance instead.');
}
if (tailor && !readings) {
tailorOptions.sleeping = false;
tailor.refresh(); return;
}
var p = read(readings);
if (!tailor && target !== el) {
p.y += target.offsetHeight;
}
var context = o.context;
el.style.left = p.x + 'px';
el.style.top = (context ? context.offsetHeight : p.y) + 'px';
}
function destroy () {
if (tailor) { tailor.destroy(); }
crossvent.remove(window, 'resize', throttledWrite);
destroyed = true;
}
}
module.exports = bullseye;
},{"./tailormade":4,"./throttle":5,"crossvent":8}],4:[function(require,module,exports){
(function (global){
'use strict';
var sell = require('sell');
var crossvent = require('crossvent');
var seleccion = require('seleccion');
var throttle = require('./throttle');
var getSelection = seleccion.get;
var props = [
'direction',
'boxSizing',
'width',
'height',
'overflowX',
'overflowY',
'borderTopWidth',
'borderRightWidth',
'borderBottomWidth',
'borderLeftWidth',
'paddingTop',
'paddingRight',
'paddingBottom',
'paddingLeft',
'fontStyle',
'fontVariant',
'fontWeight',
'fontStretch',
'fontSize',
'fontSizeAdjust',
'lineHeight',
'fontFamily',
'textAlign',
'textTransform',
'textIndent',
'textDecoration',
'letterSpacing',
'wordSpacing'
];
var win = global;
var doc = document;
var ff = win.mozInnerScreenX !== null && win.mozInnerScreenX !== void 0;
function tailormade (el, options) {
var textInput = el.tagName === 'INPUT' || el.tagName === 'TEXTAREA';
var throttledRefresh = throttle(refresh, 30);
var o = options || {};
bind();
return {
read: readPosition,
refresh: throttledRefresh,
destroy: destroy
};
function noop () {}
function readPosition () { return (textInput ? coordsText : coordsHTML)(); }
function refresh () {
if (o.sleeping) {
return;
}
return (o.update || noop)(readPosition());
}
function coordsText () {
var p = sell(el);
var context = prepare();
var readings = readTextCoords(context, p.start);
doc.body.removeChild(context.mirror);
return readings;
}
function coordsHTML () {
var sel = getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
var needsToWorkAroundNewlineBug = range.startContainer.nodeName === 'P' && range.startOffset === 0;
if (needsToWorkAroundNewlineBug) {
return {
x: range.startContainer.offsetLeft,
y: range.startContainer.offsetTop,
absolute: true
};
}
if (range.getClientRects) {
var rects = range.getClientRects();
if (rects.length > 0) {
return {
x: rects[0].left,
y: rects[0].top,
absolute: true
};
}
}
}
return { x: 0, y: 0 };
}
function readTextCoords (context, p) {
var rest = doc.createElement('span');
var mirror = context.mirror;
var computed = context.computed;
write(mirror, read(el).substring(0, p));
if (el.tagName === 'INPUT') {
mirror.textContent = mirror.textContent.replace(/\s/g, '\u00a0');
}
write(rest, read(el).substring(p) || '.');
mirror.appendChild(rest);
return {
x: rest.offsetLeft + parseInt(computed['borderLeftWidth']),
y: rest.offsetTop + parseInt(computed['borderTopWidth'])
};
}
function read (el) {
return textInput ? el.value : el.innerHTML;
}
function prepare () {
var computed = win.getComputedStyle ? getComputedStyle(el) : el.currentStyle;
var mirror = doc.createElement('div');
var style = mirror.style;
doc.body.appendChild(mirror);
if (el.tagName !== 'INPUT') {
style.wordWrap = 'break-word';
}
style.whiteSpace = 'pre-wrap';
style.position = 'absolute';
style.visibility = 'hidden';
props.forEach(copy);
if (ff) {
style.width = parseInt(computed.width) - 2 + 'px';
if (el.scrollHeight > parseInt(computed.height)) {
style.overflowY = 'scroll';
}
} else {
style.overflow = 'hidden';
}
return { mirror: mirror, computed: computed };
function copy (prop) {
style[prop] = computed[prop];
}
}
function write (el, value) {
if (textInput) {
el.textContent = value;
} else {
el.innerHTML = value;
}
}
function bind (remove) {
var op = remove ? 'remove' : 'add';
crossvent[op](el, 'keydown', throttledRefresh);
crossvent[op](el, 'keyup', throttledRefresh);
crossvent[op](el, 'input', throttledRefresh);
crossvent[op](el, 'paste', throttledRefresh);
crossvent[op](el, 'change', throttledRefresh);
}
function destroy () {
bind(true);
}
}
module.exports = tailormade;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./throttle":5,"crossvent":8,"seleccion":27,"sell":29}],5:[function(require,module,exports){
'use strict';
function throttle (fn, boundary) {
var last = -Infinity;
var timer;
return function bounced () {
if (timer) {
return;
}
unbound();
function unbound () {
clearTimeout(timer);
timer = null;
var next = last + boundary;
var now = Date.now();
if (now > next) {
last = now;
fn();
} else {
timer = setTimeout(unbound, next - now);
}
}
};
}
module.exports = throttle;
},{}],6:[function(require,module,exports){
'use strict';
var ticky = require('ticky');
module.exports = function debounce (fn, args, ctx) {
if (!fn) { return; }
ticky(function run () {
fn.apply(ctx || null, args || []);
});
};
},{"ticky":30}],7:[function(require,module,exports){
'use strict';
var atoa = require('atoa');
var debounce = require('./debounce');
module.exports = function emitter (thing, options) {
var opts = options || {};
var evt = {};
if (thing === undefined) { thing = {}; }
thing.on = function (type, fn) {
if (!evt[type]) {
evt[type] = [fn];
} else {
evt[type].push(fn);
}
return thing;
};
thing.once = function (type, fn) {
fn._once = true; // thing.off(fn) still works!
thing.on(type, fn);
return thing;
};
thing.off = function (type, fn) {
var c = arguments.length;
if (c === 1) {
delete evt[type];
} else if (c === 0) {
evt = {};
} else {
var et = evt[type];
if (!et) { return thing; }
et.splice(et.indexOf(fn), 1);
}
return thing;
};
thing.emit = function () {
var args = atoa(arguments);
return thing.emitterSnapshot(args.shift()).apply(this, args);
};
thing.emitterSnapshot = function (type) {
var et = (evt[type] || []).slice(0);
return function () {
var args = atoa(arguments);
var ctx = this || thing;
if (type === 'error' && opts.throws !== false && !et.length) { throw args.length === 1 ? args[0] : args; }
et.forEach(function emitter (listen) {
if (opts.async) { debounce(listen, args, ctx); } else { listen.apply(ctx, args); }
if (listen._once) { thing.off(type, listen); }
});
return thing;
};
};
return thing;
};
},{"./debounce":6,"atoa":2}],8:[function(require,module,exports){
(function (global){
'use strict';
var customEvent = require('custom-event');
var eventmap = require('./eventmap');
var doc = global.document;
var addEvent = addEventEasy;
var removeEvent = removeEventEasy;
var hardCache = [];
if (!global.addEventListener) {
addEvent = addEventHard;
removeEvent = removeEventHard;
}
module.exports = {
add: addEvent,
remove: removeEvent,
fabricate: fabricateEvent
};
function addEventEasy (el, type, fn, capturing) {
return el.addEventListener(type, fn, capturing);
}
function addEventHard (el, type, fn) {
return el.attachEvent('on' + type, wrap(el, type, fn));
}
function removeEventEasy (el, type, fn, capturing) {
return el.removeEventListener(type, fn, capturing);
}
function removeEventHard (el, type, fn) {
var listener = unwrap(el, type, fn);
if (listener) {
return el.detachEvent('on' + type, listener);
}
}
function fabricateEvent (el, type, model) {
var e = eventmap.indexOf(type) === -1 ? makeCustomEvent() : makeClassicEvent();
if (el.dispatchEvent) {
el.dispatchEvent(e);
} else {
el.fireEvent('on' + type, e);
}
function makeClassicEvent () {
var e;
if (doc.createEvent) {
e = doc.createEvent('Event');
e.initEvent(type, true, true);
} else if (doc.createEventObject) {
e = doc.createEventObject();
}
return e;
}
function makeCustomEvent () {
return new customEvent(type, { detail: model });
}
}
function wrapperFactory (el, type, fn) {
return function wrapper (originalEvent) {
var e = originalEvent || global.event;
e.target = e.target || e.srcElement;
e.preventDefault = e.preventDefault || function preventDefault () { e.returnValue = false; };
e.stopPropagation = e.stopPropagation || function stopPropagation () { e.cancelBubble = true; };
e.which = e.which || e.keyCode;
fn.call(el, e);
};
}
function wrap (el, type, fn) {
var wrapper = unwrap(el, type, fn) || wrapperFactory(el, type, fn);
hardCache.push({
wrapper: wrapper,
element: el,
type: type,
fn: fn
});
return wrapper;
}
function unwrap (el, type, fn) {
var i = find(el, type, fn);
if (i) {
var wrapper = hardCache[i].wrapper;
hardCache.splice(i, 1); // free up a tad of memory
return wrapper;
}
}
function find (el, type, fn) {
var i, item;
for (i = 0; i < hardCache.length; i++) {
item = hardCache[i];
if (item.element === el && item.type === type && item.fn === fn) {
return i;
}
}
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./eventmap":9,"custom-event":10}],9:[function(require,module,exports){
(function (global){
'use strict';
var eventmap = [];
var eventname = '';
var ron = /^on/;
for (eventname in global) {
if (ron.test(eventname)) {
eventmap.push(eventname.slice(2));
}
}
module.exports = eventmap;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],10:[function(require,module,exports){
(function (global){
var NativeCustomEvent = global.CustomEvent;
function useNative () {
try {
var p = new NativeCustomEvent('cat', { detail: { foo: 'bar' } });
return 'cat' === p.type && 'bar' === p.detail.foo;
} catch (e) {
}
return false;
}
/**
* Cross-browser `CustomEvent` constructor.
*
* https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent.CustomEvent
*
* @public
*/
module.exports = useNative() ? NativeCustomEvent :
// IE >= 9
'function' === typeof document.createEvent ? function CustomEvent (type, params) {
var e = document.createEvent('CustomEvent');
if (params) {
e.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
} else {
e.initCustomEvent(type, false, false, void 0);
}
return e;
} :
// IE <= 8
function CustomEvent (type, params) {
var e = document.createEventObject();
e.type = type;
if (params) {
e.bubbles = Boolean(params.bubbles);
e.cancelable = Boolean(params.cancelable);
e.detail = params.detail;
} else {
e.bubbles = false;
e.cancelable = false;
e.detail = void 0;
}
return e;
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],11:[function(require,module,exports){
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
module.exports = fuzzysearch;
},{}],12:[function(require,module,exports){
'use strict';
function pad (hash, len) {
while (hash.length < len) {
hash = '0' + hash;
}
return hash;
}
function fold (hash, text) {
var i;
var chr;
var len;
if (text.length === 0) {
return hash;
}
for (i = 0, len = text.length; i < len; i++) {
chr = text.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0;
}
return hash < 0 ? hash * -2 : hash;
}
function foldObject (hash, o, seen) {
return Object.keys(o).sort().reduce(foldKey, hash);
function foldKey (hash, key) {
return foldValue(hash, o[key], key, seen);
}
}
function foldValue (input, value, key, seen) {
var hash = fold(fold(fold(input, key), toString(value)), typeof value);
if (value === null) {
return fold(hash, 'null');
}
if (value === undefined) {
return fold(hash, 'undefined');
}
if (typeof value === 'object') {
if (seen.indexOf(value) !== -1) {
return fold(hash, '[Circular]' + key);
}
seen.push(value);
return foldObject(hash, value, seen);
}
return fold(hash, value.toString());
}
function toString (o) {
return Object.prototype.toString.call(o);
}
function sum (o) {
return pad(foldValue(0, o, '', []).toString(16), 8);
}
module.exports = sum;
},{}],13:[function(require,module,exports){
var isObject = require('./isObject'),
now = require('./now'),
toNumber = require('./toNumber');
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* Provide an options object to indicate whether `func` should be invoked on
* the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
* with the last arguments provided to the debounced function. Subsequent calls
* to the debounced function return the result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
* on the trailing edge of the timeout only if the debounced function is
* invoked more than once during the `wait` timeout.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // Avoid costly calculations while the window size is in flux.
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
* jQuery(element).on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
* jQuery(source).on('message', debounced);
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime,
lastInvokeTime = 0,
leading = false,
maxing = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
maxing = 'maxWait' in options;
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs,
thisArg = lastThis;
lastArgs = lastThis = undefined;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time;
// Start the timer for the trailing edge.
timerId = setTimeout(timerExpired, wait);
// Invoke the leading edge.
return leading ? invokeFunc(time) : result;
}
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
result = wait - timeSinceLastCall;
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
}
function shouldInvoke(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
}
function timerExpired() {
var time = now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = undefined;
return result;
}
function cancel() {
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge(now());
}
function debounced() {
var time = now(),
isInvoking = shouldInvoke(time);
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime);
}
if (maxing) {
// Handle invocations in a tight loop.
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
module.exports = debounce;
},{"./isObject":15,"./now":18,"./toNumber":19}],14:[function(require,module,exports){
var isObject = require('./isObject');
/** `Object#toString` result references. */
var funcTag = '[object Function]',
genTag = '[object GeneratorFunction]';
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified,
* else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 8 which returns 'object' for typed array and weak map constructors,
// and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
var tag = isObject(value) ? objectToString.call(value) : '';
return tag == funcTag || tag == genTag;
}
module.exports = isFunction;
},{"./isObject":15}],15:[function(require,module,exports){
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
module.exports = isObject;
},{}],16:[function(require,module,exports){
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
module.exports = isObjectLike;
},{}],17:[function(require,module,exports){
var isObjectLike = require('./isObjectLike');
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified,
* else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && objectToString.call(value) == symbolTag);
}
module.exports = isSymbol;
},{"./isObjectLike":16}],18:[function(require,module,exports){
/**
* Gets the timestamp of the number of milliseconds that have elapsed since
* the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @since 2.4.0
* @category Date
* @returns {number} Returns the timestamp.
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => Logs the number of milliseconds it took for the deferred invocation.
*/
function now() {
return Date.now();
}
module.exports = now;
},{}],19:[function(require,module,exports){
var isFunction = require('./isFunction'),
isObject = require('./isObject'),
isSymbol = require('./isSymbol');
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** Used to match leading and trailing whitespace. */
var reTrim = /^\s+|\s+$/g;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/**
* Converts `value` to a number.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* @example
*
* _.toNumber(3.2);
* // => 3.2
*
* _.toNumber(Number.MIN_VALUE);
* // => 5e-324
*
* _.toNumber(Infinity);
* // => Infinity
*
* _.toNumber('3.2');
* // => 3.2
*/
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = isFunction(value.valueOf) ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = value.replace(reTrim, '');
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
module.exports = toNumber;
},{"./isFunction":14,"./isObject":15,"./isSymbol":17}],20:[function(require,module,exports){
(function (global){
'use strict';
var expando = 'sektor-' + Date.now();
var rsiblings = /[+~]/;
var document = global.document;
var del = document.documentElement || {};
var match = (
del.matches ||
del.webkitMatchesSelector ||
del.mozMatchesSelector ||
del.oMatchesSelector ||
del.msMatchesSelector ||
never
);
module.exports = sektor;
sektor.matches = matches;
sektor.matchesSelector = matchesSelector;
function qsa (selector, context) {
var existed, id, prefix, prefixed, adapter, hack = context !== document;
if (hack) { // id hack for context-rooted queries
existed = context.getAttribute('id');
id = existed || expando;
prefix = '#' + id + ' ';
prefixed = prefix + selector.replace(/,/g, ',' + prefix);
adapter = rsiblings.test(selector) && context.parentNode;
if (!existed) { context.setAttribute('id', id); }
}
try {
return (adapter || context).querySelectorAll(prefixed || selector);
} catch (e) {
return [];
} finally {
if (existed === null) { context.removeAttribute('id'); }
}
}
function sektor (selector, ctx, collection, seed) {
var element;
var context = ctx || document;
var results = collection || [];
var i = 0;
if (typeof selector !== 'string') {
return results;
}
if (context.nodeType !== 1 && context.nodeType !== 9) {
return []; // bail if context is not an element or document
}
if (seed) {
while ((element = seed[i++])) {
if (matchesSelector(element, selector)) {
results.push(element);
}
}
} else {
results.push.apply(results, qsa(selector, context));
}
return results;
}
function matches (selector, elements) {
return sektor(selector, null, null, elements);
}
function matchesSelector (element, selector) {
return match.call(element, selector);
}
function never () { return false; }
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],21:[function(require,module,exports){
(function (global){
'use strict';
var getSelection;
var doc = global.document;
var getSelectionRaw = require('./getSelectionRaw');
var getSelectionNullOp = require('./getSelectionNullOp');
var getSelectionSynthetic = require('./getSelectionSynthetic');
var isHost = require('./isHost');
if (isHost.method(global, 'getSelection')) {
getSelection = getSelectionRaw;
} else if (typeof doc.selection === 'object' && doc.selection) {
getSelection = getSelectionSynthetic;
} else {
getSelection = getSelectionNullOp;
}
module.exports = getSelection;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./getSelectionNullOp":22,"./getSelectionRaw":23,"./getSelectionSynthetic":24,"./isHost":25}],22:[function(require,module,exports){
'use strict';
function noop () {}
function getSelectionNullOp () {
return {
removeAllRanges: noop,
addRange: noop
};
}
module.exports = getSelectionNullOp;
},{}],23:[function(require,module,exports){
(function (global){
'use strict';
function getSelectionRaw () {
return global.getSelection();
}
module.exports = getSelectionRaw;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],24:[function(require,module,exports){
(function (global){
'use strict';
var rangeToTextRange = require('./rangeToTextRange');
var doc = global.document;
var body = doc.body;
var GetSelectionProto = GetSelection.prototype;
function GetSelection (selection) {
var self = this;
var range = selection.createRange();
this._selection = selection;
this._ranges = [];
if (selection.type === 'Control') {
updateControlSelection(self);
} else if (isTextRange(range)) {
updateFromTextRange(self, range);
} else {
updateEmptySelection(self);
}
}
GetSelectionProto.removeAllRanges = function () {
var textRange;
try {
this._selection.empty();
if (this._selection.type !== 'None') {
textRange = body.createTextRange();
textRange.select();
this._selection.empty();
}
} catch (e) {
}
updateEmptySelection(this);
};
GetSelectionProto.addRange = function (range) {
if (this._selection.type === 'Control') {
addRangeToControlSelection(this, range);
} else {
rangeToTextRange(range).select();
this._ranges[0] = range;
this.rangeCount = 1;
this.isCollapsed = this._ranges[0].collapsed;
updateAnchorAndFocusFromRange(this, range, false);
}
};
GetSelectionProto.setRanges = function (ranges) {
this.removeAllRanges();
var rangeCount = ranges.length;
if (rangeCount > 1) {
createControlSelection(this, ranges);
} else if (rangeCount) {
this.addRange(ranges[0]);
}
};
GetSelectionProto.getRangeAt = function (index) {
if (index < 0 || index >= this.rangeCount) {
throw new Error('getRangeAt(): index out of bounds');
} else {
return this._ranges[index].cloneRange();
}
};
GetSelectionProto.removeRange = function (range) {
if (this._selection.type !== 'Control') {
removeRangeManually(this, range);
return;
}
var controlRange = this._selection.createRange();
var rangeElement = getSingleElementFromRange(range);
var newControlRange = body.createControlRange();
var el;
var removed = false;
for (var i = 0, len = controlRange.length; i < len; ++i) {
el = controlRange.item(i);
if (el !== rangeElement || removed) {
newControlRange.add(controlRange.item(i));
} else {
removed = true;
}
}
newControlRange.select();
updateControlSelection(this);
};
GetSelectionProto.eachRange = function (fn, returnValue) {
var i = 0;
var len = this._ranges.length;
for (i = 0; i < len; ++i) {
if (fn(this.getRangeAt(i))) {
return returnValue;
}
}
};
GetSelectionProto.getAllRanges = function () {
var ranges = [];
this.eachRange(function (range) {
ranges.push(range);
});
return ranges;
};
GetSelectionProto.setSingleRange = function (range) {
this.removeAllRanges();
this.addRange(range);
};
function createControlSelection (sel, ranges) {
var controlRange = body.createControlRange();
for (var i = 0, el, len = ranges.length; i < len; ++i) {
el = getSingleElementFromRange(ranges[i]);
try {
controlRange.add(el);
} catch (e) {
throw new Error('setRanges(): Element could not be added to control selection');
}
}
controlRange.select();
updateControlSelection(sel);
}
function removeRangeManually (sel, range) {
var ranges = sel.getAllRanges();
sel.removeAllRanges();
for (var i = 0, len = ranges.length; i < len; ++i) {
if (!isSameRange(range, ranges[i])) {
sel.addRange(ranges[i]);
}
}
if (!sel.rangeCount) {
updateEmptySelection(sel);
}
}
function updateAnchorAndFocusFromRange (sel, range) {
var anchorPrefix = 'start';
var focusPrefix = 'end';
sel.anchorNode = range[anchorPrefix + 'Container'];
sel.anchorOffset = range[anchorPrefix + 'Offset'];
sel.focusNode = range[focusPrefix + 'Container'];
sel.focusOffset = range[focusPrefix + 'Offset'];
}
function updateEmptySelection (sel) {
sel.anchorNode = sel.focusNode = null;
sel.anchorOffset = sel.focusOffset = 0;
sel.rangeCount = 0;
sel.isCollapsed = true;
sel._ranges.length = 0;
}
function rangeContainsSingleElement (rangeNodes) {
if (!rangeNodes.length || rangeNodes[0].nodeType !== 1) {
return false;
}
for (var i = 1, len = rangeNodes.length; i < len; ++i) {
if (!isAncestorOf(rangeNodes[0], rangeNodes[i])) {
return false;
}
}
return true;
}
function getSingleElementFromRange (range) {
var nodes = range.getNodes();
if (!rangeContainsSingleElement(nodes)) {
throw new Error('getSingleElementFromRange(): range did not consist of a single element');
}
return nodes[0];
}
function isTextRange (range) {
return range && range.text !== void 0;
}
function updateFromTextRange (sel, range) {
sel._ranges = [range];
updateAnchorAndFocusFromRange(sel, range, false);
sel.rangeCount = 1;
sel.isCollapsed = range.collapsed;
}
function updateControlSelection (sel) {
sel._ranges.length = 0;
if (sel._selection.type === 'None') {
updateEmptySelection(sel);
} else {
var controlRange = sel._selection.createRange();
if (isTextRange(controlRange)) {
updateFromTextRange(sel, controlRange);
} else {
sel.rangeCount = controlRange.length;
var range;
for (var i = 0; i < sel.rangeCount; ++i) {
range = doc.createRange();
range.selectNode(controlRange.item(i));
sel._ranges.push(range);
}
sel.isCollapsed = sel.rangeCount === 1 && sel._ranges[0].collapsed;
updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);
}
}
}
function addRangeToControlSelection (sel, range) {
var controlRange = sel._selection.createRange();
var rangeElement = getSingleElementFromRange(range);
var newControlRange = body.createControlRange();
for (var i = 0, len = controlRange.length; i < len; ++i) {
newControlRange.add(controlRange.item(i));
}
try {
newControlRange.add(rangeElement);
} catch (e) {
throw new Error('addRange(): Element could not be added to control selection');
}
newControlRange.select();
updateControlSelection(sel);
}
function isSameRange (left, right) {
return (
left.startContainer === right.startContainer &&
left.startOffset === right.startOffset &&
left.endContainer === right.endContainer &&
left.endOffset === right.endOffset
);
}
function isAncestorOf (ancestor, descendant) {
var node = descendant;
while (node.parentNode) {
if (node.parentNode === ancestor) {
return true;
}
node = node.parentNode;
}
return false;
}
function getSelection () {
return new GetSelection(global.document.selection);
}
module.exports = getSelection;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./rangeToTextRange":26}],25:[function(require,module,exports){
'use strict';
function isHostMethod (host, prop) {
var type = typeof host[prop];
return type === 'function' || !!(type === 'object' && host[prop]) || type === 'unknown';
}
function isHostProperty (host, prop) {
return typeof host[prop] !== 'undefined';
}
function many (fn) {
return function areHosted (host, props) {
var i = props.length;
while (i--) {
if (!fn(host, props[i])) {
return false;
}
}
return true;
};
}
module.exports = {
method: isHostMethod,
methods: many(isHostMethod),
property: isHostProperty,
properties: many(isHostProperty)
};
},{}],26:[function(require,module,exports){
(function (global){
'use strict';
var doc = global.document;
var body = doc.body;
function rangeToTextRange (p) {
if (p.collapsed) {
return createBoundaryTextRange({ node: p.startContainer, offset: p.startOffset }, true);
}
var startRange = createBoundaryTextRange({ node: p.startContainer, offset: p.startOffset }, true);
var endRange = createBoundaryTextRange({ node: p.endContainer, offset: p.endOffset }, false);
var textRange = body.createTextRange();
textRange.setEndPoint('StartToStart', startRange);
textRange.setEndPoint('EndToEnd', endRange);
return textRange;
}
function isCharacterDataNode (node) {
var t = node.nodeType;
return t === 3 || t === 4 || t === 8 ;
}
function createBoundaryTextRange (p, starting) {
var bound;
var parent;
var offset = p.offset;
var workingNode;
var childNodes;
var range = body.createTextRange();
var data = isCharacterDataNode(p.node);
if (data) {
bound = p.node;
parent = bound.parentNode;
} else {
childNodes = p.node.childNodes;
bound = offset < childNodes.length ? childNodes[offset] : null;
parent = p.node;
}
workingNode = doc.createElement('span');
workingNode.innerHTML = '&#feff;';
if (bound) {
parent.insertBefore(workingNode, bound);
} else {
parent.appendChild(workingNode);
}
range.moveToElementText(workingNode);
range.collapse(!starting);
parent.removeChild(workingNode);
if (data) {
range[starting ? 'moveStart' : 'moveEnd']('character', offset);
}
return range;
}
module.exports = rangeToTextRange;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],27:[function(require,module,exports){
'use strict';
var getSelection = require('./getSelection');
var setSelection = require('./setSelection');
module.exports = {
get: getSelection,
set: setSelection
};
},{"./getSelection":21,"./setSelection":28}],28:[function(require,module,exports){
(function (global){
'use strict';
var getSelection = require('./getSelection');
var rangeToTextRange = require('./rangeToTextRange');
var doc = global.document;
function setSelection (p) {
if (doc.createRange) {
modernSelection();
} else {
oldSelection();
}
function modernSelection () {
var sel = getSelection();
var range = doc.createRange();
if (!p.startContainer) {
return;
}
if (p.endContainer) {
range.setEnd(p.endContainer, p.endOffset);
} else {
range.setEnd(p.startContainer, p.startOffset);
}
range.setStart(p.startContainer, p.startOffset);
sel.removeAllRanges();
sel.addRange(range);
}
function oldSelection () {
rangeToTextRange(p).select();
}
}
module.exports = setSelection;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./getSelection":21,"./rangeToTextRange":26}],29:[function(require,module,exports){
'use strict';
var get = easyGet;
var set = easySet;
if (document.selection && document.selection.createRange) {
get = hardGet;
set = hardSet;
}
function easyGet (el) {
return {
start: el.selectionStart,
end: el.selectionEnd
};
}
function hardGet (el) {
var active = document.activeElement;
if (active !== el) {
el.focus();
}
var range = document.selection.createRange();
var bookmark = range.getBookmark();
var original = el.value;
var marker = getUniqueMarker(original);
var parent = range.parentElement();
if (parent === null || !inputs(parent)) {
return result(0, 0);
}
range.text = marker + range.text + marker;
var contents = el.value;
el.value = original;
range.moveToBookmark(bookmark);
range.select();
return result(contents.indexOf(marker), contents.lastIndexOf(marker) - marker.length);
function result (start, end) {
if (active !== el) { // don't disrupt pre-existing state
if (active) {
active.focus();
} else {
el.blur();
}
}
return { start: start, end: end };
}
}
function getUniqueMarker (contents) {
var marker;
do {
marker = '@@marker.' + Math.random() * new Date();
} while (contents.indexOf(marker) !== -1);
return marker;
}
function inputs (el) {
return ((el.tagName === 'INPUT' && el.type === 'text') || el.tagName === 'TEXTAREA');
}
function easySet (el, p) {
el.selectionStart = parse(el, p.start);
el.selectionEnd = parse(el, p.end);
}
function hardSet (el, p) {
var range = el.createTextRange();
if (p.start === 'end' && p.end === 'end') {
range.collapse(false);
range.select();
} else {
range.collapse(true);
range.moveEnd('character', parse(el, p.end));
range.moveStart('character', parse(el, p.start));
range.select();
}
}
function parse (el, value) {
return value === 'end' ? el.value.length : value || 0;
}
function sell (el, p) {
if (arguments.length === 2) {
set(el, p);
}
return get(el);
}
module.exports = sell;
},{}],30:[function(require,module,exports){
var si = typeof setImmediate === 'function', tick;
if (si) {
tick = function (fn) { setImmediate(fn); };
} else {
tick = function (fn) { setTimeout(fn, 0); };
}
module.exports = tick;
},{}]},{},[1])(1)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJob3JzZXkuanMiLCJub2RlX21vZHVsZXMvYXRvYS9hdG9hLmpzIiwibm9kZV9tb2R1bGVzL2J1bGxzZXllL2J1bGxzZXllLmpzIiwibm9kZV9tb2R1bGVzL2J1bGxzZXllL3RhaWxvcm1hZGUuanMiLCJub2RlX21vZHVsZXMvYnVsbHNleWUvdGhyb3R0bGUuanMiLCJub2RlX21vZHVsZXMvY29udHJhL2RlYm91bmNlLmpzIiwibm9kZV9tb2R1bGVzL2NvbnRyYS9lbWl0dGVyLmpzIiwibm9kZV9tb2R1bGVzL2Nyb3NzdmVudC9zcmMvY3Jvc3N2ZW50LmpzIiwibm9kZV9tb2R1bGVzL2Nyb3NzdmVudC9zcmMvZXZlbnRtYXAuanMiLCJub2RlX21vZHVsZXMvY3VzdG9tLWV2ZW50L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Z1enp5c2VhcmNoL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2hhc2gtc3VtL2hhc2gtc3VtLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9kZWJvdW5jZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNTeW1ib2wuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdG9OdW1iZXIuanMiLCJub2RlX21vZHVsZXMvc2VrdG9yL3NyYy9zZWt0b3IuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb25OdWxsT3AuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb25SYXcuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb25TeW50aGV0aWMuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9pc0hvc3QuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9yYW5nZVRvVGV4dFJhbmdlLmpzIiwibm9kZV9tb2R1bGVzL3NlbGVjY2lvbi9zcmMvc2VsZWNjaW9uLmpzIiwibm9kZV9tb2R1bGVzL3NlbGVjY2lvbi9zcmMvc2V0U2VsZWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3NlbGwvc2VsbC5qcyIsIm5vZGVfbW9kdWxlcy90aWNreS90aWNreS1icm93c2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7QUFDQSxJQUFNLGdCQUFnQixDQUF0QjtBQUNBLElBQU0sWUFBWSxFQUFsQjtBQUNBLElBQU0sVUFBVSxFQUFoQjtBQUNBLElBQU0sU0FBUyxFQUFmO0FBQ0EsSUFBTSxXQUFXLEVBQWpCO0FBQ0EsSUFBTSxVQUFVLENBQWhCO0FBQ0EsSUFBTSxNQUFNLFFBQVo7QUFDQSxJQUFNLGFBQWEsSUFBSSxlQUF2Qjs7QUFFQSxTQUFTLE1BQVQsQ0FBaUIsRUFBakIsRUFBbUM7QUFBQSxNQUFkLE9BQWMseURBQUosRUFBSTtBQUFBLE1BRS9CLFVBRitCLEdBYzdCLE9BZDZCLENBRS9CLFVBRitCO0FBQUEsTUFHL0IsSUFIK0IsR0FjN0IsT0FkNkIsQ0FHL0IsR0FIK0I7QUFBQSxNQUkvQixNQUorQixHQWM3QixPQWQ2QixDQUkvQixNQUorQjtBQUFBLE1BSy9CLE1BTCtCLEdBYzdCLE9BZDZCLENBSy9CLE1BTCtCO0FBQUEsdUJBYzdCLE9BZDZCLENBTS9CLEtBTitCO0FBQUEsTUFNL0IsS0FOK0Isa0NBTXZCLEVBTnVCO0FBQUEsTUFPL0IsaUJBUCtCLEdBYzdCLE9BZDZCLENBTy9CLGlCQVArQjtBQUFBLE1BUS9CLFVBUitCLEdBYzdCLE9BZDZCLENBUS9CLFVBUitCO0FBQUEsTUFTL0IsY0FUK0IsR0FjN0IsT0FkNkIsQ0FTL0IsY0FUK0I7QUFBQSxNQVUvQixXQVYrQixHQWM3QixPQWQ2QixDQVUvQixXQVYrQjtBQUFBLE1BVy9CLFFBWCtCLEdBYzdCLE9BZDZCLENBVy9CLFFBWCtCO0FBQUEsTUFZL0IsTUFaK0IsR0FjN0IsT0FkNkIsQ0FZL0IsTUFaK0I7QUFBQSxNQWEvQixRQWIrQixHQWM3QixPQWQ2QixDQWEvQixRQWIrQjs7QUFlakMsTUFBTSxVQUFVLFFBQVEsS0FBUixLQUFrQixLQUFsQztBQUNBLE1BQUksQ0FBQyxNQUFMLEVBQWE7QUFDWDtBQUNEOztBQUVELE1BQU0sY0FBYyxRQUFRLE9BQTVCO0FBQ0EsTUFBTSxlQUFlLFFBQVEsUUFBN0I7QUFDQSxNQUFNLFVBQ0osT0FBTyxXQUFQLEtBQXVCLFFBQXZCLEdBQWtDO0FBQUEsV0FBSyxFQUFFLFdBQUYsQ0FBTDtBQUFBLEdBQWxDLEdBQ0EsT0FBTyxXQUFQLEtBQXVCLFVBQXZCLEdBQW9DLFdBQXBDLEdBQ0E7QUFBQSxXQUFLLEVBQUUsUUFBRixFQUFMO0FBQUEsR0FIRjtBQUtBLE1BQU0sV0FDSixPQUFPLFlBQVAsS0FBd0IsUUFBeEIsR0FBbUM7QUFBQSxXQUFLLEVBQUUsWUFBRixDQUFMO0FBQUEsR0FBbkMsR0FDQSxPQUFPLFlBQVAsS0FBd0IsVUFBeEIsR0FBcUMsWUFBckMsR0FDQTtBQUFBLFdBQUssQ0FBTDtBQUFBLEdBSEY7O0FBTUEsTUFBSSxzQkFBc0IsRUFBMUI7QUFDQSxNQUFJLG9CQUFvQixJQUF4QjtBQUNBLE1BQU0sUUFBUSxPQUFPLFFBQVEsS0FBZixLQUF5QixRQUF2QztBQUNBLE1BQU0sWUFBWSxhQUFhLEVBQWIsRUFBaUI7QUFDakMsWUFBUSxjQUR5QjtBQUVqQyxnQkFGaUM7QUFHakMsb0JBSGlDO0FBSWpDLHNCQUppQztBQUtqQywwQkFMaUM7QUFNakMsd0NBTmlDO0FBT2pDLDBCQVBpQztBQVFqQyxrQ0FSaUM7QUFTakMsc0JBVGlDO0FBVWpDLGtCQVZpQztBQVdqQyx3QkFYaUM7QUFZakMsbUJBQWUsUUFBUSxTQVpVO0FBYWpDLDRCQWJpQztBQWNqQyxzQkFkaUM7QUFlakMsT0FmaUMsZUFlNUIsQ0FmNEIsRUFlekI7QUFDTixVQUFJLGVBQWUsSUFBbkIsRUFBeUI7QUFDdkIsV0FBRyxLQUFILEdBQVcsRUFBWDtBQUNEO0FBQ0QsMEJBQW9CLENBQXBCO0FBQ0EsT0FBQyxRQUFPLFVBQVUsYUFBbEIsRUFBaUMsUUFBUSxDQUFSLENBQWpDLEVBQTZDLENBQTdDO0FBQ0EsZ0JBQVUsSUFBVixDQUFlLFVBQWY7QUFDRCxLQXRCZ0M7O0FBdUJqQztBQXZCaUMsR0FBakIsQ0FBbEI7QUF5QkEsU0FBTyxTQUFQO0FBQ0EsV0FBUyxTQUFULENBQW9CLElBQXBCLEVBQTBCO0FBQ3hCLFFBQUksQ0FBQyxRQUFRLFNBQWIsRUFBd0I7QUFDdEIsYUFBTyxLQUFQO0FBQ0Q7QUFDRCxXQUFPLEtBQUssS0FBTCxDQUFXLE1BQWxCO0FBQ0Q7QUFDRCxXQUFTLGNBQVQsQ0FBeUIsSUFBekIsRUFBK0IsSUFBL0IsRUFBcUM7QUFBQSxRQUM1QixLQUQ0QixHQUNaLElBRFksQ0FDNUIsS0FENEI7QUFBQSxRQUNyQixLQURxQixHQUNaLElBRFksQ0FDckIsS0FEcUI7O0FBRW5DLFFBQUksQ0FBQyxRQUFRLFdBQVQsSUFBd0IsTUFBTSxNQUFOLEtBQWlCLENBQTdDLEVBQWdEO0FBQzlDLFdBQUssSUFBTCxFQUFXLEVBQVgsRUFBZSxJQUFmLEVBQXNCO0FBQ3ZCO0FBQ0QsUUFBSSxTQUFKLEVBQWU7QUFDYixnQkFBVSxJQUFWLENBQWUsY0FBZjtBQUNEO0FBQ0QsUUFBTSxPQUFPLHVCQUFJLEtBQUosQ0FBYixDO0FBQ0EsUUFBSSxPQUFKLEVBQWE7QUFDWCxVQUFNLFFBQVEsTUFBTSxJQUFOLENBQWQ7QUFDQSxVQUFJLEtBQUosRUFBVztBQUNULFlBQU0sUUFBUSxNQUFNLE9BQU4sQ0FBYyxPQUFkLEVBQWQ7QUFDQSxZQUFNLFdBQVcsTUFBTSxRQUFOLElBQWtCLEtBQUssRUFBTCxHQUFVLEVBQTdDO0FBQ0EsWUFBTSxPQUFPLFdBQVcsSUFBeEI7QUFDQSxZQUFNLFFBQVEsSUFBSSxJQUFKLENBQVMsUUFBUSxJQUFqQixJQUF5QixJQUFJLElBQUosRUFBdkM7QUFDQSxZQUFJLEtBQUosRUFBVztBQUNULGVBQUssSUFBTCxFQUFXLE1BQU0sS0FBTixDQUFZLEtBQVosRUFBWCxFQUFpQztBQUNsQztBQUNGO0FBQ0Y7QUFDRCxRQUFJLGFBQWE7QUFDZiwyQkFBcUIsb0JBQW9CLEtBQXBCLEVBRE47QUFFZiwwQ0FGZTtBQUdmLGFBQU8sS0FIUTtBQUlmLDRCQUplO0FBS2Ysb0NBTGU7QUFNZjtBQU5lLEtBQWpCO0FBUUEsUUFBSSxPQUFPLFFBQVEsTUFBZixLQUEwQixVQUE5QixFQUEwQztBQUN4QyxjQUFRLE1BQVIsQ0FBZSxVQUFmLEVBQTJCLE9BQTNCO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsY0FBUSxJQUFSLEVBQWMsUUFBUSxNQUF0QjtBQUNEO0FBQ0QsYUFBUyxPQUFULENBQWtCLEdBQWxCLEVBQXVCLE1BQXZCLEVBQStCO0FBQzdCLFVBQUksR0FBSixFQUFTO0FBQ1AsZ0JBQVEsR0FBUixDQUFZLDRCQUFaLEVBQTBDLEdBQTFDLEVBQStDLEVBQS9DO0FBQ0EsYUFBSyxHQUFMLEVBQVUsRUFBVjtBQUNEO0FBQ0QsVUFBTSxRQUFRLE1BQU0sT0FBTixDQUFjLE1BQWQsSUFBd0IsTUFBeEIsR0FBaUMsRUFBL0M7QUFDQSxVQUFJLE9BQUosRUFBYTtBQUNYLGNBQU0sSUFBTixJQUFjLEVBQUUsU0FBUyxJQUFJLElBQUosRUFBWCxFQUF1QixZQUF2QixFQUFkO0FBQ0Q7QUFDRCw0QkFBc0IsS0FBdEI7QUFDQSxXQUFLLElBQUwsRUFBVyxNQUFNLEtBQU4sRUFBWDtBQUNEO0FBQ0Y7QUFDRjs7QUFFRCxTQUFTLFlBQVQsQ0FBdUIsRUFBdkIsRUFBeUM7QUFBQSxNQUFkLE9BQWMseURBQUosRUFBSTs7QUFDdkMsTUFBTSxJQUFJLE9BQVY7QUFDQSxNQUFNLFNBQVMsRUFBRSxRQUFGLElBQWMsSUFBSSxJQUFqQztBQUZ1QyxNQUlyQyxPQUpxQyxHQWVuQyxDQWZtQyxDQUlyQyxPQUpxQztBQUFBLE1BS3JDLFFBTHFDLEdBZW5DLENBZm1DLENBS3JDLFFBTHFDO0FBQUEsTUFNckMsSUFOcUMsR0FlbkMsQ0FmbUMsQ0FNckMsSUFOcUM7QUFBQSxNQU9yQyxNQVBxQyxHQWVuQyxDQWZtQyxDQU9yQyxNQVBxQztBQUFBLE1BUXJDLFNBUnFDLEdBZW5DLENBZm1DLENBUXJDLFNBUnFDO0FBQUEsTUFTckMsYUFUcUMsR0FlbkMsQ0FmbUMsQ0FTckMsYUFUcUM7QUFBQSx1QkFlbkMsQ0FmbUMsQ0FVckMsV0FWcUM7QUFBQSxNQVVyQyxXQVZxQyxrQ0FVdkIsSUFWdUI7QUFBQSw4QkFlbkMsQ0FmbUMsQ0FXckMsc0JBWHFDO0FBQUEsTUFXckMsc0JBWHFDLHlDQVdaLElBWFk7QUFBQSxzQkFlbkMsQ0FmbUMsQ0FZckMsVUFacUM7QUFBQSxNQVlyQyxVQVpxQyxpQ0FZeEIsbUJBWndCO0FBQUEsMEJBZW5DLENBZm1DLENBYXJDLGNBYnFDO0FBQUEsTUFhckMsY0FicUMscUNBYXBCLHVCQWJvQjtBQUFBLE1BY3JDLFVBZHFDLEdBZW5DLENBZm1DLENBY3JDLFVBZHFDOztBQWdCdkMsTUFBTSxRQUFRLE9BQU8sRUFBRSxLQUFULEtBQW1CLFFBQW5CLEdBQThCLEVBQUUsS0FBaEMsR0FBd0MsUUFBdEQ7QUFDQSxNQUFNLGFBQWEsRUFBRSxNQUFGLElBQVksYUFBL0I7QUFDQSxNQUFNLFVBQVUsRUFBRSxHQUFGLElBQVMsYUFBekI7QUFDQSxNQUFNLGFBQWEsSUFBSSxLQUFKLEVBQVcsZ0JBQVgsQ0FBbkI7QUFDQSxNQUFNLFlBQVksSUFBSSxLQUFKLEVBQVcsZUFBWCxDQUFsQjtBQUNBLE1BQU0sb0JBQW9CLE1BQU0sU0FBTixDQUExQjtBQUNBLE1BQU0sUUFBUSxFQUFFLFNBQVMsQ0FBWCxFQUFjLE9BQU8sSUFBckIsRUFBZDtBQUNBLE1BQUksY0FBYyxPQUFPLE1BQVAsQ0FBYyxJQUFkLENBQWxCO0FBQ0EsTUFBSSxZQUFZLElBQWhCO0FBQ0EsTUFBSSxZQUFKO0FBQ0EsTUFBSSxhQUFhLEVBQWpCO0FBQ0EsTUFBSSxrQkFBSjtBQUNBLE1BQUksa0JBQUo7QUFDQSxNQUFJLGlCQUFKO0FBQ0EsTUFBSSxvQkFBSjtBQUNBLE1BQUkscUJBQUo7QUFDQSxNQUFJLGFBQWEsRUFBakI7QUFDQSxNQUFNLGVBQWUsRUFBRSxRQUFGLElBQWMsR0FBbkM7QUFDQSxNQUFNLG1CQUFtQix3QkFBUyxPQUFULEVBQWtCLFlBQWxCLENBQXpCOztBQUVBLE1BQUksRUFBRSxjQUFGLEtBQXFCLEtBQUssQ0FBOUIsRUFBaUM7QUFBRSxNQUFFLGNBQUYsR0FBbUIsSUFBbkI7QUFBMEI7QUFDN0QsTUFBSSxFQUFFLGVBQUYsS0FBc0IsS0FBSyxDQUEvQixFQUFrQztBQUFFLE1BQUUsZUFBRixHQUFvQixJQUFwQjtBQUEyQjtBQUMvRCxNQUFJLEVBQUUsZ0JBQUYsS0FBdUIsS0FBSyxDQUFoQyxFQUFtQztBQUFFLE1BQUUsZ0JBQUYsR0FBcUIsR0FBRyxPQUFILEtBQWUsT0FBcEM7QUFBOEM7QUFDbkYsTUFBSSxFQUFFLE1BQU4sRUFBYztBQUNaLGtCQUFjLElBQUksTUFBSixDQUFXLE1BQU0sRUFBRSxNQUFuQixDQUFkO0FBQ0EsbUJBQWUsSUFBSSxNQUFKLENBQVcsRUFBRSxNQUFGLEdBQVcsR0FBdEIsQ0FBZjtBQUNEOztBQUVELE1BQUksV0FBVyxLQUFmO0FBQ0EsTUFBTSxNQUFNLHVCQUFRO0FBQ2xCLFlBQVEsRUFBRSxNQURRO0FBRWxCLGdCQUZrQjtBQUdsQixjQUhrQjtBQUlsQixjQUprQjtBQUtsQixrQkFMa0I7QUFNbEIsb0JBTmtCO0FBT2xCLG9DQVBrQjtBQVFsQiwwQkFSa0I7QUFTbEIsMEJBVGtCO0FBVWxCLDBDQVZrQjtBQVdsQiwwQ0FYa0I7QUFZbEIsdUJBQW1CLFVBWkQ7QUFhbEIsZ0NBYmtCO0FBY2xCLDRDQWRrQjtBQWVsQixvREFma0I7QUFnQmxCLGdDQWhCa0I7QUFpQmxCLHNCQWpCa0I7QUFrQmxCLDBCQWxCa0I7QUFtQmxCLFlBQVE7QUFuQlUsR0FBUixDQUFaOztBQXNCQSxXQUFTLEVBQVQ7QUFDQSxZQUFVLFdBQVYsQ0FBc0IsVUFBdEI7QUFDQSxNQUFJLGFBQWEsYUFBakIsRUFBZ0M7QUFDOUIsZ0JBQVksSUFBSSxLQUFKLEVBQVcsb0JBQVgsQ0FBWjtBQUNBLFNBQUssU0FBTCxFQUFnQixhQUFoQjtBQUNBLGNBQVUsV0FBVixDQUFzQixTQUF0QjtBQUNEO0FBQ0QsU0FBTyxXQUFQLENBQW1CLFNBQW5CO0FBQ0EsS0FBRyxZQUFILENBQWdCLGNBQWhCLEVBQWdDLEtBQWhDOztBQUVBLE1BQUksTUFBTSxPQUFOLENBQWMsTUFBZCxDQUFKLEVBQTJCO0FBQ3pCLFdBQU8sTUFBUCxFQUFlLEtBQWY7QUFDRDs7QUFFRCxTQUFPLEdBQVA7O0FBRUEsV0FBUyxRQUFULENBQW1CLEVBQW5CLEVBQXVCO0FBQ3JCLGdCQUFZLElBQVo7QUFDQSxpQkFBYSxJQUFJLFVBQUosR0FBaUIsRUFBOUI7QUFDQSxnQkFBWSxXQUFXLE9BQVgsS0FBdUIsT0FBdkIsSUFBa0MsV0FBVyxPQUFYLEtBQXVCLFVBQXJFO0FBQ0EsZUFBVyxhQUFhLFdBQVcsVUFBWCxDQUF4QjtBQUNBO0FBQ0Q7O0FBRUQsV0FBUyxlQUFULEdBQTRCO0FBQzFCLFFBQUksR0FBSixFQUFTO0FBQUUsVUFBSSxPQUFKO0FBQWdCO0FBQzVCOztBQUVELFdBQVMsT0FBVCxDQUFrQixTQUFsQixFQUE2QjtBQUMzQixRQUFJLE9BQU8sTUFBUCxLQUFrQixVQUF0QixFQUFrQztBQUNoQztBQUNEO0FBQ0Qsd0JBQVUsTUFBVixDQUFpQixVQUFqQixFQUE2QixPQUE3QixFQUFzQyxPQUF0QztBQUNBLFFBQU0sUUFBUSxXQUFkO0FBQ0EsUUFBSSxVQUFVLE1BQU0sS0FBcEIsRUFBMkI7QUFDekI7QUFDRDtBQUNELGVBQVcsS0FBWDtBQUNBLFVBQU0sS0FBTixHQUFjLEtBQWQ7O0FBRUEsUUFBTSxVQUFVLEVBQUUsTUFBTSxPQUF4Qjs7QUFFQSxXQUFPLEVBQUUsWUFBRixFQUFTLFlBQVQsRUFBUCxFQUF5QixPQUF6Qjs7QUFFQSxhQUFTLE9BQVQsQ0FBa0IsR0FBbEIsRUFBdUIsTUFBdkIsRUFBK0IsVUFBL0IsRUFBMkM7QUFDekMsVUFBSSxNQUFNLE9BQU4sS0FBa0IsT0FBdEIsRUFBK0I7QUFDN0I7QUFDRDtBQUNELGFBQU8sTUFBUCxFQUFlLFNBQWY7QUFDQSxVQUFJLE9BQU8sVUFBWCxFQUF1QjtBQUNyQixtQkFBVyxLQUFYO0FBQ0Q7QUFDRjtBQUNGOztBQUVELFdBQVMsTUFBVCxDQUFpQixVQUFqQixFQUE2QixTQUE3QixFQUF3QztBQUN0QztBQUNBLGVBQVcsSUFBWDtBQUNBLFFBQUksTUFBSixHQUFhLEVBQWI7QUFDQSxlQUFXLE9BQVgsQ0FBbUI7QUFBQSxhQUFPLElBQUksSUFBSixDQUFTLE9BQVQsQ0FBaUI7QUFBQSxlQUFjLElBQUksVUFBSixFQUFnQixHQUFoQixDQUFkO0FBQUEsT0FBakIsQ0FBUDtBQUFBLEtBQW5CO0FBQ0EsUUFBSSxTQUFKLEVBQWU7QUFDYjtBQUNEO0FBQ0Q7QUFDRDs7QUFFRCxXQUFTLEtBQVQsR0FBa0I7QUFDaEI7QUFDQSxXQUFPLFdBQVcsU0FBbEIsRUFBNkI7QUFDM0IsaUJBQVcsV0FBWCxDQUF1QixXQUFXLFNBQWxDO0FBQ0Q7QUFDRCxrQkFBYyxPQUFPLE1BQVAsQ0FBYyxJQUFkLENBQWQ7QUFDQSxlQUFXLEtBQVg7QUFDRDs7QUFFRCxXQUFTLFNBQVQsR0FBc0I7QUFDcEIsV0FBTyxDQUFDLFlBQVksR0FBRyxLQUFmLEdBQXVCLEdBQUcsU0FBM0IsRUFBc0MsSUFBdEMsRUFBUDtBQUNEOztBQUVELFdBQVMsV0FBVCxDQUFzQixJQUF0QixFQUE0QjtBQUMxQixRQUFJLENBQUMsS0FBSyxFQUFWLEVBQWM7QUFDWixXQUFLLEVBQUwsR0FBVSxTQUFWO0FBQ0Q7QUFDRCxRQUFJLENBQUMsWUFBWSxLQUFLLEVBQWpCLENBQUwsRUFBMkI7QUFDekIsa0JBQVksS0FBSyxFQUFqQixJQUF1QixnQkFBdkI7QUFDRDtBQUNELFdBQU8sWUFBWSxLQUFLLEVBQWpCLENBQVA7QUFDQSxhQUFTLGNBQVQsR0FBMkI7QUFDekIsVUFBTSxXQUFXLElBQUksS0FBSixFQUFXLGNBQVgsQ0FBakI7QUFDQSxVQUFNLEtBQUssSUFBSSxJQUFKLEVBQVUsVUFBVixDQUFYO0FBQ0EscUJBQWUsUUFBZixFQUF5QixJQUF6QjtBQUNBLGVBQVMsV0FBVCxDQUFxQixFQUFyQjtBQUNBLGlCQUFXLFdBQVgsQ0FBdUIsUUFBdkI7QUFDQSxhQUFPLEVBQUUsVUFBRixFQUFRLE1BQVIsRUFBUDtBQUNEO0FBQ0Y7O0FBRUQsV0FBUyxHQUFULENBQWMsVUFBZCxFQUEwQixZQUExQixFQUF3QztBQUN0QyxRQUFNLE1BQU0sWUFBWSxZQUFaLENBQVo7QUFDQSxRQUFNLEtBQUssSUFBSSxJQUFKLEVBQVUsVUFBVixDQUFYO0FBQ0EsZUFBVyxFQUFYLEVBQWUsVUFBZjtBQUNBLFFBQUksV0FBSixFQUFpQjtBQUNmLDRCQUFzQixFQUF0QjtBQUNEO0FBQ0Qsd0JBQVUsR0FBVixDQUFjLEVBQWQsRUFBa0IsWUFBbEIsRUFBZ0MsZUFBaEM7QUFDQSx3QkFBVSxHQUFWLENBQWMsRUFBZCxFQUFrQixPQUFsQixFQUEyQixpQkFBM0I7QUFDQSx3QkFBVSxHQUFWLENBQWMsRUFBZCxFQUFrQixlQUFsQixFQUFtQyxVQUFuQztBQUNBLHdCQUFVLEdBQVYsQ0FBYyxFQUFkLEVBQWtCLGFBQWxCLEVBQWlDLFFBQWpDO0FBQ0EsUUFBSSxFQUFKLENBQU8sV0FBUCxDQUFtQixFQUFuQjtBQUNBLFFBQUksTUFBSixDQUFXLElBQVgsQ0FBZ0IsVUFBaEI7QUFDQSxXQUFPLEVBQVA7O0FBRUEsYUFBUyxlQUFULEdBQTRCO0FBQzFCLGFBQU8sRUFBUDtBQUNEOztBQUVELGFBQVMsaUJBQVQsR0FBOEI7QUFDNUIsVUFBTSxRQUFRLFFBQVEsVUFBUixDQUFkO0FBQ0EsVUFBSSxVQUFKO0FBQ0E7QUFDQSxpQkFBVyxLQUFYO0FBQ0EsbUJBQWEsRUFBRSxpQkFBRixJQUF1QixFQUFFLGlCQUFGLENBQW9CO0FBQ3RELGVBQU8sS0FEK0M7QUFFdEQsZ0JBQVEsSUFBSSxNQUFKLENBQVcsS0FBWCxFQUY4QztBQUd0RCxtQkFBVztBQUgyQyxPQUFwQixDQUF2QixJQUlQLEVBSk47QUFLQSxVQUFJLFVBQUosRUFBZ0I7QUFDZCxXQUFHLEtBQUgsR0FBVyxVQUFYO0FBQ0EsV0FBRyxNQUFIO0FBQ0E7QUFDQTtBQUNEO0FBQ0Y7O0FBRUQsYUFBUyxVQUFULEdBQXVCO0FBQ3JCLFVBQU0sUUFBUSxXQUFkO0FBQ0EsVUFBSSxPQUFPLEtBQVAsRUFBYyxVQUFkLENBQUosRUFBK0I7QUFDN0IsV0FBRyxTQUFILEdBQWUsR0FBRyxTQUFILENBQWEsT0FBYixDQUFxQixZQUFyQixFQUFtQyxFQUFuQyxDQUFmO0FBQ0QsT0FGRCxNQUVPO0FBQ0wsNEJBQVUsU0FBVixDQUFvQixFQUFwQixFQUF3QixhQUF4QjtBQUNEO0FBQ0Y7O0FBRUQsYUFBUyxRQUFULEdBQXFCO0FBQ25CLFVBQUksQ0FBQyxPQUFPLEVBQVAsQ0FBTCxFQUFpQjtBQUNmLFdBQUcsU0FBSCxJQUFnQixXQUFoQjtBQUNBLFlBQUksY0FBYyxFQUFsQixFQUFzQjtBQUNwQjtBQUNEO0FBQ0Y7QUFDRjtBQUNGOztBQUVELFdBQVMscUJBQVQsQ0FBZ0MsRUFBaEMsRUFBb0M7QUFDbEMsb0JBQWdCLEVBQWhCLEVBQW9CLE9BQXBCLENBQTRCLGNBQU07QUFDaEMsVUFBTSxTQUFTLEdBQUcsYUFBbEI7QUFDQSxVQUFNLE9BQU8sR0FBRyxXQUFILElBQWtCLEdBQUcsU0FBckIsSUFBa0MsRUFBL0M7QUFDQSxVQUFJLEtBQUssTUFBTCxLQUFnQixDQUFwQixFQUF1QjtBQUNyQjtBQUNEO0FBTCtCO0FBQUE7QUFBQTs7QUFBQTtBQU1oQyw2QkFBaUIsSUFBakIsOEhBQXVCO0FBQUEsY0FBZCxJQUFjOztBQUNyQixpQkFBTyxZQUFQLENBQW9CLFFBQVEsSUFBUixDQUFwQixFQUFtQyxFQUFuQztBQUNEO0FBUitCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7O0FBU2hDLGFBQU8sV0FBUCxDQUFtQixFQUFuQjtBQUNBLGVBQVMsT0FBVCxDQUFrQixJQUFsQixFQUF3QjtBQUN0QixZQUFNLE9BQU8sSUFBSSxhQUFKLENBQWtCLE1BQWxCLENBQWI7QUFDQSxhQUFLLFNBQUwsR0FBaUIsVUFBakI7QUFDQSxhQUFLLFdBQUwsR0FBbUIsS0FBSyxTQUFMLEdBQWlCLElBQXBDO0FBQ0EsZUFBTyxJQUFQO0FBQ0Q7QUFDRixLQWhCRDtBQWlCRDs7QUFFRCxXQUFTLFNBQVQsQ0FBb0IsRUFBcEIsRUFBd0IsTUFBeEIsRUFBZ0M7QUFDOUIsUUFBTSxRQUFRLG1CQUFkO0FBQ0EsUUFBTSxRQUFRLE9BQU8sS0FBUCxDQUFhLEtBQWIsRUFBb0IsTUFBcEIsQ0FBMkI7QUFBQSxhQUFLLEVBQUUsTUFBUDtBQUFBLEtBQTNCLENBQWQ7QUFDQSxRQUFNLHFDQUFZLEdBQUcsZ0JBQUgsQ0FBb0IsV0FBcEIsQ0FBWixFQUFOO0FBQ0EsUUFBSSxjQUFKO0FBQ0EsUUFBSSxhQUFhLENBQWpCOztBQUVBO0FBQ0EsUUFBSSxzQkFBSixFQUE0QjtBQUMxQjtBQUNEO0FBQ0Q7QUFDQTs7QUFFQSxhQUFTLE9BQVQsR0FBb0I7QUFDbEIsY0FBUSxNQUFNLEdBQU4sQ0FBVTtBQUFBLGVBQU0sR0FBRyxTQUFILElBQWdCLEdBQUcsV0FBekI7QUFBQSxPQUFWLENBQVI7QUFDRDs7QUFFRCxhQUFTLEtBQVQsR0FBa0I7QUFBQTtBQUFBO0FBQUE7O0FBQUE7QUFDaEIsOEJBQWlCLEtBQWpCLG1JQUF3QjtBQUFBLGNBQWYsSUFBZTs7QUFDdEIsY0FBSSxZQUFZLFVBQWhCO0FBQ0EsaUJBQU8sT0FBTyxjQUFjLENBQUMsQ0FBdEIsRUFBeUI7QUFDOUIsZ0JBQUksT0FBTyxJQUFYO0FBQ0EsZ0JBQUksWUFBWSxTQUFoQjtBQUY4QjtBQUFBO0FBQUE7O0FBQUE7QUFHOUIsb0NBQWlCLElBQWpCLG1JQUF1QjtBQUFBLG9CQUFkLElBQWM7O0FBQ3JCLG9CQUFNLElBQUksTUFBTSxPQUFOLENBQWMsSUFBZCxFQUFvQixZQUFZLENBQWhDLENBQVY7QUFDQSxvQkFBTSxPQUFPLE1BQU0sQ0FBQyxDQUFQLElBQWEsQ0FBQyxJQUFELElBQVMsWUFBWSxDQUFaLEtBQWtCLENBQXJEO0FBQ0Esb0JBQUksSUFBSixFQUFVO0FBQ1IseUJBQU8sS0FBUDtBQUNBLDhCQUFZLENBQVo7QUFDRDtBQUNELG9CQUFJLElBQUosRUFBVTtBQUNSLDJCQUFTLEtBQVQ7QUFDRDtBQUNELDRCQUFZLENBQVo7QUFDRDtBQWQ2QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQUE7QUFBQTs7QUFBQTtBQWU5QixvQ0FBZSxNQUFNLE1BQU4sQ0FBYSxTQUFiLEVBQXdCLElBQUksU0FBSixHQUFnQixTQUF4QyxDQUFmLG1JQUFtRTtBQUFBLG9CQUExRCxHQUEwRDs7QUFDakUsbUJBQUcsR0FBSDtBQUNEO0FBakI2QjtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOztBQWtCOUI7QUFDQSxxQkFBUyxPQUFPLE9BQVAsQ0FBZSxJQUFmLEVBQXFCLEVBQXJCLENBQVQ7QUFDQTtBQUNEO0FBQ0Y7QUF6QmU7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQTBCakI7O0FBRUQsYUFBUyxLQUFULEdBQWtCO0FBQUE7QUFBQTtBQUFBOztBQUFBO0FBQ2hCLDhCQUFrQixNQUFsQixtSUFBMEI7QUFBQSxjQUFqQixLQUFpQjs7QUFDeEIsaUJBQU8sTUFBTSxNQUFiLEVBQXFCO0FBQ25CLGdCQUFJLE9BQUssTUFBTSxLQUFOLEVBQVQ7QUFDQSxnQkFBSSxDQUFDLEtBQUcsU0FBSCxJQUFnQixLQUFHLFdBQXBCLE1BQXFDLEtBQXpDLEVBQWdEO0FBQzlDLGlCQUFHLElBQUg7QUFDQTtBQUNELGFBSEQsTUFHTztBQUNMLGtCQUFJLElBQUo7QUFDRDtBQUNGO0FBQ0Y7QUFYZTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBWWpCOztBQUVELGFBQVMsY0FBVCxHQUEyQjtBQUN6QixhQUFPLE1BQU0sTUFBYixFQUFxQjtBQUNuQixZQUFJLE1BQU0sS0FBTixFQUFKO0FBQ0Q7QUFDRjs7QUFFRCxhQUFTLEVBQVQsQ0FBYSxFQUFiLEVBQWlCO0FBQ2YsU0FBRyxTQUFILENBQWEsR0FBYixDQUFpQixvQkFBakI7QUFDRDtBQUNELGFBQVMsR0FBVCxDQUFjLEVBQWQsRUFBa0I7QUFDaEIsU0FBRyxTQUFILENBQWEsTUFBYixDQUFvQixvQkFBcEI7QUFDRDtBQUNGOztBQUVELFdBQVMsZUFBVCxDQUEwQixFQUExQixFQUE4QjtBQUM1QixRQUFNLFFBQVEsRUFBZDtBQUNBLFFBQU0sU0FBUyxTQUFTLGdCQUFULENBQTBCLEVBQTFCLEVBQThCLFdBQVcsU0FBekMsRUFBb0QsSUFBcEQsRUFBMEQsS0FBMUQsQ0FBZjtBQUNBLFFBQUksYUFBSjtBQUNBLFdBQU8sT0FBTyxPQUFPLFFBQVAsRUFBZCxFQUFpQztBQUMvQixZQUFNLElBQU4sQ0FBVyxJQUFYO0FBQ0Q7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFFRCxXQUFTLEdBQVQsQ0FBYyxLQUFkLEVBQXFCO0FBQ25CLFFBQUksRUFBRSxNQUFOLEVBQWM7QUFDWixhQUFPLENBQUMsV0FBVyxJQUFJLFVBQWYsR0FBNEIsSUFBSSxVQUFqQyxFQUE2QyxTQUFTLEtBQVQsQ0FBN0MsQ0FBUDtBQUNEO0FBQ0QsWUFBUSxLQUFSO0FBQ0Q7O0FBRUQsV0FBUyxNQUFULENBQWlCLEtBQWpCLEVBQXdCLFVBQXhCLEVBQW9DO0FBQ2xDLFFBQUksRUFBRSxNQUFOLEVBQWM7QUFDWixVQUFNLEtBQUssQ0FBQyxXQUFXLElBQUksa0JBQWYsR0FBb0MsSUFBSSxrQkFBekMsRUFBNkQsS0FBN0QsRUFBb0UsVUFBcEUsQ0FBWDtBQUNBLGFBQU8sS0FBSyxXQUFXLEdBQUcsS0FBZCxFQUFxQixHQUFHLFVBQXhCLENBQUwsR0FBMkMsS0FBbEQ7QUFDRDtBQUNELFdBQU8sV0FBVyxLQUFYLEVBQWtCLFVBQWxCLENBQVA7QUFDRDs7QUFFRCxXQUFTLE1BQVQsR0FBbUI7QUFBRSxXQUFPLFFBQVEsVUFBUixDQUFQO0FBQTZCO0FBQ2xELFdBQVMsT0FBVCxHQUFvQjtBQUFFLFdBQU8sVUFBVSxTQUFWLENBQW9CLE9BQXBCLENBQTRCLFVBQTVCLE1BQTRDLENBQUMsQ0FBcEQ7QUFBd0Q7QUFDOUUsV0FBUyxNQUFULENBQWlCLEVBQWpCLEVBQXFCO0FBQUUsV0FBTyxHQUFHLFNBQUgsQ0FBYSxPQUFiLENBQXFCLFVBQXJCLE1BQXFDLENBQUMsQ0FBN0M7QUFBaUQ7O0FBRXhFLFdBQVMsSUFBVCxHQUFpQjtBQUNmLFFBQUksT0FBSjtBQUNBLFFBQUksQ0FBQyxTQUFMLEVBQWdCO0FBQ2QsZ0JBQVUsU0FBVixJQUF1QixXQUF2QjtBQUNBLDBCQUFVLFNBQVYsQ0FBb0IsVUFBcEIsRUFBZ0MsYUFBaEM7QUFDRDtBQUNGOztBQUVELFdBQVMsT0FBVCxDQUFrQixDQUFsQixFQUFxQjtBQUNuQixRQUFNLE9BQU8sRUFBRSxLQUFGLEtBQVksQ0FBWixJQUFpQixDQUFDLEVBQUUsT0FBcEIsSUFBK0IsQ0FBQyxFQUFFLE9BQS9DO0FBQ0EsUUFBSSxTQUFTLEtBQWIsRUFBb0I7QUFDbEIsYTtBQUNEO0FBQ0Q7QUFDRDs7QUFFRCxXQUFTLE1BQVQsR0FBbUI7QUFDakIsUUFBSSxDQUFDLFNBQUwsRUFBZ0I7QUFDZDtBQUNELEtBRkQsTUFFTztBQUNMO0FBQ0Q7QUFDRjs7QUFFRCxXQUFTLE1BQVQsQ0FBaUIsRUFBakIsRUFBcUI7QUFDbkI7QUFDQSxRQUFJLEVBQUosRUFBUTtBQUNOLGtCQUFZLEVBQVo7QUFDQSxnQkFBVSxTQUFWLElBQXVCLGVBQXZCO0FBQ0Q7QUFDRjs7QUFFRCxXQUFTLFFBQVQsR0FBcUI7QUFDbkIsUUFBSSxTQUFKLEVBQWU7QUFDYixnQkFBVSxTQUFWLEdBQXNCLFVBQVUsU0FBVixDQUFvQixPQUFwQixDQUE0QixnQkFBNUIsRUFBOEMsRUFBOUMsQ0FBdEI7QUFDQSxrQkFBWSxJQUFaO0FBQ0Q7QUFDRjs7QUFFRCxXQUFTLElBQVQsQ0FBZSxFQUFmLEVBQW1CLEtBQW5CLEVBQTBCO0FBQ3hCLFFBQU0sUUFBUSxJQUFJLE1BQUosQ0FBVyxNQUF6QjtBQUNBLFFBQUksVUFBVSxDQUFkLEVBQWlCO0FBQ2Y7QUFDRDtBQUNELFFBQUksUUFBUSxLQUFaLEVBQW1CO0FBQ2pCO0FBQ0E7QUFDRDtBQUNELFFBQU0sTUFBTSxhQUFhLFNBQWIsS0FBMkIsV0FBVyxVQUFsRDtBQUNBLFFBQU0sUUFBUSxLQUFLLFdBQUwsR0FBbUIsWUFBakM7QUFDQSxRQUFNLE9BQU8sS0FBSyxZQUFMLEdBQW9CLFdBQWpDO0FBQ0EsUUFBTSxPQUFPLEtBQUssaUJBQUwsR0FBeUIsYUFBdEM7QUFDQSxRQUFNLE9BQU8sS0FBSyxhQUFMLEdBQXFCLGlCQUFsQztBQUNBLFFBQU0sS0FBSyxVQUFYO0FBQ0EsV0FBTyxFQUFQOztBQUVBLFFBQUksT0FBTyxFQUFQLENBQUosRUFBZ0I7QUFDZCxXQUFLLEVBQUwsRUFBUyxRQUFRLFFBQVEsQ0FBaEIsR0FBb0IsQ0FBN0I7QUFDRDs7QUFFRCxhQUFTLFlBQVQsQ0FBdUIsRUFBdkIsRUFBMkI7QUFDekIsYUFBTyxFQUFQLEVBQVc7QUFDVCxZQUFJLGlCQUFPLGVBQVAsQ0FBdUIsR0FBRyxhQUExQixFQUF5QyxlQUF6QyxDQUFKLEVBQStEO0FBQzdELGlCQUFPLEdBQUcsYUFBVjtBQUNEO0FBQ0QsYUFBSyxHQUFHLGFBQVI7QUFDRDtBQUNELGFBQU8sSUFBUDtBQUNEOztBQUVELGFBQVMsUUFBVCxHQUFxQjtBQUNuQixVQUFJLFNBQUosRUFBZTtBQUNiLFlBQUksVUFBVSxJQUFWLENBQUosRUFBcUI7QUFDbkIsaUJBQU8sVUFBVSxJQUFWLENBQVA7QUFDRDtBQUNELFlBQUksSUFBSSxJQUFKLEtBQWEsU0FBUyxJQUFJLElBQUosQ0FBVCxFQUFvQixLQUFwQixDQUFqQixFQUE2QztBQUMzQyxpQkFBTyxTQUFTLElBQUksSUFBSixDQUFULEVBQW9CLEtBQXBCLENBQVA7QUFDRDtBQUNGO0FBQ0QsYUFBTyxTQUFTLFdBQVcsS0FBWCxDQUFULEVBQTRCLEtBQTVCLENBQVA7QUFDRDtBQUNGOztBQUVELFdBQVMsSUFBVCxHQUFpQjtBQUNmLFFBQUksS0FBSjtBQUNBLGNBQVUsU0FBVixHQUFzQixVQUFVLFNBQVYsQ0FBb0IsT0FBcEIsQ0FBNEIsWUFBNUIsRUFBMEMsRUFBMUMsQ0FBdEI7QUFDQTtBQUNBLHdCQUFVLFNBQVYsQ0FBb0IsVUFBcEIsRUFBZ0MsYUFBaEM7QUFDQSxRQUFJLEdBQUcsS0FBSCxLQUFhLFVBQWpCLEVBQTZCO0FBQzNCLFNBQUcsS0FBSCxHQUFXLEVBQVg7QUFDRDtBQUNGOztBQUVELFdBQVMsT0FBVCxDQUFrQixDQUFsQixFQUFxQjtBQUNuQixRQUFNLFFBQVEsU0FBZDtBQUNBLFFBQU0sUUFBUSxFQUFFLEtBQUYsSUFBVyxFQUFFLE9BQTNCO0FBQ0EsUUFBSSxVQUFVLFFBQWQsRUFBd0I7QUFDdEIsVUFBSSxZQUFZLEVBQUUsZ0JBQWxCLEVBQW9DO0FBQ2xDO0FBQ0Q7QUFDRCxVQUFJLEtBQUosRUFBVztBQUNUO0FBQ0EsYUFBSyxDQUFMO0FBQ0Q7QUFDRixLQVJELE1BUU8sSUFBSSxVQUFVLE1BQWQsRUFBc0I7QUFDM0IsVUFBSSxZQUFZLEVBQUUsZ0JBQWxCLEVBQW9DO0FBQ2xDO0FBQ0Q7QUFDRCxVQUFJLEtBQUosRUFBVztBQUNULGFBQUssSUFBTDtBQUNBLGFBQUssQ0FBTDtBQUNEO0FBQ0YsS0FSTSxNQVFBLElBQUksVUFBVSxhQUFkLEVBQTZCO0FBQ2xDLFVBQUksWUFBWSxFQUFFLGdCQUFsQixFQUFvQztBQUNsQztBQUNEO0FBQ0YsS0FKTSxNQUlBLElBQUksS0FBSixFQUFXO0FBQ2hCLFVBQUksVUFBVSxTQUFkLEVBQXlCO0FBQ3ZCLFlBQUksU0FBSixFQUFlO0FBQ2IsOEJBQVUsU0FBVixDQUFvQixTQUFwQixFQUErQixPQUEvQjtBQUNELFNBRkQsTUFFTztBQUNMO0FBQ0Q7QUFDRCxhQUFLLENBQUw7QUFDRCxPQVBELE1BT08sSUFBSSxVQUFVLE9BQWQsRUFBdUI7QUFDNUI7QUFDQSxhQUFLLENBQUw7QUFDRDtBQUNGO0FBQ0Y7O0FBRUQsV0FBUyxJQUFULENBQWUsQ0FBZixFQUFrQjtBQUNoQixNQUFFLGVBQUY7QUFDQSxNQUFFLGNBQUY7QUFDRDs7QUFFRCxXQUFTLGFBQVQsR0FBMEI7QUFDeEIsUUFBSSxTQUFKLEVBQWU7QUFDYixnQkFBVSxTQUFWLENBQW9CLE1BQXBCLENBQTJCLFVBQTNCO0FBQ0Q7QUFDRjs7QUFFRCxXQUFTLGFBQVQsR0FBMEI7QUFDeEIsUUFBSSxTQUFKLEVBQWU7QUFDYixnQkFBVSxTQUFWLENBQW9CLEdBQXBCLENBQXdCLFVBQXhCO0FBQ0Q7QUFDRjs7QUFFRCxXQUFTLFNBQVQsR0FBc0I7QUFDcEIsUUFBSSxDQUFDLFNBQUwsRUFBZ0I7QUFDZDtBQUNEO0FBQ0QscUJBQWlCLElBQWpCO0FBQ0Esd0JBQVUsU0FBVixDQUFvQixVQUFwQixFQUFnQyxlQUFoQztBQUNBLFFBQU0sUUFBUSxXQUFkO0FBQ0EsUUFBSSxDQUFDLEVBQUUsV0FBSCxJQUFrQixDQUFDLEtBQXZCLEVBQThCO0FBQzVCLGFBQVE7QUFDVDtBQUNELFFBQU0sVUFBVSxVQUFVLEVBQUUsT0FBTyxLQUFULEVBQVYsQ0FBaEI7QUFDQSxRQUFJLFFBQVEsZ0JBQVo7QUFDQSxRQUFJLFVBQVUsQ0FBVixJQUFlLE9BQWYsSUFBMEIsUUFBOUIsRUFBd0M7QUFDdEM7QUFDRCxLQUZELE1BRU87QUFDTDtBQUNEO0FBQ0QsUUFBSSxDQUFDLFNBQUwsRUFBZ0I7QUFDZDtBQUNEO0FBQ0QsUUFBSSxDQUFDLFNBQUQsSUFBYyxDQUFDLE9BQW5CLEVBQTRCO0FBQzFCO0FBQ0Q7QUFDRCxhQUFTLGNBQVQsR0FBMkI7QUFDekIsVUFBSSxXQUFXLFdBQVcsVUFBMUI7QUFDQSxVQUFJLFFBQVEsQ0FBWjtBQUNBLGFBQU8sUUFBUCxFQUFpQjtBQUNmLFlBQU0sT0FBTyxTQUFTLFFBQVQsQ0FBYjtBQUNBLFlBQU0sVUFBVSxhQUFhLElBQWIsQ0FBaEI7QUFDQSxZQUFJLFlBQVksQ0FBaEIsRUFBbUI7QUFDakIsbUJBQVMsU0FBVCxDQUFtQixHQUFuQixDQUF1QixVQUF2QjtBQUNELFNBRkQsTUFFTztBQUNMLG1CQUFTLFNBQVQsQ0FBbUIsTUFBbkIsQ0FBMEIsVUFBMUI7QUFDRDtBQUNELGlCQUFTLE9BQVQ7QUFDQSxtQkFBVyxTQUFTLFdBQXBCO0FBQ0Q7QUFDRCxhQUFPLEtBQVA7QUFDRDtBQUNELGFBQVMsWUFBVCxDQUF1QixFQUF2QixFQUEyQjtBQUN6QixVQUFJLEtBQUssR0FBRyxVQUFaO0FBQ0EsVUFBSSxRQUFRLENBQVo7QUFDQSxhQUFPLEVBQVAsRUFBVztBQUNULFlBQUksU0FBUyxLQUFiLEVBQW9CO0FBQ2xCLDhCQUFVLFNBQVYsQ0FBb0IsRUFBcEIsRUFBd0IsYUFBeEI7QUFDRCxTQUZELE1BRU87QUFDTCw4QkFBVSxTQUFWLENBQW9CLEVBQXBCLEVBQXdCLGVBQXhCO0FBQ0EsY0FBSSxHQUFHLFNBQUgsQ0FBYSxPQUFiLENBQXFCLFVBQXJCLE1BQXFDLENBQUMsQ0FBMUMsRUFBNkM7QUFDM0M7QUFDQSxnQkFBSSxXQUFKLEVBQWlCO0FBQ2Ysd0JBQVUsRUFBVixFQUFjLEtBQWQ7QUFDRDtBQUNGO0FBQ0Y7QUFDRCxhQUFLLEdBQUcsV0FBUjtBQUNEO0FBQ0QsYUFBTyxLQUFQO0FBQ0Q7QUFDRjs7QUFFRCxXQUFTLHdCQUFULENBQW1DLENBQW5DLEVBQXNDO0FBQ3BDLFFBQU0sUUFBUSxFQUFFLEtBQUYsSUFBVyxFQUFFLE9BQTNCO0FBQ0EsUUFBSSxVQUFVLFNBQWQsRUFBeUI7QUFDdkI7QUFDRDtBQUNEO0FBQ0Q7O0FBRUQsV0FBUyxZQUFULENBQXVCLENBQXZCLEVBQTBCO0FBQ3hCLFFBQU0sUUFBUSxFQUFFLEtBQUYsSUFBVyxFQUFFLE9BQTNCO0FBQ0EsUUFBSSxVQUFVLFNBQVYsSUFBdUIsVUFBVSxPQUFyQyxFQUE4QztBQUM1QztBQUNEO0FBQ0QsZUFBVyxJQUFYLEVBQWlCLENBQWpCO0FBQ0Q7O0FBRUQsV0FBUyx1QkFBVCxDQUFrQyxDQUFsQyxFQUFxQztBQUNuQyxRQUFJLFNBQVMsRUFBRSxNQUFmO0FBQ0EsUUFBSSxXQUFXLFVBQWYsRUFBMkI7QUFDekIsYUFBTyxJQUFQO0FBQ0Q7QUFDRCxXQUFPLE1BQVAsRUFBZTtBQUNiLFVBQUksV0FBVyxTQUFYLElBQXdCLFdBQVcsVUFBdkMsRUFBbUQ7QUFDakQsZUFBTyxJQUFQO0FBQ0Q7QUFDRCxlQUFTLE9BQU8sVUFBaEI7QUFDRDtBQUNGOztBQUVELFdBQVMsVUFBVCxDQUFxQixDQUFyQixFQUF3QjtBQUN0QixRQUFNLFFBQVEsRUFBRSxLQUFGLElBQVcsRUFBRSxPQUEzQjtBQUNBLFFBQUksVUFBVSxPQUFkLEVBQXVCO0FBQ3JCO0FBQ0Q7QUFDRjs7QUFFRCxXQUFTLFdBQVQsQ0FBc0IsQ0FBdEIsRUFBeUI7QUFDdkIsUUFBSSx3QkFBd0IsQ0FBeEIsQ0FBSixFQUFnQztBQUM5QjtBQUNEO0FBQ0Q7QUFDRDs7QUFFRCxXQUFTLFdBQVQsQ0FBc0IsTUFBdEIsRUFBOEI7QUFDNUIsUUFBTSxLQUFLLFNBQVMsUUFBVCxHQUFvQixLQUEvQjtBQUNBLFFBQUksR0FBSixFQUFTO0FBQ1AsVUFBSSxPQUFKO0FBQ0EsWUFBTSxJQUFOO0FBQ0Q7QUFDRCxRQUFJLENBQUMsTUFBTCxFQUFhO0FBQ1gsWUFBTSx3QkFBUyxTQUFULEVBQW9CLFVBQXBCLEVBQWdDO0FBQ3BDLGVBQU8sWUFBWSxXQUFXLE9BQVgsS0FBdUIsT0FETjtBQUVwQyxpQkFBUyxFQUFFO0FBRnlCLE9BQWhDLENBQU47QUFJQSxVQUFJLENBQUMsU0FBTCxFQUFnQjtBQUFFLFlBQUksS0FBSjtBQUFjO0FBQ2pDO0FBQ0QsUUFBSSxVQUFXLFlBQVksSUFBSSxhQUFKLEtBQXNCLFVBQWpELEVBQThEO0FBQzVELDBCQUFVLEVBQVYsRUFBYyxVQUFkLEVBQTBCLE9BQTFCLEVBQW1DLE9BQW5DO0FBQ0QsS0FGRCxNQUVPO0FBQ0w7QUFDRDtBQUNELFFBQUksUUFBSixFQUFjO0FBQ1osMEJBQVUsRUFBVixFQUFjLFVBQWQsRUFBMEIsVUFBMUIsRUFBc0MsWUFBdEM7QUFDQSwwQkFBVSxFQUFWLEVBQWMsVUFBZCxFQUEwQixVQUExQixFQUFzQyxpQkFBdEM7QUFDQSwwQkFBVSxFQUFWLEVBQWMsVUFBZCxFQUEwQixTQUExQixFQUFxQyx3QkFBckM7QUFDQSwwQkFBVSxFQUFWLEVBQWMsVUFBZCxFQUEwQixPQUExQixFQUFtQyxpQkFBbkM7QUFDQSwwQkFBVSxFQUFWLEVBQWMsVUFBZCxFQUEwQixTQUExQixFQUFxQyxPQUFyQztBQUNBLFVBQUksRUFBRSxjQUFOLEVBQXNCO0FBQUUsNEJBQVUsRUFBVixFQUFjLFVBQWQsRUFBMEIsU0FBMUIsRUFBcUMsVUFBckM7QUFBbUQ7QUFDNUUsS0FQRCxNQU9PO0FBQ0wsMEJBQVUsRUFBVixFQUFjLFVBQWQsRUFBMEIsT0FBMUIsRUFBbUMsT0FBbkM7QUFDQSwwQkFBVSxFQUFWLEVBQWMsVUFBZCxFQUEwQixTQUExQixFQUFxQyxPQUFyQztBQUNEO0FBQ0QsUUFBSSxFQUFFLGVBQU4sRUFBdUI7QUFBRSwwQkFBVSxFQUFWLEVBQWMsR0FBZCxFQUFtQixPQUFuQixFQUE0QixXQUE1QjtBQUEyQztBQUNwRSxRQUFJLElBQUosRUFBVTtBQUFFLDBCQUFVLEVBQVYsRUFBYyxJQUFkLEVBQW9CLFFBQXBCLEVBQThCLElBQTlCO0FBQXNDO0FBQ25EOztBQUVELFdBQVMsT0FBVCxHQUFvQjtBQUNsQixnQkFBWSxJQUFaO0FBQ0EsUUFBSSxPQUFPLFFBQVAsQ0FBZ0IsU0FBaEIsQ0FBSixFQUFnQztBQUFFLGFBQU8sV0FBUCxDQUFtQixTQUFuQjtBQUFnQztBQUNuRTs7QUFFRCxXQUFTLGFBQVQsQ0FBd0IsS0FBeEIsRUFBK0I7QUFDN0IsUUFBSSxTQUFKLEVBQWU7QUFDYixVQUFJLGVBQWUsSUFBbkIsRUFBeUI7QUFDdkIsV0FBRyxLQUFILElBQVksTUFBTSxLQUFsQjtBQUNELE9BRkQsTUFFTztBQUNMLFdBQUcsS0FBSCxHQUFXLEtBQVg7QUFDRDtBQUNGLEtBTkQsTUFNTztBQUNMLFVBQUksZUFBZSxJQUFuQixFQUF5QjtBQUN2QixXQUFHLFNBQUgsSUFBZ0IsTUFBTSxLQUF0QjtBQUNELE9BRkQsTUFFTztBQUNMLFdBQUcsU0FBSCxHQUFlLEtBQWY7QUFDRDtBQUNGO0FBQ0Y7O0FBRUQsV0FBUyxtQkFBVCxDQUE4QixFQUE5QixFQUFrQyxVQUFsQyxFQUE4QztBQUM1QyxTQUFLLEVBQUwsRUFBUyxRQUFRLFVBQVIsQ0FBVDtBQUNEOztBQUVELFdBQVMsdUJBQVQsQ0FBa0MsR0FBbEMsRUFBdUMsSUFBdkMsRUFBNkM7QUFDM0MsUUFBSSxLQUFLLEVBQUwsS0FBWSxTQUFoQixFQUEyQjtBQUN6QixVQUFNLEtBQUssSUFBSSxLQUFKLEVBQVcsaUJBQVgsQ0FBWDtBQUNBLFVBQUksV0FBSixDQUFnQixFQUFoQjtBQUNBLFdBQUssRUFBTCxFQUFTLEtBQUssRUFBZDtBQUNEO0FBQ0Y7O0FBRUQsV0FBUyxhQUFULENBQXdCLENBQXhCLEVBQTJCLFVBQTNCLEVBQXVDO0FBQ3JDLFFBQU0sU0FBUyxFQUFFLFdBQUYsRUFBZjtBQUNBLFFBQU0sT0FBTyxRQUFRLFVBQVIsS0FBdUIsRUFBcEM7QUFDQSxRQUFJLDJCQUFZLE1BQVosRUFBb0IsS0FBSyxXQUFMLEVBQXBCLENBQUosRUFBNkM7QUFDM0MsYUFBTyxJQUFQO0FBQ0Q7QUFDRCxRQUFNLFFBQVEsU0FBUyxVQUFULEtBQXdCLEVBQXRDO0FBQ0EsUUFBSSxPQUFPLEtBQVAsS0FBaUIsUUFBckIsRUFBK0I7QUFDN0IsYUFBTyxLQUFQO0FBQ0Q7QUFDRCxXQUFPLDJCQUFZLE1BQVosRUFBb0IsTUFBTSxXQUFOLEVBQXBCLENBQVA7QUFDRDs7QUFFRCxXQUFTLGdCQUFULENBQTJCLElBQTNCLEVBQWlDLENBQWpDLEVBQW9DO0FBQ2xDLFFBQUksU0FBUyxFQUFiO0FBQ0EsUUFBSSxXQUFXLEtBQWY7QUFDQSxRQUFJLFFBQVEsRUFBRSxLQUFkO0FBQ0EsV0FBTyxhQUFhLEtBQWIsSUFBc0IsU0FBUyxDQUF0QyxFQUF5QztBQUN2QyxlQUFTLEtBQUssTUFBTCxDQUFZLFFBQVEsQ0FBcEIsRUFBdUIsRUFBRSxLQUFGLEdBQVUsS0FBVixHQUFrQixDQUF6QyxDQUFUO0FBQ0EsaUJBQVcsWUFBWSxJQUFaLENBQWlCLE1BQWpCLENBQVg7QUFDQTtBQUNEO0FBQ0QsV0FBTztBQUNMLFlBQU0sV0FBVyxNQUFYLEdBQW9CLElBRHJCO0FBRUw7QUFGSyxLQUFQO0FBSUQ7O0FBRUQsV0FBUyxrQkFBVCxDQUE2QixDQUE3QixFQUFnQyxVQUFoQyxFQUE0QztBQUMxQyxRQUFNLFdBQVcsb0JBQUssRUFBTCxDQUFqQjtBQUNBLFFBQU0sUUFBUSxpQkFBaUIsQ0FBakIsRUFBb0IsUUFBcEIsRUFBOEIsSUFBNUM7QUFDQSxRQUFJLEtBQUosRUFBVztBQUNULGFBQU8sRUFBRSxZQUFGLEVBQVMsc0JBQVQsRUFBUDtBQUNEO0FBQ0Y7O0FBRUQsV0FBUyxVQUFULENBQXFCLEtBQXJCLEVBQTRCO0FBQzFCLFFBQU0sVUFBVSxHQUFHLEtBQW5CO0FBQ0EsUUFBTSxXQUFXLG9CQUFLLEVBQUwsQ0FBakI7QUFDQSxRQUFNLFFBQVEsaUJBQWlCLE9BQWpCLEVBQTBCLFFBQTFCLENBQWQ7QUFDQSxRQUFNLE9BQU8sUUFBUSxNQUFSLENBQWUsQ0FBZixFQUFrQixNQUFNLEtBQXhCLENBQWI7QUFDQSxRQUFNLFFBQVEsUUFBUSxNQUFSLENBQWUsTUFBTSxLQUFOLEdBQWMsTUFBTSxJQUFOLENBQVcsTUFBekIsSUFBbUMsU0FBUyxHQUFULEdBQWUsU0FBUyxLQUEzRCxDQUFmLENBQWQ7QUFDQSxRQUFNLFNBQVMsT0FBTyxLQUFQLEdBQWUsR0FBOUI7O0FBRUEsT0FBRyxLQUFILEdBQVcsU0FBUyxLQUFwQjtBQUNBLHdCQUFLLEVBQUwsRUFBUyxFQUFFLE9BQU8sT0FBTyxNQUFoQixFQUF3QixLQUFLLE9BQU8sTUFBcEMsRUFBVDtBQUNEOztBQUVELFdBQVMsa0JBQVQsR0FBK0I7QUFDN0IsVUFBTSxJQUFJLEtBQUosQ0FBVSx3REFBVixDQUFOO0FBQ0Q7O0FBRUQsV0FBUyxVQUFULEdBQXVCO0FBQ3JCLFVBQU0sSUFBSSxLQUFKLENBQVUsd0RBQVYsQ0FBTjtBQUNEOztBQUVELFdBQVMsUUFBVCxDQUFtQixRQUFuQixFQUE2QjtBQUFFLFdBQU8sc0JBQU8sV0FBUCxFQUFvQixRQUFwQixFQUE4QixDQUE5QixDQUFQO0FBQTBDO0FBQzFFOztBQUVELFNBQVMsT0FBVCxDQUFrQixFQUFsQixFQUFzQjtBQUFFLFNBQU8sR0FBRyxPQUFILEtBQWUsT0FBZixJQUEwQixHQUFHLE9BQUgsS0FBZSxVQUFoRDtBQUE2RDs7QUFFckYsU0FBUyxHQUFULENBQWMsSUFBZCxFQUFvQixTQUFwQixFQUErQjtBQUM3QixNQUFNLEtBQUssSUFBSSxhQUFKLENBQWtCLElBQWxCLENBQVg7QUFDQSxLQUFHLFNBQUgsR0FBZSxTQUFmO0FBQ0EsU0FBTyxFQUFQO0FBQ0Q7O0FBRUQsU0FBUyxLQUFULENBQWdCLEVBQWhCLEVBQW9CO0FBQUUsU0FBTyxZQUFZO0FBQUUsZUFBVyxFQUFYLEVBQWUsQ0FBZjtBQUFvQixHQUF6QztBQUE0QztBQUNsRSxTQUFTLElBQVQsQ0FBZSxFQUFmLEVBQW1CLEtBQW5CLEVBQTBCO0FBQUUsS0FBRyxTQUFILEdBQWUsR0FBRyxXQUFILEdBQWlCLEtBQWhDO0FBQXdDOztBQUVwRSxTQUFTLFVBQVQsQ0FBcUIsRUFBckIsRUFBeUI7QUFDdkIsTUFBTSxRQUFRLEdBQUcsWUFBSCxDQUFnQixpQkFBaEIsQ0FBZDtBQUNBLE1BQUksVUFBVSxPQUFkLEVBQXVCO0FBQ3JCLFdBQU8sS0FBUDtBQUNEO0FBQ0QsTUFBSSxVQUFVLE1BQWQsRUFBc0I7QUFDcEIsV0FBTyxJQUFQO0FBQ0Q7QUFDRCxNQUFJLEdBQUcsYUFBUCxFQUFzQjtBQUNwQixXQUFPLFdBQVcsR0FBRyxhQUFkLENBQVA7QUFDRDtBQUNELFNBQU8sS0FBUDtBQUNEOztBQUVELE9BQU8sT0FBUCxHQUFpQixNQUFqQjs7O0FDaDNCQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3JHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBzdW0gZnJvbSAnaGFzaC1zdW0nO1xuaW1wb3J0IHNlbGwgZnJvbSAnc2VsbCc7XG5pbXBvcnQgc2VrdG9yIGZyb20gJ3Nla3Rvcic7XG5pbXBvcnQgZW1pdHRlciBmcm9tICdjb250cmEvZW1pdHRlcic7XG5pbXBvcnQgYnVsbHNleWUgZnJvbSAnYnVsbHNleWUnO1xuaW1wb3J0IGNyb3NzdmVudCBmcm9tICdjcm9zc3ZlbnQnO1xuaW1wb3J0IGZ1enp5c2VhcmNoIGZyb20gJ2Z1enp5c2VhcmNoJztcbmltcG9ydCBkZWJvdW5jZSBmcm9tICdsb2Rhc2gvZGVib3VuY2UnO1xuY29uc3QgS0VZX0JBQ0tTUEFDRSA9IDg7XG5jb25zdCBLRVlfRU5URVIgPSAxMztcbmNvbnN0IEtFWV9FU0MgPSAyNztcbmNvbnN0IEtFWV9VUCA9IDM4O1xuY29uc3QgS0VZX0RPV04gPSA0MDtcbmNvbnN0IEtFWV9UQUIgPSA5O1xuY29uc3QgZG9jID0gZG9jdW1lbnQ7XG5jb25zdCBkb2NFbGVtZW50ID0gZG9jLmRvY3VtZW50RWxlbWVudDtcblxuZnVuY3Rpb24gaG9yc2V5IChlbCwgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHtcbiAgICBzZXRBcHBlbmRzLFxuICAgIHNldCxcbiAgICBmaWx0ZXIsXG4gICAgc291cmNlLFxuICAgIGNhY2hlID0ge30sXG4gICAgcHJlZGljdE5leHRTZWFyY2gsXG4gICAgcmVuZGVySXRlbSxcbiAgICByZW5kZXJDYXRlZ29yeSxcbiAgICBibGFua1NlYXJjaCxcbiAgICBhcHBlbmRUbyxcbiAgICBhbmNob3IsXG4gICAgZGVib3VuY2VcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGNhY2hpbmcgPSBvcHRpb25zLmNhY2hlICE9PSBmYWxzZTtcbiAgaWYgKCFzb3VyY2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB1c2VyR2V0VGV4dCA9IG9wdGlvbnMuZ2V0VGV4dDtcbiAgY29uc3QgdXNlckdldFZhbHVlID0gb3B0aW9ucy5nZXRWYWx1ZTtcbiAgY29uc3QgZ2V0VGV4dCA9IChcbiAgICB0eXBlb2YgdXNlckdldFRleHQgPT09ICdzdHJpbmcnID8gZCA9PiBkW3VzZXJHZXRUZXh0XSA6XG4gICAgdHlwZW9mIHVzZXJHZXRUZXh0ID09PSAnZnVuY3Rpb24nID8gdXNlckdldFRleHQgOlxuICAgIGQgPT4gZC50b1N0cmluZygpXG4gICk7XG4gIGNvbnN0IGdldFZhbHVlID0gKFxuICAgIHR5cGVvZiB1c2VyR2V0VmFsdWUgPT09ICdzdHJpbmcnID8gZCA9PiBkW3VzZXJHZXRWYWx1ZV0gOlxuICAgIHR5cGVvZiB1c2VyR2V0VmFsdWUgPT09ICdmdW5jdGlvbicgPyB1c2VyR2V0VmFsdWUgOlxuICAgIGQgPT4gZFxuICApO1xuXG4gIGxldCBwcmV2aW91c1N1Z2dlc3Rpb25zID0gW107XG4gIGxldCBwcmV2aW91c1NlbGVjdGlvbiA9IG51bGw7XG4gIGNvbnN0IGxpbWl0ID0gTnVtYmVyKG9wdGlvbnMubGltaXQpIHx8IEluZmluaXR5O1xuICBjb25zdCBjb21wbGV0ZXIgPSBhdXRvY29tcGxldGUoZWwsIHtcbiAgICBzb3VyY2U6IHNvdXJjZUZ1bmN0aW9uLFxuICAgIGxpbWl0LFxuICAgIGdldFRleHQsXG4gICAgZ2V0VmFsdWUsXG4gICAgc2V0QXBwZW5kcyxcbiAgICBwcmVkaWN0TmV4dFNlYXJjaCxcbiAgICByZW5kZXJJdGVtLFxuICAgIHJlbmRlckNhdGVnb3J5LFxuICAgIGFwcGVuZFRvLFxuICAgIGFuY2hvcixcbiAgICBub01hdGNoZXMsXG4gICAgbm9NYXRjaGVzVGV4dDogb3B0aW9ucy5ub01hdGNoZXMsXG4gICAgYmxhbmtTZWFyY2gsXG4gICAgZGVib3VuY2UsXG4gICAgc2V0IChzKSB7XG4gICAgICBpZiAoc2V0QXBwZW5kcyAhPT0gdHJ1ZSkge1xuICAgICAgICBlbC52YWx1ZSA9ICcnO1xuICAgICAgfVxuICAgICAgcHJldmlvdXNTZWxlY3Rpb24gPSBzO1xuICAgICAgKHNldCB8fCBjb21wbGV0ZXIuZGVmYXVsdFNldHRlcikoZ2V0VGV4dChzKSwgcyk7XG4gICAgICBjb21wbGV0ZXIuZW1pdCgnYWZ0ZXJTZXQnKTtcbiAgICB9LFxuICAgIGZpbHRlclxuICB9KTtcbiAgcmV0dXJuIGNvbXBsZXRlcjtcbiAgZnVuY3Rpb24gbm9NYXRjaGVzIChkYXRhKSB7XG4gICAgaWYgKCFvcHRpb25zLm5vTWF0Y2hlcykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YS5xdWVyeS5sZW5ndGg7XG4gIH1cbiAgZnVuY3Rpb24gc291cmNlRnVuY3Rpb24gKGRhdGEsIGRvbmUpIHtcbiAgICBjb25zdCB7cXVlcnksIGxpbWl0fSA9IGRhdGE7XG4gICAgaWYgKCFvcHRpb25zLmJsYW5rU2VhcmNoICYmIHF1ZXJ5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgZG9uZShudWxsLCBbXSwgdHJ1ZSk7IHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNvbXBsZXRlcikge1xuICAgICAgY29tcGxldGVyLmVtaXQoJ2JlZm9yZVVwZGF0ZScpO1xuICAgIH1cbiAgICBjb25zdCBoYXNoID0gc3VtKHF1ZXJ5KTsgLy8gZmFzdCwgY2FzZSBpbnNlbnNpdGl2ZSwgcHJldmVudHMgY29sbGlzaW9uc1xuICAgIGlmIChjYWNoaW5nKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IGNhY2hlW2hhc2hdO1xuICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gZW50cnkuY3JlYXRlZC5nZXRUaW1lKCk7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uID0gY2FjaGUuZHVyYXRpb24gfHwgNjAgKiA2MCAqIDI0O1xuICAgICAgICBjb25zdCBkaWZmID0gZHVyYXRpb24gKiAxMDAwO1xuICAgICAgICBjb25zdCBmcmVzaCA9IG5ldyBEYXRlKHN0YXJ0ICsgZGlmZikgPiBuZXcgRGF0ZSgpO1xuICAgICAgICBpZiAoZnJlc2gpIHtcbiAgICAgICAgICBkb25lKG51bGwsIGVudHJ5Lml0ZW1zLnNsaWNlKCkpOyByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHNvdXJjZURhdGEgPSB7XG4gICAgICBwcmV2aW91c1N1Z2dlc3Rpb25zOiBwcmV2aW91c1N1Z2dlc3Rpb25zLnNsaWNlKCksXG4gICAgICBwcmV2aW91c1NlbGVjdGlvbixcbiAgICAgIGlucHV0OiBxdWVyeSxcbiAgICAgIHJlbmRlckl0ZW0sXG4gICAgICByZW5kZXJDYXRlZ29yeSxcbiAgICAgIGxpbWl0XG4gICAgfTtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuc291cmNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBvcHRpb25zLnNvdXJjZShzb3VyY2VEYXRhLCBzb3VyY2VkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc291cmNlZChudWxsLCBvcHRpb25zLnNvdXJjZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHNvdXJjZWQgKGVyciwgcmVzdWx0KSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdBdXRvY29tcGxldGUgc291cmNlIGVycm9yLicsIGVyciwgZWwpO1xuICAgICAgICBkb25lKGVyciwgW10pO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbXMgPSBBcnJheS5pc0FycmF5KHJlc3VsdCkgPyByZXN1bHQgOiBbXTtcbiAgICAgIGlmIChjYWNoaW5nKSB7XG4gICAgICAgIGNhY2hlW2hhc2hdID0geyBjcmVhdGVkOiBuZXcgRGF0ZSgpLCBpdGVtcyB9O1xuICAgICAgfVxuICAgICAgcHJldmlvdXNTdWdnZXN0aW9ucyA9IGl0ZW1zO1xuICAgICAgZG9uZShudWxsLCBpdGVtcy5zbGljZSgpKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYXV0b2NvbXBsZXRlIChlbCwgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IG8gPSBvcHRpb25zO1xuICBjb25zdCBwYXJlbnQgPSBvLmFwcGVuZFRvIHx8IGRvYy5ib2R5O1xuICBjb25zdCB7XG4gICAgZ2V0VGV4dCxcbiAgICBnZXRWYWx1ZSxcbiAgICBmb3JtLFxuICAgIHNvdXJjZSxcbiAgICBub01hdGNoZXMsXG4gICAgbm9NYXRjaGVzVGV4dCxcbiAgICBoaWdobGlnaHRlciA9IHRydWUsXG4gICAgaGlnaGxpZ2h0Q29tcGxldGVXb3JkcyA9IHRydWUsXG4gICAgcmVuZGVySXRlbSA9IGRlZmF1bHRJdGVtUmVuZGVyZXIsXG4gICAgcmVuZGVyQ2F0ZWdvcnkgPSBkZWZhdWx0Q2F0ZWdvcnlSZW5kZXJlcixcbiAgICBzZXRBcHBlbmRzXG4gIH0gPSBvO1xuICBjb25zdCBsaW1pdCA9IHR5cGVvZiBvLmxpbWl0ID09PSAnbnVtYmVyJyA/IG8ubGltaXQgOiBJbmZpbml0eTtcbiAgY29uc3QgdXNlckZpbHRlciA9IG8uZmlsdGVyIHx8IGRlZmF1bHRGaWx0ZXI7XG4gIGNvbnN0IHVzZXJTZXQgPSBvLnNldCB8fCBkZWZhdWx0U2V0dGVyO1xuICBjb25zdCBjYXRlZ29yaWVzID0gdGFnKCdkaXYnLCAnc2V5LWNhdGVnb3JpZXMnKTtcbiAgY29uc3QgY29udGFpbmVyID0gdGFnKCdkaXYnLCAnc2V5LWNvbnRhaW5lcicpO1xuICBjb25zdCBkZWZlcnJlZEZpbHRlcmluZyA9IGRlZmVyKGZpbHRlcmluZyk7XG4gIGNvbnN0IHN0YXRlID0geyBjb3VudGVyOiAwLCBxdWVyeTogbnVsbCB9O1xuICBsZXQgY2F0ZWdvcnlNYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBsZXQgc2VsZWN0aW9uID0gbnVsbDtcbiAgbGV0IGV5ZTtcbiAgbGV0IGF0dGFjaG1lbnQgPSBlbDtcbiAgbGV0IG5vbmVNYXRjaDtcbiAgbGV0IHRleHRJbnB1dDtcbiAgbGV0IGFueUlucHV0O1xuICBsZXQgcmFuY2hvcmxlZnQ7XG4gIGxldCByYW5jaG9ycmlnaHQ7XG4gIGxldCBsYXN0UHJlZml4ID0gJyc7XG4gIGNvbnN0IGRlYm91bmNlVGltZSA9IG8uZGVib3VuY2UgfHwgMzAwO1xuICBjb25zdCBkZWJvdW5jZWRMb2FkaW5nID0gZGVib3VuY2UobG9hZGluZywgZGVib3VuY2VUaW1lKTtcblxuICBpZiAoby5hdXRvSGlkZU9uQmx1ciA9PT0gdm9pZCAwKSB7IG8uYXV0b0hpZGVPbkJsdXIgPSB0cnVlOyB9XG4gIGlmIChvLmF1dG9IaWRlT25DbGljayA9PT0gdm9pZCAwKSB7IG8uYXV0b0hpZGVPbkNsaWNrID0gdHJ1ZTsgfVxuICBpZiAoby5hdXRvU2hvd09uVXBEb3duID09PSB2b2lkIDApIHsgby5hdXRvU2hvd09uVXBEb3duID0gZWwudGFnTmFtZSA9PT0gJ0lOUFVUJzsgfVxuICBpZiAoby5hbmNob3IpIHtcbiAgICByYW5jaG9ybGVmdCA9IG5ldyBSZWdFeHAoJ14nICsgby5hbmNob3IpO1xuICAgIHJhbmNob3JyaWdodCA9IG5ldyBSZWdFeHAoby5hbmNob3IgKyAnJCcpO1xuICB9XG5cbiAgbGV0IGhhc0l0ZW1zID0gZmFsc2U7XG4gIGNvbnN0IGFwaSA9IGVtaXR0ZXIoe1xuICAgIGFuY2hvcjogby5hbmNob3IsXG4gICAgY2xlYXIsXG4gICAgc2hvdyxcbiAgICBoaWRlLFxuICAgIHRvZ2dsZSxcbiAgICBkZXN0cm95LFxuICAgIHJlZnJlc2hQb3NpdGlvbixcbiAgICBhcHBlbmRUZXh0LFxuICAgIGFwcGVuZEhUTUwsXG4gICAgZmlsdGVyQW5jaG9yZWRUZXh0LFxuICAgIGZpbHRlckFuY2hvcmVkSFRNTCxcbiAgICBkZWZhdWx0QXBwZW5kVGV4dDogYXBwZW5kVGV4dCxcbiAgICBkZWZhdWx0RmlsdGVyLFxuICAgIGRlZmF1bHRJdGVtUmVuZGVyZXIsXG4gICAgZGVmYXVsdENhdGVnb3J5UmVuZGVyZXIsXG4gICAgZGVmYXVsdFNldHRlcixcbiAgICByZXRhcmdldCxcbiAgICBhdHRhY2htZW50LFxuICAgIHNvdXJjZTogW11cbiAgfSk7XG5cbiAgcmV0YXJnZXQoZWwpO1xuICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2F0ZWdvcmllcyk7XG4gIGlmIChub01hdGNoZXMgJiYgbm9NYXRjaGVzVGV4dCkge1xuICAgIG5vbmVNYXRjaCA9IHRhZygnZGl2JywgJ3NleS1lbXB0eSBzZXktaGlkZScpO1xuICAgIHRleHQobm9uZU1hdGNoLCBub01hdGNoZXNUZXh0KTtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobm9uZU1hdGNoKTtcbiAgfVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdhdXRvY29tcGxldGUnLCAnb2ZmJyk7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoc291cmNlKSkge1xuICAgIGxvYWRlZChzb3VyY2UsIGZhbHNlKTtcbiAgfVxuXG4gIHJldHVybiBhcGk7XG5cbiAgZnVuY3Rpb24gcmV0YXJnZXQgKGVsKSB7XG4gICAgaW5wdXRFdmVudHModHJ1ZSk7XG4gICAgYXR0YWNobWVudCA9IGFwaS5hdHRhY2htZW50ID0gZWw7XG4gICAgdGV4dElucHV0ID0gYXR0YWNobWVudC50YWdOYW1lID09PSAnSU5QVVQnIHx8IGF0dGFjaG1lbnQudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJztcbiAgICBhbnlJbnB1dCA9IHRleHRJbnB1dCB8fCBpc0VkaXRhYmxlKGF0dGFjaG1lbnQpO1xuICAgIGlucHV0RXZlbnRzKCk7XG4gIH1cblxuICBmdW5jdGlvbiByZWZyZXNoUG9zaXRpb24gKCkge1xuICAgIGlmIChleWUpIHsgZXllLnJlZnJlc2goKTsgfVxuICB9XG5cbiAgZnVuY3Rpb24gbG9hZGluZyAoZm9yY2VTaG93KSB7XG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY3Jvc3N2ZW50LnJlbW92ZShhdHRhY2htZW50LCAnZm9jdXMnLCBsb2FkaW5nKTtcbiAgICBjb25zdCBxdWVyeSA9IHJlYWRJbnB1dCgpO1xuICAgIGlmIChxdWVyeSA9PT0gc3RhdGUucXVlcnkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaGFzSXRlbXMgPSBmYWxzZTtcbiAgICBzdGF0ZS5xdWVyeSA9IHF1ZXJ5O1xuXG4gICAgY29uc3QgY291bnRlciA9ICsrc3RhdGUuY291bnRlcjtcblxuICAgIHNvdXJjZSh7IHF1ZXJ5LCBsaW1pdCB9LCBzb3VyY2VkKTtcblxuICAgIGZ1bmN0aW9uIHNvdXJjZWQgKGVyciwgcmVzdWx0LCBibGFua1F1ZXJ5KSB7XG4gICAgICBpZiAoc3RhdGUuY291bnRlciAhPT0gY291bnRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2FkZWQocmVzdWx0LCBmb3JjZVNob3cpO1xuICAgICAgaWYgKGVyciB8fCBibGFua1F1ZXJ5KSB7XG4gICAgICAgIGhhc0l0ZW1zID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbG9hZGVkIChjYXRlZ29yaWVzLCBmb3JjZVNob3cpIHtcbiAgICBjbGVhcigpO1xuICAgIGhhc0l0ZW1zID0gdHJ1ZTtcbiAgICBhcGkuc291cmNlID0gW107XG4gICAgY2F0ZWdvcmllcy5mb3JFYWNoKGNhdCA9PiBjYXQubGlzdC5mb3JFYWNoKHN1Z2dlc3Rpb24gPT4gYWRkKHN1Z2dlc3Rpb24sIGNhdCkpKTtcbiAgICBpZiAoZm9yY2VTaG93KSB7XG4gICAgICBzaG93KCk7XG4gICAgfVxuICAgIGZpbHRlcmluZygpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXIgKCkge1xuICAgIHVuc2VsZWN0KCk7XG4gICAgd2hpbGUgKGNhdGVnb3JpZXMubGFzdENoaWxkKSB7XG4gICAgICBjYXRlZ29yaWVzLnJlbW92ZUNoaWxkKGNhdGVnb3JpZXMubGFzdENoaWxkKTtcbiAgICB9XG4gICAgY2F0ZWdvcnlNYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGhhc0l0ZW1zID0gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiByZWFkSW5wdXQgKCkge1xuICAgIHJldHVybiAodGV4dElucHV0ID8gZWwudmFsdWUgOiBlbC5pbm5lckhUTUwpLnRyaW0oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENhdGVnb3J5IChkYXRhKSB7XG4gICAgaWYgKCFkYXRhLmlkKSB7XG4gICAgICBkYXRhLmlkID0gJ2RlZmF1bHQnO1xuICAgIH1cbiAgICBpZiAoIWNhdGVnb3J5TWFwW2RhdGEuaWRdKSB7XG4gICAgICBjYXRlZ29yeU1hcFtkYXRhLmlkXSA9IGNyZWF0ZUNhdGVnb3J5KCk7XG4gICAgfVxuICAgIHJldHVybiBjYXRlZ29yeU1hcFtkYXRhLmlkXTtcbiAgICBmdW5jdGlvbiBjcmVhdGVDYXRlZ29yeSAoKSB7XG4gICAgICBjb25zdCBjYXRlZ29yeSA9IHRhZygnZGl2JywgJ3NleS1jYXRlZ29yeScpO1xuICAgICAgY29uc3QgdWwgPSB0YWcoJ3VsJywgJ3NleS1saXN0Jyk7XG4gICAgICByZW5kZXJDYXRlZ29yeShjYXRlZ29yeSwgZGF0YSk7XG4gICAgICBjYXRlZ29yeS5hcHBlbmRDaGlsZCh1bCk7XG4gICAgICBjYXRlZ29yaWVzLmFwcGVuZENoaWxkKGNhdGVnb3J5KTtcbiAgICAgIHJldHVybiB7IGRhdGEsIHVsIH07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYWRkIChzdWdnZXN0aW9uLCBjYXRlZ29yeURhdGEpIHtcbiAgICBjb25zdCBjYXQgPSBnZXRDYXRlZ29yeShjYXRlZ29yeURhdGEpO1xuICAgIGNvbnN0IGxpID0gdGFnKCdsaScsICdzZXktaXRlbScpO1xuICAgIHJlbmRlckl0ZW0obGksIHN1Z2dlc3Rpb24pO1xuICAgIGlmIChoaWdobGlnaHRlcikge1xuICAgICAgYnJlYWt1cEZvckhpZ2hsaWdodGVyKGxpKTtcbiAgICB9XG4gICAgY3Jvc3N2ZW50LmFkZChsaSwgJ21vdXNlZW50ZXInLCBob3ZlclN1Z2dlc3Rpb24pO1xuICAgIGNyb3NzdmVudC5hZGQobGksICdjbGljaycsIGNsaWNrZWRTdWdnZXN0aW9uKTtcbiAgICBjcm9zc3ZlbnQuYWRkKGxpLCAnaG9yc2V5LWZpbHRlcicsIGZpbHRlckl0ZW0pO1xuICAgIGNyb3NzdmVudC5hZGQobGksICdob3JzZXktaGlkZScsIGhpZGVJdGVtKTtcbiAgICBjYXQudWwuYXBwZW5kQ2hpbGQobGkpO1xuICAgIGFwaS5zb3VyY2UucHVzaChzdWdnZXN0aW9uKTtcbiAgICByZXR1cm4gbGk7XG5cbiAgICBmdW5jdGlvbiBob3ZlclN1Z2dlc3Rpb24gKCkge1xuICAgICAgc2VsZWN0KGxpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGlja2VkU3VnZ2VzdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnB1dCA9IGdldFRleHQoc3VnZ2VzdGlvbik7XG4gICAgICBzZXQoc3VnZ2VzdGlvbik7XG4gICAgICBoaWRlKCk7XG4gICAgICBhdHRhY2htZW50LmZvY3VzKCk7XG4gICAgICBsYXN0UHJlZml4ID0gby5wcmVkaWN0TmV4dFNlYXJjaCAmJiBvLnByZWRpY3ROZXh0U2VhcmNoKHtcbiAgICAgICAgaW5wdXQ6IGlucHV0LFxuICAgICAgICBzb3VyY2U6IGFwaS5zb3VyY2Uuc2xpY2UoKSxcbiAgICAgICAgc2VsZWN0aW9uOiBzdWdnZXN0aW9uXG4gICAgICB9KSB8fCAnJztcbiAgICAgIGlmIChsYXN0UHJlZml4KSB7XG4gICAgICAgIGVsLnZhbHVlID0gbGFzdFByZWZpeDtcbiAgICAgICAgZWwuc2VsZWN0KCk7XG4gICAgICAgIHNob3coKTtcbiAgICAgICAgZmlsdGVyaW5nKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmlsdGVySXRlbSAoKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlYWRJbnB1dCgpO1xuICAgICAgaWYgKGZpbHRlcih2YWx1ZSwgc3VnZ2VzdGlvbikpIHtcbiAgICAgICAgbGkuY2xhc3NOYW1lID0gbGkuY2xhc3NOYW1lLnJlcGxhY2UoLyBzZXktaGlkZS9nLCAnJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGxpLCAnaG9yc2V5LWhpZGUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoaWRlSXRlbSAoKSB7XG4gICAgICBpZiAoIWhpZGRlbihsaSkpIHtcbiAgICAgICAgbGkuY2xhc3NOYW1lICs9ICcgc2V5LWhpZGUnO1xuICAgICAgICBpZiAoc2VsZWN0aW9uID09PSBsaSkge1xuICAgICAgICAgIHVuc2VsZWN0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBicmVha3VwRm9ySGlnaGxpZ2h0ZXIgKGVsKSB7XG4gICAgZ2V0VGV4dENoaWxkcmVuKGVsKS5mb3JFYWNoKGVsID0+IHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IGVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICBjb25zdCB0ZXh0ID0gZWwudGV4dENvbnRlbnQgfHwgZWwubm9kZVZhbHVlIHx8ICcnO1xuICAgICAgaWYgKHRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGNoYXIgb2YgdGV4dCkge1xuICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHNwYW5Gb3IoY2hhciksIGVsKTtcbiAgICAgIH1cbiAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbCk7XG4gICAgICBmdW5jdGlvbiBzcGFuRm9yIChjaGFyKSB7XG4gICAgICAgIGNvbnN0IHNwYW4gPSBkb2MuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICBzcGFuLmNsYXNzTmFtZSA9ICdzZXktY2hhcic7XG4gICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSBzcGFuLmlubmVyVGV4dCA9IGNoYXI7XG4gICAgICAgIHJldHVybiBzcGFuO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGlnaGxpZ2h0IChlbCwgbmVlZGxlKSB7XG4gICAgY29uc3QgcndvcmQgPSAvW1xccywuX1xcW1xcXXt9KCktXS9nO1xuICAgIGNvbnN0IHdvcmRzID0gbmVlZGxlLnNwbGl0KHJ3b3JkKS5maWx0ZXIodyA9PiB3Lmxlbmd0aCk7XG4gICAgY29uc3QgZWxlbXMgPSBbLi4uZWwucXVlcnlTZWxlY3RvckFsbCgnLnNleS1jaGFyJyldO1xuICAgIGxldCBjaGFycztcbiAgICBsZXQgc3RhcnRJbmRleCA9IDA7XG5cbiAgICBiYWxhbmNlKCk7XG4gICAgaWYgKGhpZ2hsaWdodENvbXBsZXRlV29yZHMpIHtcbiAgICAgIHdob2xlKCk7XG4gICAgfVxuICAgIGZ1enp5KCk7XG4gICAgY2xlYXJSZW1haW5kZXIoKTtcblxuICAgIGZ1bmN0aW9uIGJhbGFuY2UgKCkge1xuICAgICAgY2hhcnMgPSBlbGVtcy5tYXAoZWwgPT4gZWwuaW5uZXJUZXh0IHx8IGVsLnRleHRDb250ZW50KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3aG9sZSAoKSB7XG4gICAgICBmb3IgKGxldCB3b3JkIG9mIHdvcmRzKSB7XG4gICAgICAgIGxldCB0ZW1wSW5kZXggPSBzdGFydEluZGV4O1xuICAgICAgICByZXRyeTogd2hpbGUgKHRlbXBJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBsZXQgaW5pdCA9IHRydWU7XG4gICAgICAgICAgbGV0IHByZXZJbmRleCA9IHRlbXBJbmRleDtcbiAgICAgICAgICBmb3IgKGxldCBjaGFyIG9mIHdvcmQpIHtcbiAgICAgICAgICAgIGNvbnN0IGkgPSBjaGFycy5pbmRleE9mKGNoYXIsIHByZXZJbmRleCArIDEpO1xuICAgICAgICAgICAgY29uc3QgZmFpbCA9IGkgPT09IC0xIHx8ICghaW5pdCAmJiBwcmV2SW5kZXggKyAxICE9PSBpKTtcbiAgICAgICAgICAgIGlmIChpbml0KSB7XG4gICAgICAgICAgICAgIGluaXQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgdGVtcEluZGV4ID0gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmYWlsKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIHJldHJ5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJldkluZGV4ID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChsZXQgZWwgb2YgZWxlbXMuc3BsaWNlKHRlbXBJbmRleCwgMSArIHByZXZJbmRleCAtIHRlbXBJbmRleCkpIHtcbiAgICAgICAgICAgIG9uKGVsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYmFsYW5jZSgpO1xuICAgICAgICAgIG5lZWRsZSA9IG5lZWRsZS5yZXBsYWNlKHdvcmQsICcnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZ1enp5ICgpIHtcbiAgICAgIGZvciAobGV0IGlucHV0IG9mIG5lZWRsZSkge1xuICAgICAgICB3aGlsZSAoZWxlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgbGV0IGVsID0gZWxlbXMuc2hpZnQoKTtcbiAgICAgICAgICBpZiAoKGVsLmlubmVyVGV4dCB8fCBlbC50ZXh0Q29udGVudCkgPT09IGlucHV0KSB7XG4gICAgICAgICAgICBvbihlbCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2ZmKGVsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhclJlbWFpbmRlciAoKSB7XG4gICAgICB3aGlsZSAoZWxlbXMubGVuZ3RoKSB7XG4gICAgICAgIG9mZihlbGVtcy5zaGlmdCgpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvbiAoY2gpIHtcbiAgICAgIGNoLmNsYXNzTGlzdC5hZGQoJ3NleS1jaGFyLWhpZ2hsaWdodCcpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBvZmYgKGNoKSB7XG4gICAgICBjaC5jbGFzc0xpc3QucmVtb3ZlKCdzZXktY2hhci1oaWdobGlnaHQnKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnZXRUZXh0Q2hpbGRyZW4gKGVsKSB7XG4gICAgY29uc3QgdGV4dHMgPSBbXTtcbiAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKGVsLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCwgbnVsbCwgZmFsc2UpO1xuICAgIGxldCBub2RlO1xuICAgIHdoaWxlIChub2RlID0gd2Fsa2VyLm5leHROb2RlKCkpIHtcbiAgICAgIHRleHRzLnB1c2gobm9kZSk7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldCAodmFsdWUpIHtcbiAgICBpZiAoby5hbmNob3IpIHtcbiAgICAgIHJldHVybiAoaXNUZXh0KCkgPyBhcGkuYXBwZW5kVGV4dCA6IGFwaS5hcHBlbmRIVE1MKShnZXRWYWx1ZSh2YWx1ZSkpO1xuICAgIH1cbiAgICB1c2VyU2V0KHZhbHVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlciAodmFsdWUsIHN1Z2dlc3Rpb24pIHtcbiAgICBpZiAoby5hbmNob3IpIHtcbiAgICAgIGNvbnN0IGlsID0gKGlzVGV4dCgpID8gYXBpLmZpbHRlckFuY2hvcmVkVGV4dCA6IGFwaS5maWx0ZXJBbmNob3JlZEhUTUwpKHZhbHVlLCBzdWdnZXN0aW9uKTtcbiAgICAgIHJldHVybiBpbCA/IHVzZXJGaWx0ZXIoaWwuaW5wdXQsIGlsLnN1Z2dlc3Rpb24pIDogZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB1c2VyRmlsdGVyKHZhbHVlLCBzdWdnZXN0aW9uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzVGV4dCAoKSB7IHJldHVybiBpc0lucHV0KGF0dGFjaG1lbnQpOyB9XG4gIGZ1bmN0aW9uIHZpc2libGUgKCkgeyByZXR1cm4gY29udGFpbmVyLmNsYXNzTmFtZS5pbmRleE9mKCdzZXktc2hvdycpICE9PSAtMTsgfVxuICBmdW5jdGlvbiBoaWRkZW4gKGxpKSB7IHJldHVybiBsaS5jbGFzc05hbWUuaW5kZXhPZignc2V5LWhpZGUnKSAhPT0gLTE7IH1cblxuICBmdW5jdGlvbiBzaG93ICgpIHtcbiAgICBleWUucmVmcmVzaCgpO1xuICAgIGlmICghdmlzaWJsZSgpKSB7XG4gICAgICBjb250YWluZXIuY2xhc3NOYW1lICs9ICcgc2V5LXNob3cnO1xuICAgICAgY3Jvc3N2ZW50LmZhYnJpY2F0ZShhdHRhY2htZW50LCAnaG9yc2V5LXNob3cnKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0b2dnbGVyIChlKSB7XG4gICAgY29uc3QgbGVmdCA9IGUud2hpY2ggPT09IDEgJiYgIWUubWV0YUtleSAmJiAhZS5jdHJsS2V5O1xuICAgIGlmIChsZWZ0ID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuOyAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgaG9uZXN0IHRvIGdvZCBsZWZ0LWNsaWNrc1xuICAgIH1cbiAgICB0b2dnbGUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvZ2dsZSAoKSB7XG4gICAgaWYgKCF2aXNpYmxlKCkpIHtcbiAgICAgIHNob3coKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlkZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNlbGVjdCAobGkpIHtcbiAgICB1bnNlbGVjdCgpO1xuICAgIGlmIChsaSkge1xuICAgICAgc2VsZWN0aW9uID0gbGk7XG4gICAgICBzZWxlY3Rpb24uY2xhc3NOYW1lICs9ICcgc2V5LXNlbGVjdGVkJztcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1bnNlbGVjdCAoKSB7XG4gICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgc2VsZWN0aW9uLmNsYXNzTmFtZSA9IHNlbGVjdGlvbi5jbGFzc05hbWUucmVwbGFjZSgvIHNleS1zZWxlY3RlZC9nLCAnJyk7XG4gICAgICBzZWxlY3Rpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdmUgKHVwLCBtb3Zlcykge1xuICAgIGNvbnN0IHRvdGFsID0gYXBpLnNvdXJjZS5sZW5ndGg7XG4gICAgaWYgKHRvdGFsID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChtb3ZlcyA+IHRvdGFsKSB7XG4gICAgICB1bnNlbGVjdCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjYXQgPSBmaW5kQ2F0ZWdvcnkoc2VsZWN0aW9uKSB8fCBjYXRlZ29yaWVzLmZpcnN0Q2hpbGQ7XG4gICAgY29uc3QgZmlyc3QgPSB1cCA/ICdsYXN0Q2hpbGQnIDogJ2ZpcnN0Q2hpbGQnO1xuICAgIGNvbnN0IGxhc3QgPSB1cCA/ICdmaXJzdENoaWxkJyA6ICdsYXN0Q2hpbGQnO1xuICAgIGNvbnN0IG5leHQgPSB1cCA/ICdwcmV2aW91c1NpYmxpbmcnIDogJ25leHRTaWJsaW5nJztcbiAgICBjb25zdCBwcmV2ID0gdXAgPyAnbmV4dFNpYmxpbmcnIDogJ3ByZXZpb3VzU2libGluZyc7XG4gICAgY29uc3QgbGkgPSBmaW5kTmV4dCgpO1xuICAgIHNlbGVjdChsaSk7XG5cbiAgICBpZiAoaGlkZGVuKGxpKSkge1xuICAgICAgbW92ZSh1cCwgbW92ZXMgPyBtb3ZlcyArIDEgOiAxKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmaW5kQ2F0ZWdvcnkgKGVsKSB7XG4gICAgICB3aGlsZSAoZWwpIHtcbiAgICAgICAgaWYgKHNla3Rvci5tYXRjaGVzU2VsZWN0b3IoZWwucGFyZW50RWxlbWVudCwgJy5zZXktY2F0ZWdvcnknKSkge1xuICAgICAgICAgIHJldHVybiBlbC5wYXJlbnRFbGVtZW50O1xuICAgICAgICB9XG4gICAgICAgIGVsID0gZWwucGFyZW50RWxlbWVudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZpbmROZXh0ICgpIHtcbiAgICAgIGlmIChzZWxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHNlbGVjdGlvbltuZXh0XSkge1xuICAgICAgICAgIHJldHVybiBzZWxlY3Rpb25bbmV4dF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNhdFtuZXh0XSAmJiBmaW5kTGlzdChjYXRbbmV4dF0pW2ZpcnN0XSkge1xuICAgICAgICAgIHJldHVybiBmaW5kTGlzdChjYXRbbmV4dF0pW2ZpcnN0XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZpbmRMaXN0KGNhdGVnb3JpZXNbZmlyc3RdKVtmaXJzdF07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGlkZSAoKSB7XG4gICAgZXllLnNsZWVwKCk7XG4gICAgY29udGFpbmVyLmNsYXNzTmFtZSA9IGNvbnRhaW5lci5jbGFzc05hbWUucmVwbGFjZSgvIHNleS1zaG93L2csICcnKTtcbiAgICB1bnNlbGVjdCgpO1xuICAgIGNyb3NzdmVudC5mYWJyaWNhdGUoYXR0YWNobWVudCwgJ2hvcnNleS1oaWRlJyk7XG4gICAgaWYgKGVsLnZhbHVlID09PSBsYXN0UHJlZml4KSB7XG4gICAgICBlbC52YWx1ZSA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGtleWRvd24gKGUpIHtcbiAgICBjb25zdCBzaG93biA9IHZpc2libGUoKTtcbiAgICBjb25zdCB3aGljaCA9IGUud2hpY2ggfHwgZS5rZXlDb2RlO1xuICAgIGlmICh3aGljaCA9PT0gS0VZX0RPV04pIHtcbiAgICAgIGlmIChhbnlJbnB1dCAmJiBvLmF1dG9TaG93T25VcERvd24pIHtcbiAgICAgICAgc2hvdygpO1xuICAgICAgfVxuICAgICAgaWYgKHNob3duKSB7XG4gICAgICAgIG1vdmUoKTtcbiAgICAgICAgc3RvcChlKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHdoaWNoID09PSBLRVlfVVApIHtcbiAgICAgIGlmIChhbnlJbnB1dCAmJiBvLmF1dG9TaG93T25VcERvd24pIHtcbiAgICAgICAgc2hvdygpO1xuICAgICAgfVxuICAgICAgaWYgKHNob3duKSB7XG4gICAgICAgIG1vdmUodHJ1ZSk7XG4gICAgICAgIHN0b3AoZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh3aGljaCA9PT0gS0VZX0JBQ0tTUEFDRSkge1xuICAgICAgaWYgKGFueUlucHV0ICYmIG8uYXV0b1Nob3dPblVwRG93bikge1xuICAgICAgICBzaG93KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzaG93bikge1xuICAgICAgaWYgKHdoaWNoID09PSBLRVlfRU5URVIpIHtcbiAgICAgICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgICAgIGNyb3NzdmVudC5mYWJyaWNhdGUoc2VsZWN0aW9uLCAnY2xpY2snKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgc3RvcChlKTtcbiAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT09IEtFWV9FU0MpIHtcbiAgICAgICAgaGlkZSgpO1xuICAgICAgICBzdG9wKGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0b3AgKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3dOb1Jlc3VsdHMgKCkge1xuICAgIGlmIChub25lTWF0Y2gpIHtcbiAgICAgIG5vbmVNYXRjaC5jbGFzc0xpc3QucmVtb3ZlKCdzZXktaGlkZScpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZGVOb1Jlc3VsdHMgKCkge1xuICAgIGlmIChub25lTWF0Y2gpIHtcbiAgICAgIG5vbmVNYXRjaC5jbGFzc0xpc3QuYWRkKCdzZXktaGlkZScpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlcmluZyAoKSB7XG4gICAgaWYgKCF2aXNpYmxlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVib3VuY2VkTG9hZGluZyh0cnVlKTtcbiAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGF0dGFjaG1lbnQsICdob3JzZXktZmlsdGVyJyk7XG4gICAgY29uc3QgdmFsdWUgPSByZWFkSW5wdXQoKTtcbiAgICBpZiAoIW8uYmxhbmtTZWFyY2ggJiYgIXZhbHVlKSB7XG4gICAgICBoaWRlKCk7IHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgbm9tYXRjaCA9IG5vTWF0Y2hlcyh7IHF1ZXJ5OiB2YWx1ZSB9KTtcbiAgICBsZXQgY291bnQgPSB3YWxrQ2F0ZWdvcmllcygpO1xuICAgIGlmIChjb3VudCA9PT0gMCAmJiBub21hdGNoICYmIGhhc0l0ZW1zKSB7XG4gICAgICBzaG93Tm9SZXN1bHRzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZGVOb1Jlc3VsdHMoKTtcbiAgICB9XG4gICAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICAgIG1vdmUoKTtcbiAgICB9XG4gICAgaWYgKCFzZWxlY3Rpb24gJiYgIW5vbWF0Y2gpIHtcbiAgICAgIGhpZGUoKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gd2Fsa0NhdGVnb3JpZXMgKCkge1xuICAgICAgbGV0IGNhdGVnb3J5ID0gY2F0ZWdvcmllcy5maXJzdENoaWxkO1xuICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgIHdoaWxlIChjYXRlZ29yeSkge1xuICAgICAgICBjb25zdCBsaXN0ID0gZmluZExpc3QoY2F0ZWdvcnkpO1xuICAgICAgICBjb25zdCBwYXJ0aWFsID0gd2Fsa0NhdGVnb3J5KGxpc3QpO1xuICAgICAgICBpZiAocGFydGlhbCA9PT0gMCkge1xuICAgICAgICAgIGNhdGVnb3J5LmNsYXNzTGlzdC5hZGQoJ3NleS1oaWRlJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2F0ZWdvcnkuY2xhc3NMaXN0LnJlbW92ZSgnc2V5LWhpZGUnKTtcbiAgICAgICAgfVxuICAgICAgICBjb3VudCArPSBwYXJ0aWFsO1xuICAgICAgICBjYXRlZ29yeSA9IGNhdGVnb3J5Lm5leHRTaWJsaW5nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvdW50O1xuICAgIH1cbiAgICBmdW5jdGlvbiB3YWxrQ2F0ZWdvcnkgKHVsKSB7XG4gICAgICBsZXQgbGkgPSB1bC5maXJzdENoaWxkO1xuICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgIHdoaWxlIChsaSkge1xuICAgICAgICBpZiAoY291bnQgPj0gbGltaXQpIHtcbiAgICAgICAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGxpLCAnaG9yc2V5LWhpZGUnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGxpLCAnaG9yc2V5LWZpbHRlcicpO1xuICAgICAgICAgIGlmIChsaS5jbGFzc05hbWUuaW5kZXhPZignc2V5LWhpZGUnKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGNvdW50Kys7XG4gICAgICAgICAgICBpZiAoaGlnaGxpZ2h0ZXIpIHtcbiAgICAgICAgICAgICAgaGlnaGxpZ2h0KGxpLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxpID0gbGkubmV4dFNpYmxpbmc7XG4gICAgICB9XG4gICAgICByZXR1cm4gY291bnQ7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZGVmZXJyZWRGaWx0ZXJpbmdOb0VudGVyIChlKSB7XG4gICAgY29uc3Qgd2hpY2ggPSBlLndoaWNoIHx8IGUua2V5Q29kZTtcbiAgICBpZiAod2hpY2ggPT09IEtFWV9FTlRFUikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkZWZlcnJlZEZpbHRlcmluZygpO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVmZXJyZWRTaG93IChlKSB7XG4gICAgY29uc3Qgd2hpY2ggPSBlLndoaWNoIHx8IGUua2V5Q29kZTtcbiAgICBpZiAod2hpY2ggPT09IEtFWV9FTlRFUiB8fCB3aGljaCA9PT0gS0VZX1RBQikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRUaW1lb3V0KHNob3csIDApO1xuICB9XG5cbiAgZnVuY3Rpb24gYXV0b2NvbXBsZXRlRXZlbnRUYXJnZXQgKGUpIHtcbiAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgaWYgKHRhcmdldCA9PT0gYXR0YWNobWVudCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHdoaWxlICh0YXJnZXQpIHtcbiAgICAgIGlmICh0YXJnZXQgPT09IGNvbnRhaW5lciB8fCB0YXJnZXQgPT09IGF0dGFjaG1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlT25CbHVyIChlKSB7XG4gICAgY29uc3Qgd2hpY2ggPSBlLndoaWNoIHx8IGUua2V5Q29kZTtcbiAgICBpZiAod2hpY2ggPT09IEtFWV9UQUIpIHtcbiAgICAgIGhpZGUoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlT25DbGljayAoZSkge1xuICAgIGlmIChhdXRvY29tcGxldGVFdmVudFRhcmdldChlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBoaWRlKCk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnB1dEV2ZW50cyAocmVtb3ZlKSB7XG4gICAgY29uc3Qgb3AgPSByZW1vdmUgPyAncmVtb3ZlJyA6ICdhZGQnO1xuICAgIGlmIChleWUpIHtcbiAgICAgIGV5ZS5kZXN0cm95KCk7XG4gICAgICBleWUgPSBudWxsO1xuICAgIH1cbiAgICBpZiAoIXJlbW92ZSkge1xuICAgICAgZXllID0gYnVsbHNleWUoY29udGFpbmVyLCBhdHRhY2htZW50LCB7XG4gICAgICAgIGNhcmV0OiBhbnlJbnB1dCAmJiBhdHRhY2htZW50LnRhZ05hbWUgIT09ICdJTlBVVCcsXG4gICAgICAgIGNvbnRleHQ6IG8uYXBwZW5kVG9cbiAgICAgIH0pO1xuICAgICAgaWYgKCF2aXNpYmxlKCkpIHsgZXllLnNsZWVwKCk7IH1cbiAgICB9XG4gICAgaWYgKHJlbW92ZSB8fCAoYW55SW5wdXQgJiYgZG9jLmFjdGl2ZUVsZW1lbnQgIT09IGF0dGFjaG1lbnQpKSB7XG4gICAgICBjcm9zc3ZlbnRbb3BdKGF0dGFjaG1lbnQsICdmb2N1cycsIGxvYWRpbmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2FkaW5nKCk7XG4gICAgfVxuICAgIGlmIChhbnlJbnB1dCkge1xuICAgICAgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5cHJlc3MnLCBkZWZlcnJlZFNob3cpO1xuICAgICAgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5cHJlc3MnLCBkZWZlcnJlZEZpbHRlcmluZyk7XG4gICAgICBjcm9zc3ZlbnRbb3BdKGF0dGFjaG1lbnQsICdrZXlkb3duJywgZGVmZXJyZWRGaWx0ZXJpbmdOb0VudGVyKTtcbiAgICAgIGNyb3NzdmVudFtvcF0oYXR0YWNobWVudCwgJ3Bhc3RlJywgZGVmZXJyZWRGaWx0ZXJpbmcpO1xuICAgICAgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5ZG93bicsIGtleWRvd24pO1xuICAgICAgaWYgKG8uYXV0b0hpZGVPbkJsdXIpIHsgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5ZG93bicsIGhpZGVPbkJsdXIpOyB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNyb3NzdmVudFtvcF0oYXR0YWNobWVudCwgJ2NsaWNrJywgdG9nZ2xlcik7XG4gICAgICBjcm9zc3ZlbnRbb3BdKGRvY0VsZW1lbnQsICdrZXlkb3duJywga2V5ZG93bik7XG4gICAgfVxuICAgIGlmIChvLmF1dG9IaWRlT25DbGljaykgeyBjcm9zc3ZlbnRbb3BdKGRvYywgJ2NsaWNrJywgaGlkZU9uQ2xpY2spOyB9XG4gICAgaWYgKGZvcm0pIHsgY3Jvc3N2ZW50W29wXShmb3JtLCAnc3VibWl0JywgaGlkZSk7IH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3kgKCkge1xuICAgIGlucHV0RXZlbnRzKHRydWUpO1xuICAgIGlmIChwYXJlbnQuY29udGFpbnMoY29udGFpbmVyKSkgeyBwYXJlbnQucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTsgfVxuICB9XG5cbiAgZnVuY3Rpb24gZGVmYXVsdFNldHRlciAodmFsdWUpIHtcbiAgICBpZiAodGV4dElucHV0KSB7XG4gICAgICBpZiAoc2V0QXBwZW5kcyA9PT0gdHJ1ZSkge1xuICAgICAgICBlbC52YWx1ZSArPSAnICcgKyB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsLnZhbHVlID0gdmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzZXRBcHBlbmRzID09PSB0cnVlKSB7XG4gICAgICAgIGVsLmlubmVySFRNTCArPSAnICcgKyB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsLmlubmVySFRNTCA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZmF1bHRJdGVtUmVuZGVyZXIgKGxpLCBzdWdnZXN0aW9uKSB7XG4gICAgdGV4dChsaSwgZ2V0VGV4dChzdWdnZXN0aW9uKSk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0Q2F0ZWdvcnlSZW5kZXJlciAoZGl2LCBkYXRhKSB7XG4gICAgaWYgKGRhdGEuaWQgIT09ICdkZWZhdWx0Jykge1xuICAgICAgY29uc3QgaWQgPSB0YWcoJ2RpdicsICdzZXktY2F0ZWdvcnktaWQnKTtcbiAgICAgIGRpdi5hcHBlbmRDaGlsZChpZCk7XG4gICAgICB0ZXh0KGlkLCBkYXRhLmlkKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0RmlsdGVyIChxLCBzdWdnZXN0aW9uKSB7XG4gICAgY29uc3QgbmVlZGxlID0gcS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IHRleHQgPSBnZXRUZXh0KHN1Z2dlc3Rpb24pIHx8ICcnO1xuICAgIGlmIChmdXp6eXNlYXJjaChuZWVkbGUsIHRleHQudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IGdldFZhbHVlKHN1Z2dlc3Rpb24pIHx8ICcnO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBmdXp6eXNlYXJjaChuZWVkbGUsIHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gbG9vcGJhY2tUb0FuY2hvciAodGV4dCwgcCkge1xuICAgIGxldCByZXN1bHQgPSAnJztcbiAgICBsZXQgYW5jaG9yZWQgPSBmYWxzZTtcbiAgICBsZXQgc3RhcnQgPSBwLnN0YXJ0O1xuICAgIHdoaWxlIChhbmNob3JlZCA9PT0gZmFsc2UgJiYgc3RhcnQgPj0gMCkge1xuICAgICAgcmVzdWx0ID0gdGV4dC5zdWJzdHIoc3RhcnQgLSAxLCBwLnN0YXJ0IC0gc3RhcnQgKyAxKTtcbiAgICAgIGFuY2hvcmVkID0gcmFuY2hvcmxlZnQudGVzdChyZXN1bHQpO1xuICAgICAgc3RhcnQtLTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRleHQ6IGFuY2hvcmVkID8gcmVzdWx0IDogbnVsbCxcbiAgICAgIHN0YXJ0XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlckFuY2hvcmVkVGV4dCAocSwgc3VnZ2VzdGlvbikge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gc2VsbChlbCk7XG4gICAgY29uc3QgaW5wdXQgPSBsb29wYmFja1RvQW5jaG9yKHEsIHBvc2l0aW9uKS50ZXh0O1xuICAgIGlmIChpbnB1dCkge1xuICAgICAgcmV0dXJuIHsgaW5wdXQsIHN1Z2dlc3Rpb24gfTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBhcHBlbmRUZXh0ICh2YWx1ZSkge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBlbC52YWx1ZTtcbiAgICBjb25zdCBwb3NpdGlvbiA9IHNlbGwoZWwpO1xuICAgIGNvbnN0IGlucHV0ID0gbG9vcGJhY2tUb0FuY2hvcihjdXJyZW50LCBwb3NpdGlvbik7XG4gICAgY29uc3QgbGVmdCA9IGN1cnJlbnQuc3Vic3RyKDAsIGlucHV0LnN0YXJ0KTtcbiAgICBjb25zdCByaWdodCA9IGN1cnJlbnQuc3Vic3RyKGlucHV0LnN0YXJ0ICsgaW5wdXQudGV4dC5sZW5ndGggKyAocG9zaXRpb24uZW5kIC0gcG9zaXRpb24uc3RhcnQpKTtcbiAgICBjb25zdCBiZWZvcmUgPSBsZWZ0ICsgdmFsdWUgKyAnICc7XG5cbiAgICBlbC52YWx1ZSA9IGJlZm9yZSArIHJpZ2h0O1xuICAgIHNlbGwoZWwsIHsgc3RhcnQ6IGJlZm9yZS5sZW5ndGgsIGVuZDogYmVmb3JlLmxlbmd0aCB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlckFuY2hvcmVkSFRNTCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBbmNob3JpbmcgaW4gZWRpdGFibGUgZWxlbWVudHMgaXMgZGlzYWJsZWQgYnkgZGVmYXVsdC4nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGVuZEhUTUwgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQW5jaG9yaW5nIGluIGVkaXRhYmxlIGVsZW1lbnRzIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQuJyk7XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kTGlzdCAoY2F0ZWdvcnkpIHsgcmV0dXJuIHNla3RvcignLnNleS1saXN0JywgY2F0ZWdvcnkpWzBdOyB9XG59XG5cbmZ1bmN0aW9uIGlzSW5wdXQgKGVsKSB7IHJldHVybiBlbC50YWdOYW1lID09PSAnSU5QVVQnIHx8IGVsLnRhZ05hbWUgPT09ICdURVhUQVJFQSc7IH1cblxuZnVuY3Rpb24gdGFnICh0eXBlLCBjbGFzc05hbWUpIHtcbiAgY29uc3QgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCh0eXBlKTtcbiAgZWwuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICByZXR1cm4gZWw7XG59XG5cbmZ1bmN0aW9uIGRlZmVyIChmbikgeyByZXR1cm4gZnVuY3Rpb24gKCkgeyBzZXRUaW1lb3V0KGZuLCAwKTsgfTsgfVxuZnVuY3Rpb24gdGV4dCAoZWwsIHZhbHVlKSB7IGVsLmlubmVyVGV4dCA9IGVsLnRleHRDb250ZW50ID0gdmFsdWU7IH1cblxuZnVuY3Rpb24gaXNFZGl0YWJsZSAoZWwpIHtcbiAgY29uc3QgdmFsdWUgPSBlbC5nZXRBdHRyaWJ1dGUoJ2NvbnRlbnRFZGl0YWJsZScpO1xuICBpZiAodmFsdWUgPT09ICdmYWxzZScpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHZhbHVlID09PSAndHJ1ZScpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoZWwucGFyZW50RWxlbWVudCkge1xuICAgIHJldHVybiBpc0VkaXRhYmxlKGVsLnBhcmVudEVsZW1lbnQpO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBob3JzZXk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGF0b2EgKGEsIG4pIHsgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGEsIG4pOyB9XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjcm9zc3ZlbnQgPSByZXF1aXJlKCdjcm9zc3ZlbnQnKTtcbnZhciB0aHJvdHRsZSA9IHJlcXVpcmUoJy4vdGhyb3R0bGUnKTtcbnZhciB0YWlsb3JtYWRlID0gcmVxdWlyZSgnLi90YWlsb3JtYWRlJyk7XG5cbmZ1bmN0aW9uIGJ1bGxzZXllIChlbCwgdGFyZ2V0LCBvcHRpb25zKSB7XG4gIHZhciBvID0gb3B0aW9ucztcbiAgdmFyIGRvbVRhcmdldCA9IHRhcmdldCAmJiB0YXJnZXQudGFnTmFtZTtcblxuICBpZiAoIWRvbVRhcmdldCAmJiBhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgbyA9IHRhcmdldDtcbiAgfVxuICBpZiAoIWRvbVRhcmdldCkge1xuICAgIHRhcmdldCA9IGVsO1xuICB9XG4gIGlmICghbykgeyBvID0ge307IH1cblxuICB2YXIgZGVzdHJveWVkID0gZmFsc2U7XG4gIHZhciB0aHJvdHRsZWRXcml0ZSA9IHRocm90dGxlKHdyaXRlLCAzMCk7XG4gIHZhciB0YWlsb3JPcHRpb25zID0geyB1cGRhdGU6IG8uYXV0b3VwZGF0ZVRvQ2FyZXQgIT09IGZhbHNlICYmIHVwZGF0ZSB9O1xuICB2YXIgdGFpbG9yID0gby5jYXJldCAmJiB0YWlsb3JtYWRlKHRhcmdldCwgdGFpbG9yT3B0aW9ucyk7XG5cbiAgd3JpdGUoKTtcblxuICBpZiAoby50cmFja2luZyAhPT0gZmFsc2UpIHtcbiAgICBjcm9zc3ZlbnQuYWRkKHdpbmRvdywgJ3Jlc2l6ZScsIHRocm90dGxlZFdyaXRlKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgcmVhZDogcmVhZE51bGwsXG4gICAgcmVmcmVzaDogd3JpdGUsXG4gICAgZGVzdHJveTogZGVzdHJveSxcbiAgICBzbGVlcDogc2xlZXBcbiAgfTtcblxuICBmdW5jdGlvbiBzbGVlcCAoKSB7XG4gICAgdGFpbG9yT3B0aW9ucy5zbGVlcGluZyA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiByZWFkTnVsbCAoKSB7IHJldHVybiByZWFkKCk7IH1cblxuICBmdW5jdGlvbiByZWFkIChyZWFkaW5ncykge1xuICAgIHZhciBib3VuZHMgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIHNjcm9sbFRvcCA9IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7XG4gICAgaWYgKHRhaWxvcikge1xuICAgICAgcmVhZGluZ3MgPSB0YWlsb3IucmVhZCgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgeDogKHJlYWRpbmdzLmFic29sdXRlID8gMCA6IGJvdW5kcy5sZWZ0KSArIHJlYWRpbmdzLngsXG4gICAgICAgIHk6IChyZWFkaW5ncy5hYnNvbHV0ZSA/IDAgOiBib3VuZHMudG9wKSArIHNjcm9sbFRvcCArIHJlYWRpbmdzLnkgKyAyMFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGJvdW5kcy5sZWZ0LFxuICAgICAgeTogYm91bmRzLnRvcCArIHNjcm9sbFRvcFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUgKHJlYWRpbmdzKSB7XG4gICAgd3JpdGUocmVhZGluZ3MpO1xuICB9XG5cbiAgZnVuY3Rpb24gd3JpdGUgKHJlYWRpbmdzKSB7XG4gICAgaWYgKGRlc3Ryb3llZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCdWxsc2V5ZSBjYW5cXCd0IHJlZnJlc2ggYWZ0ZXIgYmVpbmcgZGVzdHJveWVkLiBDcmVhdGUgYW5vdGhlciBpbnN0YW5jZSBpbnN0ZWFkLicpO1xuICAgIH1cbiAgICBpZiAodGFpbG9yICYmICFyZWFkaW5ncykge1xuICAgICAgdGFpbG9yT3B0aW9ucy5zbGVlcGluZyA9IGZhbHNlO1xuICAgICAgdGFpbG9yLnJlZnJlc2goKTsgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcCA9IHJlYWQocmVhZGluZ3MpO1xuICAgIGlmICghdGFpbG9yICYmIHRhcmdldCAhPT0gZWwpIHtcbiAgICAgIHAueSArPSB0YXJnZXQub2Zmc2V0SGVpZ2h0O1xuICAgIH1cbiAgICB2YXIgY29udGV4dCA9IG8uY29udGV4dDtcbiAgICBlbC5zdHlsZS5sZWZ0ID0gcC54ICsgJ3B4JztcbiAgICBlbC5zdHlsZS50b3AgPSAoY29udGV4dCA/IGNvbnRleHQub2Zmc2V0SGVpZ2h0IDogcC55KSArICdweCc7XG4gIH1cblxuICBmdW5jdGlvbiBkZXN0cm95ICgpIHtcbiAgICBpZiAodGFpbG9yKSB7IHRhaWxvci5kZXN0cm95KCk7IH1cbiAgICBjcm9zc3ZlbnQucmVtb3ZlKHdpbmRvdywgJ3Jlc2l6ZScsIHRocm90dGxlZFdyaXRlKTtcbiAgICBkZXN0cm95ZWQgPSB0cnVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnVsbHNleWU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBzZWxsID0gcmVxdWlyZSgnc2VsbCcpO1xudmFyIGNyb3NzdmVudCA9IHJlcXVpcmUoJ2Nyb3NzdmVudCcpO1xudmFyIHNlbGVjY2lvbiA9IHJlcXVpcmUoJ3NlbGVjY2lvbicpO1xudmFyIHRocm90dGxlID0gcmVxdWlyZSgnLi90aHJvdHRsZScpO1xudmFyIGdldFNlbGVjdGlvbiA9IHNlbGVjY2lvbi5nZXQ7XG52YXIgcHJvcHMgPSBbXG4gICdkaXJlY3Rpb24nLFxuICAnYm94U2l6aW5nJyxcbiAgJ3dpZHRoJyxcbiAgJ2hlaWdodCcsXG4gICdvdmVyZmxvd1gnLFxuICAnb3ZlcmZsb3dZJyxcbiAgJ2JvcmRlclRvcFdpZHRoJyxcbiAgJ2JvcmRlclJpZ2h0V2lkdGgnLFxuICAnYm9yZGVyQm90dG9tV2lkdGgnLFxuICAnYm9yZGVyTGVmdFdpZHRoJyxcbiAgJ3BhZGRpbmdUb3AnLFxuICAncGFkZGluZ1JpZ2h0JyxcbiAgJ3BhZGRpbmdCb3R0b20nLFxuICAncGFkZGluZ0xlZnQnLFxuICAnZm9udFN0eWxlJyxcbiAgJ2ZvbnRWYXJpYW50JyxcbiAgJ2ZvbnRXZWlnaHQnLFxuICAnZm9udFN0cmV0Y2gnLFxuICAnZm9udFNpemUnLFxuICAnZm9udFNpemVBZGp1c3QnLFxuICAnbGluZUhlaWdodCcsXG4gICdmb250RmFtaWx5JyxcbiAgJ3RleHRBbGlnbicsXG4gICd0ZXh0VHJhbnNmb3JtJyxcbiAgJ3RleHRJbmRlbnQnLFxuICAndGV4dERlY29yYXRpb24nLFxuICAnbGV0dGVyU3BhY2luZycsXG4gICd3b3JkU3BhY2luZydcbl07XG52YXIgd2luID0gZ2xvYmFsO1xudmFyIGRvYyA9IGRvY3VtZW50O1xudmFyIGZmID0gd2luLm1veklubmVyU2NyZWVuWCAhPT0gbnVsbCAmJiB3aW4ubW96SW5uZXJTY3JlZW5YICE9PSB2b2lkIDA7XG5cbmZ1bmN0aW9uIHRhaWxvcm1hZGUgKGVsLCBvcHRpb25zKSB7XG4gIHZhciB0ZXh0SW5wdXQgPSBlbC50YWdOYW1lID09PSAnSU5QVVQnIHx8IGVsLnRhZ05hbWUgPT09ICdURVhUQVJFQSc7XG4gIHZhciB0aHJvdHRsZWRSZWZyZXNoID0gdGhyb3R0bGUocmVmcmVzaCwgMzApO1xuICB2YXIgbyA9IG9wdGlvbnMgfHwge307XG5cbiAgYmluZCgpO1xuXG4gIHJldHVybiB7XG4gICAgcmVhZDogcmVhZFBvc2l0aW9uLFxuICAgIHJlZnJlc2g6IHRocm90dGxlZFJlZnJlc2gsXG4gICAgZGVzdHJveTogZGVzdHJveVxuICB9O1xuXG4gIGZ1bmN0aW9uIG5vb3AgKCkge31cbiAgZnVuY3Rpb24gcmVhZFBvc2l0aW9uICgpIHsgcmV0dXJuICh0ZXh0SW5wdXQgPyBjb29yZHNUZXh0IDogY29vcmRzSFRNTCkoKTsgfVxuXG4gIGZ1bmN0aW9uIHJlZnJlc2ggKCkge1xuICAgIGlmIChvLnNsZWVwaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiAoby51cGRhdGUgfHwgbm9vcCkocmVhZFBvc2l0aW9uKCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gY29vcmRzVGV4dCAoKSB7XG4gICAgdmFyIHAgPSBzZWxsKGVsKTtcbiAgICB2YXIgY29udGV4dCA9IHByZXBhcmUoKTtcbiAgICB2YXIgcmVhZGluZ3MgPSByZWFkVGV4dENvb3Jkcyhjb250ZXh0LCBwLnN0YXJ0KTtcbiAgICBkb2MuYm9keS5yZW1vdmVDaGlsZChjb250ZXh0Lm1pcnJvcik7XG4gICAgcmV0dXJuIHJlYWRpbmdzO1xuICB9XG5cbiAgZnVuY3Rpb24gY29vcmRzSFRNTCAoKSB7XG4gICAgdmFyIHNlbCA9IGdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWwucmFuZ2VDb3VudCkge1xuICAgICAgdmFyIHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCk7XG4gICAgICB2YXIgbmVlZHNUb1dvcmtBcm91bmROZXdsaW5lQnVnID0gcmFuZ2Uuc3RhcnRDb250YWluZXIubm9kZU5hbWUgPT09ICdQJyAmJiByYW5nZS5zdGFydE9mZnNldCA9PT0gMDtcbiAgICAgIGlmIChuZWVkc1RvV29ya0Fyb3VuZE5ld2xpbmVCdWcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB4OiByYW5nZS5zdGFydENvbnRhaW5lci5vZmZzZXRMZWZ0LFxuICAgICAgICAgIHk6IHJhbmdlLnN0YXJ0Q29udGFpbmVyLm9mZnNldFRvcCxcbiAgICAgICAgICBhYnNvbHV0ZTogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHJhbmdlLmdldENsaWVudFJlY3RzKSB7XG4gICAgICAgIHZhciByZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgIGlmIChyZWN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHJlY3RzWzBdLmxlZnQsXG4gICAgICAgICAgICB5OiByZWN0c1swXS50b3AsXG4gICAgICAgICAgICBhYnNvbHV0ZTogdHJ1ZVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgeDogMCwgeTogMCB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVhZFRleHRDb29yZHMgKGNvbnRleHQsIHApIHtcbiAgICB2YXIgcmVzdCA9IGRvYy5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgdmFyIG1pcnJvciA9IGNvbnRleHQubWlycm9yO1xuICAgIHZhciBjb21wdXRlZCA9IGNvbnRleHQuY29tcHV0ZWQ7XG5cbiAgICB3cml0ZShtaXJyb3IsIHJlYWQoZWwpLnN1YnN0cmluZygwLCBwKSk7XG5cbiAgICBpZiAoZWwudGFnTmFtZSA9PT0gJ0lOUFVUJykge1xuICAgICAgbWlycm9yLnRleHRDb250ZW50ID0gbWlycm9yLnRleHRDb250ZW50LnJlcGxhY2UoL1xccy9nLCAnXFx1MDBhMCcpO1xuICAgIH1cblxuICAgIHdyaXRlKHJlc3QsIHJlYWQoZWwpLnN1YnN0cmluZyhwKSB8fCAnLicpO1xuXG4gICAgbWlycm9yLmFwcGVuZENoaWxkKHJlc3QpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHJlc3Qub2Zmc2V0TGVmdCArIHBhcnNlSW50KGNvbXB1dGVkWydib3JkZXJMZWZ0V2lkdGgnXSksXG4gICAgICB5OiByZXN0Lm9mZnNldFRvcCArIHBhcnNlSW50KGNvbXB1dGVkWydib3JkZXJUb3BXaWR0aCddKVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChlbCkge1xuICAgIHJldHVybiB0ZXh0SW5wdXQgPyBlbC52YWx1ZSA6IGVsLmlubmVySFRNTDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByZXBhcmUgKCkge1xuICAgIHZhciBjb21wdXRlZCA9IHdpbi5nZXRDb21wdXRlZFN0eWxlID8gZ2V0Q29tcHV0ZWRTdHlsZShlbCkgOiBlbC5jdXJyZW50U3R5bGU7XG4gICAgdmFyIG1pcnJvciA9IGRvYy5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB2YXIgc3R5bGUgPSBtaXJyb3Iuc3R5bGU7XG5cbiAgICBkb2MuYm9keS5hcHBlbmRDaGlsZChtaXJyb3IpO1xuXG4gICAgaWYgKGVsLnRhZ05hbWUgIT09ICdJTlBVVCcpIHtcbiAgICAgIHN0eWxlLndvcmRXcmFwID0gJ2JyZWFrLXdvcmQnO1xuICAgIH1cbiAgICBzdHlsZS53aGl0ZVNwYWNlID0gJ3ByZS13cmFwJztcbiAgICBzdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgIHByb3BzLmZvckVhY2goY29weSk7XG5cbiAgICBpZiAoZmYpIHtcbiAgICAgIHN0eWxlLndpZHRoID0gcGFyc2VJbnQoY29tcHV0ZWQud2lkdGgpIC0gMiArICdweCc7XG4gICAgICBpZiAoZWwuc2Nyb2xsSGVpZ2h0ID4gcGFyc2VJbnQoY29tcHV0ZWQuaGVpZ2h0KSkge1xuICAgICAgICBzdHlsZS5vdmVyZmxvd1kgPSAnc2Nyb2xsJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcbiAgICB9XG4gICAgcmV0dXJuIHsgbWlycm9yOiBtaXJyb3IsIGNvbXB1dGVkOiBjb21wdXRlZCB9O1xuXG4gICAgZnVuY3Rpb24gY29weSAocHJvcCkge1xuICAgICAgc3R5bGVbcHJvcF0gPSBjb21wdXRlZFtwcm9wXTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB3cml0ZSAoZWwsIHZhbHVlKSB7XG4gICAgaWYgKHRleHRJbnB1dCkge1xuICAgICAgZWwudGV4dENvbnRlbnQgPSB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWwuaW5uZXJIVE1MID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYmluZCAocmVtb3ZlKSB7XG4gICAgdmFyIG9wID0gcmVtb3ZlID8gJ3JlbW92ZScgOiAnYWRkJztcbiAgICBjcm9zc3ZlbnRbb3BdKGVsLCAna2V5ZG93bicsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdrZXl1cCcsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdpbnB1dCcsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdwYXN0ZScsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdjaGFuZ2UnLCB0aHJvdHRsZWRSZWZyZXNoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3kgKCkge1xuICAgIGJpbmQodHJ1ZSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0YWlsb3JtYWRlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiB0aHJvdHRsZSAoZm4sIGJvdW5kYXJ5KSB7XG4gIHZhciBsYXN0ID0gLUluZmluaXR5O1xuICB2YXIgdGltZXI7XG4gIHJldHVybiBmdW5jdGlvbiBib3VuY2VkICgpIHtcbiAgICBpZiAodGltZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdW5ib3VuZCgpO1xuXG4gICAgZnVuY3Rpb24gdW5ib3VuZCAoKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgdmFyIG5leHQgPSBsYXN0ICsgYm91bmRhcnk7XG4gICAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGlmIChub3cgPiBuZXh0KSB7XG4gICAgICAgIGxhc3QgPSBub3c7XG4gICAgICAgIGZuKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQodW5ib3VuZCwgbmV4dCAtIG5vdyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRocm90dGxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdGlja3kgPSByZXF1aXJlKCd0aWNreScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGRlYm91bmNlIChmbiwgYXJncywgY3R4KSB7XG4gIGlmICghZm4pIHsgcmV0dXJuOyB9XG4gIHRpY2t5KGZ1bmN0aW9uIHJ1biAoKSB7XG4gICAgZm4uYXBwbHkoY3R4IHx8IG51bGwsIGFyZ3MgfHwgW10pO1xuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBhdG9hID0gcmVxdWlyZSgnYXRvYScpO1xudmFyIGRlYm91bmNlID0gcmVxdWlyZSgnLi9kZWJvdW5jZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGVtaXR0ZXIgKHRoaW5nLCBvcHRpb25zKSB7XG4gIHZhciBvcHRzID0gb3B0aW9ucyB8fCB7fTtcbiAgdmFyIGV2dCA9IHt9O1xuICBpZiAodGhpbmcgPT09IHVuZGVmaW5lZCkgeyB0aGluZyA9IHt9OyB9XG4gIHRoaW5nLm9uID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgaWYgKCFldnRbdHlwZV0pIHtcbiAgICAgIGV2dFt0eXBlXSA9IFtmbl07XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2dFt0eXBlXS5wdXNoKGZuKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaW5nO1xuICB9O1xuICB0aGluZy5vbmNlID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgZm4uX29uY2UgPSB0cnVlOyAvLyB0aGluZy5vZmYoZm4pIHN0aWxsIHdvcmtzIVxuICAgIHRoaW5nLm9uKHR5cGUsIGZuKTtcbiAgICByZXR1cm4gdGhpbmc7XG4gIH07XG4gIHRoaW5nLm9mZiA9IGZ1bmN0aW9uICh0eXBlLCBmbikge1xuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBpZiAoYyA9PT0gMSkge1xuICAgICAgZGVsZXRlIGV2dFt0eXBlXTtcbiAgICB9IGVsc2UgaWYgKGMgPT09IDApIHtcbiAgICAgIGV2dCA9IHt9O1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZXQgPSBldnRbdHlwZV07XG4gICAgICBpZiAoIWV0KSB7IHJldHVybiB0aGluZzsgfVxuICAgICAgZXQuc3BsaWNlKGV0LmluZGV4T2YoZm4pLCAxKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaW5nO1xuICB9O1xuICB0aGluZy5lbWl0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gYXRvYShhcmd1bWVudHMpO1xuICAgIHJldHVybiB0aGluZy5lbWl0dGVyU25hcHNob3QoYXJncy5zaGlmdCgpKS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfTtcbiAgdGhpbmcuZW1pdHRlclNuYXBzaG90ID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICB2YXIgZXQgPSAoZXZ0W3R5cGVdIHx8IFtdKS5zbGljZSgwKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGFyZ3MgPSBhdG9hKGFyZ3VtZW50cyk7XG4gICAgICB2YXIgY3R4ID0gdGhpcyB8fCB0aGluZztcbiAgICAgIGlmICh0eXBlID09PSAnZXJyb3InICYmIG9wdHMudGhyb3dzICE9PSBmYWxzZSAmJiAhZXQubGVuZ3RoKSB7IHRocm93IGFyZ3MubGVuZ3RoID09PSAxID8gYXJnc1swXSA6IGFyZ3M7IH1cbiAgICAgIGV0LmZvckVhY2goZnVuY3Rpb24gZW1pdHRlciAobGlzdGVuKSB7XG4gICAgICAgIGlmIChvcHRzLmFzeW5jKSB7IGRlYm91bmNlKGxpc3RlbiwgYXJncywgY3R4KTsgfSBlbHNlIHsgbGlzdGVuLmFwcGx5KGN0eCwgYXJncyk7IH1cbiAgICAgICAgaWYgKGxpc3Rlbi5fb25jZSkgeyB0aGluZy5vZmYodHlwZSwgbGlzdGVuKTsgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdGhpbmc7XG4gICAgfTtcbiAgfTtcbiAgcmV0dXJuIHRoaW5nO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1c3RvbUV2ZW50ID0gcmVxdWlyZSgnY3VzdG9tLWV2ZW50Jyk7XG52YXIgZXZlbnRtYXAgPSByZXF1aXJlKCcuL2V2ZW50bWFwJyk7XG52YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xudmFyIGFkZEV2ZW50ID0gYWRkRXZlbnRFYXN5O1xudmFyIHJlbW92ZUV2ZW50ID0gcmVtb3ZlRXZlbnRFYXN5O1xudmFyIGhhcmRDYWNoZSA9IFtdO1xuXG5pZiAoIWdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gIGFkZEV2ZW50ID0gYWRkRXZlbnRIYXJkO1xuICByZW1vdmVFdmVudCA9IHJlbW92ZUV2ZW50SGFyZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGFkZDogYWRkRXZlbnQsXG4gIHJlbW92ZTogcmVtb3ZlRXZlbnQsXG4gIGZhYnJpY2F0ZTogZmFicmljYXRlRXZlbnRcbn07XG5cbmZ1bmN0aW9uIGFkZEV2ZW50RWFzeSAoZWwsIHR5cGUsIGZuLCBjYXB0dXJpbmcpIHtcbiAgcmV0dXJuIGVsLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZm4sIGNhcHR1cmluZyk7XG59XG5cbmZ1bmN0aW9uIGFkZEV2ZW50SGFyZCAoZWwsIHR5cGUsIGZuKSB7XG4gIHJldHVybiBlbC5hdHRhY2hFdmVudCgnb24nICsgdHlwZSwgd3JhcChlbCwgdHlwZSwgZm4pKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRXZlbnRFYXN5IChlbCwgdHlwZSwgZm4sIGNhcHR1cmluZykge1xuICByZXR1cm4gZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBmbiwgY2FwdHVyaW5nKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRXZlbnRIYXJkIChlbCwgdHlwZSwgZm4pIHtcbiAgdmFyIGxpc3RlbmVyID0gdW53cmFwKGVsLCB0eXBlLCBmbik7XG4gIGlmIChsaXN0ZW5lcikge1xuICAgIHJldHVybiBlbC5kZXRhY2hFdmVudCgnb24nICsgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZhYnJpY2F0ZUV2ZW50IChlbCwgdHlwZSwgbW9kZWwpIHtcbiAgdmFyIGUgPSBldmVudG1hcC5pbmRleE9mKHR5cGUpID09PSAtMSA/IG1ha2VDdXN0b21FdmVudCgpIDogbWFrZUNsYXNzaWNFdmVudCgpO1xuICBpZiAoZWwuZGlzcGF0Y2hFdmVudCkge1xuICAgIGVsLmRpc3BhdGNoRXZlbnQoZSk7XG4gIH0gZWxzZSB7XG4gICAgZWwuZmlyZUV2ZW50KCdvbicgKyB0eXBlLCBlKTtcbiAgfVxuICBmdW5jdGlvbiBtYWtlQ2xhc3NpY0V2ZW50ICgpIHtcbiAgICB2YXIgZTtcbiAgICBpZiAoZG9jLmNyZWF0ZUV2ZW50KSB7XG4gICAgICBlID0gZG9jLmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgICAgZS5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfSBlbHNlIGlmIChkb2MuY3JlYXRlRXZlbnRPYmplY3QpIHtcbiAgICAgIGUgPSBkb2MuY3JlYXRlRXZlbnRPYmplY3QoKTtcbiAgICB9XG4gICAgcmV0dXJuIGU7XG4gIH1cbiAgZnVuY3Rpb24gbWFrZUN1c3RvbUV2ZW50ICgpIHtcbiAgICByZXR1cm4gbmV3IGN1c3RvbUV2ZW50KHR5cGUsIHsgZGV0YWlsOiBtb2RlbCB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiB3cmFwcGVyRmFjdG9yeSAoZWwsIHR5cGUsIGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwcGVyIChvcmlnaW5hbEV2ZW50KSB7XG4gICAgdmFyIGUgPSBvcmlnaW5hbEV2ZW50IHx8IGdsb2JhbC5ldmVudDtcbiAgICBlLnRhcmdldCA9IGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudDtcbiAgICBlLnByZXZlbnREZWZhdWx0ID0gZS5wcmV2ZW50RGVmYXVsdCB8fCBmdW5jdGlvbiBwcmV2ZW50RGVmYXVsdCAoKSB7IGUucmV0dXJuVmFsdWUgPSBmYWxzZTsgfTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbiA9IGUuc3RvcFByb3BhZ2F0aW9uIHx8IGZ1bmN0aW9uIHN0b3BQcm9wYWdhdGlvbiAoKSB7IGUuY2FuY2VsQnViYmxlID0gdHJ1ZTsgfTtcbiAgICBlLndoaWNoID0gZS53aGljaCB8fCBlLmtleUNvZGU7XG4gICAgZm4uY2FsbChlbCwgZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHdyYXAgKGVsLCB0eXBlLCBmbikge1xuICB2YXIgd3JhcHBlciA9IHVud3JhcChlbCwgdHlwZSwgZm4pIHx8IHdyYXBwZXJGYWN0b3J5KGVsLCB0eXBlLCBmbik7XG4gIGhhcmRDYWNoZS5wdXNoKHtcbiAgICB3cmFwcGVyOiB3cmFwcGVyLFxuICAgIGVsZW1lbnQ6IGVsLFxuICAgIHR5cGU6IHR5cGUsXG4gICAgZm46IGZuXG4gIH0pO1xuICByZXR1cm4gd3JhcHBlcjtcbn1cblxuZnVuY3Rpb24gdW53cmFwIChlbCwgdHlwZSwgZm4pIHtcbiAgdmFyIGkgPSBmaW5kKGVsLCB0eXBlLCBmbik7XG4gIGlmIChpKSB7XG4gICAgdmFyIHdyYXBwZXIgPSBoYXJkQ2FjaGVbaV0ud3JhcHBlcjtcbiAgICBoYXJkQ2FjaGUuc3BsaWNlKGksIDEpOyAvLyBmcmVlIHVwIGEgdGFkIG9mIG1lbW9yeVxuICAgIHJldHVybiB3cmFwcGVyO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmQgKGVsLCB0eXBlLCBmbikge1xuICB2YXIgaSwgaXRlbTtcbiAgZm9yIChpID0gMDsgaSA8IGhhcmRDYWNoZS5sZW5ndGg7IGkrKykge1xuICAgIGl0ZW0gPSBoYXJkQ2FjaGVbaV07XG4gICAgaWYgKGl0ZW0uZWxlbWVudCA9PT0gZWwgJiYgaXRlbS50eXBlID09PSB0eXBlICYmIGl0ZW0uZm4gPT09IGZuKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGV2ZW50bWFwID0gW107XG52YXIgZXZlbnRuYW1lID0gJyc7XG52YXIgcm9uID0gL15vbi87XG5cbmZvciAoZXZlbnRuYW1lIGluIGdsb2JhbCkge1xuICBpZiAocm9uLnRlc3QoZXZlbnRuYW1lKSkge1xuICAgIGV2ZW50bWFwLnB1c2goZXZlbnRuYW1lLnNsaWNlKDIpKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGV2ZW50bWFwO1xuIiwiXG52YXIgTmF0aXZlQ3VzdG9tRXZlbnQgPSBnbG9iYWwuQ3VzdG9tRXZlbnQ7XG5cbmZ1bmN0aW9uIHVzZU5hdGl2ZSAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIHAgPSBuZXcgTmF0aXZlQ3VzdG9tRXZlbnQoJ2NhdCcsIHsgZGV0YWlsOiB7IGZvbzogJ2JhcicgfSB9KTtcbiAgICByZXR1cm4gICdjYXQnID09PSBwLnR5cGUgJiYgJ2JhcicgPT09IHAuZGV0YWlsLmZvbztcbiAgfSBjYXRjaCAoZSkge1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDcm9zcy1icm93c2VyIGBDdXN0b21FdmVudGAgY29uc3RydWN0b3IuXG4gKlxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0N1c3RvbUV2ZW50LkN1c3RvbUV2ZW50XG4gKlxuICogQHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gdXNlTmF0aXZlKCkgPyBOYXRpdmVDdXN0b21FdmVudCA6XG5cbi8vIElFID49IDlcbidmdW5jdGlvbicgPT09IHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFdmVudCA/IGZ1bmN0aW9uIEN1c3RvbUV2ZW50ICh0eXBlLCBwYXJhbXMpIHtcbiAgdmFyIGUgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgaWYgKHBhcmFtcykge1xuICAgIGUuaW5pdEN1c3RvbUV2ZW50KHR5cGUsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XG4gIH0gZWxzZSB7XG4gICAgZS5pbml0Q3VzdG9tRXZlbnQodHlwZSwgZmFsc2UsIGZhbHNlLCB2b2lkIDApO1xuICB9XG4gIHJldHVybiBlO1xufSA6XG5cbi8vIElFIDw9IDhcbmZ1bmN0aW9uIEN1c3RvbUV2ZW50ICh0eXBlLCBwYXJhbXMpIHtcbiAgdmFyIGUgPSBkb2N1bWVudC5jcmVhdGVFdmVudE9iamVjdCgpO1xuICBlLnR5cGUgPSB0eXBlO1xuICBpZiAocGFyYW1zKSB7XG4gICAgZS5idWJibGVzID0gQm9vbGVhbihwYXJhbXMuYnViYmxlcyk7XG4gICAgZS5jYW5jZWxhYmxlID0gQm9vbGVhbihwYXJhbXMuY2FuY2VsYWJsZSk7XG4gICAgZS5kZXRhaWwgPSBwYXJhbXMuZGV0YWlsO1xuICB9IGVsc2Uge1xuICAgIGUuYnViYmxlcyA9IGZhbHNlO1xuICAgIGUuY2FuY2VsYWJsZSA9IGZhbHNlO1xuICAgIGUuZGV0YWlsID0gdm9pZCAwO1xuICB9XG4gIHJldHVybiBlO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBmdXp6eXNlYXJjaCAobmVlZGxlLCBoYXlzdGFjaykge1xuICB2YXIgdGxlbiA9IGhheXN0YWNrLmxlbmd0aDtcbiAgdmFyIHFsZW4gPSBuZWVkbGUubGVuZ3RoO1xuICBpZiAocWxlbiA+IHRsZW4pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHFsZW4gPT09IHRsZW4pIHtcbiAgICByZXR1cm4gbmVlZGxlID09PSBoYXlzdGFjaztcbiAgfVxuICBvdXRlcjogZm9yICh2YXIgaSA9IDAsIGogPSAwOyBpIDwgcWxlbjsgaSsrKSB7XG4gICAgdmFyIG5jaCA9IG5lZWRsZS5jaGFyQ29kZUF0KGkpO1xuICAgIHdoaWxlIChqIDwgdGxlbikge1xuICAgICAgaWYgKGhheXN0YWNrLmNoYXJDb2RlQXQoaisrKSA9PT0gbmNoKSB7XG4gICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnV6enlzZWFyY2g7XG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIHBhZCAoaGFzaCwgbGVuKSB7XG4gIHdoaWxlIChoYXNoLmxlbmd0aCA8IGxlbikge1xuICAgIGhhc2ggPSAnMCcgKyBoYXNoO1xuICB9XG4gIHJldHVybiBoYXNoO1xufVxuXG5mdW5jdGlvbiBmb2xkIChoYXNoLCB0ZXh0KSB7XG4gIHZhciBpO1xuICB2YXIgY2hyO1xuICB2YXIgbGVuO1xuICBpZiAodGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gaGFzaDtcbiAgfVxuICBmb3IgKGkgPSAwLCBsZW4gPSB0ZXh0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgY2hyID0gdGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgIGhhc2ggPSAoKGhhc2ggPDwgNSkgLSBoYXNoKSArIGNocjtcbiAgICBoYXNoIHw9IDA7XG4gIH1cbiAgcmV0dXJuIGhhc2ggPCAwID8gaGFzaCAqIC0yIDogaGFzaDtcbn1cblxuZnVuY3Rpb24gZm9sZE9iamVjdCAoaGFzaCwgbywgc2Vlbikge1xuICByZXR1cm4gT2JqZWN0LmtleXMobykuc29ydCgpLnJlZHVjZShmb2xkS2V5LCBoYXNoKTtcbiAgZnVuY3Rpb24gZm9sZEtleSAoaGFzaCwga2V5KSB7XG4gICAgcmV0dXJuIGZvbGRWYWx1ZShoYXNoLCBvW2tleV0sIGtleSwgc2Vlbik7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9sZFZhbHVlIChpbnB1dCwgdmFsdWUsIGtleSwgc2Vlbikge1xuICB2YXIgaGFzaCA9IGZvbGQoZm9sZChmb2xkKGlucHV0LCBrZXkpLCB0b1N0cmluZyh2YWx1ZSkpLCB0eXBlb2YgdmFsdWUpO1xuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZm9sZChoYXNoLCAnbnVsbCcpO1xuICB9XG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZvbGQoaGFzaCwgJ3VuZGVmaW5lZCcpO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKHNlZW4uaW5kZXhPZih2YWx1ZSkgIT09IC0xKSB7XG4gICAgICByZXR1cm4gZm9sZChoYXNoLCAnW0NpcmN1bGFyXScgKyBrZXkpO1xuICAgIH1cbiAgICBzZWVuLnB1c2godmFsdWUpO1xuICAgIHJldHVybiBmb2xkT2JqZWN0KGhhc2gsIHZhbHVlLCBzZWVuKTtcbiAgfVxuICByZXR1cm4gZm9sZChoYXNoLCB2YWx1ZS50b1N0cmluZygpKTtcbn1cblxuZnVuY3Rpb24gdG9TdHJpbmcgKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuZnVuY3Rpb24gc3VtIChvKSB7XG4gIHJldHVybiBwYWQoZm9sZFZhbHVlKDAsIG8sICcnLCBbXSkudG9TdHJpbmcoMTYpLCA4KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdW07XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgbm93ID0gcmVxdWlyZSgnLi9ub3cnKSxcbiAgICB0b051bWJlciA9IHJlcXVpcmUoJy4vdG9OdW1iZXInKTtcblxuLyoqIFVzZWQgYXMgdGhlIGBUeXBlRXJyb3JgIG1lc3NhZ2UgZm9yIFwiRnVuY3Rpb25zXCIgbWV0aG9kcy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhc1xuICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gKiBQcm92aWRlIGFuIG9wdGlvbnMgb2JqZWN0IHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgIHNob3VsZCBiZSBpbnZva2VkIG9uXG4gKiB0aGUgbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZFxuICogd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbi4gU3Vic2VxdWVudCBjYWxsc1xuICogdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbiByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2AgaW52b2NhdGlvbi5cbiAqXG4gKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzIGludm9rZWRcbiAqIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIGRlYm91bmNlZCBmdW5jdGlvbiBpc1xuICogaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICpcbiAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKVxuICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy5kZWJvdW5jZWAgYW5kIGBfLnRocm90dGxlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlYm91bmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9ZmFsc2VdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFdhaXRdXG4gKiAgVGhlIG1heGltdW0gdGltZSBgZnVuY2AgaXMgYWxsb3dlZCB0byBiZSBkZWxheWVkIGJlZm9yZSBpdCdzIGludm9rZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGRlYm91bmNlZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogLy8gQXZvaWQgY29zdGx5IGNhbGN1bGF0aW9ucyB3aGlsZSB0aGUgd2luZG93IHNpemUgaXMgaW4gZmx1eC5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gKlxuICogLy8gSW52b2tlIGBzZW5kTWFpbGAgd2hlbiBjbGlja2VkLCBkZWJvdW5jaW5nIHN1YnNlcXVlbnQgY2FsbHMuXG4gKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5kZWJvdW5jZShzZW5kTWFpbCwgMzAwLCB7XG4gKiAgICdsZWFkaW5nJzogdHJ1ZSxcbiAqICAgJ3RyYWlsaW5nJzogZmFsc2VcbiAqIH0pKTtcbiAqXG4gKiAvLyBFbnN1cmUgYGJhdGNoTG9nYCBpcyBpbnZva2VkIG9uY2UgYWZ0ZXIgMSBzZWNvbmQgb2YgZGVib3VuY2VkIGNhbGxzLlxuICogdmFyIGRlYm91bmNlZCA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDI1MCwgeyAnbWF4V2FpdCc6IDEwMDAgfSk7XG4gKiB2YXIgc291cmNlID0gbmV3IEV2ZW50U291cmNlKCcvc3RyZWFtJyk7XG4gKiBqUXVlcnkoc291cmNlKS5vbignbWVzc2FnZScsIGRlYm91bmNlZCk7XG4gKlxuICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyBkZWJvdW5jZWQgaW52b2NhdGlvbi5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIGRlYm91bmNlZC5jYW5jZWwpO1xuICovXG5mdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gIHZhciBsYXN0QXJncyxcbiAgICAgIGxhc3RUaGlzLFxuICAgICAgbWF4V2FpdCxcbiAgICAgIHJlc3VsdCxcbiAgICAgIHRpbWVySWQsXG4gICAgICBsYXN0Q2FsbFRpbWUsXG4gICAgICBsYXN0SW52b2tlVGltZSA9IDAsXG4gICAgICBsZWFkaW5nID0gZmFsc2UsXG4gICAgICBtYXhpbmcgPSBmYWxzZSxcbiAgICAgIHRyYWlsaW5nID0gdHJ1ZTtcblxuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB3YWl0ID0gdG9OdW1iZXIod2FpdCkgfHwgMDtcbiAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgbGVhZGluZyA9ICEhb3B0aW9ucy5sZWFkaW5nO1xuICAgIG1heGluZyA9ICdtYXhXYWl0JyBpbiBvcHRpb25zO1xuICAgIG1heFdhaXQgPSBtYXhpbmcgPyBuYXRpdmVNYXgodG9OdW1iZXIob3B0aW9ucy5tYXhXYWl0KSB8fCAwLCB3YWl0KSA6IG1heFdhaXQ7XG4gICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZUZ1bmModGltZSkge1xuICAgIHZhciBhcmdzID0gbGFzdEFyZ3MsXG4gICAgICAgIHRoaXNBcmcgPSBsYXN0VGhpcztcblxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxlYWRpbmdFZGdlKHRpbWUpIHtcbiAgICAvLyBSZXNldCBhbnkgYG1heFdhaXRgIHRpbWVyLlxuICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICAvLyBTdGFydCB0aGUgdGltZXIgZm9yIHRoZSB0cmFpbGluZyBlZGdlLlxuICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgLy8gSW52b2tlIHRoZSBsZWFkaW5nIGVkZ2UuXG4gICAgcmV0dXJuIGxlYWRpbmcgPyBpbnZva2VGdW5jKHRpbWUpIDogcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtYWluaW5nV2FpdCh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZSxcbiAgICAgICAgcmVzdWx0ID0gd2FpdCAtIHRpbWVTaW5jZUxhc3RDYWxsO1xuXG4gICAgcmV0dXJuIG1heGluZyA/IG5hdGl2ZU1pbihyZXN1bHQsIG1heFdhaXQgLSB0aW1lU2luY2VMYXN0SW52b2tlKSA6IHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZTtcblxuICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgLy8gdHJhaWxpbmcgZWRnZSwgdGhlIHN5c3RlbSB0aW1lIGhhcyBnb25lIGJhY2t3YXJkcyBhbmQgd2UncmUgdHJlYXRpbmdcbiAgICAvLyBpdCBhcyB0aGUgdHJhaWxpbmcgZWRnZSwgb3Igd2UndmUgaGl0IHRoZSBgbWF4V2FpdGAgbGltaXQuXG4gICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICh0aW1lU2luY2VMYXN0Q2FsbCA8IDApIHx8IChtYXhpbmcgJiYgdGltZVNpbmNlTGFzdEludm9rZSA+PSBtYXhXYWl0KSk7XG4gIH1cblxuICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgdmFyIHRpbWUgPSBub3coKTtcbiAgICBpZiAoc2hvdWxkSW52b2tlKHRpbWUpKSB7XG4gICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgIH1cbiAgICAvLyBSZXN0YXJ0IHRoZSB0aW1lci5cbiAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhaWxpbmdFZGdlKHRpbWUpIHtcbiAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gT25seSBpbnZva2UgaWYgd2UgaGF2ZSBgbGFzdEFyZ3NgIHdoaWNoIG1lYW5zIGBmdW5jYCBoYXMgYmVlblxuICAgIC8vIGRlYm91bmNlZCBhdCBsZWFzdCBvbmNlLlxuICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgcmV0dXJuIGludm9rZUZ1bmModGltZSk7XG4gICAgfVxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgbGFzdEFyZ3MgPSBsYXN0Q2FsbFRpbWUgPSBsYXN0VGhpcyA9IHRpbWVySWQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICByZXR1cm4gdGltZXJJZCA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogdHJhaWxpbmdFZGdlKG5vdygpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpLFxuICAgICAgICBpc0ludm9raW5nID0gc2hvdWxkSW52b2tlKHRpbWUpO1xuXG4gICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgIGxhc3RDYWxsVGltZSA9IHRpbWU7XG5cbiAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbGVhZGluZ0VkZ2UobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXhpbmcpIHtcbiAgICAgICAgLy8gSGFuZGxlIGludm9jYXRpb25zIGluIGEgdGlnaHQgbG9vcC5cbiAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgcmV0dXJuIGludm9rZUZ1bmMobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICBkZWJvdW5jZWQuZmx1c2ggPSBmbHVzaDtcbiAgcmV0dXJuIGRlYm91bmNlZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkZWJvdW5jZTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZVxuICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgLy8gaW4gU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgYW5kIHdlYWsgbWFwIGNvbnN0cnVjdG9ycyxcbiAgLy8gYW5kIFBoYW50b21KUyAxLjkgd2hpY2ggcmV0dXJucyAnZnVuY3Rpb24nIGZvciBgTm9kZUxpc3RgIGluc3RhbmNlcy5cbiAgdmFyIHRhZyA9IGlzT2JqZWN0KHZhbHVlKSA/IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb247XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZVxuICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChfLm5vb3ApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0TGlrZTtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZVxuICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3ltYm9sYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN5bWJvbFRhZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTeW1ib2w7XG4iLCIvKipcbiAqIEdldHMgdGhlIHRpbWVzdGFtcCBvZiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZVxuICogdGhlIFVuaXggZXBvY2ggKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAyLjQuMFxuICogQGNhdGVnb3J5IERhdGVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVzdGFtcC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICogICBjb25zb2xlLmxvZyhfLm5vdygpIC0gc3RhbXApO1xuICogfSwgXy5ub3coKSk7XG4gKiAvLyA9PiBMb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBpbnZvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBub3coKSB7XG4gIHJldHVybiBEYXRlLm5vdygpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgaXNTeW1ib2wgPSByZXF1aXJlKCcuL2lzU3ltYm9sJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b051bWJlcigzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gTkFOO1xuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSBpc0Z1bmN0aW9uKHZhbHVlLnZhbHVlT2YpID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b051bWJlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGV4cGFuZG8gPSAnc2VrdG9yLScgKyBEYXRlLm5vdygpO1xudmFyIHJzaWJsaW5ncyA9IC9bK35dLztcbnZhciBkb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudDtcbnZhciBkZWwgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwge307XG52YXIgbWF0Y2ggPSAoXG4gIGRlbC5tYXRjaGVzIHx8XG4gIGRlbC53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHxcbiAgZGVsLm1vek1hdGNoZXNTZWxlY3RvciB8fFxuICBkZWwub01hdGNoZXNTZWxlY3RvciB8fFxuICBkZWwubXNNYXRjaGVzU2VsZWN0b3IgfHxcbiAgbmV2ZXJcbik7XG5cbm1vZHVsZS5leHBvcnRzID0gc2VrdG9yO1xuXG5zZWt0b3IubWF0Y2hlcyA9IG1hdGNoZXM7XG5zZWt0b3IubWF0Y2hlc1NlbGVjdG9yID0gbWF0Y2hlc1NlbGVjdG9yO1xuXG5mdW5jdGlvbiBxc2EgKHNlbGVjdG9yLCBjb250ZXh0KSB7XG4gIHZhciBleGlzdGVkLCBpZCwgcHJlZml4LCBwcmVmaXhlZCwgYWRhcHRlciwgaGFjayA9IGNvbnRleHQgIT09IGRvY3VtZW50O1xuICBpZiAoaGFjaykgeyAvLyBpZCBoYWNrIGZvciBjb250ZXh0LXJvb3RlZCBxdWVyaWVzXG4gICAgZXhpc3RlZCA9IGNvbnRleHQuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgIGlkID0gZXhpc3RlZCB8fCBleHBhbmRvO1xuICAgIHByZWZpeCA9ICcjJyArIGlkICsgJyAnO1xuICAgIHByZWZpeGVkID0gcHJlZml4ICsgc2VsZWN0b3IucmVwbGFjZSgvLC9nLCAnLCcgKyBwcmVmaXgpO1xuICAgIGFkYXB0ZXIgPSByc2libGluZ3MudGVzdChzZWxlY3RvcikgJiYgY29udGV4dC5wYXJlbnROb2RlO1xuICAgIGlmICghZXhpc3RlZCkgeyBjb250ZXh0LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7IH1cbiAgfVxuICB0cnkge1xuICAgIHJldHVybiAoYWRhcHRlciB8fCBjb250ZXh0KS5xdWVyeVNlbGVjdG9yQWxsKHByZWZpeGVkIHx8IHNlbGVjdG9yKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBbXTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAoZXhpc3RlZCA9PT0gbnVsbCkgeyBjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSgnaWQnKTsgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNla3RvciAoc2VsZWN0b3IsIGN0eCwgY29sbGVjdGlvbiwgc2VlZCkge1xuICB2YXIgZWxlbWVudDtcbiAgdmFyIGNvbnRleHQgPSBjdHggfHwgZG9jdW1lbnQ7XG4gIHZhciByZXN1bHRzID0gY29sbGVjdGlvbiB8fCBbXTtcbiAgdmFyIGkgPSAwO1xuICBpZiAodHlwZW9mIHNlbGVjdG9yICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG4gIGlmIChjb250ZXh0Lm5vZGVUeXBlICE9PSAxICYmIGNvbnRleHQubm9kZVR5cGUgIT09IDkpIHtcbiAgICByZXR1cm4gW107IC8vIGJhaWwgaWYgY29udGV4dCBpcyBub3QgYW4gZWxlbWVudCBvciBkb2N1bWVudFxuICB9XG4gIGlmIChzZWVkKSB7XG4gICAgd2hpbGUgKChlbGVtZW50ID0gc2VlZFtpKytdKSkge1xuICAgICAgaWYgKG1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvcikpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzLnB1c2guYXBwbHkocmVzdWx0cywgcXNhKHNlbGVjdG9yLCBjb250ZXh0KSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXMgKHNlbGVjdG9yLCBlbGVtZW50cykge1xuICByZXR1cm4gc2VrdG9yKHNlbGVjdG9yLCBudWxsLCBudWxsLCBlbGVtZW50cyk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXNTZWxlY3RvciAoZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgcmV0dXJuIG1hdGNoLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpO1xufVxuXG5mdW5jdGlvbiBuZXZlciAoKSB7IHJldHVybiBmYWxzZTsgfVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZ2V0U2VsZWN0aW9uO1xudmFyIGRvYyA9IGdsb2JhbC5kb2N1bWVudDtcbnZhciBnZXRTZWxlY3Rpb25SYXcgPSByZXF1aXJlKCcuL2dldFNlbGVjdGlvblJhdycpO1xudmFyIGdldFNlbGVjdGlvbk51bGxPcCA9IHJlcXVpcmUoJy4vZ2V0U2VsZWN0aW9uTnVsbE9wJyk7XG52YXIgZ2V0U2VsZWN0aW9uU3ludGhldGljID0gcmVxdWlyZSgnLi9nZXRTZWxlY3Rpb25TeW50aGV0aWMnKTtcbnZhciBpc0hvc3QgPSByZXF1aXJlKCcuL2lzSG9zdCcpO1xuaWYgKGlzSG9zdC5tZXRob2QoZ2xvYmFsLCAnZ2V0U2VsZWN0aW9uJykpIHtcbiAgZ2V0U2VsZWN0aW9uID0gZ2V0U2VsZWN0aW9uUmF3O1xufSBlbHNlIGlmICh0eXBlb2YgZG9jLnNlbGVjdGlvbiA9PT0gJ29iamVjdCcgJiYgZG9jLnNlbGVjdGlvbikge1xuICBnZXRTZWxlY3Rpb24gPSBnZXRTZWxlY3Rpb25TeW50aGV0aWM7XG59IGVsc2Uge1xuICBnZXRTZWxlY3Rpb24gPSBnZXRTZWxlY3Rpb25OdWxsT3A7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U2VsZWN0aW9uO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBub29wICgpIHt9XG5cbmZ1bmN0aW9uIGdldFNlbGVjdGlvbk51bGxPcCAoKSB7XG4gIHJldHVybiB7XG4gICAgcmVtb3ZlQWxsUmFuZ2VzOiBub29wLFxuICAgIGFkZFJhbmdlOiBub29wXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U2VsZWN0aW9uTnVsbE9wO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb25SYXcgKCkge1xuICByZXR1cm4gZ2xvYmFsLmdldFNlbGVjdGlvbigpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFNlbGVjdGlvblJhdztcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJhbmdlVG9UZXh0UmFuZ2UgPSByZXF1aXJlKCcuL3JhbmdlVG9UZXh0UmFuZ2UnKTtcbnZhciBkb2MgPSBnbG9iYWwuZG9jdW1lbnQ7XG52YXIgYm9keSA9IGRvYy5ib2R5O1xudmFyIEdldFNlbGVjdGlvblByb3RvID0gR2V0U2VsZWN0aW9uLnByb3RvdHlwZTtcblxuZnVuY3Rpb24gR2V0U2VsZWN0aW9uIChzZWxlY3Rpb24pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcmFuZ2UgPSBzZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTtcblxuICB0aGlzLl9zZWxlY3Rpb24gPSBzZWxlY3Rpb247XG4gIHRoaXMuX3JhbmdlcyA9IFtdO1xuXG4gIGlmIChzZWxlY3Rpb24udHlwZSA9PT0gJ0NvbnRyb2wnKSB7XG4gICAgdXBkYXRlQ29udHJvbFNlbGVjdGlvbihzZWxmKTtcbiAgfSBlbHNlIGlmIChpc1RleHRSYW5nZShyYW5nZSkpIHtcbiAgICB1cGRhdGVGcm9tVGV4dFJhbmdlKHNlbGYsIHJhbmdlKTtcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGVFbXB0eVNlbGVjdGlvbihzZWxmKTtcbiAgfVxufVxuXG5HZXRTZWxlY3Rpb25Qcm90by5yZW1vdmVBbGxSYW5nZXMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0ZXh0UmFuZ2U7XG4gIHRyeSB7XG4gICAgdGhpcy5fc2VsZWN0aW9uLmVtcHR5KCk7XG4gICAgaWYgKHRoaXMuX3NlbGVjdGlvbi50eXBlICE9PSAnTm9uZScpIHtcbiAgICAgIHRleHRSYW5nZSA9IGJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7XG4gICAgICB0ZXh0UmFuZ2Uuc2VsZWN0KCk7XG4gICAgICB0aGlzLl9zZWxlY3Rpb24uZW1wdHkoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgfVxuICB1cGRhdGVFbXB0eVNlbGVjdGlvbih0aGlzKTtcbn07XG5cbkdldFNlbGVjdGlvblByb3RvLmFkZFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7XG4gIGlmICh0aGlzLl9zZWxlY3Rpb24udHlwZSA9PT0gJ0NvbnRyb2wnKSB7XG4gICAgYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2UpO1xuICB9IGVsc2Uge1xuICAgIHJhbmdlVG9UZXh0UmFuZ2UocmFuZ2UpLnNlbGVjdCgpO1xuICAgIHRoaXMuX3Jhbmdlc1swXSA9IHJhbmdlO1xuICAgIHRoaXMucmFuZ2VDb3VudCA9IDE7XG4gICAgdGhpcy5pc0NvbGxhcHNlZCA9IHRoaXMuX3Jhbmdlc1swXS5jb2xsYXBzZWQ7XG4gICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2UodGhpcywgcmFuZ2UsIGZhbHNlKTtcbiAgfVxufTtcblxuR2V0U2VsZWN0aW9uUHJvdG8uc2V0UmFuZ2VzID0gZnVuY3Rpb24gKHJhbmdlcykge1xuICB0aGlzLnJlbW92ZUFsbFJhbmdlcygpO1xuICB2YXIgcmFuZ2VDb3VudCA9IHJhbmdlcy5sZW5ndGg7XG4gIGlmIChyYW5nZUNvdW50ID4gMSkge1xuICAgIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2VzKTtcbiAgfSBlbHNlIGlmIChyYW5nZUNvdW50KSB7XG4gICAgdGhpcy5hZGRSYW5nZShyYW5nZXNbMF0pO1xuICB9XG59O1xuXG5HZXRTZWxlY3Rpb25Qcm90by5nZXRSYW5nZUF0ID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy5yYW5nZUNvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdnZXRSYW5nZUF0KCk6IGluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcy5fcmFuZ2VzW2luZGV4XS5jbG9uZVJhbmdlKCk7XG4gIH1cbn07XG5cbkdldFNlbGVjdGlvblByb3RvLnJlbW92ZVJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7XG4gIGlmICh0aGlzLl9zZWxlY3Rpb24udHlwZSAhPT0gJ0NvbnRyb2wnKSB7XG4gICAgcmVtb3ZlUmFuZ2VNYW51YWxseSh0aGlzLCByYW5nZSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjb250cm9sUmFuZ2UgPSB0aGlzLl9zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTtcbiAgdmFyIHJhbmdlRWxlbWVudCA9IGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2UpO1xuICB2YXIgbmV3Q29udHJvbFJhbmdlID0gYm9keS5jcmVhdGVDb250cm9sUmFuZ2UoKTtcbiAgdmFyIGVsO1xuICB2YXIgcmVtb3ZlZCA9IGZhbHNlO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gY29udHJvbFJhbmdlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgZWwgPSBjb250cm9sUmFuZ2UuaXRlbShpKTtcbiAgICBpZiAoZWwgIT09IHJhbmdlRWxlbWVudCB8fCByZW1vdmVkKSB7XG4gICAgICBuZXdDb250cm9sUmFuZ2UuYWRkKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVtb3ZlZCA9IHRydWU7XG4gICAgfVxuICB9XG4gIG5ld0NvbnRyb2xSYW5nZS5zZWxlY3QoKTtcbiAgdXBkYXRlQ29udHJvbFNlbGVjdGlvbih0aGlzKTtcbn07XG5cbkdldFNlbGVjdGlvblByb3RvLmVhY2hSYW5nZSA9IGZ1bmN0aW9uIChmbiwgcmV0dXJuVmFsdWUpIHtcbiAgdmFyIGkgPSAwO1xuICB2YXIgbGVuID0gdGhpcy5fcmFuZ2VzLmxlbmd0aDtcbiAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGZuKHRoaXMuZ2V0UmFuZ2VBdChpKSkpIHtcbiAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG4gIH1cbn07XG5cbkdldFNlbGVjdGlvblByb3RvLmdldEFsbFJhbmdlcyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJhbmdlcyA9IFtdO1xuICB0aGlzLmVhY2hSYW5nZShmdW5jdGlvbiAocmFuZ2UpIHtcbiAgICByYW5nZXMucHVzaChyYW5nZSk7XG4gIH0pO1xuICByZXR1cm4gcmFuZ2VzO1xufTtcblxuR2V0U2VsZWN0aW9uUHJvdG8uc2V0U2luZ2xlUmFuZ2UgPSBmdW5jdGlvbiAocmFuZ2UpIHtcbiAgdGhpcy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgdGhpcy5hZGRSYW5nZShyYW5nZSk7XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVDb250cm9sU2VsZWN0aW9uIChzZWwsIHJhbmdlcykge1xuICB2YXIgY29udHJvbFJhbmdlID0gYm9keS5jcmVhdGVDb250cm9sUmFuZ2UoKTtcbiAgZm9yICh2YXIgaSA9IDAsIGVsLCBsZW4gPSByYW5nZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBlbCA9IGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2VzW2ldKTtcbiAgICB0cnkge1xuICAgICAgY29udHJvbFJhbmdlLmFkZChlbCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZXRSYW5nZXMoKTogRWxlbWVudCBjb3VsZCBub3QgYmUgYWRkZWQgdG8gY29udHJvbCBzZWxlY3Rpb24nKTtcbiAgICB9XG4gIH1cbiAgY29udHJvbFJhbmdlLnNlbGVjdCgpO1xuICB1cGRhdGVDb250cm9sU2VsZWN0aW9uKHNlbCk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVJhbmdlTWFudWFsbHkgKHNlbCwgcmFuZ2UpIHtcbiAgdmFyIHJhbmdlcyA9IHNlbC5nZXRBbGxSYW5nZXMoKTtcbiAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKCFpc1NhbWVSYW5nZShyYW5nZSwgcmFuZ2VzW2ldKSkge1xuICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlc1tpXSk7XG4gICAgfVxuICB9XG4gIGlmICghc2VsLnJhbmdlQ291bnQpIHtcbiAgICB1cGRhdGVFbXB0eVNlbGVjdGlvbihzZWwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUFuY2hvckFuZEZvY3VzRnJvbVJhbmdlIChzZWwsIHJhbmdlKSB7XG4gIHZhciBhbmNob3JQcmVmaXggPSAnc3RhcnQnO1xuICB2YXIgZm9jdXNQcmVmaXggPSAnZW5kJztcbiAgc2VsLmFuY2hvck5vZGUgPSByYW5nZVthbmNob3JQcmVmaXggKyAnQ29udGFpbmVyJ107XG4gIHNlbC5hbmNob3JPZmZzZXQgPSByYW5nZVthbmNob3JQcmVmaXggKyAnT2Zmc2V0J107XG4gIHNlbC5mb2N1c05vZGUgPSByYW5nZVtmb2N1c1ByZWZpeCArICdDb250YWluZXInXTtcbiAgc2VsLmZvY3VzT2Zmc2V0ID0gcmFuZ2VbZm9jdXNQcmVmaXggKyAnT2Zmc2V0J107XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVtcHR5U2VsZWN0aW9uIChzZWwpIHtcbiAgc2VsLmFuY2hvck5vZGUgPSBzZWwuZm9jdXNOb2RlID0gbnVsbDtcbiAgc2VsLmFuY2hvck9mZnNldCA9IHNlbC5mb2N1c09mZnNldCA9IDA7XG4gIHNlbC5yYW5nZUNvdW50ID0gMDtcbiAgc2VsLmlzQ29sbGFwc2VkID0gdHJ1ZTtcbiAgc2VsLl9yYW5nZXMubGVuZ3RoID0gMDtcbn1cblxuZnVuY3Rpb24gcmFuZ2VDb250YWluc1NpbmdsZUVsZW1lbnQgKHJhbmdlTm9kZXMpIHtcbiAgaWYgKCFyYW5nZU5vZGVzLmxlbmd0aCB8fCByYW5nZU5vZGVzWzBdLm5vZGVUeXBlICE9PSAxKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAodmFyIGkgPSAxLCBsZW4gPSByYW5nZU5vZGVzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKCFpc0FuY2VzdG9yT2YocmFuZ2VOb2Rlc1swXSwgcmFuZ2VOb2Rlc1tpXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UgKHJhbmdlKSB7XG4gIHZhciBub2RlcyA9IHJhbmdlLmdldE5vZGVzKCk7XG4gIGlmICghcmFuZ2VDb250YWluc1NpbmdsZUVsZW1lbnQobm9kZXMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKCk6IHJhbmdlIGRpZCBub3QgY29uc2lzdCBvZiBhIHNpbmdsZSBlbGVtZW50Jyk7XG4gIH1cbiAgcmV0dXJuIG5vZGVzWzBdO1xufVxuXG5mdW5jdGlvbiBpc1RleHRSYW5nZSAocmFuZ2UpIHtcbiAgcmV0dXJuIHJhbmdlICYmIHJhbmdlLnRleHQgIT09IHZvaWQgMDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRnJvbVRleHRSYW5nZSAoc2VsLCByYW5nZSkge1xuICBzZWwuX3JhbmdlcyA9IFtyYW5nZV07XG4gIHVwZGF0ZUFuY2hvckFuZEZvY3VzRnJvbVJhbmdlKHNlbCwgcmFuZ2UsIGZhbHNlKTtcbiAgc2VsLnJhbmdlQ291bnQgPSAxO1xuICBzZWwuaXNDb2xsYXBzZWQgPSByYW5nZS5jb2xsYXBzZWQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24gKHNlbCkge1xuICBzZWwuX3Jhbmdlcy5sZW5ndGggPSAwO1xuICBpZiAoc2VsLl9zZWxlY3Rpb24udHlwZSA9PT0gJ05vbmUnKSB7XG4gICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgY29udHJvbFJhbmdlID0gc2VsLl9zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTtcbiAgICBpZiAoaXNUZXh0UmFuZ2UoY29udHJvbFJhbmdlKSkge1xuICAgICAgdXBkYXRlRnJvbVRleHRSYW5nZShzZWwsIGNvbnRyb2xSYW5nZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbC5yYW5nZUNvdW50ID0gY29udHJvbFJhbmdlLmxlbmd0aDtcbiAgICAgIHZhciByYW5nZTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsLnJhbmdlQ291bnQ7ICsraSkge1xuICAgICAgICByYW5nZSA9IGRvYy5jcmVhdGVSYW5nZSgpO1xuICAgICAgICByYW5nZS5zZWxlY3ROb2RlKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTtcbiAgICAgICAgc2VsLl9yYW5nZXMucHVzaChyYW5nZSk7XG4gICAgICB9XG4gICAgICBzZWwuaXNDb2xsYXBzZWQgPSBzZWwucmFuZ2VDb3VudCA9PT0gMSAmJiBzZWwuX3Jhbmdlc1swXS5jb2xsYXBzZWQ7XG4gICAgICB1cGRhdGVBbmNob3JBbmRGb2N1c0Zyb21SYW5nZShzZWwsIHNlbC5fcmFuZ2VzW3NlbC5yYW5nZUNvdW50IC0gMV0sIGZhbHNlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24gKHNlbCwgcmFuZ2UpIHtcbiAgdmFyIGNvbnRyb2xSYW5nZSA9IHNlbC5fc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7XG4gIHZhciByYW5nZUVsZW1lbnQgPSBnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKHJhbmdlKTtcbiAgdmFyIG5ld0NvbnRyb2xSYW5nZSA9IGJvZHkuY3JlYXRlQ29udHJvbFJhbmdlKCk7XG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjb250cm9sUmFuZ2UubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBuZXdDb250cm9sUmFuZ2UuYWRkKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTtcbiAgfVxuICB0cnkge1xuICAgIG5ld0NvbnRyb2xSYW5nZS5hZGQocmFuZ2VFbGVtZW50KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignYWRkUmFuZ2UoKTogRWxlbWVudCBjb3VsZCBub3QgYmUgYWRkZWQgdG8gY29udHJvbCBzZWxlY3Rpb24nKTtcbiAgfVxuICBuZXdDb250cm9sUmFuZ2Uuc2VsZWN0KCk7XG4gIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsKTtcbn1cblxuZnVuY3Rpb24gaXNTYW1lUmFuZ2UgKGxlZnQsIHJpZ2h0KSB7XG4gIHJldHVybiAoXG4gICAgbGVmdC5zdGFydENvbnRhaW5lciA9PT0gcmlnaHQuc3RhcnRDb250YWluZXIgJiZcbiAgICBsZWZ0LnN0YXJ0T2Zmc2V0ID09PSByaWdodC5zdGFydE9mZnNldCAmJlxuICAgIGxlZnQuZW5kQ29udGFpbmVyID09PSByaWdodC5lbmRDb250YWluZXIgJiZcbiAgICBsZWZ0LmVuZE9mZnNldCA9PT0gcmlnaHQuZW5kT2Zmc2V0XG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzQW5jZXN0b3JPZiAoYW5jZXN0b3IsIGRlc2NlbmRhbnQpIHtcbiAgdmFyIG5vZGUgPSBkZXNjZW5kYW50O1xuICB3aGlsZSAobm9kZS5wYXJlbnROb2RlKSB7XG4gICAgaWYgKG5vZGUucGFyZW50Tm9kZSA9PT0gYW5jZXN0b3IpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uICgpIHtcbiAgcmV0dXJuIG5ldyBHZXRTZWxlY3Rpb24oZ2xvYmFsLmRvY3VtZW50LnNlbGVjdGlvbik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U2VsZWN0aW9uO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBpc0hvc3RNZXRob2QgKGhvc3QsIHByb3ApIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgaG9zdFtwcm9wXTtcbiAgcmV0dXJuIHR5cGUgPT09ICdmdW5jdGlvbicgfHwgISEodHlwZSA9PT0gJ29iamVjdCcgJiYgaG9zdFtwcm9wXSkgfHwgdHlwZSA9PT0gJ3Vua25vd24nO1xufVxuXG5mdW5jdGlvbiBpc0hvc3RQcm9wZXJ0eSAoaG9zdCwgcHJvcCkge1xuICByZXR1cm4gdHlwZW9mIGhvc3RbcHJvcF0gIT09ICd1bmRlZmluZWQnO1xufVxuXG5mdW5jdGlvbiBtYW55IChmbikge1xuICByZXR1cm4gZnVuY3Rpb24gYXJlSG9zdGVkIChob3N0LCBwcm9wcykge1xuICAgIHZhciBpID0gcHJvcHMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGlmICghZm4oaG9zdCwgcHJvcHNbaV0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZXRob2Q6IGlzSG9zdE1ldGhvZCxcbiAgbWV0aG9kczogbWFueShpc0hvc3RNZXRob2QpLFxuICBwcm9wZXJ0eTogaXNIb3N0UHJvcGVydHksXG4gIHByb3BlcnRpZXM6IG1hbnkoaXNIb3N0UHJvcGVydHkpXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xudmFyIGJvZHkgPSBkb2MuYm9keTtcblxuZnVuY3Rpb24gcmFuZ2VUb1RleHRSYW5nZSAocCkge1xuICBpZiAocC5jb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UoeyBub2RlOiBwLnN0YXJ0Q29udGFpbmVyLCBvZmZzZXQ6IHAuc3RhcnRPZmZzZXQgfSwgdHJ1ZSk7XG4gIH1cbiAgdmFyIHN0YXJ0UmFuZ2UgPSBjcmVhdGVCb3VuZGFyeVRleHRSYW5nZSh7IG5vZGU6IHAuc3RhcnRDb250YWluZXIsIG9mZnNldDogcC5zdGFydE9mZnNldCB9LCB0cnVlKTtcbiAgdmFyIGVuZFJhbmdlID0gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UoeyBub2RlOiBwLmVuZENvbnRhaW5lciwgb2Zmc2V0OiBwLmVuZE9mZnNldCB9LCBmYWxzZSk7XG4gIHZhciB0ZXh0UmFuZ2UgPSBib2R5LmNyZWF0ZVRleHRSYW5nZSgpO1xuICB0ZXh0UmFuZ2Uuc2V0RW5kUG9pbnQoJ1N0YXJ0VG9TdGFydCcsIHN0YXJ0UmFuZ2UpO1xuICB0ZXh0UmFuZ2Uuc2V0RW5kUG9pbnQoJ0VuZFRvRW5kJywgZW5kUmFuZ2UpO1xuICByZXR1cm4gdGV4dFJhbmdlO1xufVxuXG5mdW5jdGlvbiBpc0NoYXJhY3RlckRhdGFOb2RlIChub2RlKSB7XG4gIHZhciB0ID0gbm9kZS5ub2RlVHlwZTtcbiAgcmV0dXJuIHQgPT09IDMgfHwgdCA9PT0gNCB8fCB0ID09PSA4IDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UgKHAsIHN0YXJ0aW5nKSB7XG4gIHZhciBib3VuZDtcbiAgdmFyIHBhcmVudDtcbiAgdmFyIG9mZnNldCA9IHAub2Zmc2V0O1xuICB2YXIgd29ya2luZ05vZGU7XG4gIHZhciBjaGlsZE5vZGVzO1xuICB2YXIgcmFuZ2UgPSBib2R5LmNyZWF0ZVRleHRSYW5nZSgpO1xuICB2YXIgZGF0YSA9IGlzQ2hhcmFjdGVyRGF0YU5vZGUocC5ub2RlKTtcblxuICBpZiAoZGF0YSkge1xuICAgIGJvdW5kID0gcC5ub2RlO1xuICAgIHBhcmVudCA9IGJvdW5kLnBhcmVudE5vZGU7XG4gIH0gZWxzZSB7XG4gICAgY2hpbGROb2RlcyA9IHAubm9kZS5jaGlsZE5vZGVzO1xuICAgIGJvdW5kID0gb2Zmc2V0IDwgY2hpbGROb2Rlcy5sZW5ndGggPyBjaGlsZE5vZGVzW29mZnNldF0gOiBudWxsO1xuICAgIHBhcmVudCA9IHAubm9kZTtcbiAgfVxuXG4gIHdvcmtpbmdOb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgd29ya2luZ05vZGUuaW5uZXJIVE1MID0gJyYjZmVmZjsnO1xuXG4gIGlmIChib3VuZCkge1xuICAgIHBhcmVudC5pbnNlcnRCZWZvcmUod29ya2luZ05vZGUsIGJvdW5kKTtcbiAgfSBlbHNlIHtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQod29ya2luZ05vZGUpO1xuICB9XG5cbiAgcmFuZ2UubW92ZVRvRWxlbWVudFRleHQod29ya2luZ05vZGUpO1xuICByYW5nZS5jb2xsYXBzZSghc3RhcnRpbmcpO1xuICBwYXJlbnQucmVtb3ZlQ2hpbGQod29ya2luZ05vZGUpO1xuXG4gIGlmIChkYXRhKSB7XG4gICAgcmFuZ2Vbc3RhcnRpbmcgPyAnbW92ZVN0YXJ0JyA6ICdtb3ZlRW5kJ10oJ2NoYXJhY3RlcicsIG9mZnNldCk7XG4gIH1cbiAgcmV0dXJuIHJhbmdlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJhbmdlVG9UZXh0UmFuZ2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBnZXRTZWxlY3Rpb24gPSByZXF1aXJlKCcuL2dldFNlbGVjdGlvbicpO1xudmFyIHNldFNlbGVjdGlvbiA9IHJlcXVpcmUoJy4vc2V0U2VsZWN0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXQ6IGdldFNlbGVjdGlvbixcbiAgc2V0OiBzZXRTZWxlY3Rpb25cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBnZXRTZWxlY3Rpb24gPSByZXF1aXJlKCcuL2dldFNlbGVjdGlvbicpO1xudmFyIHJhbmdlVG9UZXh0UmFuZ2UgPSByZXF1aXJlKCcuL3JhbmdlVG9UZXh0UmFuZ2UnKTtcbnZhciBkb2MgPSBnbG9iYWwuZG9jdW1lbnQ7XG5cbmZ1bmN0aW9uIHNldFNlbGVjdGlvbiAocCkge1xuICBpZiAoZG9jLmNyZWF0ZVJhbmdlKSB7XG4gICAgbW9kZXJuU2VsZWN0aW9uKCk7XG4gIH0gZWxzZSB7XG4gICAgb2xkU2VsZWN0aW9uKCk7XG4gIH1cblxuICBmdW5jdGlvbiBtb2Rlcm5TZWxlY3Rpb24gKCkge1xuICAgIHZhciBzZWwgPSBnZXRTZWxlY3Rpb24oKTtcbiAgICB2YXIgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICBpZiAoIXAuc3RhcnRDb250YWluZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHAuZW5kQ29udGFpbmVyKSB7XG4gICAgICByYW5nZS5zZXRFbmQocC5lbmRDb250YWluZXIsIHAuZW5kT2Zmc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmFuZ2Uuc2V0RW5kKHAuc3RhcnRDb250YWluZXIsIHAuc3RhcnRPZmZzZXQpO1xuICAgIH1cbiAgICByYW5nZS5zZXRTdGFydChwLnN0YXJ0Q29udGFpbmVyLCBwLnN0YXJ0T2Zmc2V0KTtcbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgc2VsLmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9sZFNlbGVjdGlvbiAoKSB7XG4gICAgcmFuZ2VUb1RleHRSYW5nZShwKS5zZWxlY3QoKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFNlbGVjdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGdldCA9IGVhc3lHZXQ7XG52YXIgc2V0ID0gZWFzeVNldDtcblxuaWYgKGRvY3VtZW50LnNlbGVjdGlvbiAmJiBkb2N1bWVudC5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UpIHtcbiAgZ2V0ID0gaGFyZEdldDtcbiAgc2V0ID0gaGFyZFNldDtcbn1cblxuZnVuY3Rpb24gZWFzeUdldCAoZWwpIHtcbiAgcmV0dXJuIHtcbiAgICBzdGFydDogZWwuc2VsZWN0aW9uU3RhcnQsXG4gICAgZW5kOiBlbC5zZWxlY3Rpb25FbmRcbiAgfTtcbn1cblxuZnVuY3Rpb24gaGFyZEdldCAoZWwpIHtcbiAgdmFyIGFjdGl2ZSA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gIGlmIChhY3RpdmUgIT09IGVsKSB7XG4gICAgZWwuZm9jdXMoKTtcbiAgfVxuXG4gIHZhciByYW5nZSA9IGRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpO1xuICB2YXIgYm9va21hcmsgPSByYW5nZS5nZXRCb29rbWFyaygpO1xuICB2YXIgb3JpZ2luYWwgPSBlbC52YWx1ZTtcbiAgdmFyIG1hcmtlciA9IGdldFVuaXF1ZU1hcmtlcihvcmlnaW5hbCk7XG4gIHZhciBwYXJlbnQgPSByYW5nZS5wYXJlbnRFbGVtZW50KCk7XG4gIGlmIChwYXJlbnQgPT09IG51bGwgfHwgIWlucHV0cyhwYXJlbnQpKSB7XG4gICAgcmV0dXJuIHJlc3VsdCgwLCAwKTtcbiAgfVxuICByYW5nZS50ZXh0ID0gbWFya2VyICsgcmFuZ2UudGV4dCArIG1hcmtlcjtcblxuICB2YXIgY29udGVudHMgPSBlbC52YWx1ZTtcblxuICBlbC52YWx1ZSA9IG9yaWdpbmFsO1xuICByYW5nZS5tb3ZlVG9Cb29rbWFyayhib29rbWFyayk7XG4gIHJhbmdlLnNlbGVjdCgpO1xuXG4gIHJldHVybiByZXN1bHQoY29udGVudHMuaW5kZXhPZihtYXJrZXIpLCBjb250ZW50cy5sYXN0SW5kZXhPZihtYXJrZXIpIC0gbWFya2VyLmxlbmd0aCk7XG5cbiAgZnVuY3Rpb24gcmVzdWx0IChzdGFydCwgZW5kKSB7XG4gICAgaWYgKGFjdGl2ZSAhPT0gZWwpIHsgLy8gZG9uJ3QgZGlzcnVwdCBwcmUtZXhpc3Rpbmcgc3RhdGVcbiAgICAgIGlmIChhY3RpdmUpIHtcbiAgICAgICAgYWN0aXZlLmZvY3VzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbC5ibHVyKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydCwgZW5kOiBlbmQgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRVbmlxdWVNYXJrZXIgKGNvbnRlbnRzKSB7XG4gIHZhciBtYXJrZXI7XG4gIGRvIHtcbiAgICBtYXJrZXIgPSAnQEBtYXJrZXIuJyArIE1hdGgucmFuZG9tKCkgKiBuZXcgRGF0ZSgpO1xuICB9IHdoaWxlIChjb250ZW50cy5pbmRleE9mKG1hcmtlcikgIT09IC0xKTtcbiAgcmV0dXJuIG1hcmtlcjtcbn1cblxuZnVuY3Rpb24gaW5wdXRzIChlbCkge1xuICByZXR1cm4gKChlbC50YWdOYW1lID09PSAnSU5QVVQnICYmIGVsLnR5cGUgPT09ICd0ZXh0JykgfHwgZWwudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJyk7XG59XG5cbmZ1bmN0aW9uIGVhc3lTZXQgKGVsLCBwKSB7XG4gIGVsLnNlbGVjdGlvblN0YXJ0ID0gcGFyc2UoZWwsIHAuc3RhcnQpO1xuICBlbC5zZWxlY3Rpb25FbmQgPSBwYXJzZShlbCwgcC5lbmQpO1xufVxuXG5mdW5jdGlvbiBoYXJkU2V0IChlbCwgcCkge1xuICB2YXIgcmFuZ2UgPSBlbC5jcmVhdGVUZXh0UmFuZ2UoKTtcblxuICBpZiAocC5zdGFydCA9PT0gJ2VuZCcgJiYgcC5lbmQgPT09ICdlbmQnKSB7XG4gICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuICAgIHJhbmdlLnNlbGVjdCgpO1xuICB9IGVsc2Uge1xuICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIHJhbmdlLm1vdmVFbmQoJ2NoYXJhY3RlcicsIHBhcnNlKGVsLCBwLmVuZCkpO1xuICAgIHJhbmdlLm1vdmVTdGFydCgnY2hhcmFjdGVyJywgcGFyc2UoZWwsIHAuc3RhcnQpKTtcbiAgICByYW5nZS5zZWxlY3QoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZSAoZWwsIHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gJ2VuZCcgPyBlbC52YWx1ZS5sZW5ndGggOiB2YWx1ZSB8fCAwO1xufVxuXG5mdW5jdGlvbiBzZWxsIChlbCwgcCkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xuICAgIHNldChlbCwgcCk7XG4gIH1cbiAgcmV0dXJuIGdldChlbCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2VsbDtcbiIsInZhciBzaSA9IHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicsIHRpY2s7XG5pZiAoc2kpIHtcbiAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRJbW1lZGlhdGUoZm4pOyB9O1xufSBlbHNlIHtcbiAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRUaW1lb3V0KGZuLCAwKTsgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0aWNrOyJdfQ==
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Titre de la page</title>
<style>
.alwaysdisplay {
display: block!important;
}
.transp {
stroke-opacity: 0.3;
fill: rgb(234, 234, 234);
fill-opacity: 0.2;
}
.highlight {
stroke-opacity: 1;
fill-opacity: 1;
}
.highlight-target {
stroke-width: 1px !important;
fill: yellow !important;
}
.labels {
pointer-events: none;
text-anchor: middle;
font-family: Arial, sans-serif;
font-weight: 800;
text-shadow: 1px 1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff, -1px -1px 0 #fff;
}
.transp-txt {
fill: rgb(234, 234, 234);
fill-opacity: 0.4;
}
input {
border: none;
outline: none;
background-color: #ecf0f1;
padding: 10px;
color: #14204f;
border: 0;
margin: 5px 0;
display: block;
width: 100%;
}
.sey-item {
font-size: 0.8em;
padding: 4px;
}
#report {
font-size: 0.9em;
padding-top: 25px;
}
#report.warning {
color: red;
font-style: italic;
}
.report-links {
font-size: 0.8em;
}
#report li {
padding: 6px;
}
.qqq {
font-size: 0.8em;
color: gray;
margin-left: 5px;
}
h4 {
font-style: italic;
}
button {
background-color: #434d72;
border: 0px;
color: white;
font-weight: 800;
margin-top: 10px;
padding: 8px;
}
</style>
<link href='horsey.css' rel='stylesheet' type='text/css' />
<script src="https://d3js.org/d3.v5.js"></script>
<script src="horsey.js"></script>
</head>
<body>
<div style="display:flex;" id="container_graph">
<svg></svg>
<div style="max-width:25%; padding:15px;">
<h4>Highlight a specific node !</h4>
<input id="search" />
<button id="okbutton">Hightlight</button>
<p id="report"></p>
</div>
</div>
<script>
let margin = { top: 20, right: 10, bottom: 20, left: 10 };
let width = Math.max(Math.floor(window.innerWidth * 0.69), 600) - margin.left - margin.right;
let height = Math.max(Math.floor(window.innerHeight * 0.9), 500) - margin.top - margin.bottom;
d3.select('#search').property('value', '');
let svg = d3.select('svg')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style('border', 'solid 1px lightgray')
.call(d3.zoom()
.on("zoom", function () {
d3.select('#drawgroup').attr("transform", d3.event.transform)
}))
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append('g')
.attr('id', 'drawgroup');
let simulation = d3.forceSimulation()
.force("charge", d3.forceManyBody().distanceMin(2).distanceMax(400).strength(d => d.radius * -10))
.force("link", d3.forceLink().id(function(d) { return d.id; }).distance(60).strength(d => d.type !== 'Instance of' ? 0.3 : 0.7))
.force("collide", d3.forceCollide().radius(d => d.radius * 1.5))
// .force("r", d3.forceRadial(150).strength(0.4))
.force("x", d3.forceX(width / 2))
.force("y", d3.forceY(height / 2));
let PropSizer = function (fixed_value, fixed_size) {
this.fixed_value = fixed_value;
const sqrt = Math.sqrt,
abs = Math.abs,
pi = Math.PI;
this.smax = fixed_size * fixed_size * pi;
return (val) => sqrt(abs(val) * this.smax / this.fixed_value) / pi;
};
let timeout_value;
let make_legend = (parent, legend_items, colors_link) => {
let g = parent.selectAll('.legend_item')
.data(legend_items)
.enter()
.append('g')
.attr('transform', (d, i) => `translate(0, ${i * 14})`);
g.append('rect')
.attr('width', 22)
.attr('height', d => d === 'Instance of' ? 1.5 : 3)
.attr('fill', d => colors_link(d));
g.append('text')
.attr('x', 28)
.attr('y', 5)
.style('font-size', '11px')
.text(d => d);
return g;
}
d3.csv('licenses.csv')
.then((data) => {
let _nodes = new Set();
let _links = new Set();
let nodes = [];
let links = [];
let columns_id_features = ['lic0', 'lic1', 'lic2', 'lic3'];
let columns_id_links = ['edge0', 'edge1', 'edge2', 'edge3']
data.forEach((feature) => {
feature['lic'] = +feature['lic'].replace('http://www.wikidata.org/entity/Q', '');
if (feature['lic'] && !_nodes.has(feature['lic'])) {
_nodes.add(feature['lic']);
nodes.push({
id: feature['lic'],
label: feature['licLabel'],
node_type: 'license',
count: 0,
});
}
});
data.forEach((feature) => {
columns_id_features.forEach((id_col, i) => {
feature[id_col] = +feature[id_col].replace('http://www.wikidata.org/entity/Q', '');
// if (feature[id_col] && !_nodes.has(feature[id_col])) {
// _nodes.add(feature[id_col]);
// nodes.push({
// id: feature[id_col],
// label: feature[id_col + 'Label'],
// node_type: 'other',
// count: 0,
// });
// }
if (_nodes.has(feature[id_col])
&& feature[columns_id_links[i]]
&& !_links.has(feature.lic + feature[columns_id_links[i]] + feature[id_col])) {
_links.add(feature.lic + feature[columns_id_links[i]] + feature[id_col]);
links.push({
source: feature.lic,
target: feature[id_col],
type: feature[columns_id_links[i]],
});
}
});
});
let max_q_circle = 0;
let min_q_circle = nodes[0].id;
let prop_size = PropSizer(30, 30);
links.forEach((l, ix) => {
l.id = `l_${ix}`;
nodes.filter(d => d.id === l.source || d.id === l.target).forEach(n => n.count += 1);
})
nodes.forEach(n => {
let v = n.count < 3 ? 3 : n.count;
n.radius = prop_size(v);
if (n.id > max_q_circle) max_q_circle = n.id;
if (n.id < min_q_circle) min_q_circle = n.id;
})
let colors_link = d3.scaleOrdinal(d3.schemeCategory10);
let colors_circle = d3.scaleLinear()
.domain([0, max_q_circle])
.interpolate(d3.interpolateHsl)
.range(['gray', 'white']);
let link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(links)
.enter()
.append("line")
.style('stroke', d => colors_link(d.type))
.style('stroke-width', d => (d.type === 'Instance of' ? '0.5px' : '1.5px'));
let node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr('id', d => `n_${d.id}`)
.attr("r", d => d.radius)
.style("fill", d => colors_circle(d.id))
.style('stroke', 'black')
.style('stroke-width', '0.7px')
.on('mouseover', (d) => {
d3.select(`#txt_${d.id}`).style('display', null);
})
.on('mouseout', (d) => {
d3.select(`#txt_${d.id}`).style('display', 'none');
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.on('dblclick', function (d) {
d3.event.preventDefault();
d3.event.stopPropagation();
highlightNode(d);
});
let text = svg.append("g")
.attr('class', 'labels')
.selectAll("text")
.data(nodes)
.enter()
.append("text")
.attr('id', d => `txt_${d.id}`)
.attr('class', d => d.count > 10 ? 'alwaysdisplay' : '')
.style('display', 'none')
.style('font-size', d => d.count < 10 ? '11px' : d.count > 20 ? '15px' : '13px')
.text(d => d.label);
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
let legend = make_legend(
d3.select('svg > g').append('g'),
[...new Set(links.map(d => d.type))],
colors_link,
);
horsey(document.querySelector('#search'), {
source: [{ list: nodes.map(d => ({ value: "" + d.id, text: d.label })) }],
getText: 'text',
getValue: 'value',
limit: 100,
});
d3.select('#okbutton')
.on('click', () => {
let name = document.querySelector('#search').value;
if (!name) return;
let n = nodes.find(d => d.label === name);
if (n) {
resetReport();
highlightNode(n);
} else {
d3.select('#report').classed('warning', true).text(`Unable to find '${name}'`);
setTimeout(resetReport, 3000);
}
});
function ticked() {
link.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node.attr("cx", d => d.x)
.attr("cy", d => d.y);
text.attr("x", d => d.x)
.attr("y", d => d.y);
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function resetReport() {
d3.select('#report').classed('warning', false).text('');
};
function resetHighlight() {
link.classed('highlight', false)
.classed('transp', false);
node.classed('highlight', false)
.classed('highlight-target', false)
.classed('transp', false);
text.classed('highlight', false)
.classed('transp-txt', false)
.style('font-size', d => d.count < 10 ? '11px' : d.count > 20 ? '15px' : '13px')
.style('display', 'none');
}
function highlightNode(d) {
let node_id = d.id;
let connected_links = links.filter(d => (d.source.id === node_id || d.target.id === node_id));
let other_nodes = connected_links.map(d => d.source.id !== node_id ? d.source.id : d.target.id);
let fragment_report1 = [];
let fragment_report2 = [];
connected_links.sort((a, b) => a.type > b.type);
connected_links.forEach((l) => {
if (l.source.id === node_id) {
fragment_report1.push(`<li><em>${l.type}</em> ${l.target.label}</li>`);
} else {
fragment_report2.push(`<li>${l.source.label} <em>${l.type}</em> ${l.target.label}</li>`);
}
});
connected_links = connected_links.map(d => d.id);
other_nodes.push(node_id);
clearTimeout(timeout_value);
resetHighlight();
link.each(function(elem) {
let val = connected_links.indexOf(elem.id) > -1 ? 'highlight' : 'transp';
d3.select(this).classed(val, true);
});
node.each(function(elem) {
let val = other_nodes.indexOf(elem.id) > -1 ? 'highlight' : 'transp';
d3.select(this).classed(val, true);
});
text.each(function(elem) {
let val = other_nodes.indexOf(elem.id) > -1 ? 'highlight' : 'transp-txt';
d3.select(this).classed(val, true);
});
d3.select(`#n_${node_id}`)
.classed('highlight-target', true);
d3.select(`#txt_${node_id}`)
.style('display', null)
.style('font-size', d => d.count < 10 ? '12px' : d.count > 20 ? '17px' : '15px');
d3.select('#report')
.classed('warning', false)
.html(`
${d.label} <span class="qqq">(Q${d.id})</span> <a target="_blank" href="http://www.wikidata.org/entity/Q${d.id}">&#128279;</a>
<hr>
<div class="report-links">
<ul>
${fragment_report1.join('')}
</ul>
<ul>
${fragment_report2.join('')}
</ul>
</div>`);
timeout_value = setTimeout(() => {
resetHighlight();
resetReport();
}, 4500);
}
});
</script>
</body>
</html>
lic licLabel edge1 lic1 lic1Label edge2 lic2 lic2Label edge0 lic0 lic0Label lic3 lic3Label edge3
http://www.wikidata.org/entity/Q1023365 CERN Open Hardware Licence Instance of http://www.wikidata.org/entity/Q7096068 Open Hardware License
http://www.wikidata.org/entity/Q10289473 Giftware Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q1037852 public domain software Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q1050635 LaTeX Project Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q10513445 GPL-3.0 Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license http://www.wikidata.org/entity/Q10513450 GPLv2 Follows
http://www.wikidata.org/entity/Q10513445 GPL-3.0 Instance of http://www.wikidata.org/entity/Q7603 GNU General Public License http://www.wikidata.org/entity/Q10513450 GPLv2 Follows
http://www.wikidata.org/entity/Q10513450 GPLv2 Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license http://www.wikidata.org/entity/Q10513452 GNU General Public License, version 1 Follows
http://www.wikidata.org/entity/Q10513450 GPLv2 Instance of http://www.wikidata.org/entity/Q7603 GNU General Public License http://www.wikidata.org/entity/Q10513452 GNU General Public License, version 1 Follows
http://www.wikidata.org/entity/Q10513452 GNU General Public License, version 1 Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license
http://www.wikidata.org/entity/Q10513452 GNU General Public License, version 1 Instance of http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q1052189 CeCILL Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q1052189 CeCILL Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q10909819 Q10909819 Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q1100998 Client access license Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1100998 Client access license Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q1107202 ViewFD Instance of http://www.wikidata.org/entity/Q732970 file manager
http://www.wikidata.org/entity/Q1107202 ViewFD Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1116195 Common Public Attribution License Instance of http://www.wikidata.org/entity/Q1156659 open source license Based on http://www.wikidata.org/entity/Q308915 Mozilla Public License
http://www.wikidata.org/entity/Q1116195 Common Public Attribution License Instance of http://www.wikidata.org/entity/Q207621 software license Based on http://www.wikidata.org/entity/Q308915 Mozilla Public License
http://www.wikidata.org/entity/Q11190590 AviUtl Instance of http://www.wikidata.org/entity/Q1373429 video editing software
http://www.wikidata.org/entity/Q11190590 AviUtl Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q11298685 Xelo PDF Instance of http://www.wikidata.org/entity/Q643876 Virtual printer
http://www.wikidata.org/entity/Q11298685 Xelo PDF Instance of http://www.wikidata.org/entity/Q218616 proprietary software
http://www.wikidata.org/entity/Q11298685 Xelo PDF Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1131681 GNU Affero General Public License Subclass of http://www.wikidata.org/entity/Q7603 GNU General Public License Instance of http://www.wikidata.org/entity/Q7603 GNU General Public License Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q1131681 GNU Affero General Public License Subclass of http://www.wikidata.org/entity/Q28130012 Affero General Public License Instance of http://www.wikidata.org/entity/Q7603 GNU General Public License Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q11324228 Q11324228 Instance of http://www.wikidata.org/entity/Q1373429 video editing software
http://www.wikidata.org/entity/Q11324228 Q11324228 Instance of http://www.wikidata.org/entity/Q1340793 commercial software
http://www.wikidata.org/entity/Q11324228 Q11324228 Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1139274 copyleft license Subclass of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q1139274 copyleft license Subclass of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q1149006 Jabber Open Source License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q11498505 3GP Converter Instance of http://www.wikidata.org/entity/Q5156020 video conversion software
http://www.wikidata.org/entity/Q11498505 3GP Converter Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1150694 IZArc Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1150837 SIL Open Font License Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q1153767 platform as a service Subclass of http://www.wikidata.org/entity/Q241317 computing platform
http://www.wikidata.org/entity/Q1153767 platform as a service Subclass of http://www.wikidata.org/entity/Q483639 cloud computing
http://www.wikidata.org/entity/Q1153767 platform as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q1156659 open source license Subclass of http://www.wikidata.org/entity/Q39162 open-source model Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1224853 Open Database License Instance of http://www.wikidata.org/entity/Q51754273 data copyright license
http://www.wikidata.org/entity/Q1224853 Open Database License Instance of http://www.wikidata.org/entity/Q1139274 copyleft license
http://www.wikidata.org/entity/Q12470055 Driving licence in Brazil Instance of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q1254596 software as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service Instance of http://www.wikidata.org/entity/Q28530532 type of software
http://www.wikidata.org/entity/Q1259297 Windows Malicious Software Removal Tool Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1259297 Windows Malicious Software Removal Tool Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q1281977 Eclipse Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q1281977 Eclipse Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q13257633 AROS Public License Subclass of http://www.wikidata.org/entity/Q308915 Mozilla Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license Based on http://www.wikidata.org/entity/Q308915 Mozilla Public License
http://www.wikidata.org/entity/Q1376919 European Union Public Licence Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q1376919 European Union Public Licence Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q13785927 Apache-2.0 Subclass of http://www.wikidata.org/entity/Q616526 Apache License Instance of http://www.wikidata.org/entity/Q207621 software license http://www.wikidata.org/entity/Q17817999 Apache-1.1 Follows
http://www.wikidata.org/entity/Q1396282 Q Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1396282 Q Public License Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q1412537 Open Publication License Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q1437937 permissive free software licence Subclass of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q1444631 freemium Subclass of http://www.wikidata.org/entity/Q178285 freeware Instance of http://www.wikidata.org/entity/Q3394670 pricing strategy
http://www.wikidata.org/entity/Q1444631 freemium Subclass of http://www.wikidata.org/entity/Q178285 freeware Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1444631 freemium Subclass of http://www.wikidata.org/entity/Q218616 proprietary software Instance of http://www.wikidata.org/entity/Q3394670 pricing strategy
http://www.wikidata.org/entity/Q1444631 freemium Subclass of http://www.wikidata.org/entity/Q218616 proprietary software Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1444631 freemium Subclass of http://www.wikidata.org/entity/Q815823 business model Instance of http://www.wikidata.org/entity/Q3394670 pricing strategy
http://www.wikidata.org/entity/Q1444631 freemium Subclass of http://www.wikidata.org/entity/Q815823 business model Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1448814 Osiris Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1448814 Osiris Instance of http://www.wikidata.org/entity/Q166142 application
http://www.wikidata.org/entity/Q1448814 Osiris Instance of http://www.wikidata.org/entity/Q131093 content management system
http://www.wikidata.org/entity/Q1453399 Free Download Manager Instance of http://www.wikidata.org/entity/Q21577192 BitTorrent client
http://www.wikidata.org/entity/Q1453399 Free Download Manager Instance of http://www.wikidata.org/entity/Q840703 offline reader
http://www.wikidata.org/entity/Q1453399 Free Download Manager Instance of http://www.wikidata.org/entity/Q565428 download manager
http://www.wikidata.org/entity/Q1453399 Free Download Manager Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q1453399 Free Download Manager Instance of http://www.wikidata.org/entity/Q166142 application
http://www.wikidata.org/entity/Q14624823 Artistic License 1.0 Instance of http://www.wikidata.org/entity/Q713244 Artistic License
http://www.wikidata.org/entity/Q14624826 Artistic License 2.0 Instance of http://www.wikidata.org/entity/Q3943414 free software license http://www.wikidata.org/entity/Q14624823 Artistic License 1.0 Follows
http://www.wikidata.org/entity/Q14624826 Artistic License 2.0 Instance of http://www.wikidata.org/entity/Q1156659 open source license http://www.wikidata.org/entity/Q14624823 Artistic License 1.0 Follows
http://www.wikidata.org/entity/Q14624826 Artistic License 2.0 Instance of http://www.wikidata.org/entity/Q713244 Artistic License http://www.wikidata.org/entity/Q14624823 Artistic License 1.0 Follows
http://www.wikidata.org/entity/Q1480858 European driving licence Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q1486114 GNAT Modified General Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1486447 GPL linking exception Instance of http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q14946043 Creative Commons Attribution-ShareAlike 3.0 Unported Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19113751 Creative Commons Attribution-ShareAlike 2.5 Generic Follows
http://www.wikidata.org/entity/Q14946043 Creative Commons Attribution-ShareAlike 3.0 Unported Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q19113751 Creative Commons Attribution-ShareAlike 2.5 Generic Follows
http://www.wikidata.org/entity/Q14947546 Creative Commons Attribution 3.0 Unported Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q18810333 CC BY 2.5 Follows
http://www.wikidata.org/entity/Q14947546 Creative Commons Attribution 3.0 Unported Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q18810333 CC BY 2.5 Follows
http://www.wikidata.org/entity/Q1500241 Ventrilo Instance of http://www.wikidata.org/entity/Q15614021 VoIP software
http://www.wikidata.org/entity/Q1500241 Ventrilo Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q152332 Free Art License Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q152481 WTFPL Instance of http://www.wikidata.org/entity/Q25047642 public domain equivalent license
http://www.wikidata.org/entity/Q15410639 IUPAC-InChI Trust License Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q15477153 Microsoft Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q15643954 Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported Instance of http://www.wikidata.org/entity/Q1139274 copyleft license http://www.wikidata.org/entity/Q19068212 Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Generic Follows
http://www.wikidata.org/entity/Q15643954 Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19068212 Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Generic Follows
http://www.wikidata.org/entity/Q15875459 Q15875459 Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q15914252 Creative Commons Attribution-ShareAlike 2.5 Sweden Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q16566743 Italian Open Data License Instance of http://www.wikidata.org/entity/Q51754273 data copyright license
http://www.wikidata.org/entity/Q16566743 Italian Open Data License Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q16911506 experimental use permit Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q16948289 Yahoo! Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q17011832 Eiffel Forum License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q17011832 Eiffel Forum License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q17016921 Open Government Licence Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q17016921 Open Government Licence Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q17070027 MPICH2 license Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q17087127 Cocaine Instance of http://www.wikidata.org/entity/Q1153767 platform as a service
http://www.wikidata.org/entity/Q17087127 Cocaine Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q17125478 logging as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q17143005 recovery as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q17229293 doujin-mark Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q1752744 Open Game License Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q1772828 Microsoft Reciprocal License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q17817999 Apache-1.1 Instance of http://www.wikidata.org/entity/Q616526 Apache License http://www.wikidata.org/entity/Q26897902 Apache-1.0 Follows
http://www.wikidata.org/entity/Q178285 freeware Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q178285 freeware Subclass of http://www.wikidata.org/entity/Q218616 proprietary software
http://www.wikidata.org/entity/Q1798391 LTspice Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q18195572 Creative Commons Attribution-ShareAlike 3.0 Netherlands Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q18199175 Creative Commons Attribution-ShareAlike 2.5 Netherlands Follows
http://www.wikidata.org/entity/Q18195572 Creative Commons Attribution-ShareAlike 3.0 Netherlands Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q18199175 Creative Commons Attribution-ShareAlike 2.5 Netherlands Follows
http://www.wikidata.org/entity/Q18199165 Creative Commons Attribution-ShareAlike 4.0 International Instance of http://www.wikidata.org/entity/Q6905942 Creative Commons Attribution-ShareAlike http://www.wikidata.org/entity/Q14946043 Creative Commons Attribution-ShareAlike 3.0 Unported Follows
http://www.wikidata.org/entity/Q18199165 Creative Commons Attribution-ShareAlike 4.0 International Instance of http://www.wikidata.org/entity/Q6905942 Creative Commons Attribution-ShareAlike http://www.wikidata.org/entity/Q18195572 Creative Commons Attribution-ShareAlike 3.0 Netherlands Follows
http://www.wikidata.org/entity/Q18199165 Creative Commons Attribution-ShareAlike 4.0 International Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q14946043 Creative Commons Attribution-ShareAlike 3.0 Unported Follows
http://www.wikidata.org/entity/Q18199165 Creative Commons Attribution-ShareAlike 4.0 International Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q18195572 Creative Commons Attribution-ShareAlike 3.0 Netherlands Follows
http://www.wikidata.org/entity/Q18199175 Creative Commons Attribution-ShareAlike 2.5 Netherlands Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q18199175 Creative Commons Attribution-ShareAlike 2.5 Netherlands Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q18357595 OpenSaaS Subclass of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q18378690 IBM Bluemix Instance of http://www.wikidata.org/entity/Q1153767 platform as a service
http://www.wikidata.org/entity/Q18378690 IBM Bluemix Instance of http://www.wikidata.org/entity/Q483639 cloud computing
http://www.wikidata.org/entity/Q18378690 IBM Bluemix Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q18491847 3-clause BSD License Instance of http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license
http://www.wikidata.org/entity/Q18517294 2-clause BSD license Instance of http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license
http://www.wikidata.org/entity/Q18526198 Expat license Instance of http://www.wikidata.org/entity/Q334661 MIT license
http://www.wikidata.org/entity/Q18534390 LGPL-2.1 Instance of http://www.wikidata.org/entity/Q3943414 free software license http://www.wikidata.org/entity/Q23035974 LGPL-2.0 Follows
http://www.wikidata.org/entity/Q18534393 LGPL-3.0 Instance of http://www.wikidata.org/entity/Q3943414 free software license http://www.wikidata.org/entity/Q18534390 LGPL-2.1 Follows
http://www.wikidata.org/entity/Q18563589 PostgreSQL License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q18632926 Norwegian Licence for Open Government Data Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q18632926 Norwegian Licence for Open Government Data Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q18810143 Creative Commons Attribution 3.0 United States Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q18810143 Creative Commons Attribution 3.0 United States Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q18810160 Creative Commons Attribution-NoDerivs 3.0 Unported Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q18810338 Creative Commons Attribution-NoDerivs 2.5 Generic Follows
http://www.wikidata.org/entity/Q18810331 Creative Commons Attribution-NonCommercial 3.0 Unported Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19113746 Creative Commons Attribution-NonCommercial 2.5 Generic Follows
http://www.wikidata.org/entity/Q18810333 CC BY 2.5 Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19125117 Creative Commons Attribution 2.0 Generic Follows
http://www.wikidata.org/entity/Q18810333 CC BY 2.5 Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q19125117 Creative Commons Attribution 2.0 Generic Follows
http://www.wikidata.org/entity/Q18810338 Creative Commons Attribution-NoDerivs 2.5 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q35254645 Creative Commons Attribution-NoDerivs 2.0 Generic Follows
http://www.wikidata.org/entity/Q18810341 Creative Commons Attribution-ShareAlike 3.0 United States Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license Based on http://www.wikidata.org/entity/Q14946043 Creative Commons Attribution-ShareAlike 3.0 Unported
http://www.wikidata.org/entity/Q18810341 Creative Commons Attribution-ShareAlike 3.0 United States Instance of http://www.wikidata.org/entity/Q196294 free license Based on http://www.wikidata.org/entity/Q14946043 Creative Commons Attribution-ShareAlike 3.0 Unported
http://www.wikidata.org/entity/Q18913176 Vivaldi Browser Instance of http://www.wikidata.org/entity/Q218616 proprietary software Based on http://www.wikidata.org/entity/Q48524 Chromium
http://www.wikidata.org/entity/Q18913176 Vivaldi Browser Instance of http://www.wikidata.org/entity/Q178285 freeware Based on http://www.wikidata.org/entity/Q48524 Chromium
http://www.wikidata.org/entity/Q18913176 Vivaldi Browser Instance of http://www.wikidata.org/entity/Q6368 web browser Based on http://www.wikidata.org/entity/Q48524 Chromium
http://www.wikidata.org/entity/Q18913176 Vivaldi Browser Instance of http://www.wikidata.org/entity/Q218616 proprietary software Based on http://www.wikidata.org/entity/Q41242 Opera
http://www.wikidata.org/entity/Q18913176 Vivaldi Browser Instance of http://www.wikidata.org/entity/Q178285 freeware Based on http://www.wikidata.org/entity/Q41242 Opera
http://www.wikidata.org/entity/Q18913176 Vivaldi Browser Instance of http://www.wikidata.org/entity/Q6368 web browser Based on http://www.wikidata.org/entity/Q41242 Opera
http://www.wikidata.org/entity/Q19019246 10 of Woody Guthrie's songs Instance of http://www.wikidata.org/entity/Q7725634 literary work
http://www.wikidata.org/entity/Q19019246 10 of Woody Guthrie's songs Instance of http://www.wikidata.org/entity/Q19652 public domain
http://www.wikidata.org/entity/Q1905513 Against DRM license Instance of http://www.wikidata.org/entity/Q1139274 copyleft license
http://www.wikidata.org/entity/Q19068204 Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q47008927 Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Generic Follows
http://www.wikidata.org/entity/Q19068212 Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Generic Instance of http://www.wikidata.org/entity/Q1139274 copyleft license http://www.wikidata.org/entity/Q28050835 Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic Follows
http://www.wikidata.org/entity/Q19068212 Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q28050835 Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic Follows
http://www.wikidata.org/entity/Q19068220 Creative Commons Attribution-ShareAlike 2.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q47001652 Creative Commons Attribution-ShareAlike 1.0 Generic Follows
http://www.wikidata.org/entity/Q19068220 Creative Commons Attribution-ShareAlike 2.0 Generic Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q47001652 Creative Commons Attribution-ShareAlike 1.0 Generic Follows
http://www.wikidata.org/entity/Q19113746 Creative Commons Attribution-NonCommercial 2.5 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q44128984 Creative Commons Attribution-NonCommercial 2.0 Generic Follows
http://www.wikidata.org/entity/Q19113751 Creative Commons Attribution-ShareAlike 2.5 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19068220 Creative Commons Attribution-ShareAlike 2.0 Generic Follows
http://www.wikidata.org/entity/Q19113751 Creative Commons Attribution-ShareAlike 2.5 Generic Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q19068220 Creative Commons Attribution-ShareAlike 2.0 Generic Follows
http://www.wikidata.org/entity/Q19125045 Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19068204 Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Generic Follows
http://www.wikidata.org/entity/Q19125117 Creative Commons Attribution 2.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q30942811 Creative Commons Attribution 1.0 Generic Follows
http://www.wikidata.org/entity/Q19125117 Creative Commons Attribution 2.0 Generic Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q30942811 Creative Commons Attribution 1.0 Generic Follows
http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license Subclass of http://www.wikidata.org/entity/Q1156659 open source license Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license Subclass of http://www.wikidata.org/entity/Q3943414 free software license Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q192897 GNU Lesser General Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q192897 GNU Lesser General Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q19292556 1-clause BSD License Subclass of http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q193345 adware Subclass of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q19392936 Q19392936 Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q1951343 MirOS Licence Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q196294 free license Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q19681540 Hardware license Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q1994744 data as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q20007257 Creative Commons Attribution 4.0 International Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q14947546 Creative Commons Attribution 3.0 Unported Follows
http://www.wikidata.org/entity/Q20007257 Creative Commons Attribution 4.0 International Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q14947546 Creative Commons Attribution 3.0 Unported Follows
http://www.wikidata.org/entity/Q2033808 FreeBSD Documentation License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence Based on http://www.wikidata.org/entity/Q18517294 2-clause BSD license
http://www.wikidata.org/entity/Q205647 driver's license Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q207243 zlib License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q207621 software license Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q20764732 Nethack General Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q20972134 SSLeay Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q20972134 SSLeay Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q21015577 search as a service Subclass of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q21034421 Localize Instance of http://www.wikidata.org/entity/Q4830453 business
http://www.wikidata.org/entity/Q21034421 Localize Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q21193071 Driving licence in Italy Subclass of http://www.wikidata.org/entity/Q1480858 European driving licence Instance of http://www.wikidata.org/entity/Q49848 document
http://www.wikidata.org/entity/Q2144323 parking permit Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q21503790 4-clause BSD license Instance of http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license
http://www.wikidata.org/entity/Q21659044 Unlicense Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q21659044 Unlicense Instance of http://www.wikidata.org/entity/Q4774344 Anti-copyright notice
http://www.wikidata.org/entity/Q22682017 Fair License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q2277058 MaNGOS Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q2294050 Sleepycat License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q23006354 Creative Commons Attribution-NonCommercial-NoDerivs 3.0 France Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q23035974 LGPL-2.0 Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q2306611 Netscape Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q2336497 Microsoft Research Image Composite Editor Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q2352806 Design Science License Instance of http://www.wikidata.org/entity/Q1139274 copyleft license
http://www.wikidata.org/entity/Q2353141 Boost Software License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q23927060 SafetySync Instance of http://www.wikidata.org/entity/Q4830453 business
http://www.wikidata.org/entity/Q23927060 SafetySync Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q24075562 TrapCall Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q24075562 TrapCall Instance of http://www.wikidata.org/entity/Q620615 mobile app
http://www.wikidata.org/entity/Q24082749 Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19125045 Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported Follows
http://www.wikidata.org/entity/Q2411630 The GodFather Instance of http://www.wikidata.org/entity/Q240795 tag editor
http://www.wikidata.org/entity/Q2411630 The GodFather Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q24273512 Public Domain Dedication and License v1.0 Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q24331618 Creative Commons Attribution-ShareAlike 2.5 Canada Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q24331618 Creative Commons Attribution-ShareAlike 2.5 Canada Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q24707952 free to read Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q2471941 Q2471941 Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q2477807 Common Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q2477807 Common Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q2481177 Q2481177 Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q2495855 University of Illinois/NCSA Open Source License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence Based on http://www.wikidata.org/entity/Q18526202 X11 license
http://www.wikidata.org/entity/Q2495855 University of Illinois/NCSA Open Source License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence Based on http://www.wikidata.org/entity/Q18491847 3-clause BSD License
http://www.wikidata.org/entity/Q25036597 as a service Subclass of http://www.wikidata.org/entity/Q79719 license Instance of http://www.wikidata.org/entity/Q187931 phrase
http://www.wikidata.org/entity/Q25036597 as a service Subclass of http://www.wikidata.org/entity/Q7406919 service Instance of http://www.wikidata.org/entity/Q187931 phrase
http://www.wikidata.org/entity/Q25047642 public domain equivalent license Subclass of http://www.wikidata.org/entity/Q19652 public domain
http://www.wikidata.org/entity/Q25047642 public domain equivalent license Subclass of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q25212654 mobility as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q25273268 OpenLDAP Public License Version 2.8 Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q25312823 Blackfire Profiler Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q25312823 Blackfire Profiler Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q25325251 robot as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q25345942 Harrow Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q25345942 Harrow Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q25390073 function as a Service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q25428413 MPL 2.0 Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence http://www.wikidata.org/entity/Q26737735 MPL-1.1 Follows
http://www.wikidata.org/entity/Q2598628 yEd Instance of http://www.wikidata.org/entity/Q3307487 diagramming software
http://www.wikidata.org/entity/Q2598628 yEd Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q2600299 Python Software Foundation License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q2608399 BackupHDDVD Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q26116436 Creative Commons Attribution 2.1 Japan License Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q26116436 Creative Commons Attribution 2.1 Japan License Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q26245522 Eclipse Distribution License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q26245522 Eclipse Distribution License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q26259495 Creative Commons Attribution Intergovernmental Organizations licence 3.0 Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q26259495 Creative Commons Attribution Intergovernmental Organizations licence 3.0 Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q26701938 Angband licence Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q26737735 MPL-1.1 Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence http://www.wikidata.org/entity/Q26737738 MPL-1.0 Follows
http://www.wikidata.org/entity/Q26737738 MPL-1.0 Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q26805816 Italian Open Data License 1.0 Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q26805818 Italian Open Data License 2.0 Instance of http://www.wikidata.org/entity/Q196294 free license http://www.wikidata.org/entity/Q26805816 Italian Open Data License 1.0 Follows
http://www.wikidata.org/entity/Q26897902 Apache-1.0 Instance of http://www.wikidata.org/entity/Q616526 Apache License
http://www.wikidata.org/entity/Q26904555 eCos-2.0 Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q26913038 Creative Commons Sampling Plus 1.0 Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q26913038 Creative Commons Sampling Plus 1.0 Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q26921685 GNU Free Documentation License, version 1.1 Instance of http://www.wikidata.org/entity/Q22169 GNU Free Documentation License
http://www.wikidata.org/entity/Q26921686 GFDL-1.2 Instance of http://www.wikidata.org/entity/Q22169 GNU Free Documentation License http://www.wikidata.org/entity/Q26921685 GNU Free Documentation License, version 1.1 Follows
http://www.wikidata.org/entity/Q26921691 GFDL-1.3 Instance of http://www.wikidata.org/entity/Q22169 GNU Free Documentation License http://www.wikidata.org/entity/Q26921686 GFDL-1.2 Follows
http://www.wikidata.org/entity/Q26996804 CDDL-1.1 Instance of http://www.wikidata.org/entity/Q304628 Common Development and Distribution License http://www.wikidata.org/entity/Q26996811 Common Development and Distribution License version 1.0 Follows
http://www.wikidata.org/entity/Q26996811 Common Development and Distribution License version 1.0 Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q26996811 Common Development and Distribution License version 1.0 Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q26996811 Common Development and Distribution License version 1.0 Instance of http://www.wikidata.org/entity/Q304628 Common Development and Distribution License
http://www.wikidata.org/entity/Q27016750 GPL-1.0+ Instance of http://www.wikidata.org/entity/Q10513452 GNU General Public License, version 1
http://www.wikidata.org/entity/Q27016750 GPL-1.0+ Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license
http://www.wikidata.org/entity/Q27016752 GPL-2.0+ Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license http://www.wikidata.org/entity/Q10513450 GPLv2 Follows
http://www.wikidata.org/entity/Q27016752 GPL-2.0+ Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license http://www.wikidata.org/entity/Q27016750 GPL-1.0+ Follows
http://www.wikidata.org/entity/Q27016752 GPL-2.0+ Instance of http://www.wikidata.org/entity/Q207621 software license http://www.wikidata.org/entity/Q10513450 GPLv2 Follows
http://www.wikidata.org/entity/Q27016752 GPL-2.0+ Instance of http://www.wikidata.org/entity/Q207621 software license http://www.wikidata.org/entity/Q27016750 GPL-1.0+ Follows
http://www.wikidata.org/entity/Q27016754 GPL v3 or later Instance of http://www.wikidata.org/entity/Q10513445 GPL-3.0 http://www.wikidata.org/entity/Q27016752 GPL-2.0+ Follows
http://www.wikidata.org/entity/Q27016754 GPL v3 or later Instance of http://www.wikidata.org/entity/Q3943414 free software license http://www.wikidata.org/entity/Q27016752 GPL-2.0+ Follows
http://www.wikidata.org/entity/Q27016754 GPL v3 or later Instance of http://www.wikidata.org/entity/Q207621 software license http://www.wikidata.org/entity/Q27016752 GPL-2.0+ Follows
http://www.wikidata.org/entity/Q27016757 LGPL-2.1+ Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q27016762 LGPL-3.0+ Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q27017230 AGPL v1.0 only Instance of http://www.wikidata.org/entity/Q28130012 Affero General Public License
http://www.wikidata.org/entity/Q27017232 GNU AGPL v3.0 only Instance of http://www.wikidata.org/entity/Q1131681 GNU Affero General Public License http://www.wikidata.org/entity/Q54365943 AGPL v2.0 Follows
http://www.wikidata.org/entity/Q27019786 GFDL 1.3 or later Instance of http://www.wikidata.org/entity/Q22169 GNU Free Documentation License
http://www.wikidata.org/entity/Q27020062 GNU AGPL v3.0 or later Instance of http://www.wikidata.org/entity/Q27017232 GNU AGPL v3.0 only http://www.wikidata.org/entity/Q54571707 AGPL v1.0 or later Follows
http://www.wikidata.org/entity/Q27020062 GNU AGPL v3.0 or later Instance of http://www.wikidata.org/entity/Q3943414 free software license http://www.wikidata.org/entity/Q54571707 AGPL v1.0 or later Follows
http://www.wikidata.org/entity/Q2708256 Oracle Grid Engine Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q2708256 Oracle Grid Engine Instance of http://www.wikidata.org/entity/Q218616 proprietary software
http://www.wikidata.org/entity/Q27096218 EPICS Open License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q27529879 non-Copyfree software license Subclass of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q27676327 ImageMagick License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q27940776 Creative Commons Attribution 2.5 Sweden Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q27940776 Creative Commons Attribution 2.5 Sweden Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q28050835 Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic Instance of http://www.wikidata.org/entity/Q1139274 copyleft license http://www.wikidata.org/entity/Q47008954 Creative Commons Attribution-NonCommercial-ShareAlike 1.0 Generic Follows
http://www.wikidata.org/entity/Q28050835 Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q47008954 Creative Commons Attribution-NonCommercial-ShareAlike 1.0 Generic Follows
http://www.wikidata.org/entity/Q28130012 Affero General Public License Subclass of http://www.wikidata.org/entity/Q5975031 free software copyleft license Instance of http://www.wikidata.org/entity/Q27529879 non-Copyfree software license Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q28130012 Affero General Public License Subclass of http://www.wikidata.org/entity/Q5975031 free software copyleft license Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q28130012 Affero General Public License Subclass of http://www.wikidata.org/entity/Q27529879 non-Copyfree software license Instance of http://www.wikidata.org/entity/Q27529879 non-Copyfree software license Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q28130012 Affero General Public License Subclass of http://www.wikidata.org/entity/Q27529879 non-Copyfree software license Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license Based on http://www.wikidata.org/entity/Q7603 GNU General Public License
http://www.wikidata.org/entity/Q284471 d20 System Instance of http://www.wikidata.org/entity/Q1752744 Open Game License
http://www.wikidata.org/entity/Q284471 d20 System Instance of http://www.wikidata.org/entity/Q1643932 tabletop role-playing game
http://www.wikidata.org/entity/Q28458427 monitoring as a Service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q284742 Creative Commons license Subclass of http://www.wikidata.org/entity/Q7257715 public copyright license Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q28554579 Open Web Foundation Agreement, Version 0.9 Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q28568150 R2 Docuo Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q28568150 R2 Docuo Instance of http://www.wikidata.org/entity/Q831677 document management system
http://www.wikidata.org/entity/Q28568150 R2 Docuo Instance of http://www.wikidata.org/entity/Q247423 enterprise content management
http://www.wikidata.org/entity/Q28568150 R2 Docuo Instance of http://www.wikidata.org/entity/Q166142 application
http://www.wikidata.org/entity/Q288745 IBM Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q288745 IBM Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q28914702 Microsoft end-user license agreement Instance of http://www.wikidata.org/entity/Q725920 end-user license agreement
http://www.wikidata.org/entity/Q28916324 Apache Usergrid Instance of http://www.wikidata.org/entity/Q39999225 Apache Foundation Project
http://www.wikidata.org/entity/Q28916324 Apache Usergrid Instance of http://www.wikidata.org/entity/Q4839609 mobile backend as a service
http://www.wikidata.org/entity/Q28916324 Apache Usergrid Instance of http://www.wikidata.org/entity/Q341 free software
http://www.wikidata.org/entity/Q2939745 Carnegie Mellon University License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q296677 ARIS MashZone Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q29905723 Mailjet SaaS Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q30222888 Matplotlib license Instance of http://www.wikidata.org/entity/Q196294 free license Based on http://www.wikidata.org/entity/Q2600299 Python Software Foundation License
http://www.wikidata.org/entity/Q3046258 EW-System Instance of http://www.wikidata.org/entity/Q1752744 Open Game License
http://www.wikidata.org/entity/Q3046258 EW-System Instance of http://www.wikidata.org/entity/Q277759 book series
http://www.wikidata.org/entity/Q3046258 EW-System Instance of http://www.wikidata.org/entity/Q160738 role-playing game
http://www.wikidata.org/entity/Q304628 Common Development and Distribution License Subclass of http://www.wikidata.org/entity/Q207621 software license Based on http://www.wikidata.org/entity/Q308915 Mozilla Public License
http://www.wikidata.org/entity/Q304628 Common Development and Distribution License Subclass of http://www.wikidata.org/entity/Q3943414 free software license Based on http://www.wikidata.org/entity/Q308915 Mozilla Public License
http://www.wikidata.org/entity/Q3066722 Ruby License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q308915 Mozilla Public License Subclass of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q30939938 Open Definition conformant license Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q30940585 Open Data Commons Attribution License Instance of http://www.wikidata.org/entity/Q51754273 data copyright license
http://www.wikidata.org/entity/Q30942811 Creative Commons Attribution 1.0 Generic Instance of http://www.wikidata.org/entity/Q30939938 Open Definition conformant license
http://www.wikidata.org/entity/Q30942811 Creative Commons Attribution 1.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q31202214 proprietary software license Subclass of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q31202214 proprietary software license Subclass of http://www.wikidata.org/entity/Q3238057 proprietary license
http://www.wikidata.org/entity/Q3139999 Honest Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q3153096 Interbase Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q319417 SQLite Subclass of http://www.wikidata.org/entity/Q3932296 relational database management system Instance of http://www.wikidata.org/entity/Q35687379 serverless relational database management system
http://www.wikidata.org/entity/Q319417 SQLite Subclass of http://www.wikidata.org/entity/Q3932296 relational database management system Instance of http://www.wikidata.org/entity/Q1037852 public domain software
http://www.wikidata.org/entity/Q319417 SQLite Subclass of http://www.wikidata.org/entity/Q3932296 relational database management system Instance of http://www.wikidata.org/entity/Q341 free software
http://www.wikidata.org/entity/Q3238028 Open License Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q3238028 Open License Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q3238057 proprietary license Subclass of http://www.wikidata.org/entity/Q79719 license Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q33042394 curl license Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q332155 Q332155 Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q332155 Q332155 Subclass of http://www.wikidata.org/entity/Q844482 killing
http://www.wikidata.org/entity/Q334661 MIT license Subclass of http://www.wikidata.org/entity/Q1156659 open source license Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q337279 Academic Free License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence Based on http://www.wikidata.org/entity/Q2495855 University of Illinois/NCSA Open Source License
http://www.wikidata.org/entity/Q34179348 Creative Commons Attribution-NonCommercial 4.0 License Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q18810331 Creative Commons Attribution-NonCommercial 3.0 Unported Follows
http://www.wikidata.org/entity/Q3510465 security as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service Instance of http://www.wikidata.org/entity/Q2695280 technique
http://www.wikidata.org/entity/Q35254645 Creative Commons Attribution-NoDerivs 2.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q47008966 Creative Commons Attribution-NoDerivs 1.0 Generic Follows
http://www.wikidata.org/entity/Q3564577 W3C Software Notice and License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q3570238 Wysigot Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q36795408 Creative Commons Attribution-NoDerivatives 4.0 International Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q18810160 Creative Commons Attribution-NoDerivs 3.0 Unported Follows
http://www.wikidata.org/entity/Q3731857 Erlang Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q3756289 gSOAP Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q376841 PHP License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q3780982 Zope Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q3780982 Zope Public License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q38346089 X.Net, Inc. License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q38347878 wxWindows Library License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q38349857 Vovida Software License Version 1.0 Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q38351460 Simple Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q38364310 Attribution Assurance License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q38365570 Computer Associates Trusted Open Source License, Version 1.1 Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38365646 CNRI portion of the multi-part Python License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38365770 CUA Office Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38365796 The MITRE Collaborative Virtual Workspace License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38365944 EU DataGrid Software License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38366115 Entessa Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38366264 IPA Font License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38490890 Licence Libre du Québec – Réciprocité Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38493399 Licence Libre du Québec – Permissive Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38493724 Licence Libre du Québec – Réciprocité forte Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38494497 Motosoto Open Source License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38494754 Multics License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38495282 Non-Profit Open Software License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38495487 NTP License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38495690 NAUMEN Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38495954 Nokia Open Source License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38496210 OCLC Research Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38496558 OSET Foundation Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q386474 ISC license Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q386474 ISC license Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38685700 Universal Permissive License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q38686558 Open Group Test Suite License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q389898 AIDA64 Instance of http://www.wikidata.org/entity/Q312466 utility software
http://www.wikidata.org/entity/Q389898 AIDA64 Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q39087380 Driving licence in Azerbaijan Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q3943414 free software license Subclass of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q3943414 free software license Subclass of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q3976707 SugarCRM Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q4016359 volume licensing Subclass of http://www.wikidata.org/entity/Q207621 software license Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q4021481 XMedia Recode Instance of http://www.wikidata.org/entity/Q1373429 video editing software
http://www.wikidata.org/entity/Q4021481 XMedia Recode Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q4045381 NnCron Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q4045888 Open Directory License Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q4047648 Punto Switcher Instance of http://www.wikidata.org/entity/Q312466 utility software
http://www.wikidata.org/entity/Q4047648 Punto Switcher Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q4047648 Punto Switcher Instance of http://www.wikidata.org/entity/Q166142 application
http://www.wikidata.org/entity/Q4113957 Driver's license in the United States Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q4113958 Driving licence in Sweden Instance of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q41229007 taxi permit Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q41258135 Q41258135 Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q42172282 Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Portugal Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q42553662 Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q15643954 Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported Follows
http://www.wikidata.org/entity/Q42716613 Creative Commons Attribution-ShareAlike 3.0 Germany Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q42716613 Creative Commons Attribution-ShareAlike 3.0 Germany Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q43338605 Vim license Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q43399754 HubSpot CRM Free Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q43399754 HubSpot CRM Free Instance of http://www.wikidata.org/entity/Q485643 customer relationship management
http://www.wikidata.org/entity/Q4398755 Open Content License Instance of http://www.wikidata.org/entity/Q1139274 copyleft license
http://www.wikidata.org/entity/Q44128984 Creative Commons Attribution-NonCommercial 2.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q44283370 Creative Commons Attribution-NonCommercial 1.0 Generic Follows
http://www.wikidata.org/entity/Q44282633 Creative Commons Attribution 2.0 South Korea Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q44282641 Creative Commons Attribution-ShareAlike 2.0 South Korea Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q44283370 Creative Commons Attribution-NonCommercial 1.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q4462386 Q4462386 Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q45349003 a11y.co Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q45349003 a11y.co Instance of http://www.wikidata.org/entity/Q783866 JavaScript library
http://www.wikidata.org/entity/Q45349003 a11y.co Instance of http://www.wikidata.org/entity/Q184148 plug-in
http://www.wikidata.org/entity/Q4653881 AROS Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q4680711 Adaptive Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q47001652 Creative Commons Attribution-ShareAlike 1.0 Generic Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q47001652 Creative Commons Attribution-ShareAlike 1.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q47001673 Open Government Data License Instance of http://www.wikidata.org/entity/Q51754273 data copyright license
http://www.wikidata.org/entity/Q47001673 Open Government Data License Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q47008926 Creative Commons Attribution-NonCommercial-NoDerivs 1.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q47008927 Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q47008926 Creative Commons Attribution-NonCommercial-NoDerivs 1.0 Generic Follows
http://www.wikidata.org/entity/Q47008954 Creative Commons Attribution-NonCommercial-ShareAlike 1.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q47008966 Creative Commons Attribution-NoDerivs 1.0 Generic Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q47012574 no copyright notice Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q17145201 copyright formalities
http://www.wikidata.org/entity/Q4707078 Driving license in Taiwan Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q47155361 CATS Applicant Tracking System Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q47169086 emulation as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q47246828 published before 1923 Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q2135465 legal concept
http://www.wikidata.org/entity/Q47524112 JasPer License Version 2.0 Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q47524122 Fraunhofer FDK AAC Codec Library for Android license Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q47530884 No Copyright - Non-Commercial Use Only Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q47530706 RightsStatements.org statement
http://www.wikidata.org/entity/Q47530911 No Copyright - United States Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q47530706 RightsStatements.org statement
http://www.wikidata.org/entity/Q48271011 Free Public License Subclass of http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q4839609 mobile backend as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q48463560 Se me apareció la muerte Instance of http://www.wikidata.org/entity/Q7257727 public domain music
http://www.wikidata.org/entity/Q48463560 Se me apareció la muerte Instance of http://www.wikidata.org/entity/Q943929 traditional song
http://www.wikidata.org/entity/Q48463560 Se me apareció la muerte Instance of http://www.wikidata.org/entity/Q567620 anonymous work
http://www.wikidata.org/entity/Q48467248 A las minas del Romero Instance of http://www.wikidata.org/entity/Q7257727 public domain music
http://www.wikidata.org/entity/Q48467248 A las minas del Romero Instance of http://www.wikidata.org/entity/Q943929 traditional song
http://www.wikidata.org/entity/Q48467248 A las minas del Romero Instance of http://www.wikidata.org/entity/Q567620 anonymous work
http://www.wikidata.org/entity/Q48473637 La verdulera Instance of http://www.wikidata.org/entity/Q7257727 public domain music
http://www.wikidata.org/entity/Q48473637 La verdulera Instance of http://www.wikidata.org/entity/Q943929 traditional song
http://www.wikidata.org/entity/Q48473637 La verdulera Instance of http://www.wikidata.org/entity/Q567620 anonymous work
http://www.wikidata.org/entity/Q48477347 Me tienes consumío Instance of http://www.wikidata.org/entity/Q7257727 public domain music
http://www.wikidata.org/entity/Q48477347 Me tienes consumío Instance of http://www.wikidata.org/entity/Q943929 traditional song
http://www.wikidata.org/entity/Q48477347 Me tienes consumío Instance of http://www.wikidata.org/entity/Q567620 anonymous work
http://www.wikidata.org/entity/Q48479463 Mi hora mala llegó Instance of http://www.wikidata.org/entity/Q7257727 public domain music
http://www.wikidata.org/entity/Q48479463 Mi hora mala llegó Instance of http://www.wikidata.org/entity/Q943929 traditional song
http://www.wikidata.org/entity/Q48479463 Mi hora mala llegó Instance of http://www.wikidata.org/entity/Q567620 anonymous work
http://www.wikidata.org/entity/Q48795302 Upstream Compatibility License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q48818116 SEMrush Subclass of http://www.wikidata.org/entity/Q25036597 as a service Instance of http://www.wikidata.org/entity/Q28530532 type of software
http://www.wikidata.org/entity/Q48818116 SEMrush Subclass of http://www.wikidata.org/entity/Q25036597 as a service Instance of http://www.wikidata.org/entity/Q4830453 business
http://www.wikidata.org/entity/Q48818116 SEMrush Subclass of http://www.wikidata.org/entity/Q25036597 as a service Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q4918693 BitTorrent Open Source License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q492916 Public Documentation License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q50551851 Public domain as not covered by copyright law Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q50424085 copyright status
http://www.wikidata.org/entity/Q50552069 Public domain due to expiry of copyright Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q50424085 copyright status
http://www.wikidata.org/entity/Q50829096 GFDL 1.1 or later Instance of http://www.wikidata.org/entity/Q22169 GNU Free Documentation License
http://www.wikidata.org/entity/Q50829104 GFDL 1.2 or later Instance of http://www.wikidata.org/entity/Q22169 GNU Free Documentation License
http://www.wikidata.org/entity/Q5101983 Chiropractic in Canada Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q5140041 Code Project Open License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q5169203 Copyheart Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q51754273 data copyright license Subclass of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q5183504 Creative Commons jurisdiction port Subclass of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q5190781 Cryptix General License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence Based on http://www.wikidata.org/entity/Q191307 Berkeley Software Distribution license
http://www.wikidata.org/entity/Q51915662 Bitrix24 Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q51915662 Bitrix24 Instance of http://www.wikidata.org/entity/Q485643 customer relationship management
http://www.wikidata.org/entity/Q51915662 Bitrix24 Instance of http://www.wikidata.org/entity/Q167035 project management software
http://www.wikidata.org/entity/Q5227408 Database of Molecular Motions Instance of http://www.wikidata.org/entity/Q7251500 protein structure database
http://www.wikidata.org/entity/Q5227408 Database of Molecular Motions Instance of http://www.wikidata.org/entity/Q4117139 biological database
http://www.wikidata.org/entity/Q5227408 Database of Molecular Motions Instance of http://www.wikidata.org/entity/Q3532084 Topic
http://www.wikidata.org/entity/Q5227408 Database of Molecular Motions Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q5227408 Database of Molecular Motions Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q52555753 Creative Commons Attribution 3.0 Australia Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q52555753 Creative Commons Attribution 3.0 Australia Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q5275819 Digital Commons (Elsevier) Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q5289198 DollarRevenue Instance of http://www.wikidata.org/entity/Q193345 adware
http://www.wikidata.org/entity/Q5291073 Dominion Rules Licence Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q5308101 Driving licence in India Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q5308102 Driving licence in Hong Kong Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q5308115 Driving licence in Poland Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q5308116 Driving licence in Russia Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q5308127 Driving license in Bangladesh Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q5308129 driving license in Japan Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q53410575 Antivir Personal Edition Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q53410575 Antivir Personal Edition Instance of http://www.wikidata.org/entity/Q93249 antivirus
http://www.wikidata.org/entity/Q53411361 AntiVir PersonalEdition Classic Instance of http://www.wikidata.org/entity/Q178285 freeware http://www.wikidata.org/entity/Q53410575 Antivir Personal Edition Follows
http://www.wikidata.org/entity/Q53411361 AntiVir PersonalEdition Classic Instance of http://www.wikidata.org/entity/Q93249 antivirus http://www.wikidata.org/entity/Q53410575 Antivir Personal Edition Follows
http://www.wikidata.org/entity/Q5341236 Educational Community License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q53679804 Avira AntiVir Personal - Free Antivirus Instance of http://www.wikidata.org/entity/Q178285 freeware http://www.wikidata.org/entity/Q53411361 AntiVir PersonalEdition Classic Follows
http://www.wikidata.org/entity/Q53679804 Avira AntiVir Personal - Free Antivirus Instance of http://www.wikidata.org/entity/Q93249 antivirus http://www.wikidata.org/entity/Q53411361 AntiVir PersonalEdition Classic Follows
http://www.wikidata.org/entity/Q53679891 Avira Free AntiVirus Subclass of http://www.wikidata.org/entity/Q93249 antivirus Instance of http://www.wikidata.org/entity/Q93249 antivirus http://www.wikidata.org/entity/Q53679804 Avira AntiVir Personal - Free Antivirus Follows
http://www.wikidata.org/entity/Q53679891 Avira Free AntiVirus Subclass of http://www.wikidata.org/entity/Q178285 freeware Instance of http://www.wikidata.org/entity/Q93249 antivirus http://www.wikidata.org/entity/Q53679804 Avira AntiVir Personal - Free Antivirus Follows
http://www.wikidata.org/entity/Q53859967 Creative Commons Attribution 3.0 Netherlands Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q53859967 Creative Commons Attribution 3.0 Netherlands Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q54365943 AGPL v2.0 Instance of http://www.wikidata.org/entity/Q28130012 Affero General Public License http://www.wikidata.org/entity/Q27017230 AGPL v1.0 only Follows
http://www.wikidata.org/entity/Q5440224 Federal Firearms License Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q54571707 AGPL v1.0 or later Instance of http://www.wikidata.org/entity/Q28130012 Affero General Public License
http://www.wikidata.org/entity/Q5460320 Flora License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q5477987 Frameworx License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q5477987 Frameworx License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q55075620 Taxi medallion Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q5514182 GPL font exception Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q5551105 German Free Software License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q55546690 Ventura Image Instance of http://www.wikidata.org/entity/Q6905323 Creative Commons Attribution
http://www.wikidata.org/entity/Q55546690 Ventura Image Instance of http://www.wikidata.org/entity/Q2032379 Ventura
http://www.wikidata.org/entity/Q55546690 Ventura Image Instance of http://www.wikidata.org/entity/Q478798 image
http://www.wikidata.org/entity/Q55546690 Ventura Image Instance of http://www.wikidata.org/entity/Q306147 Channel Islands of California
http://www.wikidata.org/entity/Q55546690 Ventura Image Instance of http://www.wikidata.org/entity/Q36774 web page
http://www.wikidata.org/entity/Q55603117 Twitter Brand Guidelines Instance of http://www.wikidata.org/entity/Q694975 electronic document
http://www.wikidata.org/entity/Q55603117 Twitter Brand Guidelines Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q55603117 Twitter Brand Guidelines Instance of http://www.wikidata.org/entity/Q49848 document
http://www.wikidata.org/entity/Q55603117 Twitter Brand Guidelines Instance of http://www.wikidata.org/entity/Q42848 data
http://www.wikidata.org/entity/Q55603117 Twitter Brand Guidelines Instance of http://www.wikidata.org/entity/Q42332 Portable Document Format
http://www.wikidata.org/entity/Q55633170 Eclipse Public License 1.0 Instance of http://www.wikidata.org/entity/Q1281977 Eclipse Public License
http://www.wikidata.org/entity/Q55633295 Eclipse Public License 2.0 Instance of http://www.wikidata.org/entity/Q1281977 Eclipse Public License
http://www.wikidata.org/entity/Q55824877 WikiAlerts Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q55824877 WikiAlerts Instance of http://www.wikidata.org/entity/Q35127 website
http://www.wikidata.org/entity/Q55896111 GigaMesh Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q55896111 GigaMesh Instance of http://www.wikidata.org/entity/Q166142 application
http://www.wikidata.org/entity/Q56064789 Data licence Germany - Zero - Version 2.0 Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q56292840 Creative Commons Attribution-ShareAlike 3.0 IGO Instance of http://www.wikidata.org/entity/Q3331189 version, edition, or translation
http://www.wikidata.org/entity/Q56292840 Creative Commons Attribution-ShareAlike 3.0 IGO Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q56292840 Creative Commons Attribution-ShareAlike 3.0 IGO Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q56299316 Creative Commons Attribution-NonCommercial-NoDerivs 2.0 UK: England & Wales Instance of http://www.wikidata.org/entity/Q3331189 version, edition, or translation
http://www.wikidata.org/entity/Q56299316 Creative Commons Attribution-NonCommercial-NoDerivs 2.0 UK: England & Wales Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q5637395 Hacktivismo Enhanced-Source Software License Agreement Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q56419952 Open Government Licence - Canada Instance of http://www.wikidata.org/entity/Q7257715 public copyright license
http://www.wikidata.org/entity/Q56419952 Open Government Licence - Canada Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q56641310 Driving license in Indonesia Subclass of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q5773924 Historical Permission Notice and Disclaimer Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q57826961 Q57826961 Subclass of http://www.wikidata.org/entity/Q57826980 permis bateau plaisance
http://www.wikidata.org/entity/Q57826980 permis bateau plaisance Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q5975028 Python License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q5975031 free software copyleft license Subclass of http://www.wikidata.org/entity/Q1139274 copyleft license
http://www.wikidata.org/entity/Q5975031 free software copyleft license Subclass of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q6043507 Intel Open Source License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q613680 Dokeos Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q6165015 Java Research License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q616526 Apache License Subclass of http://www.wikidata.org/entity/Q1437937 permissive free software licence Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q621330 Apple Public Source License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q627693 Open Audio License Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q635577 Sun Industry Standards Source License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q640735 International Certificate of Competence Subclass of http://www.wikidata.org/entity/Q57826980 permis bateau plaisance
http://www.wikidata.org/entity/Q648252 Sun Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license Based on http://www.wikidata.org/entity/Q308915 Mozilla Public License
http://www.wikidata.org/entity/Q6542418 Libpng License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence Based on http://www.wikidata.org/entity/Q207243 zlib License
http://www.wikidata.org/entity/Q6543023 licence to crenellate Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q6696468 Lucent Public License Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q6696468 Lucent Public License Instance of http://www.wikidata.org/entity/Q1156659 open source license
http://www.wikidata.org/entity/Q6716996 MODFLOW Instance of http://www.wikidata.org/entity/Q11121294 simulation software
http://www.wikidata.org/entity/Q6716996 MODFLOW Instance of http://www.wikidata.org/entity/Q1037852 public domain software
http://www.wikidata.org/entity/Q6720214 managed video as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q6905323 Creative Commons Attribution Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q6905323 Creative Commons Attribution Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q6905942 Creative Commons Attribution-ShareAlike Subclass of http://www.wikidata.org/entity/Q284742 Creative Commons license Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q6905942 Creative Commons Attribution-ShareAlike Subclass of http://www.wikidata.org/entity/Q1139274 copyleft license Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q6918172 Motor Vehicle Driving License Instance of http://www.wikidata.org/entity/Q205647 driver's license
http://www.wikidata.org/entity/Q6936496 Creative Commons Attribution-NonCommercial Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q6936496 Creative Commons Attribution-NonCommercial Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q6937225 Creative Commons Attribution-NonCommercial-NoDerivatives Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license http://www.wikidata.org/entity/Q19068204 Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Generic Follows
http://www.wikidata.org/entity/Q6937225 Creative Commons Attribution-NonCommercial-NoDerivatives Instance of http://www.wikidata.org/entity/Q79719 license http://www.wikidata.org/entity/Q19068204 Creative Commons Attribution-NonCommercial-NoDerivs 2.5 Generic Follows
http://www.wikidata.org/entity/Q6938433 CC0 Instance of http://www.wikidata.org/entity/Q25047642 public domain equivalent license
http://www.wikidata.org/entity/Q6938433 CC0 Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q6938433 CC0 Instance of http://www.wikidata.org/entity/Q196294 free license
http://www.wikidata.org/entity/Q6945800 My Lagan Love Instance of http://www.wikidata.org/entity/Q7257727 public domain music
http://www.wikidata.org/entity/Q6945800 My Lagan Love Instance of http://www.wikidata.org/entity/Q2188189 musical work
http://www.wikidata.org/entity/Q6945800 My Lagan Love Instance of http://www.wikidata.org/entity/Q943929 traditional song
http://www.wikidata.org/entity/Q6952418 NASA Open Source Agreement Instance of http://www.wikidata.org/entity/Q1437937 permissive free software licence
http://www.wikidata.org/entity/Q6998997 Creative Commons Attribution–NonCommercial-ShareAlike Subclass of http://www.wikidata.org/entity/Q284742 Creative Commons license Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q6998997 Creative Commons Attribution–NonCommercial-ShareAlike Subclass of http://www.wikidata.org/entity/Q1139274 copyleft license Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q6999319 Creative Commons Attribution-NoDerivatives Subclass of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q7000957 network as a service Subclass of http://www.wikidata.org/entity/Q25036597 as a service
http://www.wikidata.org/entity/Q7096068 Open Hardware License Subclass of http://www.wikidata.org/entity/Q196294 free license Instance of http://www.wikidata.org/entity/Q4167410 Wikimedia disambiguation page
http://www.wikidata.org/entity/Q7096068 Open Hardware License Subclass of http://www.wikidata.org/entity/Q19681540 Hardware license Instance of http://www.wikidata.org/entity/Q4167410 Wikimedia disambiguation page
http://www.wikidata.org/entity/Q713244 Artistic License Subclass of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q7156793 payments as a service Subclass of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q7238710 Pratique Instance of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q7257361 Creative Commons Public Domain Mark Instance of http://www.wikidata.org/entity/Q25047642 public domain equivalent license
http://www.wikidata.org/entity/Q7257361 Creative Commons Public Domain Mark Instance of http://www.wikidata.org/entity/Q284742 Creative Commons license
http://www.wikidata.org/entity/Q7257461 Public License Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q7257715 public copyright license Subclass of http://www.wikidata.org/entity/Q50423863 copyrighted
http://www.wikidata.org/entity/Q7257715 public copyright license Subclass of http://www.wikidata.org/entity/Q79719 license
http://www.wikidata.org/entity/Q7257727 public domain music Subclass of http://www.wikidata.org/entity/Q19652 public domain
http://www.wikidata.org/entity/Q725920 end-user license agreement Subclass of http://www.wikidata.org/entity/Q93288 contract
http://www.wikidata.org/entity/Q725920 end-user license agreement Subclass of http://www.wikidata.org/entity/Q3238057 proprietary license
http://www.wikidata.org/entity/Q7300815 RealNetworks Public Source License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q7302458 Reciprocal Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q7332330 Ricoh Source Code Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q7391010 SLUC Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q7521185 Simputer General Public License Instance of http://www.wikidata.org/entity/Q7096068 Open Hardware License
http://www.wikidata.org/entity/Q7638252 Sun Community Source License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q7659488 Sybase Open Watcom Public License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q7659488 Sybase Open Watcom Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q777520 Open Software License Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q7901822 UserVoice Instance of http://www.wikidata.org/entity/Q4830453 business
http://www.wikidata.org/entity/Q7901822 UserVoice Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q79719 license Subclass of http://www.wikidata.org/entity/Q93288 contract
http://www.wikidata.org/entity/Q79719 license Subclass of http://www.wikidata.org/entity/Q3312801 permit
http://www.wikidata.org/entity/Q7999853 Wikifonia Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q8023586 WinBUGS Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q8027433 WiseStamp Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q8027433 WiseStamp Instance of http://www.wikidata.org/entity/Q166142 application
http://www.wikidata.org/entity/Q8041726 XCore Open Source License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q8075320 Zuora Instance of http://www.wikidata.org/entity/Q43006303 Subscription business model
http://www.wikidata.org/entity/Q8075320 Zuora Instance of http://www.wikidata.org/entity/Q4830453 business
http://www.wikidata.org/entity/Q8075320 Zuora Instance of http://www.wikidata.org/entity/Q1254596 software as a service
http://www.wikidata.org/entity/Q8075320 Zuora Instance of http://www.wikidata.org/entity/Q322948 subscription
http://www.wikidata.org/entity/Q8075320 Zuora Instance of http://www.wikidata.org/entity/Q11016 technology
http://www.wikidata.org/entity/Q8075320 Zuora Instance of http://www.wikidata.org/entity/Q7397 software
http://www.wikidata.org/entity/Q814499 Disabled parking permit Subclass of http://www.wikidata.org/entity/Q2144323 parking permit Instance of http://www.wikidata.org/entity/Q49848 document
http://www.wikidata.org/entity/Q814499 Disabled parking permit Subclass of http://www.wikidata.org/entity/Q3630827 authorization Instance of http://www.wikidata.org/entity/Q49848 document
http://www.wikidata.org/entity/Q905768 Copyright status of work by the U.S. government Subclass of http://www.wikidata.org/entity/Q19652 public domain Instance of http://www.wikidata.org/entity/Q50424085 copyright status
http://www.wikidata.org/entity/Q9265239 Gadami Instance of http://www.wikidata.org/entity/Q2462003 instant messaging client
http://www.wikidata.org/entity/Q9265239 Gadami Instance of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q979794 Aladdin Free Public License Instance of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q10249 Beerware Instance of http://www.wikidata.org/entity/Q25047642 public domain equivalent license
http://www.wikidata.org/entity/Q10249 Beerware Instance of http://www.wikidata.org/entity/Q3943414 free software license
http://www.wikidata.org/entity/Q10267 donationware Subclass of http://www.wikidata.org/entity/Q178285 freeware
http://www.wikidata.org/entity/Q10267 donationware Subclass of http://www.wikidata.org/entity/Q207621 software license
http://www.wikidata.org/entity/Q19652 public domain Subclass of http://www.wikidata.org/entity/Q79719 license Instance of http://www.wikidata.org/entity/Q50424085 copyright status
http://www.wikidata.org/entity/Q19652 public domain Subclass of http://www.wikidata.org/entity/Q272458 public good Instance of http://www.wikidata.org/entity/Q50424085 copyright status
http://www.wikidata.org/entity/Q22169 GNU Free Documentation License Instance of http://www.wikidata.org/entity/Q5975031 free software copyleft license
http://www.wikidata.org/entity/Q22169 GNU Free Documentation License Instance of http://www.wikidata.org/entity/Q1139274 copyleft license
http://www.wikidata.org/entity/Q7603 GNU General Public License Subclass of http://www.wikidata.org/entity/Q5975031 free software copyleft license
http://www.wikidata.org/entity/Q7603 GNU General Public License Subclass of http://www.wikidata.org/entity/Q27529879 non-Copyfree software license
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment