Data from wikidata project.
Last active
November 2, 2018 23:41
-
-
Save mthh/3f70594e37c0c7ba0cc8a874d5d10e3b to your computer and use it in GitHub Desktop.
d3 graph
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJob3JzZXkuanMiLCJub2RlX21vZHVsZXMvYXRvYS9hdG9hLmpzIiwibm9kZV9tb2R1bGVzL2J1bGxzZXllL2J1bGxzZXllLmpzIiwibm9kZV9tb2R1bGVzL2J1bGxzZXllL3RhaWxvcm1hZGUuanMiLCJub2RlX21vZHVsZXMvYnVsbHNleWUvdGhyb3R0bGUuanMiLCJub2RlX21vZHVsZXMvY29udHJhL2RlYm91bmNlLmpzIiwibm9kZV9tb2R1bGVzL2NvbnRyYS9lbWl0dGVyLmpzIiwibm9kZV9tb2R1bGVzL2Nyb3NzdmVudC9zcmMvY3Jvc3N2ZW50LmpzIiwibm9kZV9tb2R1bGVzL2Nyb3NzdmVudC9zcmMvZXZlbnRtYXAuanMiLCJub2RlX21vZHVsZXMvY3VzdG9tLWV2ZW50L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Z1enp5c2VhcmNoL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2hhc2gtc3VtL2hhc2gtc3VtLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9kZWJvdW5jZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNTeW1ib2wuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdG9OdW1iZXIuanMiLCJub2RlX21vZHVsZXMvc2VrdG9yL3NyYy9zZWt0b3IuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb25OdWxsT3AuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb25SYXcuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9nZXRTZWxlY3Rpb25TeW50aGV0aWMuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9pc0hvc3QuanMiLCJub2RlX21vZHVsZXMvc2VsZWNjaW9uL3NyYy9yYW5nZVRvVGV4dFJhbmdlLmpzIiwibm9kZV9tb2R1bGVzL3NlbGVjY2lvbi9zcmMvc2VsZWNjaW9uLmpzIiwibm9kZV9tb2R1bGVzL3NlbGVjY2lvbi9zcmMvc2V0U2VsZWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3NlbGwvc2VsbC5qcyIsIm5vZGVfbW9kdWxlcy90aWNreS90aWNreS1icm93c2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7QUFDQSxJQUFNLGdCQUFnQixDQUF0QjtBQUNBLElBQU0sWUFBWSxFQUFsQjtBQUNBLElBQU0sVUFBVSxFQUFoQjtBQUNBLElBQU0sU0FBUyxFQUFmO0FBQ0EsSUFBTSxXQUFXLEVBQWpCO0FBQ0EsSUFBTSxVQUFVLENBQWhCO0FBQ0EsSUFBTSxNQUFNLFFBQVo7QUFDQSxJQUFNLGFBQWEsSUFBSSxlQUF2Qjs7QUFFQSxTQUFTLE1BQVQsQ0FBaUIsRUFBakIsRUFBbUM7QUFBQSxNQUFkLE9BQWMseURBQUosRUFBSTtBQUFBLE1BRS9CLFVBRitCLEdBYzdCLE9BZDZCLENBRS9CLFVBRitCO0FBQUEsTUFHL0IsSUFIK0IsR0FjN0IsT0FkNkIsQ0FHL0IsR0FIK0I7QUFBQSxNQUkvQixNQUorQixHQWM3QixPQWQ2QixDQUkvQixNQUorQjtBQUFBLE1BSy9CLE1BTCtCLEdBYzdCLE9BZDZCLENBSy9CLE1BTCtCO0FBQUEsdUJBYzdCLE9BZDZCLENBTS9CLEtBTitCO0FBQUEsTUFNL0IsS0FOK0Isa0NBTXZCLEVBTnVCO0FBQUEsTUFPL0IsaUJBUCtCLEdBYzdCLE9BZDZC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QUNwQixXQUFPLFdBQVcsR0FBRyxhQUFkLENBQVA7QUFDRDtBQUNELFNBQU8sS0FBUDtBQUNEOztBQUVELE9BQU8sT0FBUCxHQUFpQixNQUFqQjs7O0FDaDNCQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3JHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBzdW0gZnJvbSAnaGFzaC1zdW0nO1xuaW1wb3J0IHNlbGwgZnJvbSAnc2VsbCc7XG5pbXBvcnQgc2VrdG9yIGZyb20gJ3Nla3Rvcic7XG5pbXBvcnQgZW1pdHRlciBmcm9tICdjb250cmEvZW1pdHRlcic7XG5pbXBvcnQgYnVsbHNleWUgZnJvbSAnYnVsbHNleWUnO1xuaW1wb3J0IGNyb3NzdmVudCBmcm9tICdjcm9zc3ZlbnQnO1xuaW1wb3J0IGZ1enp5c2VhcmNoIGZyb20gJ2Z1enp5c2VhcmNoJztcbmltcG9ydCBkZWJvdW5jZSBmcm9tICdsb2Rhc2gvZGVib3VuY2UnO1xuY29uc3QgS0VZX0JBQ0tTUEFDRSA9IDg7XG5jb25zdCBLRVlfRU5URVIgPSAxMztcbmNvbnN0IEtFWV9FU0MgPSAyNztcbmNvbnN0IEtFWV9VUCA9IDM4O1xuY29uc3QgS0VZX0RPV04gPSA0MDtcbmNvbnN0IEtFWV9UQUIgPSA5O1xuY29uc3QgZG9jID0gZG9jdW1lbnQ7XG5jb25zdCBkb2NFbGVtZW50ID0gZG9jLmRvY3VtZW50RWxlbWVudDtcblxuZnVuY3Rpb24gaG9yc2V5IChlbCwgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHtcbiAgICBzZXRBcHBlbmRzLFxuICAgIHNldCxcbiAgICBmaWx0ZXIsXG4gICAgc291cmNlLFxuICAgIGNhY2hlID0ge30sXG4gICAgcHJlZGljdE5leHRTZWFyY2gsXG4gICAgcmVuZGVySXRlbSxcbiAgICByZW5kZXJDYXRlZ29yeSxcbiAgICBibGFua1NlYXJjaCxcbiAgICBhcHBlbmRUbyxcbiAgICBhbmNob3IsXG4gICAgZGVib3VuY2VcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGNhY2hpbmcgPSBvcHRpb25zLmNhY2hlICE9PSBmYWxzZTtcbiAgaWYgKCFzb3VyY2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCB1c2VyR2V0VGV4dCA9IG9wdGlvbnMuZ2V0VGV4dDtcbiAgY29uc3QgdXNlckdldFZhbHVlID0gb3B0aW9ucy5nZXRWYWx1ZTtcbiAgY29uc3QgZ2V0VGV4dCA9IChcbiAgICB0eXBlb2YgdXNlckdldFRleHQgPT09ICdzdHJpbmcnID8gZCA9PiBkW3VzZXJHZXRUZXh0XSA6XG4gICAgdHlwZW9mIHVzZXJHZXRUZXh0ID09PSAnZnVuY3Rpb24nID8gdXNlckdldFRleHQgOlxuICAgIGQgPT4gZC50b1N0cmluZygpXG4gICk7XG4gIGNvbnN0IGdldFZhbHVlID0gKFxuICAgIHR5cGVvZiB1c2VyR2V0VmFsdWUgPT09ICdzdHJpbmcnID8gZCA9PiBkW3VzZXJHZXRWYWx1ZV0gOlxuICAgIHR5cGVvZiB1c2VyR2V0VmFsdWUgPT09ICdmdW5jdGlvbicgPyB1c2VyR2V0VmFsdWUgOlxuICAgIGQgPT4gZFxuICApO1xuXG4gIGxldCBwcmV2aW91c1N1Z2dlc3Rpb25zID0gW107XG4gIGxldCBwcmV2aW91c1NlbGVjdGlvbiA9IG51bGw7XG4gIGNvbnN0IGxpbWl0ID0gTnVtYmVyKG9wdGlvbnMubGltaXQpIHx8IEluZmluaXR5O1xuICBjb25zdCBjb21wbGV0ZXIgPSBhdXRvY29tcGxldGUoZWwsIHtcbiAgICBzb3VyY2U6IHNvdXJjZUZ1bmN0aW9uLFxuICAgIGxpbWl0LFxuICAgIGdldFRleHQsXG4gICAgZ2V0VmFsdWUsXG4gICAgc2V0QXBwZW5kcyxcbiAgICBwcmVkaWN0TmV4dFNlYXJjaCxcbiAgICByZW5kZXJJdGVtLFxuICAgIHJlbmRlckNhdGVnb3J5LFxuICAgIGFwcGVuZFRvLFxuICAgIGFuY2hvcixcbiAgICBub01hdGNoZXMsXG4gICAgbm9NYXRjaGVzVGV4dDogb3B0aW9ucy5ub01hdGNoZXMsXG4gICAgYmxhbmtTZWFyY2gsXG4gICAgZGVib3VuY2UsXG4gICAgc2V0IChzKSB7XG4gICAgICBpZiAoc2V0QXBwZW5kcyAhPT0gdHJ1ZSkge1xuICAgICAgICBlbC52YWx1ZSA9ICcnO1xuICAgICAgfVxuICAgICAgcHJldmlvdXNTZWxlY3Rpb24gPSBzO1xuICAgICAgKHNldCB8fCBjb21wbGV0ZXIuZGVmYXVsdFNldHRlcikoZ2V0VGV4dChzKSwgcyk7XG4gICAgICBjb21wbGV0ZXIuZW1pdCgnYWZ0ZXJTZXQnKTtcbiAgICB9LFxuICAgIGZpbHRlclxuICB9KTtcbiAgcmV0dXJuIGNvbXBsZXRlcjtcbiAgZnVuY3Rpb24gbm9NYXRjaGVzIChkYXRhKSB7XG4gICAgaWYgKCFvcHRpb25zLm5vTWF0Y2hlcykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YS5xdWVyeS5sZW5ndGg7XG4gIH1cbiAgZnVuY3Rpb24gc291cmNlRnVuY3Rpb24gKGRhdGEsIGRvbmUpIHtcbiAgICBjb25zdCB7cXVlcnksIGxpbWl0fSA9IGRhdGE7XG4gICAgaWYgKCFvcHRpb25zLmJsYW5rU2VhcmNoICYmIHF1ZXJ5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgZG9uZShudWxsLCBbXSwgdHJ1ZSk7IHJldHVybjtcbiAgICB9XG4gICAgaWYgKGNvbXBsZXRlcikge1xuICAgICAgY29tcGxldGVyLmVtaXQoJ2JlZm9yZVVwZGF0ZScpO1xuICAgIH1cbiAgICBjb25zdCBoYXNoID0gc3VtKHF1ZXJ5KTsgLy8gZmFzdCwgY2FzZSBpbnNlbnNpdGl2ZSwgcHJldmVudHMgY29sbGlzaW9uc1xuICAgIGlmIChjYWNoaW5nKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IGNhY2hlW2hhc2hdO1xuICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gZW50cnkuY3JlYXRlZC5nZXRUaW1lKCk7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uID0gY2FjaGUuZHVyYXRpb24gfHwgNjAgKiA2MCAqIDI0O1xuICAgICAgICBjb25zdCBkaWZmID0gZHVyYXRpb24gKiAxMDAwO1xuICAgICAgICBjb25zdCBmcmVzaCA9IG5ldyBEYXRlKHN0YXJ0ICsgZGlmZikgPiBuZXcgRGF0ZSgpO1xuICAgICAgICBpZiAoZnJlc2gpIHtcbiAgICAgICAgICBkb25lKG51bGwsIGVudHJ5Lml0ZW1zLnNsaWNlKCkpOyByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHNvdXJjZURhdGEgPSB7XG4gICAgICBwcmV2aW91c1N1Z2dlc3Rpb25zOiBwcmV2aW91c1N1Z2dlc3Rpb25zLnNsaWNlKCksXG4gICAgICBwcmV2aW91c1NlbGVjdGlvbixcbiAgICAgIGlucHV0OiBxdWVyeSxcbiAgICAgIHJlbmRlckl0ZW0sXG4gICAgICByZW5kZXJDYXRlZ29yeSxcbiAgICAgIGxpbWl0XG4gICAgfTtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMuc291cmNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBvcHRpb25zLnNvdXJjZShzb3VyY2VEYXRhLCBzb3VyY2VkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc291cmNlZChudWxsLCBvcHRpb25zLnNvdXJjZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHNvdXJjZWQgKGVyciwgcmVzdWx0KSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdBdXRvY29tcGxldGUgc291cmNlIGVycm9yLicsIGVyciwgZWwpO1xuICAgICAgICBkb25lKGVyciwgW10pO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbXMgPSBBcnJheS5pc0FycmF5KHJlc3VsdCkgPyByZXN1bHQgOiBbXTtcbiAgICAgIGlmIChjYWNoaW5nKSB7XG4gICAgICAgIGNhY2hlW2hhc2hdID0geyBjcmVhdGVkOiBuZXcgRGF0ZSgpLCBpdGVtcyB9O1xuICAgICAgfVxuICAgICAgcHJldmlvdXNTdWdnZXN0aW9ucyA9IGl0ZW1zO1xuICAgICAgZG9uZShudWxsLCBpdGVtcy5zbGljZSgpKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYXV0b2NvbXBsZXRlIChlbCwgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IG8gPSBvcHRpb25zO1xuICBjb25zdCBwYXJlbnQgPSBvLmFwcGVuZFRvIHx8IGRvYy5ib2R5O1xuICBjb25zdCB7XG4gICAgZ2V0VGV4dCxcbiAgICBnZXRWYWx1ZSxcbiAgICBmb3JtLFxuICAgIHNvdXJjZSxcbiAgICBub01hdGNoZXMsXG4gICAgbm9NYXRjaGVzVGV4dCxcbiAgICBoaWdobGlnaHRlciA9IHRydWUsXG4gICAgaGlnaGxpZ2h0Q29tcGxldGVXb3JkcyA9IHRydWUsXG4gICAgcmVuZGVySXRlbSA9IGRlZmF1bHRJdGVtUmVuZGVyZXIsXG4gICAgcmVuZGVyQ2F0ZWdvcnkgPSBkZWZhdWx0Q2F0ZWdvcnlSZW5kZXJlcixcbiAgICBzZXRBcHBlbmRzXG4gIH0gPSBvO1xuICBjb25zdCBsaW1pdCA9IHR5cGVvZiBvLmxpbWl0ID09PSAnbnVtYmVyJyA/IG8ubGltaXQgOiBJbmZpbml0eTtcbiAgY29uc3QgdXNlckZpbHRlciA9IG8uZmlsdGVyIHx8IGRlZmF1bHRGaWx0ZXI7XG4gIGNvbnN0IHVzZXJTZXQgPSBvLnNldCB8fCBkZWZhdWx0U2V0dGVyO1xuICBjb25zdCBjYXRlZ29yaWVzID0gdGFnKCdkaXYnLCAnc2V5LWNhdGVnb3JpZXMnKTtcbiAgY29uc3QgY29udGFpbmVyID0gdGFnKCdkaXYnLCAnc2V5LWNvbnRhaW5lcicpO1xuICBjb25zdCBkZWZlcnJlZEZpbHRlcmluZyA9IGRlZmVyKGZpbHRlcmluZyk7XG4gIGNvbnN0IHN0YXRlID0geyBjb3VudGVyOiAwLCBxdWVyeTogbnVsbCB9O1xuICBsZXQgY2F0ZWdvcnlNYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBsZXQgc2VsZWN0aW9uID0gbnVsbDtcbiAgbGV0IGV5ZTtcbiAgbGV0IGF0dGFjaG1lbnQgPSBlbDtcbiAgbGV0IG5vbmVNYXRjaDtcbiAgbGV0IHRleHRJbnB1dDtcbiAgbGV0IGFueUlucHV0O1xuICBsZXQgcmFuY2hvcmxlZnQ7XG4gIGxldCByYW5jaG9ycmlnaHQ7XG4gIGxldCBsYXN0UHJlZml4ID0gJyc7XG4gIGNvbnN0IGRlYm91bmNlVGltZSA9IG8uZGVib3VuY2UgfHwgMzAwO1xuICBjb25zdCBkZWJvdW5jZWRMb2FkaW5nID0gZGVib3VuY2UobG9hZGluZywgZGVib3VuY2VUaW1lKTtcblxuICBpZiAoby5hdXRvSGlkZU9uQmx1ciA9PT0gdm9pZCAwKSB7IG8uYXV0b0hpZGVPbkJsdXIgPSB0cnVlOyB9XG4gIGlmIChvLmF1dG9IaWRlT25DbGljayA9PT0gdm9pZCAwKSB7IG8uYXV0b0hpZGVPbkNsaWNrID0gdHJ1ZTsgfVxuICBpZiAoby5hdXRvU2hvd09uVXBEb3duID09PSB2b2lkIDApIHsgby5hdXRvU2hvd09uVXBEb3duID0gZWwudGFnTmFtZSA9PT0gJ0lOUFVUJzsgfVxuICBpZiAoby5hbmNob3IpIHtcbiAgICByYW5jaG9ybGVmdCA9IG5ldyBSZWdFeHAoJ14nICsgby5hbmNob3IpO1xuICAgIHJhbmNob3JyaWdodCA9IG5ldyBSZWdFeHAoby5hbmNob3IgKyAnJCcpO1xuICB9XG5cbiAgbGV0IGhhc0l0ZW1zID0gZmFsc2U7XG4gIGNvbnN0IGFwaSA9IGVtaXR0ZXIoe1xuICAgIGFuY2hvcjogby5hbmNob3IsXG4gICAgY2xlYXIsXG4gICAgc2hvdyxcbiAgICBoaWRlLFxuICAgIHRvZ2dsZSxcbiAgICBkZXN0cm95LFxuICAgIHJlZnJlc2hQb3NpdGlvbixcbiAgICBhcHBlbmRUZXh0LFxuICAgIGFwcGVuZEhUTUwsXG4gICAgZmlsdGVyQW5jaG9yZWRUZXh0LFxuICAgIGZpbHRlckFuY2hvcmVkSFRNTCxcbiAgICBkZWZhdWx0QXBwZW5kVGV4dDogYXBwZW5kVGV4dCxcbiAgICBkZWZhdWx0RmlsdGVyLFxuICAgIGRlZmF1bHRJdGVtUmVuZGVyZXIsXG4gICAgZGVmYXVsdENhdGVnb3J5UmVuZGVyZXIsXG4gICAgZGVmYXVsdFNldHRlcixcbiAgICByZXRhcmdldCxcbiAgICBhdHRhY2htZW50LFxuICAgIHNvdXJjZTogW11cbiAgfSk7XG5cbiAgcmV0YXJnZXQoZWwpO1xuICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2F0ZWdvcmllcyk7XG4gIGlmIChub01hdGNoZXMgJiYgbm9NYXRjaGVzVGV4dCkge1xuICAgIG5vbmVNYXRjaCA9IHRhZygnZGl2JywgJ3NleS1lbXB0eSBzZXktaGlkZScpO1xuICAgIHRleHQobm9uZU1hdGNoLCBub01hdGNoZXNUZXh0KTtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobm9uZU1hdGNoKTtcbiAgfVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdhdXRvY29tcGxldGUnLCAnb2ZmJyk7XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoc291cmNlKSkge1xuICAgIGxvYWRlZChzb3VyY2UsIGZhbHNlKTtcbiAgfVxuXG4gIHJldHVybiBhcGk7XG5cbiAgZnVuY3Rpb24gcmV0YXJnZXQgKGVsKSB7XG4gICAgaW5wdXRFdmVudHModHJ1ZSk7XG4gICAgYXR0YWNobWVudCA9IGFwaS5hdHRhY2htZW50ID0gZWw7XG4gICAgdGV4dElucHV0ID0gYXR0YWNobWVudC50YWdOYW1lID09PSAnSU5QVVQnIHx8IGF0dGFjaG1lbnQudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJztcbiAgICBhbnlJbnB1dCA9IHRleHRJbnB1dCB8fCBpc0VkaXRhYmxlKGF0dGFjaG1lbnQpO1xuICAgIGlucHV0RXZlbnRzKCk7XG4gIH1cblxuICBmdW5jdGlvbiByZWZyZXNoUG9zaXRpb24gKCkge1xuICAgIGlmIChleWUpIHsgZXllLnJlZnJlc2goKTsgfVxuICB9XG5cbiAgZnVuY3Rpb24gbG9hZGluZyAoZm9yY2VTaG93KSB7XG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY3Jvc3N2ZW50LnJlbW92ZShhdHRhY2htZW50LCAnZm9jdXMnLCBsb2FkaW5nKTtcbiAgICBjb25zdCBxdWVyeSA9IHJlYWRJbnB1dCgpO1xuICAgIGlmIChxdWVyeSA9PT0gc3RhdGUucXVlcnkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaGFzSXRlbXMgPSBmYWxzZTtcbiAgICBzdGF0ZS5xdWVyeSA9IHF1ZXJ5O1xuXG4gICAgY29uc3QgY291bnRlciA9ICsrc3RhdGUuY291bnRlcjtcblxuICAgIHNvdXJjZSh7IHF1ZXJ5LCBsaW1pdCB9LCBzb3VyY2VkKTtcblxuICAgIGZ1bmN0aW9uIHNvdXJjZWQgKGVyciwgcmVzdWx0LCBibGFua1F1ZXJ5KSB7XG4gICAgICBpZiAoc3RhdGUuY291bnRlciAhPT0gY291bnRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsb2FkZWQocmVzdWx0LCBmb3JjZVNob3cpO1xuICAgICAgaWYgKGVyciB8fCBibGFua1F1ZXJ5KSB7XG4gICAgICAgIGhhc0l0ZW1zID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbG9hZGVkIChjYXRlZ29yaWVzLCBmb3JjZVNob3cpIHtcbiAgICBjbGVhcigpO1xuICAgIGhhc0l0ZW1zID0gdHJ1ZTtcbiAgICBhcGkuc291cmNlID0gW107XG4gICAgY2F0ZWdvcmllcy5mb3JFYWNoKGNhdCA9PiBjYXQubGlzdC5mb3JFYWNoKHN1Z2dlc3Rpb24gPT4gYWRkKHN1Z2dlc3Rpb24sIGNhdCkpKTtcbiAgICBpZiAoZm9yY2VTaG93KSB7XG4gICAgICBzaG93KCk7XG4gICAgfVxuICAgIGZpbHRlcmluZygpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXIgKCkge1xuICAgIHVuc2VsZWN0KCk7XG4gICAgd2hpbGUgKGNhdGVnb3JpZXMubGFzdENoaWxkKSB7XG4gICAgICBjYXRlZ29yaWVzLnJlbW92ZUNoaWxkKGNhdGVnb3JpZXMubGFzdENoaWxkKTtcbiAgICB9XG4gICAgY2F0ZWdvcnlNYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGhhc0l0ZW1zID0gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiByZWFkSW5wdXQgKCkge1xuICAgIHJldHVybiAodGV4dElucHV0ID8gZWwudmFsdWUgOiBlbC5pbm5lckhUTUwpLnRyaW0oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENhdGVnb3J5IChkYXRhKSB7XG4gICAgaWYgKCFkYXRhLmlkKSB7XG4gICAgICBkYXRhLmlkID0gJ2RlZmF1bHQnO1xuICAgIH1cbiAgICBpZiAoIWNhdGVnb3J5TWFwW2RhdGEuaWRdKSB7XG4gICAgICBjYXRlZ29yeU1hcFtkYXRhLmlkXSA9IGNyZWF0ZUNhdGVnb3J5KCk7XG4gICAgfVxuICAgIHJldHVybiBjYXRlZ29yeU1hcFtkYXRhLmlkXTtcbiAgICBmdW5jdGlvbiBjcmVhdGVDYXRlZ29yeSAoKSB7XG4gICAgICBjb25zdCBjYXRlZ29yeSA9IHRhZygnZGl2JywgJ3NleS1jYXRlZ29yeScpO1xuICAgICAgY29uc3QgdWwgPSB0YWcoJ3VsJywgJ3NleS1saXN0Jyk7XG4gICAgICByZW5kZXJDYXRlZ29yeShjYXRlZ29yeSwgZGF0YSk7XG4gICAgICBjYXRlZ29yeS5hcHBlbmRDaGlsZCh1bCk7XG4gICAgICBjYXRlZ29yaWVzLmFwcGVuZENoaWxkKGNhdGVnb3J5KTtcbiAgICAgIHJldHVybiB7IGRhdGEsIHVsIH07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYWRkIChzdWdnZXN0aW9uLCBjYXRlZ29yeURhdGEpIHtcbiAgICBjb25zdCBjYXQgPSBnZXRDYXRlZ29yeShjYXRlZ29yeURhdGEpO1xuICAgIGNvbnN0IGxpID0gdGFnKCdsaScsICdzZXktaXRlbScpO1xuICAgIHJlbmRlckl0ZW0obGksIHN1Z2dlc3Rpb24pO1xuICAgIGlmIChoaWdobGlnaHRlcikge1xuICAgICAgYnJlYWt1cEZvckhpZ2hsaWdodGVyKGxpKTtcbiAgICB9XG4gICAgY3Jvc3N2ZW50LmFkZChsaSwgJ21vdXNlZW50ZXInLCBob3ZlclN1Z2dlc3Rpb24pO1xuICAgIGNyb3NzdmVudC5hZGQobGksICdjbGljaycsIGNsaWNrZWRTdWdnZXN0aW9uKTtcbiAgICBjcm9zc3ZlbnQuYWRkKGxpLCAnaG9yc2V5LWZpbHRlcicsIGZpbHRlckl0ZW0pO1xuICAgIGNyb3NzdmVudC5hZGQobGksICdob3JzZXktaGlkZScsIGhpZGVJdGVtKTtcbiAgICBjYXQudWwuYXBwZW5kQ2hpbGQobGkpO1xuICAgIGFwaS5zb3VyY2UucHVzaChzdWdnZXN0aW9uKTtcbiAgICByZXR1cm4gbGk7XG5cbiAgICBmdW5jdGlvbiBob3ZlclN1Z2dlc3Rpb24gKCkge1xuICAgICAgc2VsZWN0KGxpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGlja2VkU3VnZ2VzdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnB1dCA9IGdldFRleHQoc3VnZ2VzdGlvbik7XG4gICAgICBzZXQoc3VnZ2VzdGlvbik7XG4gICAgICBoaWRlKCk7XG4gICAgICBhdHRhY2htZW50LmZvY3VzKCk7XG4gICAgICBsYXN0UHJlZml4ID0gby5wcmVkaWN0TmV4dFNlYXJjaCAmJiBvLnByZWRpY3ROZXh0U2VhcmNoKHtcbiAgICAgICAgaW5wdXQ6IGlucHV0LFxuICAgICAgICBzb3VyY2U6IGFwaS5zb3VyY2Uuc2xpY2UoKSxcbiAgICAgICAgc2VsZWN0aW9uOiBzdWdnZXN0aW9uXG4gICAgICB9KSB8fCAnJztcbiAgICAgIGlmIChsYXN0UHJlZml4KSB7XG4gICAgICAgIGVsLnZhbHVlID0gbGFzdFByZWZpeDtcbiAgICAgICAgZWwuc2VsZWN0KCk7XG4gICAgICAgIHNob3coKTtcbiAgICAgICAgZmlsdGVyaW5nKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmlsdGVySXRlbSAoKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlYWRJbnB1dCgpO1xuICAgICAgaWYgKGZpbHRlcih2YWx1ZSwgc3VnZ2VzdGlvbikpIHtcbiAgICAgICAgbGkuY2xhc3NOYW1lID0gbGkuY2xhc3NOYW1lLnJlcGxhY2UoLyBzZXktaGlkZS9nLCAnJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGxpLCAnaG9yc2V5LWhpZGUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoaWRlSXRlbSAoKSB7XG4gICAgICBpZiAoIWhpZGRlbihsaSkpIHtcbiAgICAgICAgbGkuY2xhc3NOYW1lICs9ICcgc2V5LWhpZGUnO1xuICAgICAgICBpZiAoc2VsZWN0aW9uID09PSBsaSkge1xuICAgICAgICAgIHVuc2VsZWN0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBicmVha3VwRm9ySGlnaGxpZ2h0ZXIgKGVsKSB7XG4gICAgZ2V0VGV4dENoaWxkcmVuKGVsKS5mb3JFYWNoKGVsID0+IHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IGVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICBjb25zdCB0ZXh0ID0gZWwudGV4dENvbnRlbnQgfHwgZWwubm9kZVZhbHVlIHx8ICcnO1xuICAgICAgaWYgKHRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGNoYXIgb2YgdGV4dCkge1xuICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKHNwYW5Gb3IoY2hhciksIGVsKTtcbiAgICAgIH1cbiAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbCk7XG4gICAgICBmdW5jdGlvbiBzcGFuRm9yIChjaGFyKSB7XG4gICAgICAgIGNvbnN0IHNwYW4gPSBkb2MuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICBzcGFuLmNsYXNzTmFtZSA9ICdzZXktY2hhcic7XG4gICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSBzcGFuLmlubmVyVGV4dCA9IGNoYXI7XG4gICAgICAgIHJldHVybiBzcGFuO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGlnaGxpZ2h0IChlbCwgbmVlZGxlKSB7XG4gICAgY29uc3QgcndvcmQgPSAvW1xccywuX1xcW1xcXXt9KCktXS9nO1xuICAgIGNvbnN0IHdvcmRzID0gbmVlZGxlLnNwbGl0KHJ3b3JkKS5maWx0ZXIodyA9PiB3Lmxlbmd0aCk7XG4gICAgY29uc3QgZWxlbXMgPSBbLi4uZWwucXVlcnlTZWxlY3RvckFsbCgnLnNleS1jaGFyJyldO1xuICAgIGxldCBjaGFycztcbiAgICBsZXQgc3RhcnRJbmRleCA9IDA7XG5cbiAgICBiYWxhbmNlKCk7XG4gICAgaWYgKGhpZ2hsaWdodENvbXBsZXRlV29yZHMpIHtcbiAgICAgIHdob2xlKCk7XG4gICAgfVxuICAgIGZ1enp5KCk7XG4gICAgY2xlYXJSZW1haW5kZXIoKTtcblxuICAgIGZ1bmN0aW9uIGJhbGFuY2UgKCkge1xuICAgICAgY2hhcnMgPSBlbGVtcy5tYXAoZWwgPT4gZWwuaW5uZXJUZXh0IHx8IGVsLnRleHRDb250ZW50KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3aG9sZSAoKSB7XG4gICAgICBmb3IgKGxldCB3b3JkIG9mIHdvcmRzKSB7XG4gICAgICAgIGxldCB0ZW1wSW5kZXggPSBzdGFydEluZGV4O1xuICAgICAgICByZXRyeTogd2hpbGUgKHRlbXBJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBsZXQgaW5pdCA9IHRydWU7XG4gICAgICAgICAgbGV0IHByZXZJbmRleCA9IHRlbXBJbmRleDtcbiAgICAgICAgICBmb3IgKGxldCBjaGFyIG9mIHdvcmQpIHtcbiAgICAgICAgICAgIGNvbnN0IGkgPSBjaGFycy5pbmRleE9mKGNoYXIsIHByZXZJbmRleCArIDEpO1xuICAgICAgICAgICAgY29uc3QgZmFpbCA9IGkgPT09IC0xIHx8ICghaW5pdCAmJiBwcmV2SW5kZXggKyAxICE9PSBpKTtcbiAgICAgICAgICAgIGlmIChpbml0KSB7XG4gICAgICAgICAgICAgIGluaXQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgdGVtcEluZGV4ID0gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmYWlsKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlIHJldHJ5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcHJldkluZGV4ID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yIChsZXQgZWwgb2YgZWxlbXMuc3BsaWNlKHRlbXBJbmRleCwgMSArIHByZXZJbmRleCAtIHRlbXBJbmRleCkpIHtcbiAgICAgICAgICAgIG9uKGVsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYmFsYW5jZSgpO1xuICAgICAgICAgIG5lZWRsZSA9IG5lZWRsZS5yZXBsYWNlKHdvcmQsICcnKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZ1enp5ICgpIHtcbiAgICAgIGZvciAobGV0IGlucHV0IG9mIG5lZWRsZSkge1xuICAgICAgICB3aGlsZSAoZWxlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgbGV0IGVsID0gZWxlbXMuc2hpZnQoKTtcbiAgICAgICAgICBpZiAoKGVsLmlubmVyVGV4dCB8fCBlbC50ZXh0Q29udGVudCkgPT09IGlucHV0KSB7XG4gICAgICAgICAgICBvbihlbCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2ZmKGVsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhclJlbWFpbmRlciAoKSB7XG4gICAgICB3aGlsZSAoZWxlbXMubGVuZ3RoKSB7XG4gICAgICAgIG9mZihlbGVtcy5zaGlmdCgpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvbiAoY2gpIHtcbiAgICAgIGNoLmNsYXNzTGlzdC5hZGQoJ3NleS1jaGFyLWhpZ2hsaWdodCcpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBvZmYgKGNoKSB7XG4gICAgICBjaC5jbGFzc0xpc3QucmVtb3ZlKCdzZXktY2hhci1oaWdobGlnaHQnKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnZXRUZXh0Q2hpbGRyZW4gKGVsKSB7XG4gICAgY29uc3QgdGV4dHMgPSBbXTtcbiAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKGVsLCBOb2RlRmlsdGVyLlNIT1dfVEVYVCwgbnVsbCwgZmFsc2UpO1xuICAgIGxldCBub2RlO1xuICAgIHdoaWxlIChub2RlID0gd2Fsa2VyLm5leHROb2RlKCkpIHtcbiAgICAgIHRleHRzLnB1c2gobm9kZSk7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHNldCAodmFsdWUpIHtcbiAgICBpZiAoby5hbmNob3IpIHtcbiAgICAgIHJldHVybiAoaXNUZXh0KCkgPyBhcGkuYXBwZW5kVGV4dCA6IGFwaS5hcHBlbmRIVE1MKShnZXRWYWx1ZSh2YWx1ZSkpO1xuICAgIH1cbiAgICB1c2VyU2V0KHZhbHVlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlciAodmFsdWUsIHN1Z2dlc3Rpb24pIHtcbiAgICBpZiAoby5hbmNob3IpIHtcbiAgICAgIGNvbnN0IGlsID0gKGlzVGV4dCgpID8gYXBpLmZpbHRlckFuY2hvcmVkVGV4dCA6IGFwaS5maWx0ZXJBbmNob3JlZEhUTUwpKHZhbHVlLCBzdWdnZXN0aW9uKTtcbiAgICAgIHJldHVybiBpbCA/IHVzZXJGaWx0ZXIoaWwuaW5wdXQsIGlsLnN1Z2dlc3Rpb24pIDogZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB1c2VyRmlsdGVyKHZhbHVlLCBzdWdnZXN0aW9uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzVGV4dCAoKSB7IHJldHVybiBpc0lucHV0KGF0dGFjaG1lbnQpOyB9XG4gIGZ1bmN0aW9uIHZpc2libGUgKCkgeyByZXR1cm4gY29udGFpbmVyLmNsYXNzTmFtZS5pbmRleE9mKCdzZXktc2hvdycpICE9PSAtMTsgfVxuICBmdW5jdGlvbiBoaWRkZW4gKGxpKSB7IHJldHVybiBsaS5jbGFzc05hbWUuaW5kZXhPZignc2V5LWhpZGUnKSAhPT0gLTE7IH1cblxuICBmdW5jdGlvbiBzaG93ICgpIHtcbiAgICBleWUucmVmcmVzaCgpO1xuICAgIGlmICghdmlzaWJsZSgpKSB7XG4gICAgICBjb250YWluZXIuY2xhc3NOYW1lICs9ICcgc2V5LXNob3cnO1xuICAgICAgY3Jvc3N2ZW50LmZhYnJpY2F0ZShhdHRhY2htZW50LCAnaG9yc2V5LXNob3cnKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB0b2dnbGVyIChlKSB7XG4gICAgY29uc3QgbGVmdCA9IGUud2hpY2ggPT09IDEgJiYgIWUubWV0YUtleSAmJiAhZS5jdHJsS2V5O1xuICAgIGlmIChsZWZ0ID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuOyAvLyB3ZSBvbmx5IGNhcmUgYWJvdXQgaG9uZXN0IHRvIGdvZCBsZWZ0LWNsaWNrc1xuICAgIH1cbiAgICB0b2dnbGUoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvZ2dsZSAoKSB7XG4gICAgaWYgKCF2aXNpYmxlKCkpIHtcbiAgICAgIHNob3coKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlkZSgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNlbGVjdCAobGkpIHtcbiAgICB1bnNlbGVjdCgpO1xuICAgIGlmIChsaSkge1xuICAgICAgc2VsZWN0aW9uID0gbGk7XG4gICAgICBzZWxlY3Rpb24uY2xhc3NOYW1lICs9ICcgc2V5LXNlbGVjdGVkJztcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1bnNlbGVjdCAoKSB7XG4gICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgc2VsZWN0aW9uLmNsYXNzTmFtZSA9IHNlbGVjdGlvbi5jbGFzc05hbWUucmVwbGFjZSgvIHNleS1zZWxlY3RlZC9nLCAnJyk7XG4gICAgICBzZWxlY3Rpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1vdmUgKHVwLCBtb3Zlcykge1xuICAgIGNvbnN0IHRvdGFsID0gYXBpLnNvdXJjZS5sZW5ndGg7XG4gICAgaWYgKHRvdGFsID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChtb3ZlcyA+IHRvdGFsKSB7XG4gICAgICB1bnNlbGVjdCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjYXQgPSBmaW5kQ2F0ZWdvcnkoc2VsZWN0aW9uKSB8fCBjYXRlZ29yaWVzLmZpcnN0Q2hpbGQ7XG4gICAgY29uc3QgZmlyc3QgPSB1cCA/ICdsYXN0Q2hpbGQnIDogJ2ZpcnN0Q2hpbGQnO1xuICAgIGNvbnN0IGxhc3QgPSB1cCA/ICdmaXJzdENoaWxkJyA6ICdsYXN0Q2hpbGQnO1xuICAgIGNvbnN0IG5leHQgPSB1cCA/ICdwcmV2aW91c1NpYmxpbmcnIDogJ25leHRTaWJsaW5nJztcbiAgICBjb25zdCBwcmV2ID0gdXAgPyAnbmV4dFNpYmxpbmcnIDogJ3ByZXZpb3VzU2libGluZyc7XG4gICAgY29uc3QgbGkgPSBmaW5kTmV4dCgpO1xuICAgIHNlbGVjdChsaSk7XG5cbiAgICBpZiAoaGlkZGVuKGxpKSkge1xuICAgICAgbW92ZSh1cCwgbW92ZXMgPyBtb3ZlcyArIDEgOiAxKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBmaW5kQ2F0ZWdvcnkgKGVsKSB7XG4gICAgICB3aGlsZSAoZWwpIHtcbiAgICAgICAgaWYgKHNla3Rvci5tYXRjaGVzU2VsZWN0b3IoZWwucGFyZW50RWxlbWVudCwgJy5zZXktY2F0ZWdvcnknKSkge1xuICAgICAgICAgIHJldHVybiBlbC5wYXJlbnRFbGVtZW50O1xuICAgICAgICB9XG4gICAgICAgIGVsID0gZWwucGFyZW50RWxlbWVudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGZpbmROZXh0ICgpIHtcbiAgICAgIGlmIChzZWxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHNlbGVjdGlvbltuZXh0XSkge1xuICAgICAgICAgIHJldHVybiBzZWxlY3Rpb25bbmV4dF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNhdFtuZXh0XSAmJiBmaW5kTGlzdChjYXRbbmV4dF0pW2ZpcnN0XSkge1xuICAgICAgICAgIHJldHVybiBmaW5kTGlzdChjYXRbbmV4dF0pW2ZpcnN0XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZpbmRMaXN0KGNhdGVnb3JpZXNbZmlyc3RdKVtmaXJzdF07XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGlkZSAoKSB7XG4gICAgZXllLnNsZWVwKCk7XG4gICAgY29udGFpbmVyLmNsYXNzTmFtZSA9IGNvbnRhaW5lci5jbGFzc05hbWUucmVwbGFjZSgvIHNleS1zaG93L2csICcnKTtcbiAgICB1bnNlbGVjdCgpO1xuICAgIGNyb3NzdmVudC5mYWJyaWNhdGUoYXR0YWNobWVudCwgJ2hvcnNleS1oaWRlJyk7XG4gICAgaWYgKGVsLnZhbHVlID09PSBsYXN0UHJlZml4KSB7XG4gICAgICBlbC52YWx1ZSA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGtleWRvd24gKGUpIHtcbiAgICBjb25zdCBzaG93biA9IHZpc2libGUoKTtcbiAgICBjb25zdCB3aGljaCA9IGUud2hpY2ggfHwgZS5rZXlDb2RlO1xuICAgIGlmICh3aGljaCA9PT0gS0VZX0RPV04pIHtcbiAgICAgIGlmIChhbnlJbnB1dCAmJiBvLmF1dG9TaG93T25VcERvd24pIHtcbiAgICAgICAgc2hvdygpO1xuICAgICAgfVxuICAgICAgaWYgKHNob3duKSB7XG4gICAgICAgIG1vdmUoKTtcbiAgICAgICAgc3RvcChlKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHdoaWNoID09PSBLRVlfVVApIHtcbiAgICAgIGlmIChhbnlJbnB1dCAmJiBvLmF1dG9TaG93T25VcERvd24pIHtcbiAgICAgICAgc2hvdygpO1xuICAgICAgfVxuICAgICAgaWYgKHNob3duKSB7XG4gICAgICAgIG1vdmUodHJ1ZSk7XG4gICAgICAgIHN0b3AoZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh3aGljaCA9PT0gS0VZX0JBQ0tTUEFDRSkge1xuICAgICAgaWYgKGFueUlucHV0ICYmIG8uYXV0b1Nob3dPblVwRG93bikge1xuICAgICAgICBzaG93KCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzaG93bikge1xuICAgICAgaWYgKHdoaWNoID09PSBLRVlfRU5URVIpIHtcbiAgICAgICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgICAgIGNyb3NzdmVudC5mYWJyaWNhdGUoc2VsZWN0aW9uLCAnY2xpY2snKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoaWRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgc3RvcChlKTtcbiAgICAgIH0gZWxzZSBpZiAod2hpY2ggPT09IEtFWV9FU0MpIHtcbiAgICAgICAgaGlkZSgpO1xuICAgICAgICBzdG9wKGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0b3AgKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3dOb1Jlc3VsdHMgKCkge1xuICAgIGlmIChub25lTWF0Y2gpIHtcbiAgICAgIG5vbmVNYXRjaC5jbGFzc0xpc3QucmVtb3ZlKCdzZXktaGlkZScpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhpZGVOb1Jlc3VsdHMgKCkge1xuICAgIGlmIChub25lTWF0Y2gpIHtcbiAgICAgIG5vbmVNYXRjaC5jbGFzc0xpc3QuYWRkKCdzZXktaGlkZScpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlcmluZyAoKSB7XG4gICAgaWYgKCF2aXNpYmxlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZGVib3VuY2VkTG9hZGluZyh0cnVlKTtcbiAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGF0dGFjaG1lbnQsICdob3JzZXktZmlsdGVyJyk7XG4gICAgY29uc3QgdmFsdWUgPSByZWFkSW5wdXQoKTtcbiAgICBpZiAoIW8uYmxhbmtTZWFyY2ggJiYgIXZhbHVlKSB7XG4gICAgICBoaWRlKCk7IHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgbm9tYXRjaCA9IG5vTWF0Y2hlcyh7IHF1ZXJ5OiB2YWx1ZSB9KTtcbiAgICBsZXQgY291bnQgPSB3YWxrQ2F0ZWdvcmllcygpO1xuICAgIGlmIChjb3VudCA9PT0gMCAmJiBub21hdGNoICYmIGhhc0l0ZW1zKSB7XG4gICAgICBzaG93Tm9SZXN1bHRzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhpZGVOb1Jlc3VsdHMoKTtcbiAgICB9XG4gICAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICAgIG1vdmUoKTtcbiAgICB9XG4gICAgaWYgKCFzZWxlY3Rpb24gJiYgIW5vbWF0Y2gpIHtcbiAgICAgIGhpZGUoKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gd2Fsa0NhdGVnb3JpZXMgKCkge1xuICAgICAgbGV0IGNhdGVnb3J5ID0gY2F0ZWdvcmllcy5maXJzdENoaWxkO1xuICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgIHdoaWxlIChjYXRlZ29yeSkge1xuICAgICAgICBjb25zdCBsaXN0ID0gZmluZExpc3QoY2F0ZWdvcnkpO1xuICAgICAgICBjb25zdCBwYXJ0aWFsID0gd2Fsa0NhdGVnb3J5KGxpc3QpO1xuICAgICAgICBpZiAocGFydGlhbCA9PT0gMCkge1xuICAgICAgICAgIGNhdGVnb3J5LmNsYXNzTGlzdC5hZGQoJ3NleS1oaWRlJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2F0ZWdvcnkuY2xhc3NMaXN0LnJlbW92ZSgnc2V5LWhpZGUnKTtcbiAgICAgICAgfVxuICAgICAgICBjb3VudCArPSBwYXJ0aWFsO1xuICAgICAgICBjYXRlZ29yeSA9IGNhdGVnb3J5Lm5leHRTaWJsaW5nO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvdW50O1xuICAgIH1cbiAgICBmdW5jdGlvbiB3YWxrQ2F0ZWdvcnkgKHVsKSB7XG4gICAgICBsZXQgbGkgPSB1bC5maXJzdENoaWxkO1xuICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgIHdoaWxlIChsaSkge1xuICAgICAgICBpZiAoY291bnQgPj0gbGltaXQpIHtcbiAgICAgICAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGxpLCAnaG9yc2V5LWhpZGUnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjcm9zc3ZlbnQuZmFicmljYXRlKGxpLCAnaG9yc2V5LWZpbHRlcicpO1xuICAgICAgICAgIGlmIChsaS5jbGFzc05hbWUuaW5kZXhPZignc2V5LWhpZGUnKSA9PT0gLTEpIHtcbiAgICAgICAgICAgIGNvdW50Kys7XG4gICAgICAgICAgICBpZiAoaGlnaGxpZ2h0ZXIpIHtcbiAgICAgICAgICAgICAgaGlnaGxpZ2h0KGxpLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxpID0gbGkubmV4dFNpYmxpbmc7XG4gICAgICB9XG4gICAgICByZXR1cm4gY291bnQ7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZGVmZXJyZWRGaWx0ZXJpbmdOb0VudGVyIChlKSB7XG4gICAgY29uc3Qgd2hpY2ggPSBlLndoaWNoIHx8IGUua2V5Q29kZTtcbiAgICBpZiAod2hpY2ggPT09IEtFWV9FTlRFUikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkZWZlcnJlZEZpbHRlcmluZygpO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVmZXJyZWRTaG93IChlKSB7XG4gICAgY29uc3Qgd2hpY2ggPSBlLndoaWNoIHx8IGUua2V5Q29kZTtcbiAgICBpZiAod2hpY2ggPT09IEtFWV9FTlRFUiB8fCB3aGljaCA9PT0gS0VZX1RBQikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRUaW1lb3V0KHNob3csIDApO1xuICB9XG5cbiAgZnVuY3Rpb24gYXV0b2NvbXBsZXRlRXZlbnRUYXJnZXQgKGUpIHtcbiAgICBsZXQgdGFyZ2V0ID0gZS50YXJnZXQ7XG4gICAgaWYgKHRhcmdldCA9PT0gYXR0YWNobWVudCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHdoaWxlICh0YXJnZXQpIHtcbiAgICAgIGlmICh0YXJnZXQgPT09IGNvbnRhaW5lciB8fCB0YXJnZXQgPT09IGF0dGFjaG1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlT25CbHVyIChlKSB7XG4gICAgY29uc3Qgd2hpY2ggPSBlLndoaWNoIHx8IGUua2V5Q29kZTtcbiAgICBpZiAod2hpY2ggPT09IEtFWV9UQUIpIHtcbiAgICAgIGhpZGUoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoaWRlT25DbGljayAoZSkge1xuICAgIGlmIChhdXRvY29tcGxldGVFdmVudFRhcmdldChlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBoaWRlKCk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnB1dEV2ZW50cyAocmVtb3ZlKSB7XG4gICAgY29uc3Qgb3AgPSByZW1vdmUgPyAncmVtb3ZlJyA6ICdhZGQnO1xuICAgIGlmIChleWUpIHtcbiAgICAgIGV5ZS5kZXN0cm95KCk7XG4gICAgICBleWUgPSBudWxsO1xuICAgIH1cbiAgICBpZiAoIXJlbW92ZSkge1xuICAgICAgZXllID0gYnVsbHNleWUoY29udGFpbmVyLCBhdHRhY2htZW50LCB7XG4gICAgICAgIGNhcmV0OiBhbnlJbnB1dCAmJiBhdHRhY2htZW50LnRhZ05hbWUgIT09ICdJTlBVVCcsXG4gICAgICAgIGNvbnRleHQ6IG8uYXBwZW5kVG9cbiAgICAgIH0pO1xuICAgICAgaWYgKCF2aXNpYmxlKCkpIHsgZXllLnNsZWVwKCk7IH1cbiAgICB9XG4gICAgaWYgKHJlbW92ZSB8fCAoYW55SW5wdXQgJiYgZG9jLmFjdGl2ZUVsZW1lbnQgIT09IGF0dGFjaG1lbnQpKSB7XG4gICAgICBjcm9zc3ZlbnRbb3BdKGF0dGFjaG1lbnQsICdmb2N1cycsIGxvYWRpbmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2FkaW5nKCk7XG4gICAgfVxuICAgIGlmIChhbnlJbnB1dCkge1xuICAgICAgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5cHJlc3MnLCBkZWZlcnJlZFNob3cpO1xuICAgICAgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5cHJlc3MnLCBkZWZlcnJlZEZpbHRlcmluZyk7XG4gICAgICBjcm9zc3ZlbnRbb3BdKGF0dGFjaG1lbnQsICdrZXlkb3duJywgZGVmZXJyZWRGaWx0ZXJpbmdOb0VudGVyKTtcbiAgICAgIGNyb3NzdmVudFtvcF0oYXR0YWNobWVudCwgJ3Bhc3RlJywgZGVmZXJyZWRGaWx0ZXJpbmcpO1xuICAgICAgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5ZG93bicsIGtleWRvd24pO1xuICAgICAgaWYgKG8uYXV0b0hpZGVPbkJsdXIpIHsgY3Jvc3N2ZW50W29wXShhdHRhY2htZW50LCAna2V5ZG93bicsIGhpZGVPbkJsdXIpOyB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNyb3NzdmVudFtvcF0oYXR0YWNobWVudCwgJ2NsaWNrJywgdG9nZ2xlcik7XG4gICAgICBjcm9zc3ZlbnRbb3BdKGRvY0VsZW1lbnQsICdrZXlkb3duJywga2V5ZG93bik7XG4gICAgfVxuICAgIGlmIChvLmF1dG9IaWRlT25DbGljaykgeyBjcm9zc3ZlbnRbb3BdKGRvYywgJ2NsaWNrJywgaGlkZU9uQ2xpY2spOyB9XG4gICAgaWYgKGZvcm0pIHsgY3Jvc3N2ZW50W29wXShmb3JtLCAnc3VibWl0JywgaGlkZSk7IH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3kgKCkge1xuICAgIGlucHV0RXZlbnRzKHRydWUpO1xuICAgIGlmIChwYXJlbnQuY29udGFpbnMoY29udGFpbmVyKSkgeyBwYXJlbnQucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTsgfVxuICB9XG5cbiAgZnVuY3Rpb24gZGVmYXVsdFNldHRlciAodmFsdWUpIHtcbiAgICBpZiAodGV4dElucHV0KSB7XG4gICAgICBpZiAoc2V0QXBwZW5kcyA9PT0gdHJ1ZSkge1xuICAgICAgICBlbC52YWx1ZSArPSAnICcgKyB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsLnZhbHVlID0gdmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzZXRBcHBlbmRzID09PSB0cnVlKSB7XG4gICAgICAgIGVsLmlubmVySFRNTCArPSAnICcgKyB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsLmlubmVySFRNTCA9IHZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlZmF1bHRJdGVtUmVuZGVyZXIgKGxpLCBzdWdnZXN0aW9uKSB7XG4gICAgdGV4dChsaSwgZ2V0VGV4dChzdWdnZXN0aW9uKSk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0Q2F0ZWdvcnlSZW5kZXJlciAoZGl2LCBkYXRhKSB7XG4gICAgaWYgKGRhdGEuaWQgIT09ICdkZWZhdWx0Jykge1xuICAgICAgY29uc3QgaWQgPSB0YWcoJ2RpdicsICdzZXktY2F0ZWdvcnktaWQnKTtcbiAgICAgIGRpdi5hcHBlbmRDaGlsZChpZCk7XG4gICAgICB0ZXh0KGlkLCBkYXRhLmlkKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0RmlsdGVyIChxLCBzdWdnZXN0aW9uKSB7XG4gICAgY29uc3QgbmVlZGxlID0gcS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IHRleHQgPSBnZXRUZXh0KHN1Z2dlc3Rpb24pIHx8ICcnO1xuICAgIGlmIChmdXp6eXNlYXJjaChuZWVkbGUsIHRleHQudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IGdldFZhbHVlKHN1Z2dlc3Rpb24pIHx8ICcnO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBmdXp6eXNlYXJjaChuZWVkbGUsIHZhbHVlLnRvTG93ZXJDYXNlKCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gbG9vcGJhY2tUb0FuY2hvciAodGV4dCwgcCkge1xuICAgIGxldCByZXN1bHQgPSAnJztcbiAgICBsZXQgYW5jaG9yZWQgPSBmYWxzZTtcbiAgICBsZXQgc3RhcnQgPSBwLnN0YXJ0O1xuICAgIHdoaWxlIChhbmNob3JlZCA9PT0gZmFsc2UgJiYgc3RhcnQgPj0gMCkge1xuICAgICAgcmVzdWx0ID0gdGV4dC5zdWJzdHIoc3RhcnQgLSAxLCBwLnN0YXJ0IC0gc3RhcnQgKyAxKTtcbiAgICAgIGFuY2hvcmVkID0gcmFuY2hvcmxlZnQudGVzdChyZXN1bHQpO1xuICAgICAgc3RhcnQtLTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRleHQ6IGFuY2hvcmVkID8gcmVzdWx0IDogbnVsbCxcbiAgICAgIHN0YXJ0XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlckFuY2hvcmVkVGV4dCAocSwgc3VnZ2VzdGlvbikge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gc2VsbChlbCk7XG4gICAgY29uc3QgaW5wdXQgPSBsb29wYmFja1RvQW5jaG9yKHEsIHBvc2l0aW9uKS50ZXh0O1xuICAgIGlmIChpbnB1dCkge1xuICAgICAgcmV0dXJuIHsgaW5wdXQsIHN1Z2dlc3Rpb24gfTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBhcHBlbmRUZXh0ICh2YWx1ZSkge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBlbC52YWx1ZTtcbiAgICBjb25zdCBwb3NpdGlvbiA9IHNlbGwoZWwpO1xuICAgIGNvbnN0IGlucHV0ID0gbG9vcGJhY2tUb0FuY2hvcihjdXJyZW50LCBwb3NpdGlvbik7XG4gICAgY29uc3QgbGVmdCA9IGN1cnJlbnQuc3Vic3RyKDAsIGlucHV0LnN0YXJ0KTtcbiAgICBjb25zdCByaWdodCA9IGN1cnJlbnQuc3Vic3RyKGlucHV0LnN0YXJ0ICsgaW5wdXQudGV4dC5sZW5ndGggKyAocG9zaXRpb24uZW5kIC0gcG9zaXRpb24uc3RhcnQpKTtcbiAgICBjb25zdCBiZWZvcmUgPSBsZWZ0ICsgdmFsdWUgKyAnICc7XG5cbiAgICBlbC52YWx1ZSA9IGJlZm9yZSArIHJpZ2h0O1xuICAgIHNlbGwoZWwsIHsgc3RhcnQ6IGJlZm9yZS5sZW5ndGgsIGVuZDogYmVmb3JlLmxlbmd0aCB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlckFuY2hvcmVkSFRNTCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBbmNob3JpbmcgaW4gZWRpdGFibGUgZWxlbWVudHMgaXMgZGlzYWJsZWQgYnkgZGVmYXVsdC4nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFwcGVuZEhUTUwgKCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQW5jaG9yaW5nIGluIGVkaXRhYmxlIGVsZW1lbnRzIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQuJyk7XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kTGlzdCAoY2F0ZWdvcnkpIHsgcmV0dXJuIHNla3RvcignLnNleS1saXN0JywgY2F0ZWdvcnkpWzBdOyB9XG59XG5cbmZ1bmN0aW9uIGlzSW5wdXQgKGVsKSB7IHJldHVybiBlbC50YWdOYW1lID09PSAnSU5QVVQnIHx8IGVsLnRhZ05hbWUgPT09ICdURVhUQVJFQSc7IH1cblxuZnVuY3Rpb24gdGFnICh0eXBlLCBjbGFzc05hbWUpIHtcbiAgY29uc3QgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCh0eXBlKTtcbiAgZWwuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICByZXR1cm4gZWw7XG59XG5cbmZ1bmN0aW9uIGRlZmVyIChmbikgeyByZXR1cm4gZnVuY3Rpb24gKCkgeyBzZXRUaW1lb3V0KGZuLCAwKTsgfTsgfVxuZnVuY3Rpb24gdGV4dCAoZWwsIHZhbHVlKSB7IGVsLmlubmVyVGV4dCA9IGVsLnRleHRDb250ZW50ID0gdmFsdWU7IH1cblxuZnVuY3Rpb24gaXNFZGl0YWJsZSAoZWwpIHtcbiAgY29uc3QgdmFsdWUgPSBlbC5nZXRBdHRyaWJ1dGUoJ2NvbnRlbnRFZGl0YWJsZScpO1xuICBpZiAodmFsdWUgPT09ICdmYWxzZScpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHZhbHVlID09PSAndHJ1ZScpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoZWwucGFyZW50RWxlbWVudCkge1xuICAgIHJldHVybiBpc0VkaXRhYmxlKGVsLnBhcmVudEVsZW1lbnQpO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBob3JzZXk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGF0b2EgKGEsIG4pIHsgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGEsIG4pOyB9XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjcm9zc3ZlbnQgPSByZXF1aXJlKCdjcm9zc3ZlbnQnKTtcbnZhciB0aHJvdHRsZSA9IHJlcXVpcmUoJy4vdGhyb3R0bGUnKTtcbnZhciB0YWlsb3JtYWRlID0gcmVxdWlyZSgnLi90YWlsb3JtYWRlJyk7XG5cbmZ1bmN0aW9uIGJ1bGxzZXllIChlbCwgdGFyZ2V0LCBvcHRpb25zKSB7XG4gIHZhciBvID0gb3B0aW9ucztcbiAgdmFyIGRvbVRhcmdldCA9IHRhcmdldCAmJiB0YXJnZXQudGFnTmFtZTtcblxuICBpZiAoIWRvbVRhcmdldCAmJiBhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XG4gICAgbyA9IHRhcmdldDtcbiAgfVxuICBpZiAoIWRvbVRhcmdldCkge1xuICAgIHRhcmdldCA9IGVsO1xuICB9XG4gIGlmICghbykgeyBvID0ge307IH1cblxuICB2YXIgZGVzdHJveWVkID0gZmFsc2U7XG4gIHZhciB0aHJvdHRsZWRXcml0ZSA9IHRocm90dGxlKHdyaXRlLCAzMCk7XG4gIHZhciB0YWlsb3JPcHRpb25zID0geyB1cGRhdGU6IG8uYXV0b3VwZGF0ZVRvQ2FyZXQgIT09IGZhbHNlICYmIHVwZGF0ZSB9O1xuICB2YXIgdGFpbG9yID0gby5jYXJldCAmJiB0YWlsb3JtYWRlKHRhcmdldCwgdGFpbG9yT3B0aW9ucyk7XG5cbiAgd3JpdGUoKTtcblxuICBpZiAoby50cmFja2luZyAhPT0gZmFsc2UpIHtcbiAgICBjcm9zc3ZlbnQuYWRkKHdpbmRvdywgJ3Jlc2l6ZScsIHRocm90dGxlZFdyaXRlKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgcmVhZDogcmVhZE51bGwsXG4gICAgcmVmcmVzaDogd3JpdGUsXG4gICAgZGVzdHJveTogZGVzdHJveSxcbiAgICBzbGVlcDogc2xlZXBcbiAgfTtcblxuICBmdW5jdGlvbiBzbGVlcCAoKSB7XG4gICAgdGFpbG9yT3B0aW9ucy5zbGVlcGluZyA9IHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiByZWFkTnVsbCAoKSB7IHJldHVybiByZWFkKCk7IH1cblxuICBmdW5jdGlvbiByZWFkIChyZWFkaW5ncykge1xuICAgIHZhciBib3VuZHMgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIHNjcm9sbFRvcCA9IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3A7XG4gICAgaWYgKHRhaWxvcikge1xuICAgICAgcmVhZGluZ3MgPSB0YWlsb3IucmVhZCgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgeDogKHJlYWRpbmdzLmFic29sdXRlID8gMCA6IGJvdW5kcy5sZWZ0KSArIHJlYWRpbmdzLngsXG4gICAgICAgIHk6IChyZWFkaW5ncy5hYnNvbHV0ZSA/IDAgOiBib3VuZHMudG9wKSArIHNjcm9sbFRvcCArIHJlYWRpbmdzLnkgKyAyMFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGJvdW5kcy5sZWZ0LFxuICAgICAgeTogYm91bmRzLnRvcCArIHNjcm9sbFRvcFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUgKHJlYWRpbmdzKSB7XG4gICAgd3JpdGUocmVhZGluZ3MpO1xuICB9XG5cbiAgZnVuY3Rpb24gd3JpdGUgKHJlYWRpbmdzKSB7XG4gICAgaWYgKGRlc3Ryb3llZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdCdWxsc2V5ZSBjYW5cXCd0IHJlZnJlc2ggYWZ0ZXIgYmVpbmcgZGVzdHJveWVkLiBDcmVhdGUgYW5vdGhlciBpbnN0YW5jZSBpbnN0ZWFkLicpO1xuICAgIH1cbiAgICBpZiAodGFpbG9yICYmICFyZWFkaW5ncykge1xuICAgICAgdGFpbG9yT3B0aW9ucy5zbGVlcGluZyA9IGZhbHNlO1xuICAgICAgdGFpbG9yLnJlZnJlc2goKTsgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgcCA9IHJlYWQocmVhZGluZ3MpO1xuICAgIGlmICghdGFpbG9yICYmIHRhcmdldCAhPT0gZWwpIHtcbiAgICAgIHAueSArPSB0YXJnZXQub2Zmc2V0SGVpZ2h0O1xuICAgIH1cbiAgICB2YXIgY29udGV4dCA9IG8uY29udGV4dDtcbiAgICBlbC5zdHlsZS5sZWZ0ID0gcC54ICsgJ3B4JztcbiAgICBlbC5zdHlsZS50b3AgPSAoY29udGV4dCA/IGNvbnRleHQub2Zmc2V0SGVpZ2h0IDogcC55KSArICdweCc7XG4gIH1cblxuICBmdW5jdGlvbiBkZXN0cm95ICgpIHtcbiAgICBpZiAodGFpbG9yKSB7IHRhaWxvci5kZXN0cm95KCk7IH1cbiAgICBjcm9zc3ZlbnQucmVtb3ZlKHdpbmRvdywgJ3Jlc2l6ZScsIHRocm90dGxlZFdyaXRlKTtcbiAgICBkZXN0cm95ZWQgPSB0cnVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYnVsbHNleWU7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBzZWxsID0gcmVxdWlyZSgnc2VsbCcpO1xudmFyIGNyb3NzdmVudCA9IHJlcXVpcmUoJ2Nyb3NzdmVudCcpO1xudmFyIHNlbGVjY2lvbiA9IHJlcXVpcmUoJ3NlbGVjY2lvbicpO1xudmFyIHRocm90dGxlID0gcmVxdWlyZSgnLi90aHJvdHRsZScpO1xudmFyIGdldFNlbGVjdGlvbiA9IHNlbGVjY2lvbi5nZXQ7XG52YXIgcHJvcHMgPSBbXG4gICdkaXJlY3Rpb24nLFxuICAnYm94U2l6aW5nJyxcbiAgJ3dpZHRoJyxcbiAgJ2hlaWdodCcsXG4gICdvdmVyZmxvd1gnLFxuICAnb3ZlcmZsb3dZJyxcbiAgJ2JvcmRlclRvcFdpZHRoJyxcbiAgJ2JvcmRlclJpZ2h0V2lkdGgnLFxuICAnYm9yZGVyQm90dG9tV2lkdGgnLFxuICAnYm9yZGVyTGVmdFdpZHRoJyxcbiAgJ3BhZGRpbmdUb3AnLFxuICAncGFkZGluZ1JpZ2h0JyxcbiAgJ3BhZGRpbmdCb3R0b20nLFxuICAncGFkZGluZ0xlZnQnLFxuICAnZm9udFN0eWxlJyxcbiAgJ2ZvbnRWYXJpYW50JyxcbiAgJ2ZvbnRXZWlnaHQnLFxuICAnZm9udFN0cmV0Y2gnLFxuICAnZm9udFNpemUnLFxuICAnZm9udFNpemVBZGp1c3QnLFxuICAnbGluZUhlaWdodCcsXG4gICdmb250RmFtaWx5JyxcbiAgJ3RleHRBbGlnbicsXG4gICd0ZXh0VHJhbnNmb3JtJyxcbiAgJ3RleHRJbmRlbnQnLFxuICAndGV4dERlY29yYXRpb24nLFxuICAnbGV0dGVyU3BhY2luZycsXG4gICd3b3JkU3BhY2luZydcbl07XG52YXIgd2luID0gZ2xvYmFsO1xudmFyIGRvYyA9IGRvY3VtZW50O1xudmFyIGZmID0gd2luLm1veklubmVyU2NyZWVuWCAhPT0gbnVsbCAmJiB3aW4ubW96SW5uZXJTY3JlZW5YICE9PSB2b2lkIDA7XG5cbmZ1bmN0aW9uIHRhaWxvcm1hZGUgKGVsLCBvcHRpb25zKSB7XG4gIHZhciB0ZXh0SW5wdXQgPSBlbC50YWdOYW1lID09PSAnSU5QVVQnIHx8IGVsLnRhZ05hbWUgPT09ICdURVhUQVJFQSc7XG4gIHZhciB0aHJvdHRsZWRSZWZyZXNoID0gdGhyb3R0bGUocmVmcmVzaCwgMzApO1xuICB2YXIgbyA9IG9wdGlvbnMgfHwge307XG5cbiAgYmluZCgpO1xuXG4gIHJldHVybiB7XG4gICAgcmVhZDogcmVhZFBvc2l0aW9uLFxuICAgIHJlZnJlc2g6IHRocm90dGxlZFJlZnJlc2gsXG4gICAgZGVzdHJveTogZGVzdHJveVxuICB9O1xuXG4gIGZ1bmN0aW9uIG5vb3AgKCkge31cbiAgZnVuY3Rpb24gcmVhZFBvc2l0aW9uICgpIHsgcmV0dXJuICh0ZXh0SW5wdXQgPyBjb29yZHNUZXh0IDogY29vcmRzSFRNTCkoKTsgfVxuXG4gIGZ1bmN0aW9uIHJlZnJlc2ggKCkge1xuICAgIGlmIChvLnNsZWVwaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiAoby51cGRhdGUgfHwgbm9vcCkocmVhZFBvc2l0aW9uKCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gY29vcmRzVGV4dCAoKSB7XG4gICAgdmFyIHAgPSBzZWxsKGVsKTtcbiAgICB2YXIgY29udGV4dCA9IHByZXBhcmUoKTtcbiAgICB2YXIgcmVhZGluZ3MgPSByZWFkVGV4dENvb3Jkcyhjb250ZXh0LCBwLnN0YXJ0KTtcbiAgICBkb2MuYm9keS5yZW1vdmVDaGlsZChjb250ZXh0Lm1pcnJvcik7XG4gICAgcmV0dXJuIHJlYWRpbmdzO1xuICB9XG5cbiAgZnVuY3Rpb24gY29vcmRzSFRNTCAoKSB7XG4gICAgdmFyIHNlbCA9IGdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWwucmFuZ2VDb3VudCkge1xuICAgICAgdmFyIHJhbmdlID0gc2VsLmdldFJhbmdlQXQoMCk7XG4gICAgICB2YXIgbmVlZHNUb1dvcmtBcm91bmROZXdsaW5lQnVnID0gcmFuZ2Uuc3RhcnRDb250YWluZXIubm9kZU5hbWUgPT09ICdQJyAmJiByYW5nZS5zdGFydE9mZnNldCA9PT0gMDtcbiAgICAgIGlmIChuZWVkc1RvV29ya0Fyb3VuZE5ld2xpbmVCdWcpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB4OiByYW5nZS5zdGFydENvbnRhaW5lci5vZmZzZXRMZWZ0LFxuICAgICAgICAgIHk6IHJhbmdlLnN0YXJ0Q29udGFpbmVyLm9mZnNldFRvcCxcbiAgICAgICAgICBhYnNvbHV0ZTogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHJhbmdlLmdldENsaWVudFJlY3RzKSB7XG4gICAgICAgIHZhciByZWN0cyA9IHJhbmdlLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgIGlmIChyZWN0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHg6IHJlY3RzWzBdLmxlZnQsXG4gICAgICAgICAgICB5OiByZWN0c1swXS50b3AsXG4gICAgICAgICAgICBhYnNvbHV0ZTogdHJ1ZVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgeDogMCwgeTogMCB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVhZFRleHRDb29yZHMgKGNvbnRleHQsIHApIHtcbiAgICB2YXIgcmVzdCA9IGRvYy5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgdmFyIG1pcnJvciA9IGNvbnRleHQubWlycm9yO1xuICAgIHZhciBjb21wdXRlZCA9IGNvbnRleHQuY29tcHV0ZWQ7XG5cbiAgICB3cml0ZShtaXJyb3IsIHJlYWQoZWwpLnN1YnN0cmluZygwLCBwKSk7XG5cbiAgICBpZiAoZWwudGFnTmFtZSA9PT0gJ0lOUFVUJykge1xuICAgICAgbWlycm9yLnRleHRDb250ZW50ID0gbWlycm9yLnRleHRDb250ZW50LnJlcGxhY2UoL1xccy9nLCAnXFx1MDBhMCcpO1xuICAgIH1cblxuICAgIHdyaXRlKHJlc3QsIHJlYWQoZWwpLnN1YnN0cmluZyhwKSB8fCAnLicpO1xuXG4gICAgbWlycm9yLmFwcGVuZENoaWxkKHJlc3QpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHJlc3Qub2Zmc2V0TGVmdCArIHBhcnNlSW50KGNvbXB1dGVkWydib3JkZXJMZWZ0V2lkdGgnXSksXG4gICAgICB5OiByZXN0Lm9mZnNldFRvcCArIHBhcnNlSW50KGNvbXB1dGVkWydib3JkZXJUb3BXaWR0aCddKVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiByZWFkIChlbCkge1xuICAgIHJldHVybiB0ZXh0SW5wdXQgPyBlbC52YWx1ZSA6IGVsLmlubmVySFRNTDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByZXBhcmUgKCkge1xuICAgIHZhciBjb21wdXRlZCA9IHdpbi5nZXRDb21wdXRlZFN0eWxlID8gZ2V0Q29tcHV0ZWRTdHlsZShlbCkgOiBlbC5jdXJyZW50U3R5bGU7XG4gICAgdmFyIG1pcnJvciA9IGRvYy5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB2YXIgc3R5bGUgPSBtaXJyb3Iuc3R5bGU7XG5cbiAgICBkb2MuYm9keS5hcHBlbmRDaGlsZChtaXJyb3IpO1xuXG4gICAgaWYgKGVsLnRhZ05hbWUgIT09ICdJTlBVVCcpIHtcbiAgICAgIHN0eWxlLndvcmRXcmFwID0gJ2JyZWFrLXdvcmQnO1xuICAgIH1cbiAgICBzdHlsZS53aGl0ZVNwYWNlID0gJ3ByZS13cmFwJztcbiAgICBzdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgIHByb3BzLmZvckVhY2goY29weSk7XG5cbiAgICBpZiAoZmYpIHtcbiAgICAgIHN0eWxlLndpZHRoID0gcGFyc2VJbnQoY29tcHV0ZWQud2lkdGgpIC0gMiArICdweCc7XG4gICAgICBpZiAoZWwuc2Nyb2xsSGVpZ2h0ID4gcGFyc2VJbnQoY29tcHV0ZWQuaGVpZ2h0KSkge1xuICAgICAgICBzdHlsZS5vdmVyZmxvd1kgPSAnc2Nyb2xsJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcbiAgICB9XG4gICAgcmV0dXJuIHsgbWlycm9yOiBtaXJyb3IsIGNvbXB1dGVkOiBjb21wdXRlZCB9O1xuXG4gICAgZnVuY3Rpb24gY29weSAocHJvcCkge1xuICAgICAgc3R5bGVbcHJvcF0gPSBjb21wdXRlZFtwcm9wXTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB3cml0ZSAoZWwsIHZhbHVlKSB7XG4gICAgaWYgKHRleHRJbnB1dCkge1xuICAgICAgZWwudGV4dENvbnRlbnQgPSB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWwuaW5uZXJIVE1MID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gYmluZCAocmVtb3ZlKSB7XG4gICAgdmFyIG9wID0gcmVtb3ZlID8gJ3JlbW92ZScgOiAnYWRkJztcbiAgICBjcm9zc3ZlbnRbb3BdKGVsLCAna2V5ZG93bicsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdrZXl1cCcsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdpbnB1dCcsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdwYXN0ZScsIHRocm90dGxlZFJlZnJlc2gpO1xuICAgIGNyb3NzdmVudFtvcF0oZWwsICdjaGFuZ2UnLCB0aHJvdHRsZWRSZWZyZXNoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3kgKCkge1xuICAgIGJpbmQodHJ1ZSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0YWlsb3JtYWRlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiB0aHJvdHRsZSAoZm4sIGJvdW5kYXJ5KSB7XG4gIHZhciBsYXN0ID0gLUluZmluaXR5O1xuICB2YXIgdGltZXI7XG4gIHJldHVybiBmdW5jdGlvbiBib3VuY2VkICgpIHtcbiAgICBpZiAodGltZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdW5ib3VuZCgpO1xuXG4gICAgZnVuY3Rpb24gdW5ib3VuZCAoKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgdGltZXIgPSBudWxsO1xuICAgICAgdmFyIG5leHQgPSBsYXN0ICsgYm91bmRhcnk7XG4gICAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGlmIChub3cgPiBuZXh0KSB7XG4gICAgICAgIGxhc3QgPSBub3c7XG4gICAgICAgIGZuKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQodW5ib3VuZCwgbmV4dCAtIG5vdyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRocm90dGxlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdGlja3kgPSByZXF1aXJlKCd0aWNreScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGRlYm91bmNlIChmbiwgYXJncywgY3R4KSB7XG4gIGlmICghZm4pIHsgcmV0dXJuOyB9XG4gIHRpY2t5KGZ1bmN0aW9uIHJ1biAoKSB7XG4gICAgZm4uYXBwbHkoY3R4IHx8IG51bGwsIGFyZ3MgfHwgW10pO1xuICB9KTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBhdG9hID0gcmVxdWlyZSgnYXRvYScpO1xudmFyIGRlYm91bmNlID0gcmVxdWlyZSgnLi9kZWJvdW5jZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGVtaXR0ZXIgKHRoaW5nLCBvcHRpb25zKSB7XG4gIHZhciBvcHRzID0gb3B0aW9ucyB8fCB7fTtcbiAgdmFyIGV2dCA9IHt9O1xuICBpZiAodGhpbmcgPT09IHVuZGVmaW5lZCkgeyB0aGluZyA9IHt9OyB9XG4gIHRoaW5nLm9uID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgaWYgKCFldnRbdHlwZV0pIHtcbiAgICAgIGV2dFt0eXBlXSA9IFtmbl07XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2dFt0eXBlXS5wdXNoKGZuKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaW5nO1xuICB9O1xuICB0aGluZy5vbmNlID0gZnVuY3Rpb24gKHR5cGUsIGZuKSB7XG4gICAgZm4uX29uY2UgPSB0cnVlOyAvLyB0aGluZy5vZmYoZm4pIHN0aWxsIHdvcmtzIVxuICAgIHRoaW5nLm9uKHR5cGUsIGZuKTtcbiAgICByZXR1cm4gdGhpbmc7XG4gIH07XG4gIHRoaW5nLm9mZiA9IGZ1bmN0aW9uICh0eXBlLCBmbikge1xuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBpZiAoYyA9PT0gMSkge1xuICAgICAgZGVsZXRlIGV2dFt0eXBlXTtcbiAgICB9IGVsc2UgaWYgKGMgPT09IDApIHtcbiAgICAgIGV2dCA9IHt9O1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZXQgPSBldnRbdHlwZV07XG4gICAgICBpZiAoIWV0KSB7IHJldHVybiB0aGluZzsgfVxuICAgICAgZXQuc3BsaWNlKGV0LmluZGV4T2YoZm4pLCAxKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaW5nO1xuICB9O1xuICB0aGluZy5lbWl0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gYXRvYShhcmd1bWVudHMpO1xuICAgIHJldHVybiB0aGluZy5lbWl0dGVyU25hcHNob3QoYXJncy5zaGlmdCgpKS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfTtcbiAgdGhpbmcuZW1pdHRlclNuYXBzaG90ID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgICB2YXIgZXQgPSAoZXZ0W3R5cGVdIHx8IFtdKS5zbGljZSgwKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGFyZ3MgPSBhdG9hKGFyZ3VtZW50cyk7XG4gICAgICB2YXIgY3R4ID0gdGhpcyB8fCB0aGluZztcbiAgICAgIGlmICh0eXBlID09PSAnZXJyb3InICYmIG9wdHMudGhyb3dzICE9PSBmYWxzZSAmJiAhZXQubGVuZ3RoKSB7IHRocm93IGFyZ3MubGVuZ3RoID09PSAxID8gYXJnc1swXSA6IGFyZ3M7IH1cbiAgICAgIGV0LmZvckVhY2goZnVuY3Rpb24gZW1pdHRlciAobGlzdGVuKSB7XG4gICAgICAgIGlmIChvcHRzLmFzeW5jKSB7IGRlYm91bmNlKGxpc3RlbiwgYXJncywgY3R4KTsgfSBlbHNlIHsgbGlzdGVuLmFwcGx5KGN0eCwgYXJncyk7IH1cbiAgICAgICAgaWYgKGxpc3Rlbi5fb25jZSkgeyB0aGluZy5vZmYodHlwZSwgbGlzdGVuKTsgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdGhpbmc7XG4gICAgfTtcbiAgfTtcbiAgcmV0dXJuIHRoaW5nO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGN1c3RvbUV2ZW50ID0gcmVxdWlyZSgnY3VzdG9tLWV2ZW50Jyk7XG52YXIgZXZlbnRtYXAgPSByZXF1aXJlKCcuL2V2ZW50bWFwJyk7XG52YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xudmFyIGFkZEV2ZW50ID0gYWRkRXZlbnRFYXN5O1xudmFyIHJlbW92ZUV2ZW50ID0gcmVtb3ZlRXZlbnRFYXN5O1xudmFyIGhhcmRDYWNoZSA9IFtdO1xuXG5pZiAoIWdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gIGFkZEV2ZW50ID0gYWRkRXZlbnRIYXJkO1xuICByZW1vdmVFdmVudCA9IHJlbW92ZUV2ZW50SGFyZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGFkZDogYWRkRXZlbnQsXG4gIHJlbW92ZTogcmVtb3ZlRXZlbnQsXG4gIGZhYnJpY2F0ZTogZmFicmljYXRlRXZlbnRcbn07XG5cbmZ1bmN0aW9uIGFkZEV2ZW50RWFzeSAoZWwsIHR5cGUsIGZuLCBjYXB0dXJpbmcpIHtcbiAgcmV0dXJuIGVsLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZm4sIGNhcHR1cmluZyk7XG59XG5cbmZ1bmN0aW9uIGFkZEV2ZW50SGFyZCAoZWwsIHR5cGUsIGZuKSB7XG4gIHJldHVybiBlbC5hdHRhY2hFdmVudCgnb24nICsgdHlwZSwgd3JhcChlbCwgdHlwZSwgZm4pKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRXZlbnRFYXN5IChlbCwgdHlwZSwgZm4sIGNhcHR1cmluZykge1xuICByZXR1cm4gZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBmbiwgY2FwdHVyaW5nKTtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlRXZlbnRIYXJkIChlbCwgdHlwZSwgZm4pIHtcbiAgdmFyIGxpc3RlbmVyID0gdW53cmFwKGVsLCB0eXBlLCBmbik7XG4gIGlmIChsaXN0ZW5lcikge1xuICAgIHJldHVybiBlbC5kZXRhY2hFdmVudCgnb24nICsgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZhYnJpY2F0ZUV2ZW50IChlbCwgdHlwZSwgbW9kZWwpIHtcbiAgdmFyIGUgPSBldmVudG1hcC5pbmRleE9mKHR5cGUpID09PSAtMSA/IG1ha2VDdXN0b21FdmVudCgpIDogbWFrZUNsYXNzaWNFdmVudCgpO1xuICBpZiAoZWwuZGlzcGF0Y2hFdmVudCkge1xuICAgIGVsLmRpc3BhdGNoRXZlbnQoZSk7XG4gIH0gZWxzZSB7XG4gICAgZWwuZmlyZUV2ZW50KCdvbicgKyB0eXBlLCBlKTtcbiAgfVxuICBmdW5jdGlvbiBtYWtlQ2xhc3NpY0V2ZW50ICgpIHtcbiAgICB2YXIgZTtcbiAgICBpZiAoZG9jLmNyZWF0ZUV2ZW50KSB7XG4gICAgICBlID0gZG9jLmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgICAgZS5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfSBlbHNlIGlmIChkb2MuY3JlYXRlRXZlbnRPYmplY3QpIHtcbiAgICAgIGUgPSBkb2MuY3JlYXRlRXZlbnRPYmplY3QoKTtcbiAgICB9XG4gICAgcmV0dXJuIGU7XG4gIH1cbiAgZnVuY3Rpb24gbWFrZUN1c3RvbUV2ZW50ICgpIHtcbiAgICByZXR1cm4gbmV3IGN1c3RvbUV2ZW50KHR5cGUsIHsgZGV0YWlsOiBtb2RlbCB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiB3cmFwcGVyRmFjdG9yeSAoZWwsIHR5cGUsIGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwcGVyIChvcmlnaW5hbEV2ZW50KSB7XG4gICAgdmFyIGUgPSBvcmlnaW5hbEV2ZW50IHx8IGdsb2JhbC5ldmVudDtcbiAgICBlLnRhcmdldCA9IGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudDtcbiAgICBlLnByZXZlbnREZWZhdWx0ID0gZS5wcmV2ZW50RGVmYXVsdCB8fCBmdW5jdGlvbiBwcmV2ZW50RGVmYXVsdCAoKSB7IGUucmV0dXJuVmFsdWUgPSBmYWxzZTsgfTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbiA9IGUuc3RvcFByb3BhZ2F0aW9uIHx8IGZ1bmN0aW9uIHN0b3BQcm9wYWdhdGlvbiAoKSB7IGUuY2FuY2VsQnViYmxlID0gdHJ1ZTsgfTtcbiAgICBlLndoaWNoID0gZS53aGljaCB8fCBlLmtleUNvZGU7XG4gICAgZm4uY2FsbChlbCwgZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHdyYXAgKGVsLCB0eXBlLCBmbikge1xuICB2YXIgd3JhcHBlciA9IHVud3JhcChlbCwgdHlwZSwgZm4pIHx8IHdyYXBwZXJGYWN0b3J5KGVsLCB0eXBlLCBmbik7XG4gIGhhcmRDYWNoZS5wdXNoKHtcbiAgICB3cmFwcGVyOiB3cmFwcGVyLFxuICAgIGVsZW1lbnQ6IGVsLFxuICAgIHR5cGU6IHR5cGUsXG4gICAgZm46IGZuXG4gIH0pO1xuICByZXR1cm4gd3JhcHBlcjtcbn1cblxuZnVuY3Rpb24gdW53cmFwIChlbCwgdHlwZSwgZm4pIHtcbiAgdmFyIGkgPSBmaW5kKGVsLCB0eXBlLCBmbik7XG4gIGlmIChpKSB7XG4gICAgdmFyIHdyYXBwZXIgPSBoYXJkQ2FjaGVbaV0ud3JhcHBlcjtcbiAgICBoYXJkQ2FjaGUuc3BsaWNlKGksIDEpOyAvLyBmcmVlIHVwIGEgdGFkIG9mIG1lbW9yeVxuICAgIHJldHVybiB3cmFwcGVyO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmQgKGVsLCB0eXBlLCBmbikge1xuICB2YXIgaSwgaXRlbTtcbiAgZm9yIChpID0gMDsgaSA8IGhhcmRDYWNoZS5sZW5ndGg7IGkrKykge1xuICAgIGl0ZW0gPSBoYXJkQ2FjaGVbaV07XG4gICAgaWYgKGl0ZW0uZWxlbWVudCA9PT0gZWwgJiYgaXRlbS50eXBlID09PSB0eXBlICYmIGl0ZW0uZm4gPT09IGZuKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGV2ZW50bWFwID0gW107XG52YXIgZXZlbnRuYW1lID0gJyc7XG52YXIgcm9uID0gL15vbi87XG5cbmZvciAoZXZlbnRuYW1lIGluIGdsb2JhbCkge1xuICBpZiAocm9uLnRlc3QoZXZlbnRuYW1lKSkge1xuICAgIGV2ZW50bWFwLnB1c2goZXZlbnRuYW1lLnNsaWNlKDIpKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGV2ZW50bWFwO1xuIiwiXG52YXIgTmF0aXZlQ3VzdG9tRXZlbnQgPSBnbG9iYWwuQ3VzdG9tRXZlbnQ7XG5cbmZ1bmN0aW9uIHVzZU5hdGl2ZSAoKSB7XG4gIHRyeSB7XG4gICAgdmFyIHAgPSBuZXcgTmF0aXZlQ3VzdG9tRXZlbnQoJ2NhdCcsIHsgZGV0YWlsOiB7IGZvbzogJ2JhcicgfSB9KTtcbiAgICByZXR1cm4gICdjYXQnID09PSBwLnR5cGUgJiYgJ2JhcicgPT09IHAuZGV0YWlsLmZvbztcbiAgfSBjYXRjaCAoZSkge1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDcm9zcy1icm93c2VyIGBDdXN0b21FdmVudGAgY29uc3RydWN0b3IuXG4gKlxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0N1c3RvbUV2ZW50LkN1c3RvbUV2ZW50XG4gKlxuICogQHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gdXNlTmF0aXZlKCkgPyBOYXRpdmVDdXN0b21FdmVudCA6XG5cbi8vIElFID49IDlcbidmdW5jdGlvbicgPT09IHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFdmVudCA/IGZ1bmN0aW9uIEN1c3RvbUV2ZW50ICh0eXBlLCBwYXJhbXMpIHtcbiAgdmFyIGUgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgaWYgKHBhcmFtcykge1xuICAgIGUuaW5pdEN1c3RvbUV2ZW50KHR5cGUsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XG4gIH0gZWxzZSB7XG4gICAgZS5pbml0Q3VzdG9tRXZlbnQodHlwZSwgZmFsc2UsIGZhbHNlLCB2b2lkIDApO1xuICB9XG4gIHJldHVybiBlO1xufSA6XG5cbi8vIElFIDw9IDhcbmZ1bmN0aW9uIEN1c3RvbUV2ZW50ICh0eXBlLCBwYXJhbXMpIHtcbiAgdmFyIGUgPSBkb2N1bWVudC5jcmVhdGVFdmVudE9iamVjdCgpO1xuICBlLnR5cGUgPSB0eXBlO1xuICBpZiAocGFyYW1zKSB7XG4gICAgZS5idWJibGVzID0gQm9vbGVhbihwYXJhbXMuYnViYmxlcyk7XG4gICAgZS5jYW5jZWxhYmxlID0gQm9vbGVhbihwYXJhbXMuY2FuY2VsYWJsZSk7XG4gICAgZS5kZXRhaWwgPSBwYXJhbXMuZGV0YWlsO1xuICB9IGVsc2Uge1xuICAgIGUuYnViYmxlcyA9IGZhbHNlO1xuICAgIGUuY2FuY2VsYWJsZSA9IGZhbHNlO1xuICAgIGUuZGV0YWlsID0gdm9pZCAwO1xuICB9XG4gIHJldHVybiBlO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBmdXp6eXNlYXJjaCAobmVlZGxlLCBoYXlzdGFjaykge1xuICB2YXIgdGxlbiA9IGhheXN0YWNrLmxlbmd0aDtcbiAgdmFyIHFsZW4gPSBuZWVkbGUubGVuZ3RoO1xuICBpZiAocWxlbiA+IHRsZW4pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHFsZW4gPT09IHRsZW4pIHtcbiAgICByZXR1cm4gbmVlZGxlID09PSBoYXlzdGFjaztcbiAgfVxuICBvdXRlcjogZm9yICh2YXIgaSA9IDAsIGogPSAwOyBpIDwgcWxlbjsgaSsrKSB7XG4gICAgdmFyIG5jaCA9IG5lZWRsZS5jaGFyQ29kZUF0KGkpO1xuICAgIHdoaWxlIChqIDwgdGxlbikge1xuICAgICAgaWYgKGhheXN0YWNrLmNoYXJDb2RlQXQoaisrKSA9PT0gbmNoKSB7XG4gICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnV6enlzZWFyY2g7XG4iLCIndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIHBhZCAoaGFzaCwgbGVuKSB7XG4gIHdoaWxlIChoYXNoLmxlbmd0aCA8IGxlbikge1xuICAgIGhhc2ggPSAnMCcgKyBoYXNoO1xuICB9XG4gIHJldHVybiBoYXNoO1xufVxuXG5mdW5jdGlvbiBmb2xkIChoYXNoLCB0ZXh0KSB7XG4gIHZhciBpO1xuICB2YXIgY2hyO1xuICB2YXIgbGVuO1xuICBpZiAodGV4dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gaGFzaDtcbiAgfVxuICBmb3IgKGkgPSAwLCBsZW4gPSB0ZXh0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgY2hyID0gdGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgIGhhc2ggPSAoKGhhc2ggPDwgNSkgLSBoYXNoKSArIGNocjtcbiAgICBoYXNoIHw9IDA7XG4gIH1cbiAgcmV0dXJuIGhhc2ggPCAwID8gaGFzaCAqIC0yIDogaGFzaDtcbn1cblxuZnVuY3Rpb24gZm9sZE9iamVjdCAoaGFzaCwgbywgc2Vlbikge1xuICByZXR1cm4gT2JqZWN0LmtleXMobykuc29ydCgpLnJlZHVjZShmb2xkS2V5LCBoYXNoKTtcbiAgZnVuY3Rpb24gZm9sZEtleSAoaGFzaCwga2V5KSB7XG4gICAgcmV0dXJuIGZvbGRWYWx1ZShoYXNoLCBvW2tleV0sIGtleSwgc2Vlbik7XG4gIH1cbn1cblxuZnVuY3Rpb24gZm9sZFZhbHVlIChpbnB1dCwgdmFsdWUsIGtleSwgc2Vlbikge1xuICB2YXIgaGFzaCA9IGZvbGQoZm9sZChmb2xkKGlucHV0LCBrZXkpLCB0b1N0cmluZyh2YWx1ZSkpLCB0eXBlb2YgdmFsdWUpO1xuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZm9sZChoYXNoLCAnbnVsbCcpO1xuICB9XG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZvbGQoaGFzaCwgJ3VuZGVmaW5lZCcpO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKHNlZW4uaW5kZXhPZih2YWx1ZSkgIT09IC0xKSB7XG4gICAgICByZXR1cm4gZm9sZChoYXNoLCAnW0NpcmN1bGFyXScgKyBrZXkpO1xuICAgIH1cbiAgICBzZWVuLnB1c2godmFsdWUpO1xuICAgIHJldHVybiBmb2xkT2JqZWN0KGhhc2gsIHZhbHVlLCBzZWVuKTtcbiAgfVxuICByZXR1cm4gZm9sZChoYXNoLCB2YWx1ZS50b1N0cmluZygpKTtcbn1cblxuZnVuY3Rpb24gdG9TdHJpbmcgKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuZnVuY3Rpb24gc3VtIChvKSB7XG4gIHJldHVybiBwYWQoZm9sZFZhbHVlKDAsIG8sICcnLCBbXSkudG9TdHJpbmcoMTYpLCA4KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdW07XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgbm93ID0gcmVxdWlyZSgnLi9ub3cnKSxcbiAgICB0b051bWJlciA9IHJlcXVpcmUoJy4vdG9OdW1iZXInKTtcblxuLyoqIFVzZWQgYXMgdGhlIGBUeXBlRXJyb3JgIG1lc3NhZ2UgZm9yIFwiRnVuY3Rpb25zXCIgbWV0aG9kcy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhc1xuICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gKiBQcm92aWRlIGFuIG9wdGlvbnMgb2JqZWN0IHRvIGluZGljYXRlIHdoZXRoZXIgYGZ1bmNgIHNob3VsZCBiZSBpbnZva2VkIG9uXG4gKiB0aGUgbGVhZGluZyBhbmQvb3IgdHJhaWxpbmcgZWRnZSBvZiB0aGUgYHdhaXRgIHRpbWVvdXQuIFRoZSBgZnVuY2AgaXMgaW52b2tlZFxuICogd2l0aCB0aGUgbGFzdCBhcmd1bWVudHMgcHJvdmlkZWQgdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbi4gU3Vic2VxdWVudCBjYWxsc1xuICogdG8gdGhlIGRlYm91bmNlZCBmdW5jdGlvbiByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgbGFzdCBgZnVuY2AgaW52b2NhdGlvbi5cbiAqXG4gKiAqKk5vdGU6KiogSWYgYGxlYWRpbmdgIGFuZCBgdHJhaWxpbmdgIG9wdGlvbnMgYXJlIGB0cnVlYCwgYGZ1bmNgIGlzIGludm9rZWRcbiAqIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0IG9ubHkgaWYgdGhlIGRlYm91bmNlZCBmdW5jdGlvbiBpc1xuICogaW52b2tlZCBtb3JlIHRoYW4gb25jZSBkdXJpbmcgdGhlIGB3YWl0YCB0aW1lb3V0LlxuICpcbiAqIFNlZSBbRGF2aWQgQ29yYmFjaG8ncyBhcnRpY2xlXShodHRwczovL2Nzcy10cmlja3MuY29tL2RlYm91bmNpbmctdGhyb3R0bGluZy1leHBsYWluZWQtZXhhbXBsZXMvKVxuICogZm9yIGRldGFpbHMgb3ZlciB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBgXy5kZWJvdW5jZWAgYW5kIGBfLnRocm90dGxlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGRlYm91bmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFt3YWl0PTBdIFRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyBvYmplY3QuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxlYWRpbmc9ZmFsc2VdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1heFdhaXRdXG4gKiAgVGhlIG1heGltdW0gdGltZSBgZnVuY2AgaXMgYWxsb3dlZCB0byBiZSBkZWxheWVkIGJlZm9yZSBpdCdzIGludm9rZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnRyYWlsaW5nPXRydWVdXG4gKiAgU3BlY2lmeSBpbnZva2luZyBvbiB0aGUgdHJhaWxpbmcgZWRnZSBvZiB0aGUgdGltZW91dC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGRlYm91bmNlZCBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogLy8gQXZvaWQgY29zdGx5IGNhbGN1bGF0aW9ucyB3aGlsZSB0aGUgd2luZG93IHNpemUgaXMgaW4gZmx1eC5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdyZXNpemUnLCBfLmRlYm91bmNlKGNhbGN1bGF0ZUxheW91dCwgMTUwKSk7XG4gKlxuICogLy8gSW52b2tlIGBzZW5kTWFpbGAgd2hlbiBjbGlja2VkLCBkZWJvdW5jaW5nIHN1YnNlcXVlbnQgY2FsbHMuXG4gKiBqUXVlcnkoZWxlbWVudCkub24oJ2NsaWNrJywgXy5kZWJvdW5jZShzZW5kTWFpbCwgMzAwLCB7XG4gKiAgICdsZWFkaW5nJzogdHJ1ZSxcbiAqICAgJ3RyYWlsaW5nJzogZmFsc2VcbiAqIH0pKTtcbiAqXG4gKiAvLyBFbnN1cmUgYGJhdGNoTG9nYCBpcyBpbnZva2VkIG9uY2UgYWZ0ZXIgMSBzZWNvbmQgb2YgZGVib3VuY2VkIGNhbGxzLlxuICogdmFyIGRlYm91bmNlZCA9IF8uZGVib3VuY2UoYmF0Y2hMb2csIDI1MCwgeyAnbWF4V2FpdCc6IDEwMDAgfSk7XG4gKiB2YXIgc291cmNlID0gbmV3IEV2ZW50U291cmNlKCcvc3RyZWFtJyk7XG4gKiBqUXVlcnkoc291cmNlKS5vbignbWVzc2FnZScsIGRlYm91bmNlZCk7XG4gKlxuICogLy8gQ2FuY2VsIHRoZSB0cmFpbGluZyBkZWJvdW5jZWQgaW52b2NhdGlvbi5cbiAqIGpRdWVyeSh3aW5kb3cpLm9uKCdwb3BzdGF0ZScsIGRlYm91bmNlZC5jYW5jZWwpO1xuICovXG5mdW5jdGlvbiBkZWJvdW5jZShmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gIHZhciBsYXN0QXJncyxcbiAgICAgIGxhc3RUaGlzLFxuICAgICAgbWF4V2FpdCxcbiAgICAgIHJlc3VsdCxcbiAgICAgIHRpbWVySWQsXG4gICAgICBsYXN0Q2FsbFRpbWUsXG4gICAgICBsYXN0SW52b2tlVGltZSA9IDAsXG4gICAgICBsZWFkaW5nID0gZmFsc2UsXG4gICAgICBtYXhpbmcgPSBmYWxzZSxcbiAgICAgIHRyYWlsaW5nID0gdHJ1ZTtcblxuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB3YWl0ID0gdG9OdW1iZXIod2FpdCkgfHwgMDtcbiAgaWYgKGlzT2JqZWN0KG9wdGlvbnMpKSB7XG4gICAgbGVhZGluZyA9ICEhb3B0aW9ucy5sZWFkaW5nO1xuICAgIG1heGluZyA9ICdtYXhXYWl0JyBpbiBvcHRpb25zO1xuICAgIG1heFdhaXQgPSBtYXhpbmcgPyBuYXRpdmVNYXgodG9OdW1iZXIob3B0aW9ucy5tYXhXYWl0KSB8fCAwLCB3YWl0KSA6IG1heFdhaXQ7XG4gICAgdHJhaWxpbmcgPSAndHJhaWxpbmcnIGluIG9wdGlvbnMgPyAhIW9wdGlvbnMudHJhaWxpbmcgOiB0cmFpbGluZztcbiAgfVxuXG4gIGZ1bmN0aW9uIGludm9rZUZ1bmModGltZSkge1xuICAgIHZhciBhcmdzID0gbGFzdEFyZ3MsXG4gICAgICAgIHRoaXNBcmcgPSBsYXN0VGhpcztcblxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpc0FyZywgYXJncyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxlYWRpbmdFZGdlKHRpbWUpIHtcbiAgICAvLyBSZXNldCBhbnkgYG1heFdhaXRgIHRpbWVyLlxuICAgIGxhc3RJbnZva2VUaW1lID0gdGltZTtcbiAgICAvLyBTdGFydCB0aGUgdGltZXIgZm9yIHRoZSB0cmFpbGluZyBlZGdlLlxuICAgIHRpbWVySWQgPSBzZXRUaW1lb3V0KHRpbWVyRXhwaXJlZCwgd2FpdCk7XG4gICAgLy8gSW52b2tlIHRoZSBsZWFkaW5nIGVkZ2UuXG4gICAgcmV0dXJuIGxlYWRpbmcgPyBpbnZva2VGdW5jKHRpbWUpIDogcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtYWluaW5nV2FpdCh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZSxcbiAgICAgICAgcmVzdWx0ID0gd2FpdCAtIHRpbWVTaW5jZUxhc3RDYWxsO1xuXG4gICAgcmV0dXJuIG1heGluZyA/IG5hdGl2ZU1pbihyZXN1bHQsIG1heFdhaXQgLSB0aW1lU2luY2VMYXN0SW52b2tlKSA6IHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3VsZEludm9rZSh0aW1lKSB7XG4gICAgdmFyIHRpbWVTaW5jZUxhc3RDYWxsID0gdGltZSAtIGxhc3RDYWxsVGltZSxcbiAgICAgICAgdGltZVNpbmNlTGFzdEludm9rZSA9IHRpbWUgLSBsYXN0SW52b2tlVGltZTtcblxuICAgIC8vIEVpdGhlciB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsLCBhY3Rpdml0eSBoYXMgc3RvcHBlZCBhbmQgd2UncmUgYXQgdGhlXG4gICAgLy8gdHJhaWxpbmcgZWRnZSwgdGhlIHN5c3RlbSB0aW1lIGhhcyBnb25lIGJhY2t3YXJkcyBhbmQgd2UncmUgdHJlYXRpbmdcbiAgICAvLyBpdCBhcyB0aGUgdHJhaWxpbmcgZWRnZSwgb3Igd2UndmUgaGl0IHRoZSBgbWF4V2FpdGAgbGltaXQuXG4gICAgcmV0dXJuIChsYXN0Q2FsbFRpbWUgPT09IHVuZGVmaW5lZCB8fCAodGltZVNpbmNlTGFzdENhbGwgPj0gd2FpdCkgfHxcbiAgICAgICh0aW1lU2luY2VMYXN0Q2FsbCA8IDApIHx8IChtYXhpbmcgJiYgdGltZVNpbmNlTGFzdEludm9rZSA+PSBtYXhXYWl0KSk7XG4gIH1cblxuICBmdW5jdGlvbiB0aW1lckV4cGlyZWQoKSB7XG4gICAgdmFyIHRpbWUgPSBub3coKTtcbiAgICBpZiAoc2hvdWxkSW52b2tlKHRpbWUpKSB7XG4gICAgICByZXR1cm4gdHJhaWxpbmdFZGdlKHRpbWUpO1xuICAgIH1cbiAgICAvLyBSZXN0YXJ0IHRoZSB0aW1lci5cbiAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHJlbWFpbmluZ1dhaXQodGltZSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhaWxpbmdFZGdlKHRpbWUpIHtcbiAgICB0aW1lcklkID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gT25seSBpbnZva2UgaWYgd2UgaGF2ZSBgbGFzdEFyZ3NgIHdoaWNoIG1lYW5zIGBmdW5jYCBoYXMgYmVlblxuICAgIC8vIGRlYm91bmNlZCBhdCBsZWFzdCBvbmNlLlxuICAgIGlmICh0cmFpbGluZyAmJiBsYXN0QXJncykge1xuICAgICAgcmV0dXJuIGludm9rZUZ1bmModGltZSk7XG4gICAgfVxuICAgIGxhc3RBcmdzID0gbGFzdFRoaXMgPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbmNlbCgpIHtcbiAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgbGFzdEFyZ3MgPSBsYXN0Q2FsbFRpbWUgPSBsYXN0VGhpcyA9IHRpbWVySWQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICByZXR1cm4gdGltZXJJZCA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogdHJhaWxpbmdFZGdlKG5vdygpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpLFxuICAgICAgICBpc0ludm9raW5nID0gc2hvdWxkSW52b2tlKHRpbWUpO1xuXG4gICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgIGxhc3RDYWxsVGltZSA9IHRpbWU7XG5cbiAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbGVhZGluZ0VkZ2UobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXhpbmcpIHtcbiAgICAgICAgLy8gSGFuZGxlIGludm9jYXRpb25zIGluIGEgdGlnaHQgbG9vcC5cbiAgICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAgICAgcmV0dXJuIGludm9rZUZ1bmMobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBkZWJvdW5jZWQuY2FuY2VsID0gY2FuY2VsO1xuICBkZWJvdW5jZWQuZmx1c2ggPSBmbHVzaDtcbiAgcmV0dXJuIGRlYm91bmNlZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkZWJvdW5jZTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZVxuICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgLy8gaW4gU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgYW5kIHdlYWsgbWFwIGNvbnN0cnVjdG9ycyxcbiAgLy8gYW5kIFBoYW50b21KUyAxLjkgd2hpY2ggcmV0dXJucyAnZnVuY3Rpb24nIGZvciBgTm9kZUxpc3RgIGluc3RhbmNlcy5cbiAgdmFyIHRhZyA9IGlzT2JqZWN0KHZhbHVlKSA/IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRnVuY3Rpb247XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZVxuICogW2xhbmd1YWdlIHR5cGVdKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1lY21hc2NyaXB0LWxhbmd1YWdlLXR5cGVzKVxuICogb2YgYE9iamVjdGAuIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChfLm5vb3ApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0TGlrZTtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZVxuICogW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3ltYm9sYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN5bWJvbFRhZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTeW1ib2w7XG4iLCIvKipcbiAqIEdldHMgdGhlIHRpbWVzdGFtcCBvZiB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZVxuICogdGhlIFVuaXggZXBvY2ggKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAyLjQuMFxuICogQGNhdGVnb3J5IERhdGVcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIHRpbWVzdGFtcC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5kZWZlcihmdW5jdGlvbihzdGFtcCkge1xuICogICBjb25zb2xlLmxvZyhfLm5vdygpIC0gc3RhbXApO1xuICogfSwgXy5ub3coKSk7XG4gKiAvLyA9PiBMb2dzIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGl0IHRvb2sgZm9yIHRoZSBkZWZlcnJlZCBpbnZvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBub3coKSB7XG4gIHJldHVybiBEYXRlLm5vdygpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgaXNTeW1ib2wgPSByZXF1aXJlKCcuL2lzU3ltYm9sJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b051bWJlcigzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gTkFOO1xuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSBpc0Z1bmN0aW9uKHZhbHVlLnZhbHVlT2YpID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b051bWJlcjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGV4cGFuZG8gPSAnc2VrdG9yLScgKyBEYXRlLm5vdygpO1xudmFyIHJzaWJsaW5ncyA9IC9bK35dLztcbnZhciBkb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudDtcbnZhciBkZWwgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwge307XG52YXIgbWF0Y2ggPSAoXG4gIGRlbC5tYXRjaGVzIHx8XG4gIGRlbC53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHxcbiAgZGVsLm1vek1hdGNoZXNTZWxlY3RvciB8fFxuICBkZWwub01hdGNoZXNTZWxlY3RvciB8fFxuICBkZWwubXNNYXRjaGVzU2VsZWN0b3IgfHxcbiAgbmV2ZXJcbik7XG5cbm1vZHVsZS5leHBvcnRzID0gc2VrdG9yO1xuXG5zZWt0b3IubWF0Y2hlcyA9IG1hdGNoZXM7XG5zZWt0b3IubWF0Y2hlc1NlbGVjdG9yID0gbWF0Y2hlc1NlbGVjdG9yO1xuXG5mdW5jdGlvbiBxc2EgKHNlbGVjdG9yLCBjb250ZXh0KSB7XG4gIHZhciBleGlzdGVkLCBpZCwgcHJlZml4LCBwcmVmaXhlZCwgYWRhcHRlciwgaGFjayA9IGNvbnRleHQgIT09IGRvY3VtZW50O1xuICBpZiAoaGFjaykgeyAvLyBpZCBoYWNrIGZvciBjb250ZXh0LXJvb3RlZCBxdWVyaWVzXG4gICAgZXhpc3RlZCA9IGNvbnRleHQuZ2V0QXR0cmlidXRlKCdpZCcpO1xuICAgIGlkID0gZXhpc3RlZCB8fCBleHBhbmRvO1xuICAgIHByZWZpeCA9ICcjJyArIGlkICsgJyAnO1xuICAgIHByZWZpeGVkID0gcHJlZml4ICsgc2VsZWN0b3IucmVwbGFjZSgvLC9nLCAnLCcgKyBwcmVmaXgpO1xuICAgIGFkYXB0ZXIgPSByc2libGluZ3MudGVzdChzZWxlY3RvcikgJiYgY29udGV4dC5wYXJlbnROb2RlO1xuICAgIGlmICghZXhpc3RlZCkgeyBjb250ZXh0LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7IH1cbiAgfVxuICB0cnkge1xuICAgIHJldHVybiAoYWRhcHRlciB8fCBjb250ZXh0KS5xdWVyeVNlbGVjdG9yQWxsKHByZWZpeGVkIHx8IHNlbGVjdG9yKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBbXTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAoZXhpc3RlZCA9PT0gbnVsbCkgeyBjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSgnaWQnKTsgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHNla3RvciAoc2VsZWN0b3IsIGN0eCwgY29sbGVjdGlvbiwgc2VlZCkge1xuICB2YXIgZWxlbWVudDtcbiAgdmFyIGNvbnRleHQgPSBjdHggfHwgZG9jdW1lbnQ7XG4gIHZhciByZXN1bHRzID0gY29sbGVjdGlvbiB8fCBbXTtcbiAgdmFyIGkgPSAwO1xuICBpZiAodHlwZW9mIHNlbGVjdG9yICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG4gIGlmIChjb250ZXh0Lm5vZGVUeXBlICE9PSAxICYmIGNvbnRleHQubm9kZVR5cGUgIT09IDkpIHtcbiAgICByZXR1cm4gW107IC8vIGJhaWwgaWYgY29udGV4dCBpcyBub3QgYW4gZWxlbWVudCBvciBkb2N1bWVudFxuICB9XG4gIGlmIChzZWVkKSB7XG4gICAgd2hpbGUgKChlbGVtZW50ID0gc2VlZFtpKytdKSkge1xuICAgICAgaWYgKG1hdGNoZXNTZWxlY3RvcihlbGVtZW50LCBzZWxlY3RvcikpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzLnB1c2guYXBwbHkocmVzdWx0cywgcXNhKHNlbGVjdG9yLCBjb250ZXh0KSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXMgKHNlbGVjdG9yLCBlbGVtZW50cykge1xuICByZXR1cm4gc2VrdG9yKHNlbGVjdG9yLCBudWxsLCBudWxsLCBlbGVtZW50cyk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXNTZWxlY3RvciAoZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgcmV0dXJuIG1hdGNoLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpO1xufVxuXG5mdW5jdGlvbiBuZXZlciAoKSB7IHJldHVybiBmYWxzZTsgfVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZ2V0U2VsZWN0aW9uO1xudmFyIGRvYyA9IGdsb2JhbC5kb2N1bWVudDtcbnZhciBnZXRTZWxlY3Rpb25SYXcgPSByZXF1aXJlKCcuL2dldFNlbGVjdGlvblJhdycpO1xudmFyIGdldFNlbGVjdGlvbk51bGxPcCA9IHJlcXVpcmUoJy4vZ2V0U2VsZWN0aW9uTnVsbE9wJyk7XG52YXIgZ2V0U2VsZWN0aW9uU3ludGhldGljID0gcmVxdWlyZSgnLi9nZXRTZWxlY3Rpb25TeW50aGV0aWMnKTtcbnZhciBpc0hvc3QgPSByZXF1aXJlKCcuL2lzSG9zdCcpO1xuaWYgKGlzSG9zdC5tZXRob2QoZ2xvYmFsLCAnZ2V0U2VsZWN0aW9uJykpIHtcbiAgZ2V0U2VsZWN0aW9uID0gZ2V0U2VsZWN0aW9uUmF3O1xufSBlbHNlIGlmICh0eXBlb2YgZG9jLnNlbGVjdGlvbiA9PT0gJ29iamVjdCcgJiYgZG9jLnNlbGVjdGlvbikge1xuICBnZXRTZWxlY3Rpb24gPSBnZXRTZWxlY3Rpb25TeW50aGV0aWM7XG59IGVsc2Uge1xuICBnZXRTZWxlY3Rpb24gPSBnZXRTZWxlY3Rpb25OdWxsT3A7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U2VsZWN0aW9uO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBub29wICgpIHt9XG5cbmZ1bmN0aW9uIGdldFNlbGVjdGlvbk51bGxPcCAoKSB7XG4gIHJldHVybiB7XG4gICAgcmVtb3ZlQWxsUmFuZ2VzOiBub29wLFxuICAgIGFkZFJhbmdlOiBub29wXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U2VsZWN0aW9uTnVsbE9wO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb25SYXcgKCkge1xuICByZXR1cm4gZ2xvYmFsLmdldFNlbGVjdGlvbigpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFNlbGVjdGlvblJhdztcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIHJhbmdlVG9UZXh0UmFuZ2UgPSByZXF1aXJlKCcuL3JhbmdlVG9UZXh0UmFuZ2UnKTtcbnZhciBkb2MgPSBnbG9iYWwuZG9jdW1lbnQ7XG52YXIgYm9keSA9IGRvYy5ib2R5O1xudmFyIEdldFNlbGVjdGlvblByb3RvID0gR2V0U2VsZWN0aW9uLnByb3RvdHlwZTtcblxuZnVuY3Rpb24gR2V0U2VsZWN0aW9uIChzZWxlY3Rpb24pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcmFuZ2UgPSBzZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTtcblxuICB0aGlzLl9zZWxlY3Rpb24gPSBzZWxlY3Rpb247XG4gIHRoaXMuX3JhbmdlcyA9IFtdO1xuXG4gIGlmIChzZWxlY3Rpb24udHlwZSA9PT0gJ0NvbnRyb2wnKSB7XG4gICAgdXBkYXRlQ29udHJvbFNlbGVjdGlvbihzZWxmKTtcbiAgfSBlbHNlIGlmIChpc1RleHRSYW5nZShyYW5nZSkpIHtcbiAgICB1cGRhdGVGcm9tVGV4dFJhbmdlKHNlbGYsIHJhbmdlKTtcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGVFbXB0eVNlbGVjdGlvbihzZWxmKTtcbiAgfVxufVxuXG5HZXRTZWxlY3Rpb25Qcm90by5yZW1vdmVBbGxSYW5nZXMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB0ZXh0UmFuZ2U7XG4gIHRyeSB7XG4gICAgdGhpcy5fc2VsZWN0aW9uLmVtcHR5KCk7XG4gICAgaWYgKHRoaXMuX3NlbGVjdGlvbi50eXBlICE9PSAnTm9uZScpIHtcbiAgICAgIHRleHRSYW5nZSA9IGJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7XG4gICAgICB0ZXh0UmFuZ2Uuc2VsZWN0KCk7XG4gICAgICB0aGlzLl9zZWxlY3Rpb24uZW1wdHkoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgfVxuICB1cGRhdGVFbXB0eVNlbGVjdGlvbih0aGlzKTtcbn07XG5cbkdldFNlbGVjdGlvblByb3RvLmFkZFJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7XG4gIGlmICh0aGlzLl9zZWxlY3Rpb24udHlwZSA9PT0gJ0NvbnRyb2wnKSB7XG4gICAgYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2UpO1xuICB9IGVsc2Uge1xuICAgIHJhbmdlVG9UZXh0UmFuZ2UocmFuZ2UpLnNlbGVjdCgpO1xuICAgIHRoaXMuX3Jhbmdlc1swXSA9IHJhbmdlO1xuICAgIHRoaXMucmFuZ2VDb3VudCA9IDE7XG4gICAgdGhpcy5pc0NvbGxhcHNlZCA9IHRoaXMuX3Jhbmdlc1swXS5jb2xsYXBzZWQ7XG4gICAgdXBkYXRlQW5jaG9yQW5kRm9jdXNGcm9tUmFuZ2UodGhpcywgcmFuZ2UsIGZhbHNlKTtcbiAgfVxufTtcblxuR2V0U2VsZWN0aW9uUHJvdG8uc2V0UmFuZ2VzID0gZnVuY3Rpb24gKHJhbmdlcykge1xuICB0aGlzLnJlbW92ZUFsbFJhbmdlcygpO1xuICB2YXIgcmFuZ2VDb3VudCA9IHJhbmdlcy5sZW5ndGg7XG4gIGlmIChyYW5nZUNvdW50ID4gMSkge1xuICAgIGNyZWF0ZUNvbnRyb2xTZWxlY3Rpb24odGhpcywgcmFuZ2VzKTtcbiAgfSBlbHNlIGlmIChyYW5nZUNvdW50KSB7XG4gICAgdGhpcy5hZGRSYW5nZShyYW5nZXNbMF0pO1xuICB9XG59O1xuXG5HZXRTZWxlY3Rpb25Qcm90by5nZXRSYW5nZUF0ID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy5yYW5nZUNvdW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdnZXRSYW5nZUF0KCk6IGluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcy5fcmFuZ2VzW2luZGV4XS5jbG9uZVJhbmdlKCk7XG4gIH1cbn07XG5cbkdldFNlbGVjdGlvblByb3RvLnJlbW92ZVJhbmdlID0gZnVuY3Rpb24gKHJhbmdlKSB7XG4gIGlmICh0aGlzLl9zZWxlY3Rpb24udHlwZSAhPT0gJ0NvbnRyb2wnKSB7XG4gICAgcmVtb3ZlUmFuZ2VNYW51YWxseSh0aGlzLCByYW5nZSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBjb250cm9sUmFuZ2UgPSB0aGlzLl9zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTtcbiAgdmFyIHJhbmdlRWxlbWVudCA9IGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2UpO1xuICB2YXIgbmV3Q29udHJvbFJhbmdlID0gYm9keS5jcmVhdGVDb250cm9sUmFuZ2UoKTtcbiAgdmFyIGVsO1xuICB2YXIgcmVtb3ZlZCA9IGZhbHNlO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gY29udHJvbFJhbmdlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgZWwgPSBjb250cm9sUmFuZ2UuaXRlbShpKTtcbiAgICBpZiAoZWwgIT09IHJhbmdlRWxlbWVudCB8fCByZW1vdmVkKSB7XG4gICAgICBuZXdDb250cm9sUmFuZ2UuYWRkKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVtb3ZlZCA9IHRydWU7XG4gICAgfVxuICB9XG4gIG5ld0NvbnRyb2xSYW5nZS5zZWxlY3QoKTtcbiAgdXBkYXRlQ29udHJvbFNlbGVjdGlvbih0aGlzKTtcbn07XG5cbkdldFNlbGVjdGlvblByb3RvLmVhY2hSYW5nZSA9IGZ1bmN0aW9uIChmbiwgcmV0dXJuVmFsdWUpIHtcbiAgdmFyIGkgPSAwO1xuICB2YXIgbGVuID0gdGhpcy5fcmFuZ2VzLmxlbmd0aDtcbiAgZm9yIChpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKGZuKHRoaXMuZ2V0UmFuZ2VBdChpKSkpIHtcbiAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG4gIH1cbn07XG5cbkdldFNlbGVjdGlvblByb3RvLmdldEFsbFJhbmdlcyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJhbmdlcyA9IFtdO1xuICB0aGlzLmVhY2hSYW5nZShmdW5jdGlvbiAocmFuZ2UpIHtcbiAgICByYW5nZXMucHVzaChyYW5nZSk7XG4gIH0pO1xuICByZXR1cm4gcmFuZ2VzO1xufTtcblxuR2V0U2VsZWN0aW9uUHJvdG8uc2V0U2luZ2xlUmFuZ2UgPSBmdW5jdGlvbiAocmFuZ2UpIHtcbiAgdGhpcy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgdGhpcy5hZGRSYW5nZShyYW5nZSk7XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVDb250cm9sU2VsZWN0aW9uIChzZWwsIHJhbmdlcykge1xuICB2YXIgY29udHJvbFJhbmdlID0gYm9keS5jcmVhdGVDb250cm9sUmFuZ2UoKTtcbiAgZm9yICh2YXIgaSA9IDAsIGVsLCBsZW4gPSByYW5nZXMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBlbCA9IGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UocmFuZ2VzW2ldKTtcbiAgICB0cnkge1xuICAgICAgY29udHJvbFJhbmdlLmFkZChlbCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZXRSYW5nZXMoKTogRWxlbWVudCBjb3VsZCBub3QgYmUgYWRkZWQgdG8gY29udHJvbCBzZWxlY3Rpb24nKTtcbiAgICB9XG4gIH1cbiAgY29udHJvbFJhbmdlLnNlbGVjdCgpO1xuICB1cGRhdGVDb250cm9sU2VsZWN0aW9uKHNlbCk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVJhbmdlTWFudWFsbHkgKHNlbCwgcmFuZ2UpIHtcbiAgdmFyIHJhbmdlcyA9IHNlbC5nZXRBbGxSYW5nZXMoKTtcbiAgc2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gcmFuZ2VzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKCFpc1NhbWVSYW5nZShyYW5nZSwgcmFuZ2VzW2ldKSkge1xuICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlc1tpXSk7XG4gICAgfVxuICB9XG4gIGlmICghc2VsLnJhbmdlQ291bnQpIHtcbiAgICB1cGRhdGVFbXB0eVNlbGVjdGlvbihzZWwpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUFuY2hvckFuZEZvY3VzRnJvbVJhbmdlIChzZWwsIHJhbmdlKSB7XG4gIHZhciBhbmNob3JQcmVmaXggPSAnc3RhcnQnO1xuICB2YXIgZm9jdXNQcmVmaXggPSAnZW5kJztcbiAgc2VsLmFuY2hvck5vZGUgPSByYW5nZVthbmNob3JQcmVmaXggKyAnQ29udGFpbmVyJ107XG4gIHNlbC5hbmNob3JPZmZzZXQgPSByYW5nZVthbmNob3JQcmVmaXggKyAnT2Zmc2V0J107XG4gIHNlbC5mb2N1c05vZGUgPSByYW5nZVtmb2N1c1ByZWZpeCArICdDb250YWluZXInXTtcbiAgc2VsLmZvY3VzT2Zmc2V0ID0gcmFuZ2VbZm9jdXNQcmVmaXggKyAnT2Zmc2V0J107XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUVtcHR5U2VsZWN0aW9uIChzZWwpIHtcbiAgc2VsLmFuY2hvck5vZGUgPSBzZWwuZm9jdXNOb2RlID0gbnVsbDtcbiAgc2VsLmFuY2hvck9mZnNldCA9IHNlbC5mb2N1c09mZnNldCA9IDA7XG4gIHNlbC5yYW5nZUNvdW50ID0gMDtcbiAgc2VsLmlzQ29sbGFwc2VkID0gdHJ1ZTtcbiAgc2VsLl9yYW5nZXMubGVuZ3RoID0gMDtcbn1cblxuZnVuY3Rpb24gcmFuZ2VDb250YWluc1NpbmdsZUVsZW1lbnQgKHJhbmdlTm9kZXMpIHtcbiAgaWYgKCFyYW5nZU5vZGVzLmxlbmd0aCB8fCByYW5nZU5vZGVzWzBdLm5vZGVUeXBlICE9PSAxKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAodmFyIGkgPSAxLCBsZW4gPSByYW5nZU5vZGVzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgaWYgKCFpc0FuY2VzdG9yT2YocmFuZ2VOb2Rlc1swXSwgcmFuZ2VOb2Rlc1tpXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGdldFNpbmdsZUVsZW1lbnRGcm9tUmFuZ2UgKHJhbmdlKSB7XG4gIHZhciBub2RlcyA9IHJhbmdlLmdldE5vZGVzKCk7XG4gIGlmICghcmFuZ2VDb250YWluc1NpbmdsZUVsZW1lbnQobm9kZXMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKCk6IHJhbmdlIGRpZCBub3QgY29uc2lzdCBvZiBhIHNpbmdsZSBlbGVtZW50Jyk7XG4gIH1cbiAgcmV0dXJuIG5vZGVzWzBdO1xufVxuXG5mdW5jdGlvbiBpc1RleHRSYW5nZSAocmFuZ2UpIHtcbiAgcmV0dXJuIHJhbmdlICYmIHJhbmdlLnRleHQgIT09IHZvaWQgMDtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRnJvbVRleHRSYW5nZSAoc2VsLCByYW5nZSkge1xuICBzZWwuX3JhbmdlcyA9IFtyYW5nZV07XG4gIHVwZGF0ZUFuY2hvckFuZEZvY3VzRnJvbVJhbmdlKHNlbCwgcmFuZ2UsIGZhbHNlKTtcbiAgc2VsLnJhbmdlQ291bnQgPSAxO1xuICBzZWwuaXNDb2xsYXBzZWQgPSByYW5nZS5jb2xsYXBzZWQ7XG59XG5cbmZ1bmN0aW9uIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24gKHNlbCkge1xuICBzZWwuX3Jhbmdlcy5sZW5ndGggPSAwO1xuICBpZiAoc2VsLl9zZWxlY3Rpb24udHlwZSA9PT0gJ05vbmUnKSB7XG4gICAgdXBkYXRlRW1wdHlTZWxlY3Rpb24oc2VsKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgY29udHJvbFJhbmdlID0gc2VsLl9zZWxlY3Rpb24uY3JlYXRlUmFuZ2UoKTtcbiAgICBpZiAoaXNUZXh0UmFuZ2UoY29udHJvbFJhbmdlKSkge1xuICAgICAgdXBkYXRlRnJvbVRleHRSYW5nZShzZWwsIGNvbnRyb2xSYW5nZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbC5yYW5nZUNvdW50ID0gY29udHJvbFJhbmdlLmxlbmd0aDtcbiAgICAgIHZhciByYW5nZTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsLnJhbmdlQ291bnQ7ICsraSkge1xuICAgICAgICByYW5nZSA9IGRvYy5jcmVhdGVSYW5nZSgpO1xuICAgICAgICByYW5nZS5zZWxlY3ROb2RlKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTtcbiAgICAgICAgc2VsLl9yYW5nZXMucHVzaChyYW5nZSk7XG4gICAgICB9XG4gICAgICBzZWwuaXNDb2xsYXBzZWQgPSBzZWwucmFuZ2VDb3VudCA9PT0gMSAmJiBzZWwuX3Jhbmdlc1swXS5jb2xsYXBzZWQ7XG4gICAgICB1cGRhdGVBbmNob3JBbmRGb2N1c0Zyb21SYW5nZShzZWwsIHNlbC5fcmFuZ2VzW3NlbC5yYW5nZUNvdW50IC0gMV0sIGZhbHNlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWRkUmFuZ2VUb0NvbnRyb2xTZWxlY3Rpb24gKHNlbCwgcmFuZ2UpIHtcbiAgdmFyIGNvbnRyb2xSYW5nZSA9IHNlbC5fc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7XG4gIHZhciByYW5nZUVsZW1lbnQgPSBnZXRTaW5nbGVFbGVtZW50RnJvbVJhbmdlKHJhbmdlKTtcbiAgdmFyIG5ld0NvbnRyb2xSYW5nZSA9IGJvZHkuY3JlYXRlQ29udHJvbFJhbmdlKCk7XG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjb250cm9sUmFuZ2UubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBuZXdDb250cm9sUmFuZ2UuYWRkKGNvbnRyb2xSYW5nZS5pdGVtKGkpKTtcbiAgfVxuICB0cnkge1xuICAgIG5ld0NvbnRyb2xSYW5nZS5hZGQocmFuZ2VFbGVtZW50KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignYWRkUmFuZ2UoKTogRWxlbWVudCBjb3VsZCBub3QgYmUgYWRkZWQgdG8gY29udHJvbCBzZWxlY3Rpb24nKTtcbiAgfVxuICBuZXdDb250cm9sUmFuZ2Uuc2VsZWN0KCk7XG4gIHVwZGF0ZUNvbnRyb2xTZWxlY3Rpb24oc2VsKTtcbn1cblxuZnVuY3Rpb24gaXNTYW1lUmFuZ2UgKGxlZnQsIHJpZ2h0KSB7XG4gIHJldHVybiAoXG4gICAgbGVmdC5zdGFydENvbnRhaW5lciA9PT0gcmlnaHQuc3RhcnRDb250YWluZXIgJiZcbiAgICBsZWZ0LnN0YXJ0T2Zmc2V0ID09PSByaWdodC5zdGFydE9mZnNldCAmJlxuICAgIGxlZnQuZW5kQ29udGFpbmVyID09PSByaWdodC5lbmRDb250YWluZXIgJiZcbiAgICBsZWZ0LmVuZE9mZnNldCA9PT0gcmlnaHQuZW5kT2Zmc2V0XG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzQW5jZXN0b3JPZiAoYW5jZXN0b3IsIGRlc2NlbmRhbnQpIHtcbiAgdmFyIG5vZGUgPSBkZXNjZW5kYW50O1xuICB3aGlsZSAobm9kZS5wYXJlbnROb2RlKSB7XG4gICAgaWYgKG5vZGUucGFyZW50Tm9kZSA9PT0gYW5jZXN0b3IpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0U2VsZWN0aW9uICgpIHtcbiAgcmV0dXJuIG5ldyBHZXRTZWxlY3Rpb24oZ2xvYmFsLmRvY3VtZW50LnNlbGVjdGlvbik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U2VsZWN0aW9uO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5mdW5jdGlvbiBpc0hvc3RNZXRob2QgKGhvc3QsIHByb3ApIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgaG9zdFtwcm9wXTtcbiAgcmV0dXJuIHR5cGUgPT09ICdmdW5jdGlvbicgfHwgISEodHlwZSA9PT0gJ29iamVjdCcgJiYgaG9zdFtwcm9wXSkgfHwgdHlwZSA9PT0gJ3Vua25vd24nO1xufVxuXG5mdW5jdGlvbiBpc0hvc3RQcm9wZXJ0eSAoaG9zdCwgcHJvcCkge1xuICByZXR1cm4gdHlwZW9mIGhvc3RbcHJvcF0gIT09ICd1bmRlZmluZWQnO1xufVxuXG5mdW5jdGlvbiBtYW55IChmbikge1xuICByZXR1cm4gZnVuY3Rpb24gYXJlSG9zdGVkIChob3N0LCBwcm9wcykge1xuICAgIHZhciBpID0gcHJvcHMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGlmICghZm4oaG9zdCwgcHJvcHNbaV0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZXRob2Q6IGlzSG9zdE1ldGhvZCxcbiAgbWV0aG9kczogbWFueShpc0hvc3RNZXRob2QpLFxuICBwcm9wZXJ0eTogaXNIb3N0UHJvcGVydHksXG4gIHByb3BlcnRpZXM6IG1hbnkoaXNIb3N0UHJvcGVydHkpXG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZG9jID0gZ2xvYmFsLmRvY3VtZW50O1xudmFyIGJvZHkgPSBkb2MuYm9keTtcblxuZnVuY3Rpb24gcmFuZ2VUb1RleHRSYW5nZSAocCkge1xuICBpZiAocC5jb2xsYXBzZWQpIHtcbiAgICByZXR1cm4gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UoeyBub2RlOiBwLnN0YXJ0Q29udGFpbmVyLCBvZmZzZXQ6IHAuc3RhcnRPZmZzZXQgfSwgdHJ1ZSk7XG4gIH1cbiAgdmFyIHN0YXJ0UmFuZ2UgPSBjcmVhdGVCb3VuZGFyeVRleHRSYW5nZSh7IG5vZGU6IHAuc3RhcnRDb250YWluZXIsIG9mZnNldDogcC5zdGFydE9mZnNldCB9LCB0cnVlKTtcbiAgdmFyIGVuZFJhbmdlID0gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UoeyBub2RlOiBwLmVuZENvbnRhaW5lciwgb2Zmc2V0OiBwLmVuZE9mZnNldCB9LCBmYWxzZSk7XG4gIHZhciB0ZXh0UmFuZ2UgPSBib2R5LmNyZWF0ZVRleHRSYW5nZSgpO1xuICB0ZXh0UmFuZ2Uuc2V0RW5kUG9pbnQoJ1N0YXJ0VG9TdGFydCcsIHN0YXJ0UmFuZ2UpO1xuICB0ZXh0UmFuZ2Uuc2V0RW5kUG9pbnQoJ0VuZFRvRW5kJywgZW5kUmFuZ2UpO1xuICByZXR1cm4gdGV4dFJhbmdlO1xufVxuXG5mdW5jdGlvbiBpc0NoYXJhY3RlckRhdGFOb2RlIChub2RlKSB7XG4gIHZhciB0ID0gbm9kZS5ub2RlVHlwZTtcbiAgcmV0dXJuIHQgPT09IDMgfHwgdCA9PT0gNCB8fCB0ID09PSA4IDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQm91bmRhcnlUZXh0UmFuZ2UgKHAsIHN0YXJ0aW5nKSB7XG4gIHZhciBib3VuZDtcbiAgdmFyIHBhcmVudDtcbiAgdmFyIG9mZnNldCA9IHAub2Zmc2V0O1xuICB2YXIgd29ya2luZ05vZGU7XG4gIHZhciBjaGlsZE5vZGVzO1xuICB2YXIgcmFuZ2UgPSBib2R5LmNyZWF0ZVRleHRSYW5nZSgpO1xuICB2YXIgZGF0YSA9IGlzQ2hhcmFjdGVyRGF0YU5vZGUocC5ub2RlKTtcblxuICBpZiAoZGF0YSkge1xuICAgIGJvdW5kID0gcC5ub2RlO1xuICAgIHBhcmVudCA9IGJvdW5kLnBhcmVudE5vZGU7XG4gIH0gZWxzZSB7XG4gICAgY2hpbGROb2RlcyA9IHAubm9kZS5jaGlsZE5vZGVzO1xuICAgIGJvdW5kID0gb2Zmc2V0IDwgY2hpbGROb2Rlcy5sZW5ndGggPyBjaGlsZE5vZGVzW29mZnNldF0gOiBudWxsO1xuICAgIHBhcmVudCA9IHAubm9kZTtcbiAgfVxuXG4gIHdvcmtpbmdOb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgd29ya2luZ05vZGUuaW5uZXJIVE1MID0gJyYjZmVmZjsnO1xuXG4gIGlmIChib3VuZCkge1xuICAgIHBhcmVudC5pbnNlcnRCZWZvcmUod29ya2luZ05vZGUsIGJvdW5kKTtcbiAgfSBlbHNlIHtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQod29ya2luZ05vZGUpO1xuICB9XG5cbiAgcmFuZ2UubW92ZVRvRWxlbWVudFRleHQod29ya2luZ05vZGUpO1xuICByYW5nZS5jb2xsYXBzZSghc3RhcnRpbmcpO1xuICBwYXJlbnQucmVtb3ZlQ2hpbGQod29ya2luZ05vZGUpO1xuXG4gIGlmIChkYXRhKSB7XG4gICAgcmFuZ2Vbc3RhcnRpbmcgPyAnbW92ZVN0YXJ0JyA6ICdtb3ZlRW5kJ10oJ2NoYXJhY3RlcicsIG9mZnNldCk7XG4gIH1cbiAgcmV0dXJuIHJhbmdlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJhbmdlVG9UZXh0UmFuZ2U7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBnZXRTZWxlY3Rpb24gPSByZXF1aXJlKCcuL2dldFNlbGVjdGlvbicpO1xudmFyIHNldFNlbGVjdGlvbiA9IHJlcXVpcmUoJy4vc2V0U2VsZWN0aW9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXQ6IGdldFNlbGVjdGlvbixcbiAgc2V0OiBzZXRTZWxlY3Rpb25cbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBnZXRTZWxlY3Rpb24gPSByZXF1aXJlKCcuL2dldFNlbGVjdGlvbicpO1xudmFyIHJhbmdlVG9UZXh0UmFuZ2UgPSByZXF1aXJlKCcuL3JhbmdlVG9UZXh0UmFuZ2UnKTtcbnZhciBkb2MgPSBnbG9iYWwuZG9jdW1lbnQ7XG5cbmZ1bmN0aW9uIHNldFNlbGVjdGlvbiAocCkge1xuICBpZiAoZG9jLmNyZWF0ZVJhbmdlKSB7XG4gICAgbW9kZXJuU2VsZWN0aW9uKCk7XG4gIH0gZWxzZSB7XG4gICAgb2xkU2VsZWN0aW9uKCk7XG4gIH1cblxuICBmdW5jdGlvbiBtb2Rlcm5TZWxlY3Rpb24gKCkge1xuICAgIHZhciBzZWwgPSBnZXRTZWxlY3Rpb24oKTtcbiAgICB2YXIgcmFuZ2UgPSBkb2MuY3JlYXRlUmFuZ2UoKTtcbiAgICBpZiAoIXAuc3RhcnRDb250YWluZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHAuZW5kQ29udGFpbmVyKSB7XG4gICAgICByYW5nZS5zZXRFbmQocC5lbmRDb250YWluZXIsIHAuZW5kT2Zmc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmFuZ2Uuc2V0RW5kKHAuc3RhcnRDb250YWluZXIsIHAuc3RhcnRPZmZzZXQpO1xuICAgIH1cbiAgICByYW5nZS5zZXRTdGFydChwLnN0YXJ0Q29udGFpbmVyLCBwLnN0YXJ0T2Zmc2V0KTtcbiAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgc2VsLmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9sZFNlbGVjdGlvbiAoKSB7XG4gICAgcmFuZ2VUb1RleHRSYW5nZShwKS5zZWxlY3QoKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFNlbGVjdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGdldCA9IGVhc3lHZXQ7XG52YXIgc2V0ID0gZWFzeVNldDtcblxuaWYgKGRvY3VtZW50LnNlbGVjdGlvbiAmJiBkb2N1bWVudC5zZWxlY3Rpb24uY3JlYXRlUmFuZ2UpIHtcbiAgZ2V0ID0gaGFyZEdldDtcbiAgc2V0ID0gaGFyZFNldDtcbn1cblxuZnVuY3Rpb24gZWFzeUdldCAoZWwpIHtcbiAgcmV0dXJuIHtcbiAgICBzdGFydDogZWwuc2VsZWN0aW9uU3RhcnQsXG4gICAgZW5kOiBlbC5zZWxlY3Rpb25FbmRcbiAgfTtcbn1cblxuZnVuY3Rpb24gaGFyZEdldCAoZWwpIHtcbiAgdmFyIGFjdGl2ZSA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gIGlmIChhY3RpdmUgIT09IGVsKSB7XG4gICAgZWwuZm9jdXMoKTtcbiAgfVxuXG4gIHZhciByYW5nZSA9IGRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpO1xuICB2YXIgYm9va21hcmsgPSByYW5nZS5nZXRCb29rbWFyaygpO1xuICB2YXIgb3JpZ2luYWwgPSBlbC52YWx1ZTtcbiAgdmFyIG1hcmtlciA9IGdldFVuaXF1ZU1hcmtlcihvcmlnaW5hbCk7XG4gIHZhciBwYXJlbnQgPSByYW5nZS5wYXJlbnRFbGVtZW50KCk7XG4gIGlmIChwYXJlbnQgPT09IG51bGwgfHwgIWlucHV0cyhwYXJlbnQpKSB7XG4gICAgcmV0dXJuIHJlc3VsdCgwLCAwKTtcbiAgfVxuICByYW5nZS50ZXh0ID0gbWFya2VyICsgcmFuZ2UudGV4dCArIG1hcmtlcjtcblxuICB2YXIgY29udGVudHMgPSBlbC52YWx1ZTtcblxuICBlbC52YWx1ZSA9IG9yaWdpbmFsO1xuICByYW5nZS5tb3ZlVG9Cb29rbWFyayhib29rbWFyayk7XG4gIHJhbmdlLnNlbGVjdCgpO1xuXG4gIHJldHVybiByZXN1bHQoY29udGVudHMuaW5kZXhPZihtYXJrZXIpLCBjb250ZW50cy5sYXN0SW5kZXhPZihtYXJrZXIpIC0gbWFya2VyLmxlbmd0aCk7XG5cbiAgZnVuY3Rpb24gcmVzdWx0IChzdGFydCwgZW5kKSB7XG4gICAgaWYgKGFjdGl2ZSAhPT0gZWwpIHsgLy8gZG9uJ3QgZGlzcnVwdCBwcmUtZXhpc3Rpbmcgc3RhdGVcbiAgICAgIGlmIChhY3RpdmUpIHtcbiAgICAgICAgYWN0aXZlLmZvY3VzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbC5ibHVyKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydCwgZW5kOiBlbmQgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRVbmlxdWVNYXJrZXIgKGNvbnRlbnRzKSB7XG4gIHZhciBtYXJrZXI7XG4gIGRvIHtcbiAgICBtYXJrZXIgPSAnQEBtYXJrZXIuJyArIE1hdGgucmFuZG9tKCkgKiBuZXcgRGF0ZSgpO1xuICB9IHdoaWxlIChjb250ZW50cy5pbmRleE9mKG1hcmtlcikgIT09IC0xKTtcbiAgcmV0dXJuIG1hcmtlcjtcbn1cblxuZnVuY3Rpb24gaW5wdXRzIChlbCkge1xuICByZXR1cm4gKChlbC50YWdOYW1lID09PSAnSU5QVVQnICYmIGVsLnR5cGUgPT09ICd0ZXh0JykgfHwgZWwudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJyk7XG59XG5cbmZ1bmN0aW9uIGVhc3lTZXQgKGVsLCBwKSB7XG4gIGVsLnNlbGVjdGlvblN0YXJ0ID0gcGFyc2UoZWwsIHAuc3RhcnQpO1xuICBlbC5zZWxlY3Rpb25FbmQgPSBwYXJzZShlbCwgcC5lbmQpO1xufVxuXG5mdW5jdGlvbiBoYXJkU2V0IChlbCwgcCkge1xuICB2YXIgcmFuZ2UgPSBlbC5jcmVhdGVUZXh0UmFuZ2UoKTtcblxuICBpZiAocC5zdGFydCA9PT0gJ2VuZCcgJiYgcC5lbmQgPT09ICdlbmQnKSB7XG4gICAgcmFuZ2UuY29sbGFwc2UoZmFsc2UpO1xuICAgIHJhbmdlLnNlbGVjdCgpO1xuICB9IGVsc2Uge1xuICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIHJhbmdlLm1vdmVFbmQoJ2NoYXJhY3RlcicsIHBhcnNlKGVsLCBwLmVuZCkpO1xuICAgIHJhbmdlLm1vdmVTdGFydCgnY2hhcmFjdGVyJywgcGFyc2UoZWwsIHAuc3RhcnQpKTtcbiAgICByYW5nZS5zZWxlY3QoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZSAoZWwsIHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gJ2VuZCcgPyBlbC52YWx1ZS5sZW5ndGggOiB2YWx1ZSB8fCAwO1xufVxuXG5mdW5jdGlvbiBzZWxsIChlbCwgcCkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xuICAgIHNldChlbCwgcCk7XG4gIH1cbiAgcmV0dXJuIGdldChlbCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2VsbDtcbiIsInZhciBzaSA9IHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicsIHRpY2s7XG5pZiAoc2kpIHtcbiAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRJbW1lZGlhdGUoZm4pOyB9O1xufSBlbHNlIHtcbiAgdGljayA9IGZ1bmN0aW9uIChmbikgeyBzZXRUaW1lb3V0KGZuLCAwKTsgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0aWNrOyJdfQ== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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}">🔗</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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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