From adff07247584c8dd8deccde98c5a188a3556049b Mon Sep 17 00:00:00 2001 From: lkrsnik Date: Thu, 4 Jul 2024 13:39:46 +0200 Subject: [PATCH] Updated to new STARK version + some small updates --- app.py | 45 +- messages.pot | 138 +- setup.py | 2 +- static/js/init.js | 59 +- static/js/nouislider.js | 2282 ----------------------- static/js/nouislider.min.js | 1 - templates/base.html | 1 - templates/index.html | 39 +- translations/en/LC_MESSAGES/messages.po | 144 +- translations/sl/LC_MESSAGES/messages.po | 151 +- 10 files changed, 300 insertions(+), 2562 deletions(-) delete mode 100644 static/js/nouislider.js delete mode 100644 static/js/nouislider.min.js diff --git a/app.py b/app.py index a7d3066..2b23638 100755 --- a/app.py +++ b/app.py @@ -112,6 +112,7 @@ def create_app(): 'Number of nodes': gettext('Number of nodes'), 'Head node': gettext('Head node'), 'Grew-match URL': gettext('Grew-match URL'), + 'Ratio': gettext('Ratio'), '%DIFF': gettext('%DIFF'), 'OR': gettext('OR'), 'BIC': gettext('BIC'), @@ -162,9 +163,15 @@ def create_app(): translations = _translations[get_locale()] if request.method == 'POST': form = request.form - configs = {} + configs = { + 'greedy_counter': 'yes', + 'input_path': '', + 'tree_size': '1-1000000', + 'display_size': '1-1000000', + 'complete_tree_type': True, + 'ignored_labels': [] + } # mandatory parameters - configs['input_path'] = '' validation = {} @@ -194,29 +201,10 @@ def create_app(): validation['file'] = gettext('Please insert either input url or provide a file.') validation['input_url'] = gettext('Please insert either input url or provide a file.') - tree_size_min = None - if 'tree_size_min' in form: - tree_size_min = form['tree_size_min'] - - tree_size_max = None - if 'tree_size_max' in form: - tree_size_max = form['tree_size_max'] - - def validate_tree_size(tree_size_min, tree_size_max): - if tree_size_min is None or tree_size_max is None: - validation['tree_size'] = gettext('Please provide information about minimum and maximum tree size.') - return False - - if int(tree_size_min) > int(tree_size_max): - validation['tree_size'] = gettext('Tree size minimum should be smaller than tree size maximum.') - return False - return True - - if validate_tree_size(tree_size_min, tree_size_max): - configs['tree_size'] = f'{tree_size_min}-{tree_size_max}' if tree_size_min != tree_size_max else f'{tree_size_min}' + if 'display_size' in form and form['display_size']: + configs['display_size'] = form['display_size'] def validate_node_type(node_type): - # TODO EXPAND NODE TYPE node_type_options = {'upos', 'form', 'lemma', 'upos', 'xpos', 'feats', 'deprel'} if len(node_type) == 0: validation['node_type'] = gettext('Please select at least one node type.') @@ -230,6 +218,7 @@ def create_app(): return True node_type = [] + if 'node_type_upos' in form: node_type.append('upos') if 'node_type_form' in form: @@ -237,7 +226,9 @@ def create_app(): if 'node_type_lemma' in form: node_type.append('lemma') - if validate_node_type(node_type): + if 'node_type_none' in form: + configs['node_type'] = None + elif validate_node_type(node_type): configs['node_type'] = '+'.join(node_type) # mandatory parameters with default value @@ -246,8 +237,6 @@ def create_app(): # TODO depends on computer configs['cpu_cores'] = 12 - # TODO FINALIZE THIS! - configs['complete_tree_type'] = True configs['dependency_type'] = 'labeled_trees' in form and form['labeled_trees'] == 'on' configs['node_order'] = 'fixed_order' in form and form['fixed_order'] == 'on' configs['association_measures'] = 'association_measures' in form and form['association_measures'] == 'on' @@ -257,9 +246,13 @@ def create_app(): if 'root_restriction' in form and form['root_restriction']: configs['root_whitelist'] = form['root_restriction'].split('|') + if 'ignored_labels' in form and form['ignored_labels']: + configs['ignored_labels'] = form['ignored_labels'].split('|') + if 'query' in form and form['query']: configs['query'] = form['query'] configs['tree_size'] = '0' + configs['display_size'] = '0' else: configs['query'] = None diff --git a/messages.pot b/messages.pot index 14c03a5..72f92bf 100644 --- a/messages.pot +++ b/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2024-03-13 11:06+0100\n" +"POT-Creation-Date: 2024-07-04 11:51+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -46,88 +46,84 @@ msgid "Grew-match URL" msgstr "" #: app.py:115 -msgid "%DIFF" +msgid "Ratio" msgstr "" #: app.py:116 -msgid "OR" +msgid "%DIFF" msgstr "" #: app.py:117 -msgid "BIC" +msgid "OR" msgstr "" #: app.py:118 -msgid "MI" +msgid "BIC" msgstr "" #: app.py:119 -msgid "logDice" +msgid "MI" msgstr "" #: app.py:120 +msgid "logDice" +msgstr "" + +#: app.py:121 msgid "t-score" msgstr "" -#: app.py:123 +#: app.py:124 msgid "Frequency in A" msgstr "" -#: app.py:181 app.py:182 +#: app.py:188 app.py:189 msgid "Please insert either input url or file, not both of them." msgstr "" -#: app.py:192 app.py:287 +#: app.py:199 app.py:280 msgid "Incorrect URL!" msgstr "" -#: app.py:194 app.py:195 +#: app.py:201 app.py:202 msgid "Please insert either input url or provide a file." msgstr "" -#: app.py:207 -msgid "Please provide information about minimum and maximum tree size." -msgstr "" - -#: app.py:211 -msgid "Tree size minimum should be smaller than tree size maximum." -msgstr "" - -#: app.py:222 +#: app.py:210 msgid "Please select at least one node type." msgstr "" -#: app.py:227 +#: app.py:215 msgid "Node option" msgstr "" -#: app.py:227 +#: app.py:215 msgid "is not supported. Please enter valid options." msgstr "" -#: app.py:275 app.py:276 +#: app.py:268 app.py:269 msgid "Please insert either compare url or file, not both of them." msgstr "" -#: app.py:299 +#: app.py:292 msgid "Please insert an Integer." msgstr "" -#: app.py:324 +#: app.py:317 msgid "" "Processing failed! Please recheck your settings, e.g. input format or " "head node description." msgstr "" -#: app.py:333 +#: app.py:326 msgid "Frequency " msgstr "" -#: app.py:333 +#: app.py:326 msgid "Frequency in A " msgstr "" -#: app.py:334 templates/base.html:20 templates/base.html:22 +#: app.py:327 templates/base.html:20 templates/base.html:22 #: templates/index.html:8 templates/result.html:15 msgid "code" msgstr "" @@ -212,19 +208,19 @@ msgstr "" msgid "Upload a treebank" msgstr "" -#: templates/index.html:12 templates/index.html:20 templates/index.html:160 -#: templates/index.html:167 +#: templates/index.html:12 templates/index.html:20 templates/index.html:171 +#: templates/index.html:178 msgid "in CONLL-U format" msgstr "" -#: templates/index.html:12 templates/index.html:41 templates/index.html:49 -#: templates/index.html:89 templates/index.html:104 templates/index.html:120 -#: templates/index.html:126 templates/index.html:132 templates/index.html:140 -#: templates/index.html:159 templates/index.html:160 +#: templates/index.html:12 templates/index.html:44 templates/index.html:48 +#: templates/index.html:94 templates/index.html:109 templates/index.html:125 +#: templates/index.html:131 templates/index.html:137 templates/index.html:143 +#: templates/index.html:151 templates/index.html:170 templates/index.html:171 msgid "Help" msgstr "" -#: templates/index.html:15 templates/index.html:163 +#: templates/index.html:15 templates/index.html:174 msgid "Browse" msgstr "" @@ -232,15 +228,15 @@ msgstr "" msgid "Upload" msgstr "" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "Or" msgstr "" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "insert a URL link to a treebank in CONLL-U format" msgstr "" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "Example" msgstr "" @@ -248,117 +244,129 @@ msgstr "" msgid "Tree specification" msgstr "" -#: templates/index.html:41 +#: templates/index.html:44 msgid "Tree size" msgstr "" -#: templates/index.html:41 +#: templates/index.html:44 msgid "number of tokens in the tree" msgstr "" -#: templates/index.html:49 +#: templates/index.html:48 msgid "Node type" msgstr "" -#: templates/index.html:49 +#: templates/index.html:48 msgid "token characteristics to consider" msgstr "" -#: templates/index.html:55 +#: templates/index.html:54 +msgid "No type" +msgstr "" + +#: templates/index.html:63 msgid "Part-of-speech" msgstr "" -#: templates/index.html:64 +#: templates/index.html:69 msgid "Lemma" msgstr "" -#: templates/index.html:70 +#: templates/index.html:75 msgid "Form" msgstr "" -#: templates/index.html:84 +#: templates/index.html:89 msgid "Advanced settings" msgstr "" -#: templates/index.html:89 +#: templates/index.html:94 msgid "Labeled trees" msgstr "" -#: templates/index.html:89 +#: templates/index.html:94 msgid "include names of dependency relations" msgstr "" -#: templates/index.html:93 templates/index.html:108 templates/index.html:144 +#: templates/index.html:98 templates/index.html:113 templates/index.html:155 msgid "No" msgstr "" -#: templates/index.html:96 templates/index.html:111 templates/index.html:147 +#: templates/index.html:101 templates/index.html:116 templates/index.html:158 msgid "Yes" msgstr "" -#: templates/index.html:104 +#: templates/index.html:109 msgid "Fixed order" msgstr "" -#: templates/index.html:104 +#: templates/index.html:109 msgid "differentiate trees based on surface word order" msgstr "" -#: templates/index.html:120 +#: templates/index.html:125 msgid "Head" msgstr "" -#: templates/index.html:120 +#: templates/index.html:125 msgid "specify potential restrictions on the head node" msgstr "" -#: templates/index.html:126 +#: templates/index.html:131 +msgid "Ignored labels" +msgstr "" + +#: templates/index.html:131 +msgid "specify the dependency labels of nodes to be ignored" +msgstr "" + +#: templates/index.html:137 msgid "Query" msgstr "" -#: templates/index.html:126 +#: templates/index.html:137 msgid "write a query. Note: Tree size attribute will be ignored!" msgstr "" -#: templates/index.html:132 +#: templates/index.html:143 msgid "Frequency threshold" msgstr "" -#: templates/index.html:132 +#: templates/index.html:143 msgid "specify the minimum frequency of a tree in the treebank" msgstr "" -#: templates/index.html:140 +#: templates/index.html:151 msgid "Association measures" msgstr "" -#: templates/index.html:140 +#: templates/index.html:151 msgid "print MI, logDice and t-score" msgstr "" -#: templates/index.html:155 +#: templates/index.html:166 msgid "Compare treebanks" msgstr "" -#: templates/index.html:159 +#: templates/index.html:170 msgid "" "Select a reference treebank to identify key phenomena (prints the " "%DIFF, BIC and OR keyness scores)." msgstr "" -#: templates/index.html:160 templates/index.html:167 +#: templates/index.html:171 templates/index.html:178 msgid "Upload a compare corpus" msgstr "" -#: templates/index.html:191 +#: templates/index.html:202 msgid "Submit" msgstr "" -#: templates/index.html:199 +#: templates/index.html:210 msgid "No results" msgstr "" -#: templates/index.html:200 +#: templates/index.html:211 msgid "Processing with your settings didnt produce any results!" msgstr "" diff --git a/setup.py b/setup.py index 6334fdf..5116e6f 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,6 @@ setup(name='stark-api', 'Flask==3.0.0', 'requests==2.31.0', 'flask-babel==4.0.0', - 'stark @ git+https://github.com/clarinsi/STARK@master' + 'stark @ git+https://github.com/clarinsi/STARK@refactoring' ], ) \ No newline at end of file diff --git a/static/js/init.js b/static/js/init.js index d487952..3db4594 100644 --- a/static/js/init.js +++ b/static/js/init.js @@ -1,5 +1,5 @@ // Global array to store input names -var globalInputList = ['tree_size_min', 'tree_size_max', 'file', 'association_measures', 'labeled_trees', 'node_type_upos', 'fixed_order', 'input_url', 'node_type_lemma', 'root_restriction', 'node_type_form', 'frequency_threshold', 'query', 'compare_url', 'compare_file']; +var globalInputList = ['display_size', 'file', 'association_measures', 'labeled_trees', 'node_type_upos', 'fixed_order', 'input_url', 'node_type_lemma', 'root_restriction', 'node_type_form', 'frequency_threshold', 'node_type_none', 'query', 'compare_url', 'compare_file', 'ignored_labels']; // Function to store values to local storage function storeValuesToLocalstorage() { @@ -63,19 +63,6 @@ document.addEventListener("DOMContentLoaded", function(event) { return valuesForSlider.indexOf(Number(value)); } }; - var slider = document.getElementById('slider'); - noUiSlider.create(slider, { - start: [tree_size[0], tree_size[1]], - connect: true, - tooltips: true, - step: 1, - range: { - 'min': 0, - 'max': valuesForSlider.length - 1 - }, - format: format - }); - var urlParams = new URLSearchParams(window.location.search); var lang='en' if (urlParams.has('lang')) { @@ -146,38 +133,30 @@ document.addEventListener("DOMContentLoaded", function(event) { }); $("#submit-form").submit( function(eventObj) { - var spans = $(".noUi-tooltip").find('span'); - var tree_size_min = spans[0].innerText; - var tree_size_max = spans[1].innerText; - console.log('amm'); - $("").attr("type", "hidden") - .attr("name", "tree_size_min") - .attr("value", tree_size_min) - .appendTo("#submit-form"); - $("").attr("type", "hidden") - .attr("name", "tree_size_max") - .attr("value", tree_size_max) - .appendTo("#submit-form"); - storeValuesToLocalstorage(); return true; }); $("#switch-language").click(function(e) { - var spans = $(".noUi-tooltip").find('span'); - var tree_size_min = spans[0].innerText; - var tree_size_max = spans[1].innerText; - console.log('amm'); - $("").attr("type", "hidden") - .attr("name", "tree_size_min") - .attr("value", tree_size_min) - .appendTo("#submit-form"); - $("").attr("type", "hidden") - .attr("name", "tree_size_max") - .attr("value", tree_size_max) - .appendTo("#submit-form"); - storeValuesToLocalstorage(); return true; }); + $('input.node_type').on('change', function(e) { + if (this.name == 'node_type_none') { + $('input.node_type').not(this).prop('checked', false); + } else { + $('input.node_type_none').prop('checked', false); + } + }); + $('a.example-input-link').click(function(e) { + $('#input_url').val(this.href) + e.preventDefault(); + }); + $('a.example-compare-link').click(function(e) { + $('#compare_url').val(this.href) + e.preventDefault(); + }); + + + })(jQuery); diff --git a/static/js/nouislider.js b/static/js/nouislider.js deleted file mode 100644 index 1dff19b..0000000 --- a/static/js/nouislider.js +++ /dev/null @@ -1,2282 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : - typeof define === 'function' && define.amd ? define(['exports'], factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.noUiSlider = {})); -})(this, (function (exports) { 'use strict'; - - exports.PipsMode = void 0; - (function (PipsMode) { - PipsMode["Range"] = "range"; - PipsMode["Steps"] = "steps"; - PipsMode["Positions"] = "positions"; - PipsMode["Count"] = "count"; - PipsMode["Values"] = "values"; - })(exports.PipsMode || (exports.PipsMode = {})); - exports.PipsType = void 0; - (function (PipsType) { - PipsType[PipsType["None"] = -1] = "None"; - PipsType[PipsType["NoValue"] = 0] = "NoValue"; - PipsType[PipsType["LargeValue"] = 1] = "LargeValue"; - PipsType[PipsType["SmallValue"] = 2] = "SmallValue"; - })(exports.PipsType || (exports.PipsType = {})); - //region Helper Methods - function isValidFormatter(entry) { - return isValidPartialFormatter(entry) && typeof entry.from === "function"; - } - function isValidPartialFormatter(entry) { - // partial formatters only need a to function and not a from function - return typeof entry === "object" && typeof entry.to === "function"; - } - function removeElement(el) { - el.parentElement.removeChild(el); - } - function isSet(value) { - return value !== null && value !== undefined; - } - // Bindable version - function preventDefault(e) { - e.preventDefault(); - } - // Removes duplicates from an array. - function unique(array) { - return array.filter(function (a) { - return !this[a] ? (this[a] = true) : false; - }, {}); - } - // Round a value to the closest 'to'. - function closest(value, to) { - return Math.round(value / to) * to; - } - // Current position of an element relative to the document. - function offset(elem, orientation) { - var rect = elem.getBoundingClientRect(); - var doc = elem.ownerDocument; - var docElem = doc.documentElement; - var pageOffset = getPageOffset(doc); - // getBoundingClientRect contains left scroll in Chrome on Android. - // I haven't found a feature detection that proves this. Worst case - // scenario on mis-match: the 'tap' feature on horizontal sliders breaks. - if (/webkit.*Chrome.*Mobile/i.test(navigator.userAgent)) { - pageOffset.x = 0; - } - return orientation ? rect.top + pageOffset.y - docElem.clientTop : rect.left + pageOffset.x - docElem.clientLeft; - } - // Checks whether a value is numerical. - function isNumeric(a) { - return typeof a === "number" && !isNaN(a) && isFinite(a); - } - // Sets a class and removes it after [duration] ms. - function addClassFor(element, className, duration) { - if (duration > 0) { - addClass(element, className); - setTimeout(function () { - removeClass(element, className); - }, duration); - } - } - // Limits a value to 0 - 100 - function limit(a) { - return Math.max(Math.min(a, 100), 0); - } - // Wraps a variable as an array, if it isn't one yet. - // Note that an input array is returned by reference! - function asArray(a) { - return Array.isArray(a) ? a : [a]; - } - // Counts decimals - function countDecimals(numStr) { - numStr = String(numStr); - var pieces = numStr.split("."); - return pieces.length > 1 ? pieces[1].length : 0; - } - // http://youmightnotneedjquery.com/#add_class - function addClass(el, className) { - if (el.classList && !/\s/.test(className)) { - el.classList.add(className); - } - else { - el.className += " " + className; - } - } - // http://youmightnotneedjquery.com/#remove_class - function removeClass(el, className) { - if (el.classList && !/\s/.test(className)) { - el.classList.remove(className); - } - else { - el.className = el.className.replace(new RegExp("(^|\\b)" + className.split(" ").join("|") + "(\\b|$)", "gi"), " "); - } - } - // https://plainjs.com/javascript/attributes/adding-removing-and-testing-for-classes-9/ - function hasClass(el, className) { - return el.classList ? el.classList.contains(className) : new RegExp("\\b" + className + "\\b").test(el.className); - } - // https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollY#Notes - function getPageOffset(doc) { - var supportPageOffset = window.pageXOffset !== undefined; - var isCSS1Compat = (doc.compatMode || "") === "CSS1Compat"; - var x = supportPageOffset - ? window.pageXOffset - : isCSS1Compat - ? doc.documentElement.scrollLeft - : doc.body.scrollLeft; - var y = supportPageOffset - ? window.pageYOffset - : isCSS1Compat - ? doc.documentElement.scrollTop - : doc.body.scrollTop; - return { - x: x, - y: y, - }; - } - // we provide a function to compute constants instead - // of accessing window.* as soon as the module needs it - // so that we do not compute anything if not needed - function getActions() { - // Determine the events to bind. IE11 implements pointerEvents without - // a prefix, which breaks compatibility with the IE10 implementation. - return window.navigator.pointerEnabled - ? { - start: "pointerdown", - move: "pointermove", - end: "pointerup", - } - : window.navigator.msPointerEnabled - ? { - start: "MSPointerDown", - move: "MSPointerMove", - end: "MSPointerUp", - } - : { - start: "mousedown touchstart", - move: "mousemove touchmove", - end: "mouseup touchend", - }; - } - // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md - // Issue #785 - function getSupportsPassive() { - var supportsPassive = false; - /* eslint-disable */ - try { - var opts = Object.defineProperty({}, "passive", { - get: function () { - supportsPassive = true; - }, - }); - // @ts-ignore - window.addEventListener("test", null, opts); - } - catch (e) { } - /* eslint-enable */ - return supportsPassive; - } - function getSupportsTouchActionNone() { - return window.CSS && CSS.supports && CSS.supports("touch-action", "none"); - } - //endregion - //region Range Calculation - // Determine the size of a sub-range in relation to a full range. - function subRangeRatio(pa, pb) { - return 100 / (pb - pa); - } - // (percentage) How many percent is this value of this range? - function fromPercentage(range, value, startRange) { - return (value * 100) / (range[startRange + 1] - range[startRange]); - } - // (percentage) Where is this value on this range? - function toPercentage(range, value) { - return fromPercentage(range, range[0] < 0 ? value + Math.abs(range[0]) : value - range[0], 0); - } - // (value) How much is this percentage on this range? - function isPercentage(range, value) { - return (value * (range[1] - range[0])) / 100 + range[0]; - } - function getJ(value, arr) { - var j = 1; - while (value >= arr[j]) { - j += 1; - } - return j; - } - // (percentage) Input a value, find where, on a scale of 0-100, it applies. - function toStepping(xVal, xPct, value) { - if (value >= xVal.slice(-1)[0]) { - return 100; - } - var j = getJ(value, xVal); - var va = xVal[j - 1]; - var vb = xVal[j]; - var pa = xPct[j - 1]; - var pb = xPct[j]; - return pa + toPercentage([va, vb], value) / subRangeRatio(pa, pb); - } - // (value) Input a percentage, find where it is on the specified range. - function fromStepping(xVal, xPct, value) { - // There is no range group that fits 100 - if (value >= 100) { - return xVal.slice(-1)[0]; - } - var j = getJ(value, xPct); - var va = xVal[j - 1]; - var vb = xVal[j]; - var pa = xPct[j - 1]; - var pb = xPct[j]; - return isPercentage([va, vb], (value - pa) * subRangeRatio(pa, pb)); - } - // (percentage) Get the step that applies at a certain value. - function getStep(xPct, xSteps, snap, value) { - if (value === 100) { - return value; - } - var j = getJ(value, xPct); - var a = xPct[j - 1]; - var b = xPct[j]; - // If 'snap' is set, steps are used as fixed points on the slider. - if (snap) { - // Find the closest position, a or b. - if (value - a > (b - a) / 2) { - return b; - } - return a; - } - if (!xSteps[j - 1]) { - return value; - } - return xPct[j - 1] + closest(value - xPct[j - 1], xSteps[j - 1]); - } - //endregion - //region Spectrum - var Spectrum = /** @class */ (function () { - function Spectrum(entry, snap, singleStep) { - this.xPct = []; - this.xVal = []; - this.xSteps = []; - this.xNumSteps = []; - this.xHighestCompleteStep = []; - this.xSteps = [singleStep || false]; - this.xNumSteps = [false]; - this.snap = snap; - var index; - var ordered = []; - // Map the object keys to an array. - Object.keys(entry).forEach(function (index) { - ordered.push([asArray(entry[index]), index]); - }); - // Sort all entries by value (numeric sort). - ordered.sort(function (a, b) { - return a[0][0] - b[0][0]; - }); - // Convert all entries to subranges. - for (index = 0; index < ordered.length; index++) { - this.handleEntryPoint(ordered[index][1], ordered[index][0]); - } - // Store the actual step values. - // xSteps is sorted in the same order as xPct and xVal. - this.xNumSteps = this.xSteps.slice(0); - // Convert all numeric steps to the percentage of the subrange they represent. - for (index = 0; index < this.xNumSteps.length; index++) { - this.handleStepPoint(index, this.xNumSteps[index]); - } - } - Spectrum.prototype.getDistance = function (value) { - var distances = []; - for (var index = 0; index < this.xNumSteps.length - 1; index++) { - distances[index] = fromPercentage(this.xVal, value, index); - } - return distances; - }; - // Calculate the percentual distance over the whole scale of ranges. - // direction: 0 = backwards / 1 = forwards - Spectrum.prototype.getAbsoluteDistance = function (value, distances, direction) { - var xPct_index = 0; - // Calculate range where to start calculation - if (value < this.xPct[this.xPct.length - 1]) { - while (value > this.xPct[xPct_index + 1]) { - xPct_index++; - } - } - else if (value === this.xPct[this.xPct.length - 1]) { - xPct_index = this.xPct.length - 2; - } - // If looking backwards and the value is exactly at a range separator then look one range further - if (!direction && value === this.xPct[xPct_index + 1]) { - xPct_index++; - } - if (distances === null) { - distances = []; - } - var start_factor; - var rest_factor = 1; - var rest_rel_distance = distances[xPct_index]; - var range_pct = 0; - var rel_range_distance = 0; - var abs_distance_counter = 0; - var range_counter = 0; - // Calculate what part of the start range the value is - if (direction) { - start_factor = (value - this.xPct[xPct_index]) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]); - } - else { - start_factor = (this.xPct[xPct_index + 1] - value) / (this.xPct[xPct_index + 1] - this.xPct[xPct_index]); - } - // Do until the complete distance across ranges is calculated - while (rest_rel_distance > 0) { - // Calculate the percentage of total range - range_pct = this.xPct[xPct_index + 1 + range_counter] - this.xPct[xPct_index + range_counter]; - // Detect if the margin, padding or limit is larger then the current range and calculate - if (distances[xPct_index + range_counter] * rest_factor + 100 - start_factor * 100 > 100) { - // If larger then take the percentual distance of the whole range - rel_range_distance = range_pct * start_factor; - // Rest factor of relative percentual distance still to be calculated - rest_factor = (rest_rel_distance - 100 * start_factor) / distances[xPct_index + range_counter]; - // Set start factor to 1 as for next range it does not apply. - start_factor = 1; - } - else { - // If smaller or equal then take the percentual distance of the calculate percentual part of that range - rel_range_distance = ((distances[xPct_index + range_counter] * range_pct) / 100) * rest_factor; - // No rest left as the rest fits in current range - rest_factor = 0; - } - if (direction) { - abs_distance_counter = abs_distance_counter - rel_range_distance; - // Limit range to first range when distance becomes outside of minimum range - if (this.xPct.length + range_counter >= 1) { - range_counter--; - } - } - else { - abs_distance_counter = abs_distance_counter + rel_range_distance; - // Limit range to last range when distance becomes outside of maximum range - if (this.xPct.length - range_counter >= 1) { - range_counter++; - } - } - // Rest of relative percentual distance still to be calculated - rest_rel_distance = distances[xPct_index + range_counter] * rest_factor; - } - return value + abs_distance_counter; - }; - Spectrum.prototype.toStepping = function (value) { - value = toStepping(this.xVal, this.xPct, value); - return value; - }; - Spectrum.prototype.fromStepping = function (value) { - return fromStepping(this.xVal, this.xPct, value); - }; - Spectrum.prototype.getStep = function (value) { - value = getStep(this.xPct, this.xSteps, this.snap, value); - return value; - }; - Spectrum.prototype.getDefaultStep = function (value, isDown, size) { - var j = getJ(value, this.xPct); - // When at the top or stepping down, look at the previous sub-range - if (value === 100 || (isDown && value === this.xPct[j - 1])) { - j = Math.max(j - 1, 1); - } - return (this.xVal[j] - this.xVal[j - 1]) / size; - }; - Spectrum.prototype.getNearbySteps = function (value) { - var j = getJ(value, this.xPct); - return { - stepBefore: { - startValue: this.xVal[j - 2], - step: this.xNumSteps[j - 2], - highestStep: this.xHighestCompleteStep[j - 2], - }, - thisStep: { - startValue: this.xVal[j - 1], - step: this.xNumSteps[j - 1], - highestStep: this.xHighestCompleteStep[j - 1], - }, - stepAfter: { - startValue: this.xVal[j], - step: this.xNumSteps[j], - highestStep: this.xHighestCompleteStep[j], - }, - }; - }; - Spectrum.prototype.countStepDecimals = function () { - var stepDecimals = this.xNumSteps.map(countDecimals); - return Math.max.apply(null, stepDecimals); - }; - Spectrum.prototype.hasNoSize = function () { - return this.xVal[0] === this.xVal[this.xVal.length - 1]; - }; - // Outside testing - Spectrum.prototype.convert = function (value) { - return this.getStep(this.toStepping(value)); - }; - Spectrum.prototype.handleEntryPoint = function (index, value) { - var percentage; - // Covert min/max syntax to 0 and 100. - if (index === "min") { - percentage = 0; - } - else if (index === "max") { - percentage = 100; - } - else { - percentage = parseFloat(index); - } - // Check for correct input. - if (!isNumeric(percentage) || !isNumeric(value[0])) { - throw new Error("noUiSlider: 'range' value isn't numeric."); - } - // Store values. - this.xPct.push(percentage); - this.xVal.push(value[0]); - var value1 = Number(value[1]); - // NaN will evaluate to false too, but to keep - // logging clear, set step explicitly. Make sure - // not to override the 'step' setting with false. - if (!percentage) { - if (!isNaN(value1)) { - this.xSteps[0] = value1; - } - } - else { - this.xSteps.push(isNaN(value1) ? false : value1); - } - this.xHighestCompleteStep.push(0); - }; - Spectrum.prototype.handleStepPoint = function (i, n) { - // Ignore 'false' stepping. - if (!n) { - return; - } - // Step over zero-length ranges (#948); - if (this.xVal[i] === this.xVal[i + 1]) { - this.xSteps[i] = this.xHighestCompleteStep[i] = this.xVal[i]; - return; - } - // Factor to range ratio - this.xSteps[i] = - fromPercentage([this.xVal[i], this.xVal[i + 1]], n, 0) / subRangeRatio(this.xPct[i], this.xPct[i + 1]); - var totalSteps = (this.xVal[i + 1] - this.xVal[i]) / this.xNumSteps[i]; - var highestStep = Math.ceil(Number(totalSteps.toFixed(3)) - 1); - var step = this.xVal[i] + this.xNumSteps[i] * highestStep; - this.xHighestCompleteStep[i] = step; - }; - return Spectrum; - }()); - //endregion - //region Options - /* Every input option is tested and parsed. This will prevent - endless validation in internal methods. These tests are - structured with an item for every option available. An - option can be marked as required by setting the 'r' flag. - The testing function is provided with three arguments: - - The provided value for the option; - - A reference to the options object; - - The name for the option; - - The testing function returns false when an error is detected, - or true when everything is OK. It can also modify the option - object, to make sure all values can be correctly looped elsewhere. */ - //region Defaults - var defaultFormatter = { - to: function (value) { - return value === undefined ? "" : value.toFixed(2); - }, - from: Number, - }; - var cssClasses = { - target: "target", - base: "base", - origin: "origin", - handle: "handle", - handleLower: "handle-lower", - handleUpper: "handle-upper", - touchArea: "touch-area", - horizontal: "horizontal", - vertical: "vertical", - background: "background", - connect: "connect", - connects: "connects", - ltr: "ltr", - rtl: "rtl", - textDirectionLtr: "txt-dir-ltr", - textDirectionRtl: "txt-dir-rtl", - draggable: "draggable", - drag: "state-drag", - tap: "state-tap", - active: "active", - tooltip: "tooltip", - pips: "pips", - pipsHorizontal: "pips-horizontal", - pipsVertical: "pips-vertical", - marker: "marker", - markerHorizontal: "marker-horizontal", - markerVertical: "marker-vertical", - markerNormal: "marker-normal", - markerLarge: "marker-large", - markerSub: "marker-sub", - value: "value", - valueHorizontal: "value-horizontal", - valueVertical: "value-vertical", - valueNormal: "value-normal", - valueLarge: "value-large", - valueSub: "value-sub", - }; - // Namespaces of internal event listeners - var INTERNAL_EVENT_NS = { - tooltips: ".__tooltips", - aria: ".__aria", - }; - //endregion - function testStep(parsed, entry) { - if (!isNumeric(entry)) { - throw new Error("noUiSlider: 'step' is not numeric."); - } - // The step option can still be used to set stepping - // for linear sliders. Overwritten if set in 'range'. - parsed.singleStep = entry; - } - function testKeyboardPageMultiplier(parsed, entry) { - if (!isNumeric(entry)) { - throw new Error("noUiSlider: 'keyboardPageMultiplier' is not numeric."); - } - parsed.keyboardPageMultiplier = entry; - } - function testKeyboardMultiplier(parsed, entry) { - if (!isNumeric(entry)) { - throw new Error("noUiSlider: 'keyboardMultiplier' is not numeric."); - } - parsed.keyboardMultiplier = entry; - } - function testKeyboardDefaultStep(parsed, entry) { - if (!isNumeric(entry)) { - throw new Error("noUiSlider: 'keyboardDefaultStep' is not numeric."); - } - parsed.keyboardDefaultStep = entry; - } - function testRange(parsed, entry) { - // Filter incorrect input. - if (typeof entry !== "object" || Array.isArray(entry)) { - throw new Error("noUiSlider: 'range' is not an object."); - } - // Catch missing start or end. - if (entry.min === undefined || entry.max === undefined) { - throw new Error("noUiSlider: Missing 'min' or 'max' in 'range'."); - } - parsed.spectrum = new Spectrum(entry, parsed.snap || false, parsed.singleStep); - } - function testStart(parsed, entry) { - entry = asArray(entry); - // Validate input. Values aren't tested, as the public .val method - // will always provide a valid location. - if (!Array.isArray(entry) || !entry.length) { - throw new Error("noUiSlider: 'start' option is incorrect."); - } - // Store the number of handles. - parsed.handles = entry.length; - // When the slider is initialized, the .val method will - // be called with the start options. - parsed.start = entry; - } - function testSnap(parsed, entry) { - if (typeof entry !== "boolean") { - throw new Error("noUiSlider: 'snap' option must be a boolean."); - } - // Enforce 100% stepping within subranges. - parsed.snap = entry; - } - function testAnimate(parsed, entry) { - if (typeof entry !== "boolean") { - throw new Error("noUiSlider: 'animate' option must be a boolean."); - } - // Enforce 100% stepping within subranges. - parsed.animate = entry; - } - function testAnimationDuration(parsed, entry) { - if (typeof entry !== "number") { - throw new Error("noUiSlider: 'animationDuration' option must be a number."); - } - parsed.animationDuration = entry; - } - function testConnect(parsed, entry) { - var connect = [false]; - var i; - // Map legacy options - if (entry === "lower") { - entry = [true, false]; - } - else if (entry === "upper") { - entry = [false, true]; - } - // Handle boolean options - if (entry === true || entry === false) { - for (i = 1; i < parsed.handles; i++) { - connect.push(entry); - } - connect.push(false); - } - // Reject invalid input - else if (!Array.isArray(entry) || !entry.length || entry.length !== parsed.handles + 1) { - throw new Error("noUiSlider: 'connect' option doesn't match handle count."); - } - else { - connect = entry; - } - parsed.connect = connect; - } - function testOrientation(parsed, entry) { - // Set orientation to an a numerical value for easy - // array selection. - switch (entry) { - case "horizontal": - parsed.ort = 0; - break; - case "vertical": - parsed.ort = 1; - break; - default: - throw new Error("noUiSlider: 'orientation' option is invalid."); - } - } - function testMargin(parsed, entry) { - if (!isNumeric(entry)) { - throw new Error("noUiSlider: 'margin' option must be numeric."); - } - // Issue #582 - if (entry === 0) { - return; - } - parsed.margin = parsed.spectrum.getDistance(entry); - } - function testLimit(parsed, entry) { - if (!isNumeric(entry)) { - throw new Error("noUiSlider: 'limit' option must be numeric."); - } - parsed.limit = parsed.spectrum.getDistance(entry); - if (!parsed.limit || parsed.handles < 2) { - throw new Error("noUiSlider: 'limit' option is only supported on linear sliders with 2 or more handles."); - } - } - function testPadding(parsed, entry) { - var index; - if (!isNumeric(entry) && !Array.isArray(entry)) { - throw new Error("noUiSlider: 'padding' option must be numeric or array of exactly 2 numbers."); - } - if (Array.isArray(entry) && !(entry.length === 2 || isNumeric(entry[0]) || isNumeric(entry[1]))) { - throw new Error("noUiSlider: 'padding' option must be numeric or array of exactly 2 numbers."); - } - if (entry === 0) { - return; - } - if (!Array.isArray(entry)) { - entry = [entry, entry]; - } - // 'getDistance' returns false for invalid values. - parsed.padding = [parsed.spectrum.getDistance(entry[0]), parsed.spectrum.getDistance(entry[1])]; - for (index = 0; index < parsed.spectrum.xNumSteps.length - 1; index++) { - // last "range" can't contain step size as it is purely an endpoint. - if (parsed.padding[0][index] < 0 || parsed.padding[1][index] < 0) { - throw new Error("noUiSlider: 'padding' option must be a positive number(s)."); - } - } - var totalPadding = entry[0] + entry[1]; - var firstValue = parsed.spectrum.xVal[0]; - var lastValue = parsed.spectrum.xVal[parsed.spectrum.xVal.length - 1]; - if (totalPadding / (lastValue - firstValue) > 1) { - throw new Error("noUiSlider: 'padding' option must not exceed 100% of the range."); - } - } - function testDirection(parsed, entry) { - // Set direction as a numerical value for easy parsing. - // Invert connection for RTL sliders, so that the proper - // handles get the connect/background classes. - switch (entry) { - case "ltr": - parsed.dir = 0; - break; - case "rtl": - parsed.dir = 1; - break; - default: - throw new Error("noUiSlider: 'direction' option was not recognized."); - } - } - function testBehaviour(parsed, entry) { - // Make sure the input is a string. - if (typeof entry !== "string") { - throw new Error("noUiSlider: 'behaviour' must be a string containing options."); - } - // Check if the string contains any keywords. - // None are required. - var tap = entry.indexOf("tap") >= 0; - var drag = entry.indexOf("drag") >= 0; - var fixed = entry.indexOf("fixed") >= 0; - var snap = entry.indexOf("snap") >= 0; - var hover = entry.indexOf("hover") >= 0; - var unconstrained = entry.indexOf("unconstrained") >= 0; - var dragAll = entry.indexOf("drag-all") >= 0; - var smoothSteps = entry.indexOf("smooth-steps") >= 0; - if (fixed) { - if (parsed.handles !== 2) { - throw new Error("noUiSlider: 'fixed' behaviour must be used with 2 handles"); - } - // Use margin to enforce fixed state - testMargin(parsed, parsed.start[1] - parsed.start[0]); - } - if (unconstrained && (parsed.margin || parsed.limit)) { - throw new Error("noUiSlider: 'unconstrained' behaviour cannot be used with margin or limit"); - } - parsed.events = { - tap: tap || snap, - drag: drag, - dragAll: dragAll, - smoothSteps: smoothSteps, - fixed: fixed, - snap: snap, - hover: hover, - unconstrained: unconstrained, - }; - } - function testTooltips(parsed, entry) { - if (entry === false) { - return; - } - if (entry === true || isValidPartialFormatter(entry)) { - parsed.tooltips = []; - for (var i = 0; i < parsed.handles; i++) { - parsed.tooltips.push(entry); - } - } - else { - entry = asArray(entry); - if (entry.length !== parsed.handles) { - throw new Error("noUiSlider: must pass a formatter for all handles."); - } - entry.forEach(function (formatter) { - if (typeof formatter !== "boolean" && !isValidPartialFormatter(formatter)) { - throw new Error("noUiSlider: 'tooltips' must be passed a formatter or 'false'."); - } - }); - parsed.tooltips = entry; - } - } - function testHandleAttributes(parsed, entry) { - if (entry.length !== parsed.handles) { - throw new Error("noUiSlider: must pass a attributes for all handles."); - } - parsed.handleAttributes = entry; - } - function testAriaFormat(parsed, entry) { - if (!isValidPartialFormatter(entry)) { - throw new Error("noUiSlider: 'ariaFormat' requires 'to' method."); - } - parsed.ariaFormat = entry; - } - function testFormat(parsed, entry) { - if (!isValidFormatter(entry)) { - throw new Error("noUiSlider: 'format' requires 'to' and 'from' methods."); - } - parsed.format = entry; - } - function testKeyboardSupport(parsed, entry) { - if (typeof entry !== "boolean") { - throw new Error("noUiSlider: 'keyboardSupport' option must be a boolean."); - } - parsed.keyboardSupport = entry; - } - function testDocumentElement(parsed, entry) { - // This is an advanced option. Passed values are used without validation. - parsed.documentElement = entry; - } - function testCssPrefix(parsed, entry) { - if (typeof entry !== "string" && entry !== false) { - throw new Error("noUiSlider: 'cssPrefix' must be a string or `false`."); - } - parsed.cssPrefix = entry; - } - function testCssClasses(parsed, entry) { - if (typeof entry !== "object") { - throw new Error("noUiSlider: 'cssClasses' must be an object."); - } - if (typeof parsed.cssPrefix === "string") { - parsed.cssClasses = {}; - Object.keys(entry).forEach(function (key) { - parsed.cssClasses[key] = parsed.cssPrefix + entry[key]; - }); - } - else { - parsed.cssClasses = entry; - } - } - // Test all developer settings and parse to assumption-safe values. - function testOptions(options) { - // To prove a fix for #537, freeze options here. - // If the object is modified, an error will be thrown. - // Object.freeze(options); - var parsed = { - margin: null, - limit: null, - padding: null, - animate: true, - animationDuration: 300, - ariaFormat: defaultFormatter, - format: defaultFormatter, - }; - // Tests are executed in the order they are presented here. - var tests = { - step: { r: false, t: testStep }, - keyboardPageMultiplier: { r: false, t: testKeyboardPageMultiplier }, - keyboardMultiplier: { r: false, t: testKeyboardMultiplier }, - keyboardDefaultStep: { r: false, t: testKeyboardDefaultStep }, - start: { r: true, t: testStart }, - connect: { r: true, t: testConnect }, - direction: { r: true, t: testDirection }, - snap: { r: false, t: testSnap }, - animate: { r: false, t: testAnimate }, - animationDuration: { r: false, t: testAnimationDuration }, - range: { r: true, t: testRange }, - orientation: { r: false, t: testOrientation }, - margin: { r: false, t: testMargin }, - limit: { r: false, t: testLimit }, - padding: { r: false, t: testPadding }, - behaviour: { r: true, t: testBehaviour }, - ariaFormat: { r: false, t: testAriaFormat }, - format: { r: false, t: testFormat }, - tooltips: { r: false, t: testTooltips }, - keyboardSupport: { r: true, t: testKeyboardSupport }, - documentElement: { r: false, t: testDocumentElement }, - cssPrefix: { r: true, t: testCssPrefix }, - cssClasses: { r: true, t: testCssClasses }, - handleAttributes: { r: false, t: testHandleAttributes }, - }; - var defaults = { - connect: false, - direction: "ltr", - behaviour: "tap", - orientation: "horizontal", - keyboardSupport: true, - cssPrefix: "noUi-", - cssClasses: cssClasses, - keyboardPageMultiplier: 5, - keyboardMultiplier: 1, - keyboardDefaultStep: 10, - }; - // AriaFormat defaults to regular format, if any. - if (options.format && !options.ariaFormat) { - options.ariaFormat = options.format; - } - // Run all options through a testing mechanism to ensure correct - // input. It should be noted that options might get modified to - // be handled properly. E.g. wrapping integers in arrays. - Object.keys(tests).forEach(function (name) { - // If the option isn't set, but it is required, throw an error. - if (!isSet(options[name]) && defaults[name] === undefined) { - if (tests[name].r) { - throw new Error("noUiSlider: '" + name + "' is required."); - } - return; - } - tests[name].t(parsed, !isSet(options[name]) ? defaults[name] : options[name]); - }); - // Forward pips options - parsed.pips = options.pips; - // All recent browsers accept unprefixed transform. - // We need -ms- for IE9 and -webkit- for older Android; - // Assume use of -webkit- if unprefixed and -ms- are not supported. - // https://caniuse.com/#feat=transforms2d - var d = document.createElement("div"); - var msPrefix = d.style.msTransform !== undefined; - var noPrefix = d.style.transform !== undefined; - parsed.transformRule = noPrefix ? "transform" : msPrefix ? "msTransform" : "webkitTransform"; - // Pips don't move, so we can place them using left/top. - var styles = [ - ["left", "top"], - ["right", "bottom"], - ]; - parsed.style = styles[parsed.dir][parsed.ort]; - return parsed; - } - //endregion - function scope(target, options, originalOptions) { - var actions = getActions(); - var supportsTouchActionNone = getSupportsTouchActionNone(); - var supportsPassive = supportsTouchActionNone && getSupportsPassive(); - // All variables local to 'scope' are prefixed with 'scope_' - // Slider DOM Nodes - var scope_Target = target; - var scope_Base; - var scope_Handles; - var scope_Connects; - var scope_Pips; - var scope_Tooltips; - // Slider state values - var scope_Spectrum = options.spectrum; - var scope_Values = []; - var scope_Locations = []; - var scope_HandleNumbers = []; - var scope_ActiveHandlesCount = 0; - var scope_Events = {}; - // Document Nodes - var scope_Document = target.ownerDocument; - var scope_DocumentElement = options.documentElement || scope_Document.documentElement; - var scope_Body = scope_Document.body; - // For horizontal sliders in standard ltr documents, - // make .noUi-origin overflow to the left so the document doesn't scroll. - var scope_DirOffset = scope_Document.dir === "rtl" || options.ort === 1 ? 0 : 100; - // Creates a node, adds it to target, returns the new node. - function addNodeTo(addTarget, className) { - var div = scope_Document.createElement("div"); - if (className) { - addClass(div, className); - } - addTarget.appendChild(div); - return div; - } - // Append a origin to the base - function addOrigin(base, handleNumber) { - var origin = addNodeTo(base, options.cssClasses.origin); - var handle = addNodeTo(origin, options.cssClasses.handle); - addNodeTo(handle, options.cssClasses.touchArea); - handle.setAttribute("data-handle", String(handleNumber)); - if (options.keyboardSupport) { - // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex - // 0 = focusable and reachable - handle.setAttribute("tabindex", "0"); - handle.addEventListener("keydown", function (event) { - return eventKeydown(event, handleNumber); - }); - } - if (options.handleAttributes !== undefined) { - var attributes_1 = options.handleAttributes[handleNumber]; - Object.keys(attributes_1).forEach(function (attribute) { - handle.setAttribute(attribute, attributes_1[attribute]); - }); - } - handle.setAttribute("role", "slider"); - handle.setAttribute("aria-orientation", options.ort ? "vertical" : "horizontal"); - if (handleNumber === 0) { - addClass(handle, options.cssClasses.handleLower); - } - else if (handleNumber === options.handles - 1) { - addClass(handle, options.cssClasses.handleUpper); - } - origin.handle = handle; - return origin; - } - // Insert nodes for connect elements - function addConnect(base, add) { - if (!add) { - return false; - } - return addNodeTo(base, options.cssClasses.connect); - } - // Add handles to the slider base. - function addElements(connectOptions, base) { - var connectBase = addNodeTo(base, options.cssClasses.connects); - scope_Handles = []; - scope_Connects = []; - scope_Connects.push(addConnect(connectBase, connectOptions[0])); - // [::::O====O====O====] - // connectOptions = [0, 1, 1, 1] - for (var i = 0; i < options.handles; i++) { - // Keep a list of all added handles. - scope_Handles.push(addOrigin(base, i)); - scope_HandleNumbers[i] = i; - scope_Connects.push(addConnect(connectBase, connectOptions[i + 1])); - } - } - // Initialize a single slider. - function addSlider(addTarget) { - // Apply classes and data to the target. - addClass(addTarget, options.cssClasses.target); - if (options.dir === 0) { - addClass(addTarget, options.cssClasses.ltr); - } - else { - addClass(addTarget, options.cssClasses.rtl); - } - if (options.ort === 0) { - addClass(addTarget, options.cssClasses.horizontal); - } - else { - addClass(addTarget, options.cssClasses.vertical); - } - var textDirection = getComputedStyle(addTarget).direction; - if (textDirection === "rtl") { - addClass(addTarget, options.cssClasses.textDirectionRtl); - } - else { - addClass(addTarget, options.cssClasses.textDirectionLtr); - } - return addNodeTo(addTarget, options.cssClasses.base); - } - function addTooltip(handle, handleNumber) { - if (!options.tooltips || !options.tooltips[handleNumber]) { - return false; - } - return addNodeTo(handle.firstChild, options.cssClasses.tooltip); - } - function isSliderDisabled() { - return scope_Target.hasAttribute("disabled"); - } - // Disable the slider dragging if any handle is disabled - function isHandleDisabled(handleNumber) { - var handleOrigin = scope_Handles[handleNumber]; - return handleOrigin.hasAttribute("disabled"); - } - function disable(handleNumber) { - if (handleNumber !== null && handleNumber !== undefined) { - scope_Handles[handleNumber].setAttribute("disabled", ""); - scope_Handles[handleNumber].handle.removeAttribute("tabindex"); - } - else { - scope_Target.setAttribute("disabled", ""); - scope_Handles.forEach(function (handle) { - handle.handle.removeAttribute("tabindex"); - }); - } - } - function enable(handleNumber) { - if (handleNumber !== null && handleNumber !== undefined) { - scope_Handles[handleNumber].removeAttribute("disabled"); - scope_Handles[handleNumber].handle.setAttribute("tabindex", "0"); - } - else { - scope_Target.removeAttribute("disabled"); - scope_Handles.forEach(function (handle) { - handle.removeAttribute("disabled"); - handle.handle.setAttribute("tabindex", "0"); - }); - } - } - function removeTooltips() { - if (scope_Tooltips) { - removeEvent("update" + INTERNAL_EVENT_NS.tooltips); - scope_Tooltips.forEach(function (tooltip) { - if (tooltip) { - removeElement(tooltip); - } - }); - scope_Tooltips = null; - } - } - // The tooltips option is a shorthand for using the 'update' event. - function tooltips() { - removeTooltips(); - // Tooltips are added with options.tooltips in original order. - scope_Tooltips = scope_Handles.map(addTooltip); - bindEvent("update" + INTERNAL_EVENT_NS.tooltips, function (values, handleNumber, unencoded) { - if (!scope_Tooltips || !options.tooltips) { - return; - } - if (scope_Tooltips[handleNumber] === false) { - return; - } - var formattedValue = values[handleNumber]; - if (options.tooltips[handleNumber] !== true) { - formattedValue = options.tooltips[handleNumber].to(unencoded[handleNumber]); - } - scope_Tooltips[handleNumber].innerHTML = formattedValue; - }); - } - function aria() { - removeEvent("update" + INTERNAL_EVENT_NS.aria); - bindEvent("update" + INTERNAL_EVENT_NS.aria, function (values, handleNumber, unencoded, tap, positions) { - // Update Aria Values for all handles, as a change in one changes min and max values for the next. - scope_HandleNumbers.forEach(function (index) { - var handle = scope_Handles[index]; - var min = checkHandlePosition(scope_Locations, index, 0, true, true, true); - var max = checkHandlePosition(scope_Locations, index, 100, true, true, true); - var now = positions[index]; - // Formatted value for display - var text = String(options.ariaFormat.to(unencoded[index])); - // Map to slider range values - min = scope_Spectrum.fromStepping(min).toFixed(1); - max = scope_Spectrum.fromStepping(max).toFixed(1); - now = scope_Spectrum.fromStepping(now).toFixed(1); - handle.children[0].setAttribute("aria-valuemin", min); - handle.children[0].setAttribute("aria-valuemax", max); - handle.children[0].setAttribute("aria-valuenow", now); - handle.children[0].setAttribute("aria-valuetext", text); - }); - }); - } - function getGroup(pips) { - // Use the range. - if (pips.mode === exports.PipsMode.Range || pips.mode === exports.PipsMode.Steps) { - return scope_Spectrum.xVal; - } - if (pips.mode === exports.PipsMode.Count) { - if (pips.values < 2) { - throw new Error("noUiSlider: 'values' (>= 2) required for mode 'count'."); - } - // Divide 0 - 100 in 'count' parts. - var interval = pips.values - 1; - var spread = 100 / interval; - var values = []; - // List these parts and have them handled as 'positions'. - while (interval--) { - values[interval] = interval * spread; - } - values.push(100); - return mapToRange(values, pips.stepped); - } - if (pips.mode === exports.PipsMode.Positions) { - // Map all percentages to on-range values. - return mapToRange(pips.values, pips.stepped); - } - if (pips.mode === exports.PipsMode.Values) { - // If the value must be stepped, it needs to be converted to a percentage first. - if (pips.stepped) { - return pips.values.map(function (value) { - // Convert to percentage, apply step, return to value. - return scope_Spectrum.fromStepping(scope_Spectrum.getStep(scope_Spectrum.toStepping(value))); - }); - } - // Otherwise, we can simply use the values. - return pips.values; - } - return []; // pips.mode = never - } - function mapToRange(values, stepped) { - return values.map(function (value) { - return scope_Spectrum.fromStepping(stepped ? scope_Spectrum.getStep(value) : value); - }); - } - function generateSpread(pips) { - function safeIncrement(value, increment) { - // Avoid floating point variance by dropping the smallest decimal places. - return Number((value + increment).toFixed(7)); - } - var group = getGroup(pips); - var indexes = {}; - var firstInRange = scope_Spectrum.xVal[0]; - var lastInRange = scope_Spectrum.xVal[scope_Spectrum.xVal.length - 1]; - var ignoreFirst = false; - var ignoreLast = false; - var prevPct = 0; - // Create a copy of the group, sort it and filter away all duplicates. - group = unique(group.slice().sort(function (a, b) { - return a - b; - })); - // Make sure the range starts with the first element. - if (group[0] !== firstInRange) { - group.unshift(firstInRange); - ignoreFirst = true; - } - // Likewise for the last one. - if (group[group.length - 1] !== lastInRange) { - group.push(lastInRange); - ignoreLast = true; - } - group.forEach(function (current, index) { - // Get the current step and the lower + upper positions. - var step; - var i; - var q; - var low = current; - var high = group[index + 1]; - var newPct; - var pctDifference; - var pctPos; - var type; - var steps; - var realSteps; - var stepSize; - var isSteps = pips.mode === exports.PipsMode.Steps; - // When using 'steps' mode, use the provided steps. - // Otherwise, we'll step on to the next subrange. - if (isSteps) { - step = scope_Spectrum.xNumSteps[index]; - } - // Default to a 'full' step. - if (!step) { - step = high - low; - } - // If high is undefined we are at the last subrange. Make sure it iterates once (#1088) - if (high === undefined) { - high = low; - } - // Make sure step isn't 0, which would cause an infinite loop (#654) - step = Math.max(step, 0.0000001); - // Find all steps in the subrange. - for (i = low; i <= high; i = safeIncrement(i, step)) { - // Get the percentage value for the current step, - // calculate the size for the subrange. - newPct = scope_Spectrum.toStepping(i); - pctDifference = newPct - prevPct; - steps = pctDifference / (pips.density || 1); - realSteps = Math.round(steps); - // This ratio represents the amount of percentage-space a point indicates. - // For a density 1 the points/percentage = 1. For density 2, that percentage needs to be re-divided. - // Round the percentage offset to an even number, then divide by two - // to spread the offset on both sides of the range. - stepSize = pctDifference / realSteps; - // Divide all points evenly, adding the correct number to this subrange. - // Run up to <= so that 100% gets a point, event if ignoreLast is set. - for (q = 1; q <= realSteps; q += 1) { - // The ratio between the rounded value and the actual size might be ~1% off. - // Correct the percentage offset by the number of points - // per subrange. density = 1 will result in 100 points on the - // full range, 2 for 50, 4 for 25, etc. - pctPos = prevPct + q * stepSize; - indexes[pctPos.toFixed(5)] = [scope_Spectrum.fromStepping(pctPos), 0]; - } - // Determine the point type. - type = group.indexOf(i) > -1 ? exports.PipsType.LargeValue : isSteps ? exports.PipsType.SmallValue : exports.PipsType.NoValue; - // Enforce the 'ignoreFirst' option by overwriting the type for 0. - if (!index && ignoreFirst && i !== high) { - type = 0; - } - if (!(i === high && ignoreLast)) { - // Mark the 'type' of this point. 0 = plain, 1 = real value, 2 = step value. - indexes[newPct.toFixed(5)] = [i, type]; - } - // Update the percentage count. - prevPct = newPct; - } - }); - return indexes; - } - function addMarking(spread, filterFunc, formatter) { - var _a, _b; - var element = scope_Document.createElement("div"); - var valueSizeClasses = (_a = {}, - _a[exports.PipsType.None] = "", - _a[exports.PipsType.NoValue] = options.cssClasses.valueNormal, - _a[exports.PipsType.LargeValue] = options.cssClasses.valueLarge, - _a[exports.PipsType.SmallValue] = options.cssClasses.valueSub, - _a); - var markerSizeClasses = (_b = {}, - _b[exports.PipsType.None] = "", - _b[exports.PipsType.NoValue] = options.cssClasses.markerNormal, - _b[exports.PipsType.LargeValue] = options.cssClasses.markerLarge, - _b[exports.PipsType.SmallValue] = options.cssClasses.markerSub, - _b); - var valueOrientationClasses = [options.cssClasses.valueHorizontal, options.cssClasses.valueVertical]; - var markerOrientationClasses = [options.cssClasses.markerHorizontal, options.cssClasses.markerVertical]; - addClass(element, options.cssClasses.pips); - addClass(element, options.ort === 0 ? options.cssClasses.pipsHorizontal : options.cssClasses.pipsVertical); - function getClasses(type, source) { - var a = source === options.cssClasses.value; - var orientationClasses = a ? valueOrientationClasses : markerOrientationClasses; - var sizeClasses = a ? valueSizeClasses : markerSizeClasses; - return source + " " + orientationClasses[options.ort] + " " + sizeClasses[type]; - } - function addSpread(offset, value, type) { - // Apply the filter function, if it is set. - type = filterFunc ? filterFunc(value, type) : type; - if (type === exports.PipsType.None) { - return; - } - // Add a marker for every point - var node = addNodeTo(element, false); - node.className = getClasses(type, options.cssClasses.marker); - node.style[options.style] = offset + "%"; - // Values are only appended for points marked '1' or '2'. - if (type > exports.PipsType.NoValue) { - node = addNodeTo(element, false); - node.className = getClasses(type, options.cssClasses.value); - node.setAttribute("data-value", String(value)); - node.style[options.style] = offset + "%"; - node.innerHTML = String(formatter.to(value)); - } - } - // Append all points. - Object.keys(spread).forEach(function (offset) { - addSpread(offset, spread[offset][0], spread[offset][1]); - }); - return element; - } - function removePips() { - if (scope_Pips) { - removeElement(scope_Pips); - scope_Pips = null; - } - } - function pips(pips) { - // Fix #669 - removePips(); - var spread = generateSpread(pips); - var filter = pips.filter; - var format = pips.format || { - to: function (value) { - return String(Math.round(value)); - }, - }; - scope_Pips = scope_Target.appendChild(addMarking(spread, filter, format)); - return scope_Pips; - } - // Shorthand for base dimensions. - function baseSize() { - var rect = scope_Base.getBoundingClientRect(); - var alt = ("offset" + ["Width", "Height"][options.ort]); - return options.ort === 0 ? rect.width || scope_Base[alt] : rect.height || scope_Base[alt]; - } - // Handler for attaching events trough a proxy. - function attachEvent(events, element, callback, data) { - // This function can be used to 'filter' events to the slider. - // element is a node, not a nodeList - var method = function (event) { - var e = fixEvent(event, data.pageOffset, data.target || element); - // fixEvent returns false if this event has a different target - // when handling (multi-) touch events; - if (!e) { - return false; - } - // doNotReject is passed by all end events to make sure released touches - // are not rejected, leaving the slider "stuck" to the cursor; - if (isSliderDisabled() && !data.doNotReject) { - return false; - } - // Stop if an active 'tap' transition is taking place. - if (hasClass(scope_Target, options.cssClasses.tap) && !data.doNotReject) { - return false; - } - // Ignore right or middle clicks on start #454 - if (events === actions.start && e.buttons !== undefined && e.buttons > 1) { - return false; - } - // Ignore right or middle clicks on start #454 - if (data.hover && e.buttons) { - return false; - } - // 'supportsPassive' is only true if a browser also supports touch-action: none in CSS. - // iOS safari does not, so it doesn't get to benefit from passive scrolling. iOS does support - // touch-action: manipulation, but that allows panning, which breaks - // sliders after zooming/on non-responsive pages. - // See: https://bugs.webkit.org/show_bug.cgi?id=133112 - if (!supportsPassive) { - e.preventDefault(); - } - e.calcPoint = e.points[options.ort]; - // Call the event handler with the event [ and additional data ]. - callback(e, data); - return; - }; - var methods = []; - // Bind a closure on the target for every event type. - events.split(" ").forEach(function (eventName) { - element.addEventListener(eventName, method, supportsPassive ? { passive: true } : false); - methods.push([eventName, method]); - }); - return methods; - } - // Provide a clean event with standardized offset values. - function fixEvent(e, pageOffset, eventTarget) { - // Filter the event to register the type, which can be - // touch, mouse or pointer. Offset changes need to be - // made on an event specific basis. - var touch = e.type.indexOf("touch") === 0; - var mouse = e.type.indexOf("mouse") === 0; - var pointer = e.type.indexOf("pointer") === 0; - var x = 0; - var y = 0; - // IE10 implemented pointer events with a prefix; - if (e.type.indexOf("MSPointer") === 0) { - pointer = true; - } - // Erroneous events seem to be passed in occasionally on iOS/iPadOS after user finishes interacting with - // the slider. They appear to be of type MouseEvent, yet they don't have usual properties set. Ignore - // events that have no touches or buttons associated with them. (#1057, #1079, #1095) - if (e.type === "mousedown" && !e.buttons && !e.touches) { - return false; - } - // The only thing one handle should be concerned about is the touches that originated on top of it. - if (touch) { - // Returns true if a touch originated on the target. - var isTouchOnTarget = function (checkTouch) { - var target = checkTouch.target; - return (target === eventTarget || - eventTarget.contains(target) || - (e.composed && e.composedPath().shift() === eventTarget)); - }; - // In the case of touchstart events, we need to make sure there is still no more than one - // touch on the target so we look amongst all touches. - if (e.type === "touchstart") { - var targetTouches = Array.prototype.filter.call(e.touches, isTouchOnTarget); - // Do not support more than one touch per handle. - if (targetTouches.length > 1) { - return false; - } - x = targetTouches[0].pageX; - y = targetTouches[0].pageY; - } - else { - // In the other cases, find on changedTouches is enough. - var targetTouch = Array.prototype.find.call(e.changedTouches, isTouchOnTarget); - // Cancel if the target touch has not moved. - if (!targetTouch) { - return false; - } - x = targetTouch.pageX; - y = targetTouch.pageY; - } - } - pageOffset = pageOffset || getPageOffset(scope_Document); - if (mouse || pointer) { - x = e.clientX + pageOffset.x; - y = e.clientY + pageOffset.y; - } - e.pageOffset = pageOffset; - e.points = [x, y]; - e.cursor = mouse || pointer; // Fix #435 - return e; - } - // Translate a coordinate in the document to a percentage on the slider - function calcPointToPercentage(calcPoint) { - var location = calcPoint - offset(scope_Base, options.ort); - var proposal = (location * 100) / baseSize(); - // Clamp proposal between 0% and 100% - // Out-of-bound coordinates may occur when .noUi-base pseudo-elements - // are used (e.g. contained handles feature) - proposal = limit(proposal); - return options.dir ? 100 - proposal : proposal; - } - // Find handle closest to a certain percentage on the slider - function getClosestHandle(clickedPosition) { - var smallestDifference = 100; - var handleNumber = false; - scope_Handles.forEach(function (handle, index) { - // Disabled handles are ignored - if (isHandleDisabled(index)) { - return; - } - var handlePosition = scope_Locations[index]; - var differenceWithThisHandle = Math.abs(handlePosition - clickedPosition); - // Initial state - var clickAtEdge = differenceWithThisHandle === 100 && smallestDifference === 100; - // Difference with this handle is smaller than the previously checked handle - var isCloser = differenceWithThisHandle < smallestDifference; - var isCloserAfter = differenceWithThisHandle <= smallestDifference && clickedPosition > handlePosition; - if (isCloser || isCloserAfter || clickAtEdge) { - handleNumber = index; - smallestDifference = differenceWithThisHandle; - } - }); - return handleNumber; - } - // Fire 'end' when a mouse or pen leaves the document. - function documentLeave(event, data) { - if (event.type === "mouseout" && - event.target.nodeName === "HTML" && - event.relatedTarget === null) { - eventEnd(event, data); - } - } - // Handle movement on document for handle and range drag. - function eventMove(event, data) { - // Fix #498 - // Check value of .buttons in 'start' to work around a bug in IE10 mobile (data.buttonsProperty). - // https://connect.microsoft.com/IE/feedback/details/927005/mobile-ie10-windows-phone-buttons-property-of-pointermove-event-always-zero - // IE9 has .buttons and .which zero on mousemove. - // Firefox breaks the spec MDN defines. - if (navigator.appVersion.indexOf("MSIE 9") === -1 && event.buttons === 0 && data.buttonsProperty !== 0) { - return eventEnd(event, data); - } - // Check if we are moving up or down - var movement = (options.dir ? -1 : 1) * (event.calcPoint - data.startCalcPoint); - // Convert the movement into a percentage of the slider width/height - var proposal = (movement * 100) / data.baseSize; - moveHandles(movement > 0, proposal, data.locations, data.handleNumbers, data.connect); - } - // Unbind move events on document, call callbacks. - function eventEnd(event, data) { - // The handle is no longer active, so remove the class. - if (data.handle) { - removeClass(data.handle, options.cssClasses.active); - scope_ActiveHandlesCount -= 1; - } - // Unbind the move and end events, which are added on 'start'. - data.listeners.forEach(function (c) { - scope_DocumentElement.removeEventListener(c[0], c[1]); - }); - if (scope_ActiveHandlesCount === 0) { - // Remove dragging class. - removeClass(scope_Target, options.cssClasses.drag); - setZindex(); - // Remove cursor styles and text-selection events bound to the body. - if (event.cursor) { - scope_Body.style.cursor = ""; - scope_Body.removeEventListener("selectstart", preventDefault); - } - } - if (options.events.smoothSteps) { - data.handleNumbers.forEach(function (handleNumber) { - setHandle(handleNumber, scope_Locations[handleNumber], true, true, false, false); - }); - data.handleNumbers.forEach(function (handleNumber) { - fireEvent("update", handleNumber); - }); - } - data.handleNumbers.forEach(function (handleNumber) { - fireEvent("change", handleNumber); - fireEvent("set", handleNumber); - fireEvent("end", handleNumber); - }); - } - // Bind move events on document. - function eventStart(event, data) { - // Ignore event if any handle is disabled - if (data.handleNumbers.some(isHandleDisabled)) { - return; - } - var handle; - if (data.handleNumbers.length === 1) { - var handleOrigin = scope_Handles[data.handleNumbers[0]]; - handle = handleOrigin.children[0]; - scope_ActiveHandlesCount += 1; - // Mark the handle as 'active' so it can be styled. - addClass(handle, options.cssClasses.active); - } - // A drag should never propagate up to the 'tap' event. - event.stopPropagation(); - // Record the event listeners. - var listeners = []; - // Attach the move and end events. - var moveEvent = attachEvent(actions.move, scope_DocumentElement, eventMove, { - // The event target has changed so we need to propagate the original one so that we keep - // relying on it to extract target touches. - target: event.target, - handle: handle, - connect: data.connect, - listeners: listeners, - startCalcPoint: event.calcPoint, - baseSize: baseSize(), - pageOffset: event.pageOffset, - handleNumbers: data.handleNumbers, - buttonsProperty: event.buttons, - locations: scope_Locations.slice(), - }); - var endEvent = attachEvent(actions.end, scope_DocumentElement, eventEnd, { - target: event.target, - handle: handle, - listeners: listeners, - doNotReject: true, - handleNumbers: data.handleNumbers, - }); - var outEvent = attachEvent("mouseout", scope_DocumentElement, documentLeave, { - target: event.target, - handle: handle, - listeners: listeners, - doNotReject: true, - handleNumbers: data.handleNumbers, - }); - // We want to make sure we pushed the listeners in the listener list rather than creating - // a new one as it has already been passed to the event handlers. - listeners.push.apply(listeners, moveEvent.concat(endEvent, outEvent)); - // Text selection isn't an issue on touch devices, - // so adding cursor styles can be skipped. - if (event.cursor) { - // Prevent the 'I' cursor and extend the range-drag cursor. - scope_Body.style.cursor = getComputedStyle(event.target).cursor; - // Mark the target with a dragging state. - if (scope_Handles.length > 1) { - addClass(scope_Target, options.cssClasses.drag); - } - // Prevent text selection when dragging the handles. - // In noUiSlider <= 9.2.0, this was handled by calling preventDefault on mouse/touch start/move, - // which is scroll blocking. The selectstart event is supported by FireFox starting from version 52, - // meaning the only holdout is iOS Safari. This doesn't matter: text selection isn't triggered there. - // The 'cursor' flag is false. - // See: http://caniuse.com/#search=selectstart - scope_Body.addEventListener("selectstart", preventDefault, false); - } - data.handleNumbers.forEach(function (handleNumber) { - fireEvent("start", handleNumber); - }); - } - // Move closest handle to tapped location. - function eventTap(event) { - // The tap event shouldn't propagate up - event.stopPropagation(); - var proposal = calcPointToPercentage(event.calcPoint); - var handleNumber = getClosestHandle(proposal); - // Tackle the case that all handles are 'disabled'. - if (handleNumber === false) { - return; - } - // Flag the slider as it is now in a transitional state. - // Transition takes a configurable amount of ms (default 300). Re-enable the slider after that. - if (!options.events.snap) { - addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration); - } - setHandle(handleNumber, proposal, true, true); - setZindex(); - fireEvent("slide", handleNumber, true); - fireEvent("update", handleNumber, true); - if (!options.events.snap) { - fireEvent("change", handleNumber, true); - fireEvent("set", handleNumber, true); - } - else { - eventStart(event, { handleNumbers: [handleNumber] }); - } - } - // Fires a 'hover' event for a hovered mouse/pen position. - function eventHover(event) { - var proposal = calcPointToPercentage(event.calcPoint); - var to = scope_Spectrum.getStep(proposal); - var value = scope_Spectrum.fromStepping(to); - Object.keys(scope_Events).forEach(function (targetEvent) { - if ("hover" === targetEvent.split(".")[0]) { - scope_Events[targetEvent].forEach(function (callback) { - callback.call(scope_Self, value); - }); - } - }); - } - // Handles keydown on focused handles - // Don't move the document when pressing arrow keys on focused handles - function eventKeydown(event, handleNumber) { - if (isSliderDisabled() || isHandleDisabled(handleNumber)) { - return false; - } - var horizontalKeys = ["Left", "Right"]; - var verticalKeys = ["Down", "Up"]; - var largeStepKeys = ["PageDown", "PageUp"]; - var edgeKeys = ["Home", "End"]; - if (options.dir && !options.ort) { - // On an right-to-left slider, the left and right keys act inverted - horizontalKeys.reverse(); - } - else if (options.ort && !options.dir) { - // On a top-to-bottom slider, the up and down keys act inverted - verticalKeys.reverse(); - largeStepKeys.reverse(); - } - // Strip "Arrow" for IE compatibility. https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key - var key = event.key.replace("Arrow", ""); - var isLargeDown = key === largeStepKeys[0]; - var isLargeUp = key === largeStepKeys[1]; - var isDown = key === verticalKeys[0] || key === horizontalKeys[0] || isLargeDown; - var isUp = key === verticalKeys[1] || key === horizontalKeys[1] || isLargeUp; - var isMin = key === edgeKeys[0]; - var isMax = key === edgeKeys[1]; - if (!isDown && !isUp && !isMin && !isMax) { - return true; - } - event.preventDefault(); - var to; - if (isUp || isDown) { - var direction = isDown ? 0 : 1; - var steps = getNextStepsForHandle(handleNumber); - var step = steps[direction]; - // At the edge of a slider, do nothing - if (step === null) { - return false; - } - // No step set, use the default of 10% of the sub-range - if (step === false) { - step = scope_Spectrum.getDefaultStep(scope_Locations[handleNumber], isDown, options.keyboardDefaultStep); - } - if (isLargeUp || isLargeDown) { - step *= options.keyboardPageMultiplier; - } - else { - step *= options.keyboardMultiplier; - } - // Step over zero-length ranges (#948); - step = Math.max(step, 0.0000001); - // Decrement for down steps - step = (isDown ? -1 : 1) * step; - to = scope_Values[handleNumber] + step; - } - else if (isMax) { - // End key - to = options.spectrum.xVal[options.spectrum.xVal.length - 1]; - } - else { - // Home key - to = options.spectrum.xVal[0]; - } - setHandle(handleNumber, scope_Spectrum.toStepping(to), true, true); - fireEvent("slide", handleNumber); - fireEvent("update", handleNumber); - fireEvent("change", handleNumber); - fireEvent("set", handleNumber); - return false; - } - // Attach events to several slider parts. - function bindSliderEvents(behaviour) { - // Attach the standard drag event to the handles. - if (!behaviour.fixed) { - scope_Handles.forEach(function (handle, index) { - // These events are only bound to the visual handle - // element, not the 'real' origin element. - attachEvent(actions.start, handle.children[0], eventStart, { - handleNumbers: [index], - }); - }); - } - // Attach the tap event to the slider base. - if (behaviour.tap) { - attachEvent(actions.start, scope_Base, eventTap, {}); - } - // Fire hover events - if (behaviour.hover) { - attachEvent(actions.move, scope_Base, eventHover, { - hover: true, - }); - } - // Make the range draggable. - if (behaviour.drag) { - scope_Connects.forEach(function (connect, index) { - if (connect === false || index === 0 || index === scope_Connects.length - 1) { - return; - } - var handleBefore = scope_Handles[index - 1]; - var handleAfter = scope_Handles[index]; - var eventHolders = [connect]; - var handlesToDrag = [handleBefore, handleAfter]; - var handleNumbersToDrag = [index - 1, index]; - addClass(connect, options.cssClasses.draggable); - // When the range is fixed, the entire range can - // be dragged by the handles. The handle in the first - // origin will propagate the start event upward, - // but it needs to be bound manually on the other. - if (behaviour.fixed) { - eventHolders.push(handleBefore.children[0]); - eventHolders.push(handleAfter.children[0]); - } - if (behaviour.dragAll) { - handlesToDrag = scope_Handles; - handleNumbersToDrag = scope_HandleNumbers; - } - eventHolders.forEach(function (eventHolder) { - attachEvent(actions.start, eventHolder, eventStart, { - handles: handlesToDrag, - handleNumbers: handleNumbersToDrag, - connect: connect, - }); - }); - }); - } - } - // Attach an event to this slider, possibly including a namespace - function bindEvent(namespacedEvent, callback) { - scope_Events[namespacedEvent] = scope_Events[namespacedEvent] || []; - scope_Events[namespacedEvent].push(callback); - // If the event bound is 'update,' fire it immediately for all handles. - if (namespacedEvent.split(".")[0] === "update") { - scope_Handles.forEach(function (a, index) { - fireEvent("update", index); - }); - } - } - function isInternalNamespace(namespace) { - return namespace === INTERNAL_EVENT_NS.aria || namespace === INTERNAL_EVENT_NS.tooltips; - } - // Undo attachment of event - function removeEvent(namespacedEvent) { - var event = namespacedEvent && namespacedEvent.split(".")[0]; - var namespace = event ? namespacedEvent.substring(event.length) : namespacedEvent; - Object.keys(scope_Events).forEach(function (bind) { - var tEvent = bind.split(".")[0]; - var tNamespace = bind.substring(tEvent.length); - if ((!event || event === tEvent) && (!namespace || namespace === tNamespace)) { - // only delete protected internal event if intentional - if (!isInternalNamespace(tNamespace) || namespace === tNamespace) { - delete scope_Events[bind]; - } - } - }); - } - // External event handling - function fireEvent(eventName, handleNumber, tap) { - Object.keys(scope_Events).forEach(function (targetEvent) { - var eventType = targetEvent.split(".")[0]; - if (eventName === eventType) { - scope_Events[targetEvent].forEach(function (callback) { - callback.call( - // Use the slider public API as the scope ('this') - scope_Self, - // Return values as array, so arg_1[arg_2] is always valid. - scope_Values.map(options.format.to), - // Handle index, 0 or 1 - handleNumber, - // Un-formatted slider values - scope_Values.slice(), - // Event is fired by tap, true or false - tap || false, - // Left offset of the handle, in relation to the slider - scope_Locations.slice(), - // add the slider public API to an accessible parameter when this is unavailable - scope_Self); - }); - } - }); - } - // Split out the handle positioning logic so the Move event can use it, too - function checkHandlePosition(reference, handleNumber, to, lookBackward, lookForward, getValue, smoothSteps) { - var distance; - // For sliders with multiple handles, limit movement to the other handle. - // Apply the margin option by adding it to the handle positions. - if (scope_Handles.length > 1 && !options.events.unconstrained) { - if (lookBackward && handleNumber > 0) { - distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.margin, false); - to = Math.max(to, distance); - } - if (lookForward && handleNumber < scope_Handles.length - 1) { - distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.margin, true); - to = Math.min(to, distance); - } - } - // The limit option has the opposite effect, limiting handles to a - // maximum distance from another. Limit must be > 0, as otherwise - // handles would be unmovable. - if (scope_Handles.length > 1 && options.limit) { - if (lookBackward && handleNumber > 0) { - distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber - 1], options.limit, false); - to = Math.min(to, distance); - } - if (lookForward && handleNumber < scope_Handles.length - 1) { - distance = scope_Spectrum.getAbsoluteDistance(reference[handleNumber + 1], options.limit, true); - to = Math.max(to, distance); - } - } - // The padding option keeps the handles a certain distance from the - // edges of the slider. Padding must be > 0. - if (options.padding) { - if (handleNumber === 0) { - distance = scope_Spectrum.getAbsoluteDistance(0, options.padding[0], false); - to = Math.max(to, distance); - } - if (handleNumber === scope_Handles.length - 1) { - distance = scope_Spectrum.getAbsoluteDistance(100, options.padding[1], true); - to = Math.min(to, distance); - } - } - if (!smoothSteps) { - to = scope_Spectrum.getStep(to); - } - // Limit percentage to the 0 - 100 range - to = limit(to); - // Return false if handle can't move - if (to === reference[handleNumber] && !getValue) { - return false; - } - return to; - } - // Uses slider orientation to create CSS rules. a = base value; - function inRuleOrder(v, a) { - var o = options.ort; - return (o ? a : v) + ", " + (o ? v : a); - } - // Moves handle(s) by a percentage - // (bool, % to move, [% where handle started, ...], [index in scope_Handles, ...]) - function moveHandles(upward, proposal, locations, handleNumbers, connect) { - var proposals = locations.slice(); - // Store first handle now, so we still have it in case handleNumbers is reversed - var firstHandle = handleNumbers[0]; - var smoothSteps = options.events.smoothSteps; - var b = [!upward, upward]; - var f = [upward, !upward]; - // Copy handleNumbers so we don't change the dataset - handleNumbers = handleNumbers.slice(); - // Check to see which handle is 'leading'. - // If that one can't move the second can't either. - if (upward) { - handleNumbers.reverse(); - } - // Step 1: get the maximum percentage that any of the handles can move - if (handleNumbers.length > 1) { - handleNumbers.forEach(function (handleNumber, o) { - var to = checkHandlePosition(proposals, handleNumber, proposals[handleNumber] + proposal, b[o], f[o], false, smoothSteps); - // Stop if one of the handles can't move. - if (to === false) { - proposal = 0; - } - else { - proposal = to - proposals[handleNumber]; - proposals[handleNumber] = to; - } - }); - } - // If using one handle, check backward AND forward - else { - b = f = [true]; - } - var state = false; - // Step 2: Try to set the handles with the found percentage - handleNumbers.forEach(function (handleNumber, o) { - state = - setHandle(handleNumber, locations[handleNumber] + proposal, b[o], f[o], false, smoothSteps) || state; - }); - // Step 3: If a handle moved, fire events - if (state) { - handleNumbers.forEach(function (handleNumber) { - fireEvent("update", handleNumber); - fireEvent("slide", handleNumber); - }); - // If target is a connect, then fire drag event - if (connect != undefined) { - fireEvent("drag", firstHandle); - } - } - } - // Takes a base value and an offset. This offset is used for the connect bar size. - // In the initial design for this feature, the origin element was 1% wide. - // Unfortunately, a rounding bug in Chrome makes it impossible to implement this feature - // in this manner: https://bugs.chromium.org/p/chromium/issues/detail?id=798223 - function transformDirection(a, b) { - return options.dir ? 100 - a - b : a; - } - // Updates scope_Locations and scope_Values, updates visual state - function updateHandlePosition(handleNumber, to) { - // Update locations. - scope_Locations[handleNumber] = to; - // Convert the value to the slider stepping/range. - scope_Values[handleNumber] = scope_Spectrum.fromStepping(to); - var translation = transformDirection(to, 0) - scope_DirOffset; - var translateRule = "translate(" + inRuleOrder(translation + "%", "0") + ")"; - scope_Handles[handleNumber].style[options.transformRule] = translateRule; - updateConnect(handleNumber); - updateConnect(handleNumber + 1); - } - // Handles before the slider middle are stacked later = higher, - // Handles after the middle later is lower - // [[7] [8] .......... | .......... [5] [4] - function setZindex() { - scope_HandleNumbers.forEach(function (handleNumber) { - var dir = scope_Locations[handleNumber] > 50 ? -1 : 1; - var zIndex = 3 + (scope_Handles.length + dir * handleNumber); - scope_Handles[handleNumber].style.zIndex = String(zIndex); - }); - } - // Test suggested values and apply margin, step. - // if exactInput is true, don't run checkHandlePosition, then the handle can be placed in between steps (#436) - function setHandle(handleNumber, to, lookBackward, lookForward, exactInput, smoothSteps) { - if (!exactInput) { - to = checkHandlePosition(scope_Locations, handleNumber, to, lookBackward, lookForward, false, smoothSteps); - } - if (to === false) { - return false; - } - updateHandlePosition(handleNumber, to); - return true; - } - // Updates style attribute for connect nodes - function updateConnect(index) { - // Skip connects set to false - if (!scope_Connects[index]) { - return; - } - var l = 0; - var h = 100; - if (index !== 0) { - l = scope_Locations[index - 1]; - } - if (index !== scope_Connects.length - 1) { - h = scope_Locations[index]; - } - // We use two rules: - // 'translate' to change the left/top offset; - // 'scale' to change the width of the element; - // As the element has a width of 100%, a translation of 100% is equal to 100% of the parent (.noUi-base) - var connectWidth = h - l; - var translateRule = "translate(" + inRuleOrder(transformDirection(l, connectWidth) + "%", "0") + ")"; - var scaleRule = "scale(" + inRuleOrder(connectWidth / 100, "1") + ")"; - scope_Connects[index].style[options.transformRule] = - translateRule + " " + scaleRule; - } - // Parses value passed to .set method. Returns current value if not parse-able. - function resolveToValue(to, handleNumber) { - // Setting with null indicates an 'ignore'. - // Inputting 'false' is invalid. - if (to === null || to === false || to === undefined) { - return scope_Locations[handleNumber]; - } - // If a formatted number was passed, attempt to decode it. - if (typeof to === "number") { - to = String(to); - } - to = options.format.from(to); - if (to !== false) { - to = scope_Spectrum.toStepping(to); - } - // If parsing the number failed, use the current value. - if (to === false || isNaN(to)) { - return scope_Locations[handleNumber]; - } - return to; - } - // Set the slider value. - function valueSet(input, fireSetEvent, exactInput) { - var values = asArray(input); - var isInit = scope_Locations[0] === undefined; - // Event fires by default - fireSetEvent = fireSetEvent === undefined ? true : fireSetEvent; - // Animation is optional. - // Make sure the initial values were set before using animated placement. - if (options.animate && !isInit) { - addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration); - } - // First pass, without lookAhead but with lookBackward. Values are set from left to right. - scope_HandleNumbers.forEach(function (handleNumber) { - setHandle(handleNumber, resolveToValue(values[handleNumber], handleNumber), true, false, exactInput); - }); - var i = scope_HandleNumbers.length === 1 ? 0 : 1; - // Spread handles evenly across the slider if the range has no size (min=max) - if (isInit && scope_Spectrum.hasNoSize()) { - exactInput = true; - scope_Locations[0] = 0; - if (scope_HandleNumbers.length > 1) { - var space_1 = 100 / (scope_HandleNumbers.length - 1); - scope_HandleNumbers.forEach(function (handleNumber) { - scope_Locations[handleNumber] = handleNumber * space_1; - }); - } - } - // Secondary passes. Now that all base values are set, apply constraints. - // Iterate all handles to ensure constraints are applied for the entire slider (Issue #1009) - for (; i < scope_HandleNumbers.length; ++i) { - scope_HandleNumbers.forEach(function (handleNumber) { - setHandle(handleNumber, scope_Locations[handleNumber], true, true, exactInput); - }); - } - setZindex(); - scope_HandleNumbers.forEach(function (handleNumber) { - fireEvent("update", handleNumber); - // Fire the event only for handles that received a new value, as per #579 - if (values[handleNumber] !== null && fireSetEvent) { - fireEvent("set", handleNumber); - } - }); - } - // Reset slider to initial values - function valueReset(fireSetEvent) { - valueSet(options.start, fireSetEvent); - } - // Set value for a single handle - function valueSetHandle(handleNumber, value, fireSetEvent, exactInput) { - // Ensure numeric input - handleNumber = Number(handleNumber); - if (!(handleNumber >= 0 && handleNumber < scope_HandleNumbers.length)) { - throw new Error("noUiSlider: invalid handle number, got: " + handleNumber); - } - // Look both backward and forward, since we don't want this handle to "push" other handles (#960); - // The exactInput argument can be used to ignore slider stepping (#436) - setHandle(handleNumber, resolveToValue(value, handleNumber), true, true, exactInput); - fireEvent("update", handleNumber); - if (fireSetEvent) { - fireEvent("set", handleNumber); - } - } - // Get the slider value. - function valueGet(unencoded) { - if (unencoded === void 0) { unencoded = false; } - if (unencoded) { - // return a copy of the raw values - return scope_Values.length === 1 ? scope_Values[0] : scope_Values.slice(0); - } - var values = scope_Values.map(options.format.to); - // If only one handle is used, return a single value. - if (values.length === 1) { - return values[0]; - } - return values; - } - // Removes classes from the root and empties it. - function destroy() { - // remove protected internal listeners - removeEvent(INTERNAL_EVENT_NS.aria); - removeEvent(INTERNAL_EVENT_NS.tooltips); - Object.keys(options.cssClasses).forEach(function (key) { - removeClass(scope_Target, options.cssClasses[key]); - }); - while (scope_Target.firstChild) { - scope_Target.removeChild(scope_Target.firstChild); - } - delete scope_Target.noUiSlider; - } - function getNextStepsForHandle(handleNumber) { - var location = scope_Locations[handleNumber]; - var nearbySteps = scope_Spectrum.getNearbySteps(location); - var value = scope_Values[handleNumber]; - var increment = nearbySteps.thisStep.step; - var decrement = null; - // If snapped, directly use defined step value - if (options.snap) { - return [ - value - nearbySteps.stepBefore.startValue || null, - nearbySteps.stepAfter.startValue - value || null, - ]; - } - // If the next value in this step moves into the next step, - // the increment is the start of the next step - the current value - if (increment !== false) { - if (value + increment > nearbySteps.stepAfter.startValue) { - increment = nearbySteps.stepAfter.startValue - value; - } - } - // If the value is beyond the starting point - if (value > nearbySteps.thisStep.startValue) { - decrement = nearbySteps.thisStep.step; - } - else if (nearbySteps.stepBefore.step === false) { - decrement = false; - } - // If a handle is at the start of a step, it always steps back into the previous step first - else { - decrement = value - nearbySteps.stepBefore.highestStep; - } - // Now, if at the slider edges, there is no in/decrement - if (location === 100) { - increment = null; - } - else if (location === 0) { - decrement = null; - } - // As per #391, the comparison for the decrement step can have some rounding issues. - var stepDecimals = scope_Spectrum.countStepDecimals(); - // Round per #391 - if (increment !== null && increment !== false) { - increment = Number(increment.toFixed(stepDecimals)); - } - if (decrement !== null && decrement !== false) { - decrement = Number(decrement.toFixed(stepDecimals)); - } - return [decrement, increment]; - } - // Get the current step size for the slider. - function getNextSteps() { - return scope_HandleNumbers.map(getNextStepsForHandle); - } - // Updatable: margin, limit, padding, step, range, animate, snap - function updateOptions(optionsToUpdate, fireSetEvent) { - // Spectrum is created using the range, snap, direction and step options. - // 'snap' and 'step' can be updated. - // If 'snap' and 'step' are not passed, they should remain unchanged. - var v = valueGet(); - var updateAble = [ - "margin", - "limit", - "padding", - "range", - "animate", - "snap", - "step", - "format", - "pips", - "tooltips", - ]; - // Only change options that we're actually passed to update. - updateAble.forEach(function (name) { - // Check for undefined. null removes the value. - if (optionsToUpdate[name] !== undefined) { - originalOptions[name] = optionsToUpdate[name]; - } - }); - var newOptions = testOptions(originalOptions); - // Load new options into the slider state - updateAble.forEach(function (name) { - if (optionsToUpdate[name] !== undefined) { - options[name] = newOptions[name]; - } - }); - scope_Spectrum = newOptions.spectrum; - // Limit, margin and padding depend on the spectrum but are stored outside of it. (#677) - options.margin = newOptions.margin; - options.limit = newOptions.limit; - options.padding = newOptions.padding; - // Update pips, removes existing. - if (options.pips) { - pips(options.pips); - } - else { - removePips(); - } - // Update tooltips, removes existing. - if (options.tooltips) { - tooltips(); - } - else { - removeTooltips(); - } - // Invalidate the current positioning so valueSet forces an update. - scope_Locations = []; - valueSet(isSet(optionsToUpdate.start) ? optionsToUpdate.start : v, fireSetEvent); - } - // Initialization steps - function setupSlider() { - // Create the base element, initialize HTML and set classes. - // Add handles and connect elements. - scope_Base = addSlider(scope_Target); - addElements(options.connect, scope_Base); - // Attach user events. - bindSliderEvents(options.events); - // Use the public value method to set the start values. - valueSet(options.start); - if (options.pips) { - pips(options.pips); - } - if (options.tooltips) { - tooltips(); - } - aria(); - } - setupSlider(); - var scope_Self = { - destroy: destroy, - steps: getNextSteps, - on: bindEvent, - off: removeEvent, - get: valueGet, - set: valueSet, - setHandle: valueSetHandle, - reset: valueReset, - disable: disable, - enable: enable, - // Exposed for unit testing, don't use this in your application. - __moveHandles: function (upward, proposal, handleNumbers) { - moveHandles(upward, proposal, scope_Locations, handleNumbers); - }, - options: originalOptions, - updateOptions: updateOptions, - target: scope_Target, - removePips: removePips, - removeTooltips: removeTooltips, - getPositions: function () { - return scope_Locations.slice(); - }, - getTooltips: function () { - return scope_Tooltips; - }, - getOrigins: function () { - return scope_Handles; - }, - pips: pips, // Issue #594 - }; - return scope_Self; - } - // Run the standard initializer - function initialize(target, originalOptions) { - if (!target || !target.nodeName) { - throw new Error("noUiSlider: create requires a single element, got: " + target); - } - // Throw an error if the slider was already initialized. - if (target.noUiSlider) { - throw new Error("noUiSlider: Slider was already initialized."); - } - // Test the options and create the slider environment; - var options = testOptions(originalOptions); - var api = scope(target, options, originalOptions); - target.noUiSlider = api; - return api; - } - var nouislider = { - // Exposed for unit testing, don't use this in your application. - __spectrum: Spectrum, - // A reference to the default classes, allows global changes. - // Use the cssClasses option for changes to one slider. - cssClasses: cssClasses, - create: initialize, - }; - - exports.create = initialize; - exports.cssClasses = cssClasses; - exports["default"] = nouislider; - - Object.defineProperty(exports, '__esModule', { value: true }); - -})); diff --git a/static/js/nouislider.min.js b/static/js/nouislider.min.js deleted file mode 100644 index dc46047..0000000 --- a/static/js/nouislider.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){function t(t){return t.split("").reverse().join("")}function e(t,e,n){if((t[e]||t[n])&&t[e]===t[n])throw Error(e)}function n(e,n,r,i,o,s,a,u,l,c,f,p){a=p;var d,h=f="";return s&&(p=s(p)),!("number"!=typeof p||!isFinite(p))&&(e&&0===parseFloat(p.toFixed(e))&&(p=0),0>p&&(d=!0,p=Math.abs(p)),e&&(s=Math.pow(10,e),p=(Math.round(p*s)/s).toFixed(e)),-1!==(p=p.toString()).indexOf(".")&&(e=p.split("."),p=e[0],r&&(f=r+e[1])),n&&(p=t(p).match(/.{1,3}/g),p=t(p.join(t(n)))),d&&u&&(h+=u),i&&(h+=i),d&&l&&(h+=l),h=h+p+f,o&&(h+=o),c&&(h=c(h,a)),h)}function r(t,e,n,r,i,o,s,a,u,l,c,f){var p;return t="",c&&(f=c(f)),!(!f||"string"!=typeof f)&&(a&&f.substring(0,a.length)===a&&(f=f.replace(a,""),p=!0),r&&f.substring(0,r.length)===r&&(f=f.replace(r,"")),u&&f.substring(0,u.length)===u&&(f=f.replace(u,""),p=!0),i&&f.slice(-1*i.length)===i&&(f=f.slice(0,-1*i.length)),e&&(f=f.split(e).join("")),n&&(f=f.replace(n,".")),p&&(t+="-"),t=Number((t+f).replace(/[^0-9\.\-.]/g,"")),s&&(t=s(t)),!("number"!=typeof t||!isFinite(t))&&t)}function i(t){var n,r,i,o={};for(n=0;ni&&(o[r]=i):"encoder"===r||"decoder"===r||"edit"===r||"undo"===r?"function"==typeof i&&(o[r]=i):"string"==typeof i&&(o[r]=i);return e(o,"mark","thousand"),e(o,"prefix","negative"),e(o,"prefix","negativeBefore"),o}function o(t,e,n){var r,i=[];for(r=0;r0&&(l(t,e),setTimeout(function(){c(t,e)},n))}function s(t){return Math.max(Math.min(t,100),0)}function a(t){return Array.isArray(t)?t:[t]}function u(t){var e=(t=String(t)).split(".");return e.length>1?e[1].length:0}function l(t,e){t.classList?t.classList.add(e):t.className+=" "+e}function c(t,e){t.classList?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\b)"+e.split(" ").join("|")+"(\\b|$)","gi")," ")}function f(t,e){return t.classList?t.classList.contains(e):new RegExp("\\b"+e+"\\b").test(t.className)}function p(){var t=void 0!==window.pageXOffset,e="CSS1Compat"===(document.compatMode||"");return{x:t?window.pageXOffset:e?document.documentElement.scrollLeft:document.body.scrollLeft,y:t?window.pageYOffset:e?document.documentElement.scrollTop:document.body.scrollTop}}function d(){return window.navigator.pointerEnabled?{start:"pointerdown",move:"pointermove",end:"pointerup"}:window.navigator.msPointerEnabled?{start:"MSPointerDown",move:"MSPointerMove",end:"MSPointerUp"}:{start:"mousedown touchstart",move:"mousemove touchmove",end:"mouseup touchend"}}function h(t,e){return 100/(e-t)}function m(t,e){return 100*e/(t[1]-t[0])}function g(t,e){return m(t,t[0]<0?e+Math.abs(t[0]):e-t[0])}function v(t,e){return e*(t[1]-t[0])/100+t[0]}function b(t,e){for(var n=1;t>=e[n];)n+=1;return n}function w(t,e,n){if(n>=t.slice(-1)[0])return 100;var r,i,o,s,a=b(n,t);return r=t[a-1],i=t[a],o=e[a-1],s=e[a],o+g([r,i],n)/h(o,s)}function S(t,e,n){if(n>=100)return t.slice(-1)[0];var r,i,o,s,a=b(n,e);return r=t[a-1],i=t[a],o=e[a-1],s=e[a],v([r,i],(n-o)*h(o,s))}function x(t,e,r,i){if(100===i)return i;var o,s,a=b(i,t);return r?(o=t[a-1],s=t[a],i-o>(s-o)/2?s:o):e[a-1]?t[a-1]+n(i-t[a-1],e[a-1]):i}function y(t,e,n){var r;if("number"==typeof e&&(e=[e]),"[object Array]"!==Object.prototype.toString.call(e))throw new Error("noUiSlider: 'range' contains invalid value.");if(r="min"===t?0:"max"===t?100:parseFloat(t),!i(r)||!i(e[0]))throw new Error("noUiSlider: 'range' value isn't numeric.");n.xPct.push(r),n.xVal.push(e[0]),r?n.xSteps.push(!isNaN(e[1])&&e[1]):isNaN(e[1])||(n.xSteps[0]=e[1]),n.xHighestCompleteStep.push(0)}function E(t,e,n){if(!e)return!0;n.xSteps[t]=m([n.xVal[t],n.xVal[t+1]],e)/h(n.xPct[t],n.xPct[t+1]);var r=(n.xVal[t+1]-n.xVal[t])/n.xNumSteps[t],i=Math.ceil(Number(r.toFixed(3))-1),o=n.xVal[t]+n.xNumSteps[t]*i;n.xHighestCompleteStep[t]=o}function C(t,e,n,r){this.xPct=[],this.xVal=[],this.xSteps=[r||!1],this.xNumSteps=[!1],this.xHighestCompleteStep=[],this.snap=e,this.direction=n;var i,o=[];for(i in t)t.hasOwnProperty(i)&&o.push([t[i],i]);for(o.length&&"object"==typeof o[0][0]?o.sort(function(t,e){return t[0][0]-e[0][0]}):o.sort(function(t,e){return t[0]-e[0]}),i=0;i=50)throw new Error("noUiSlider: 'padding' option must be less than half the range.")}}function z(t,e){switch(e){case"ltr":t.dir=0;break;case"rtl":t.dir=1;break;default:throw new Error("noUiSlider: 'direction' option was not recognized.")}}function H(t,e){if("string"!=typeof e)throw new Error("noUiSlider: 'behaviour' must be a string containing options.");var n=e.indexOf("tap")>=0,r=e.indexOf("drag")>=0,i=e.indexOf("fixed")>=0,o=e.indexOf("snap")>=0,s=e.indexOf("hover")>=0;if(i){if(2!==t.handles)throw new Error("noUiSlider: 'fixed' behaviour must be used with 2 handles");L(t,t.start[1]-t.start[0])}t.events={tap:n||o,drag:r,fixed:i,snap:o,hover:s}}function D(t,e){if(!1!==e)if(!0===e){t.tooltips=[];for(var n=0;n-1?1:"steps"===n?2:0,!s&&u&&(m=0),f===S&&l||(o[d.toFixed(5)]=[f,m]),c=d}}),o}function w(t,e,n){function r(t,e){var n=e===i.cssClasses.value,r=n?p:d,o=n?c:f;return e+" "+r[i.ort]+" "+o[t]}function o(t,e,n){return'class="'+r(n[1],e)+'" style="'+i.style+": "+t+'%"'}function s(t,r){r[1]=r[1]&&e?e(r[0],r[1]):r[1],u+="
",r[1]&&(u+="
"+n.to(r[0])+"
")}var a=document.createElement("div"),u="",c=[i.cssClasses.valueNormal,i.cssClasses.valueLarge,i.cssClasses.valueSub],f=[i.cssClasses.markerNormal,i.cssClasses.markerLarge,i.cssClasses.markerSub],p=[i.cssClasses.valueHorizontal,i.cssClasses.valueVertical],d=[i.cssClasses.markerHorizontal,i.cssClasses.markerVertical];return l(a,i.cssClasses.pips),l(a,0===i.ort?i.cssClasses.pipsHorizontal:i.cssClasses.pipsVertical),Object.keys(t).forEach(function(e){s(e,t[e])}),a.innerHTML=u,a}function S(t){var e=t.mode,n=t.density||1,r=t.filter||!1,i=b(n,e,v(e,t.values||!1,t.stepped||!1)),o=t.format||{to:Math.round};return J.appendChild(w(i,r,o))}function x(){var t=I.getBoundingClientRect(),e="offset"+["Width","Height"][i.ort];return 0===i.ort?t.width||I[e]:t.height||I[e]}function y(t,e,n,r){var o=function(e){return!J.hasAttribute("disabled")&&(!f(J,i.cssClasses.tap)&&(!!(e=E(e,r.pageOffset))&&(!(t===G.start&&void 0!==e.buttons&&e.buttons>1)&&((!r.hover||!e.buttons)&&(e.calcPoint=e.points[i.ort],void n(e,r))))))},s=[];return t.split(" ").forEach(function(t){e.addEventListener(t,o,!1),s.push([t,o])}),s}function E(t,e){t.preventDefault();var n,r,i=0===t.type.indexOf("touch"),o=0===t.type.indexOf("mouse"),s=0===t.type.indexOf("pointer");if(0===t.type.indexOf("MSPointer")&&(s=!0),i){if(t.touches.length>1)return!1;n=t.changedTouches[0].pageX,r=t.changedTouches[0].pageY}return e=e||p(),(o||s)&&(n=t.clientX+e.x,r=t.clientY+e.y),t.pageOffset=e,t.points=[n,r],t.cursor=o||s,t}function C(t){var e=100*(t-r(I,i.ort))/x();return i.dir?100-e:e}function N(t){var e=100,n=!1;return _.forEach(function(r,i){if(!r.hasAttribute("disabled")){var o=Math.abs(K[i]-t);o1?r.forEach(function(t,n){var r=F(i,t,i[t]+e,o[n],s[n]);!1===r?e=0:(e=r-i[t],i[t]=r)}):o=s=[!0];var a=!1;r.forEach(function(t,r){a=D(t,n[t]+e,o[r],s[r])||a}),a&&r.forEach(function(t){M("update",t),M("slide",t)})}function M(t,e,n){Object.keys(nt).forEach(function(r){var o=r.split(".")[0];t===o&&nt[r].forEach(function(t){t.call($,et.map(i.format.to),e,et.slice(),n||!1,K.slice())})})}function P(t,e){"mouseout"===t.type&&"HTML"===t.target.nodeName&&null===t.relatedTarget&&O(t,e)}function k(t,e){if(-1===navigator.appVersion.indexOf("MSIE 9")&&0===t.buttons&&0!==e.buttonsProperty)return O(t,e);var n=(i.dir?-1:1)*(t.calcPoint-e.startCalcPoint);U(n>0,100*n/e.baseSize,e.locations,e.handleNumbers)}function O(t,e){Z&&(c(Z,i.cssClasses.active),Z=!1),t.cursor&&(document.body.style.cursor="",document.body.removeEventListener("selectstart",document.body.noUiListener)),document.documentElement.noUiListeners.forEach(function(t){document.documentElement.removeEventListener(t[0],t[1])}),c(J,i.cssClasses.drag),H(),e.handleNumbers.forEach(function(t){M("set",t),M("change",t),M("end",t)})}function V(t,e){if(1===e.handleNumbers.length){var n=_[e.handleNumbers[0]];if(n.hasAttribute("disabled"))return!1;l(Z=n.children[0],i.cssClasses.active)}t.preventDefault(),t.stopPropagation();var r=y(G.move,document.documentElement,k,{startCalcPoint:t.calcPoint,baseSize:x(),pageOffset:t.pageOffset,handleNumbers:e.handleNumbers,buttonsProperty:t.buttons,locations:K.slice()}),o=y(G.end,document.documentElement,O,{handleNumbers:e.handleNumbers}),s=y("mouseout",document.documentElement,P,{handleNumbers:e.handleNumbers});if(document.documentElement.noUiListeners=r.concat(o,s),t.cursor){document.body.style.cursor=getComputedStyle(t.target).cursor,_.length>1&&l(J,i.cssClasses.drag);var a=function(){return!1};document.body.noUiListener=a,document.body.addEventListener("selectstart",a,!1)}e.handleNumbers.forEach(function(t){M("start",t)})}function A(t){t.stopPropagation();var e=C(t.calcPoint),n=N(e);if(!1===n)return!1;i.events.snap||o(J,i.cssClasses.tap,i.animationDuration),D(n,e,!0,!0),H(),M("slide",n,!0),M("set",n,!0),M("change",n,!0),M("update",n,!0),i.events.snap&&V(t,{handleNumbers:[n]})}function L(t){var e=C(t.calcPoint),n=tt.getStep(e),r=tt.fromStepping(n);Object.keys(nt).forEach(function(t){"hover"===t.split(".")[0]&&nt[t].forEach(function(t){t.call($,r)})})}function F(t,e,n,r,o){return _.length>1&&(r&&e>0&&(n=Math.max(n,t[e-1]+i.margin)),o&&e<_.length-1&&(n=Math.min(n,t[e+1]-i.margin))),_.length>1&&i.limit&&(r&&e>0&&(n=Math.min(n,t[e-1]+i.limit)),o&&e<_.length-1&&(n=Math.max(n,t[e+1]-i.limit))),i.padding&&(0===e&&(n=Math.max(n,i.padding)),e===_.length-1&&(n=Math.min(n,100-i.padding))),n=tt.getStep(n),(n=s(n))!==t[e]&&n}function j(t){return t+"%"}function z(t,e){K[t]=e,et[t]=tt.fromStepping(e);var n=function(){_[t].style[i.style]=j(e),T(t),T(t+1)};window.requestAnimationFrame&&i.useRequestAnimationFrame?window.requestAnimationFrame(n):n()}function H(){Q.forEach(function(t){var e=K[t]>50?-1:1,n=3+(_.length+e*t);_[t].childNodes[0].style.zIndex=n})}function D(t,e,n,r){return!1!==(e=F(K,t,e,n,r))&&(z(t,e),!0)}function T(t){if(W[t]){var e=0,n=100;0!==t&&(e=K[t-1]),t!==W.length-1&&(n=K[t]),W[t].style[i.style]=j(e),W[t].style[i.styleOposite]=j(100-n)}}function q(t,e){null!==t&&!1!==t&&("number"==typeof t&&(t=String(t)),!1===(t=i.format.from(t))||isNaN(t)||D(e,tt.toStepping(t),!1,!1))}function R(t,e){var n=a(t),r=void 0===K[0];e=void 0===e||!!e,n.forEach(q),i.animate&&!r&&o(J,i.cssClasses.tap,i.animationDuration),Q.forEach(function(t){D(t,K[t],!0,!1)}),H(),Q.forEach(function(t){M("update",t),null!==n[t]&&e&&M("set",t)})}function B(){var t=et.map(i.format.to);return 1===t.length?t[0]:t}function Y(t,e){nt[t]=nt[t]||[],nt[t].push(e),"update"===t.split(".")[0]&&_.forEach(function(t,e){M("update",e)})}var I,_,W,$,G=d(),J=n,K=[],Q=[],Z=!1,tt=i.spectrum,et=[],nt={};if(J.noUiSlider)throw new Error("Slider was already initialized.");return function(e){l(e,i.cssClasses.target),0===i.dir?l(e,i.cssClasses.ltr):l(e,i.cssClasses.rtl),0===i.ort?l(e,i.cssClasses.horizontal):l(e,i.cssClasses.vertical),I=t(e,i.cssClasses.base)}(J),function(t,e){_=[],(W=[]).push(m(e,t[0]));for(var n=0;nn.stepAfter.startValue&&(i=n.stepAfter.startValue-r),o=r>n.thisStep.startValue?n.thisStep.step:!1!==n.stepBefore.step&&r-n.stepBefore.highestStep,100===t?i=null:0===t&&(o=null);var s=tt.countStepDecimals();return null!==i&&!1!==i&&(i=Number(i.toFixed(s))),null!==o&&!1!==o&&(o=Number(o.toFixed(s))),[o,i]})},on:Y,off:function(t){var e=t&&t.split(".")[0],n=e&&t.substring(e.length);Object.keys(nt).forEach(function(t){var r=t.split(".")[0],i=t.substring(r.length);e&&e!==r||n&&n!==i||delete nt[t]})},get:B,set:R,reset:function(t){R(i.start,t)},__moveHandles:function(t,e,n){U(t,e,K,n)},options:u,updateOptions:function(t,e){var n=B(),r=["margin","limit","padding","range","animate","snap","step","format"];r.forEach(function(e){void 0!==t[e]&&(u[e]=t[e])});var o=X(u);r.forEach(function(e){void 0!==t[e]&&(i[e]=o[e])}),o.spectrum.direction=tt.direction,tt=o.spectrum,i.margin=o.margin,i.limit=o.limit,i.padding=o.padding,K=[],R(t.start||n,e)},target:J,pips:S},function(t){t.fixed||_.forEach(function(t,e){y(G.start,t.children[0],V,{handleNumbers:[e]})}),t.tap&&y(G.start,I,A,{}),t.hover&&y(G.move,I,L,{hover:!0}),t.drag&&W.forEach(function(e,n){if(!1!==e&&0!==n&&n!==W.length-1){var r=_[n-1],o=_[n],s=[e];l(e,i.cssClasses.draggable),t.fixed&&(s.push(r.children[0]),s.push(o.children[0])),s.forEach(function(t){y(G.start,t,V,{handles:[r,o],handleNumbers:[n-1,n]})})}})}(i.events),R(i.start),i.pips&&S(i.pips),i.tooltips&&function(){var t=_.map(g);Y("update",function(e,n,r){if(t[n]){var o=e[n];!0!==i.tooltips[n]&&(o=i.tooltips[n].to(r[n])),t[n].innerHTML=""+o+""}})}(),$}C.prototype.getMargin=function(t){var e=this.xNumSteps[0];if(e&&t/e%1!=0)throw new Error("noUiSlider: 'limit', 'margin' and 'padding' must be divisible by step.");return 2===this.xPct.length&&m(this.xVal,t)},C.prototype.toStepping=function(t){return t=w(this.xVal,this.xPct,t)},C.prototype.fromStepping=function(t){return S(this.xVal,this.xPct,t)},C.prototype.getStep=function(t){return t=x(this.xPct,this.xSteps,this.snap,t)},C.prototype.getNearbySteps=function(t){var e=b(t,this.xPct);return{stepBefore:{startValue:this.xVal[e-2],step:this.xNumSteps[e-2],highestStep:this.xHighestCompleteStep[e-2]},thisStep:{startValue:this.xVal[e-1],step:this.xNumSteps[e-1],highestStep:this.xHighestCompleteStep[e-1]},stepAfter:{startValue:this.xVal[e-0],step:this.xNumSteps[e-0],highestStep:this.xHighestCompleteStep[e-0]}}},C.prototype.countStepDecimals=function(){var t=this.xNumSteps.map(u);return Math.max.apply(null,t)},C.prototype.convert=function(t){return this.getStep(this.toStepping(t))};var I={to:function(t){return void 0!==t&&t.toFixed(2)},from:Number};return{create:function(t,e){if(!t.nodeName)throw new Error("noUiSlider.create requires a single element.");void 0===e.tooltips&&(e.tooltips=!0);var n=Y(t,X(e,t),e);return t.noUiSlider=n,n}}}); \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index b74d569..19e8aa9 100644 --- a/templates/base.html +++ b/templates/base.html @@ -73,7 +73,6 @@ - {% block custom_js %}{% endblock %} diff --git a/templates/index.html b/templates/index.html index 98427c1..10ef92c 100644 --- a/templates/index.html +++ b/templates/index.html @@ -26,7 +26,9 @@
- + {% if 'input_url' in validation %} {% endif %} @@ -38,35 +40,40 @@
{{ _('Tree specification') }}
-
-
-
+ +
-
+
-
+
+
+
+
-
+
@@ -120,6 +127,12 @@
+
+
+ + +
+
@@ -174,7 +187,9 @@
- + {% if 'compare_url' in validation %} {% endif %} diff --git a/translations/en/LC_MESSAGES/messages.po b/translations/en/LC_MESSAGES/messages.po index 065b4f9..620cccd 100644 --- a/translations/en/LC_MESSAGES/messages.po +++ b/translations/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2024-03-13 10:26+0100\n" +"POT-Creation-Date: 2024-07-04 11:51+0200\n" "PO-Revision-Date: 2024-02-14 14:36+0100\n" "Last-Translator: FULL NAME \n" "Language-Team: en \n" @@ -47,74 +47,70 @@ msgid "Grew-match URL" msgstr "" #: app.py:115 -msgid "%DIFF" +msgid "Ratio" msgstr "" #: app.py:116 -msgid "OR" +msgid "%DIFF" msgstr "" #: app.py:117 -msgid "BIC" +msgid "OR" msgstr "" #: app.py:118 -msgid "MI" +msgid "BIC" msgstr "" #: app.py:119 -msgid "logDice" +msgid "MI" msgstr "" #: app.py:120 +msgid "logDice" +msgstr "" + +#: app.py:121 msgid "t-score" msgstr "" -#: app.py:123 +#: app.py:124 msgid "Frequency in A" msgstr "Frequency-A" -#: app.py:181 app.py:182 +#: app.py:188 app.py:189 msgid "Please insert either input url or file, not both of them." msgstr "Please insert either a file or a URL link, not both of them." -#: app.py:192 app.py:287 +#: app.py:199 app.py:280 msgid "Incorrect URL!" msgstr "" -#: app.py:194 app.py:195 +#: app.py:201 app.py:202 msgid "Please insert either input url or provide a file." msgstr "Please insert either a file or a URL link." -#: app.py:207 -msgid "Please provide information about minimum and maximum tree size." -msgstr "" - -#: app.py:211 -msgid "Tree size minimum should be smaller than tree size maximum." -msgstr "" - -#: app.py:222 +#: app.py:210 msgid "Please select at least one node type." msgstr "" -#: app.py:227 +#: app.py:215 msgid "Node option" msgstr "Node option" -#: app.py:227 +#: app.py:215 msgid "is not supported. Please enter valid options." msgstr "" -#: app.py:275 app.py:276 +#: app.py:268 app.py:269 msgid "Please insert either compare url or file, not both of them." msgstr "Please insert either a file or a URL link, not both of them." -#: app.py:299 +#: app.py:292 msgid "Please insert an Integer." msgstr "Please insert an integer number." -#: app.py:324 +#: app.py:317 msgid "" "Processing failed! Please recheck your settings, e.g. input format or head " "node description." @@ -122,15 +118,15 @@ msgstr "" "Processing failed! Please recheck your settings, e.g. input format or query " "description." -#: app.py:333 +#: app.py:326 msgid "Frequency " msgstr "" -#: app.py:333 +#: app.py:326 msgid "Frequency in A " msgstr "Frequency-A " -#: app.py:334 templates/base.html:20 templates/base.html:22 +#: app.py:327 templates/base.html:20 templates/base.html:22 #: templates/index.html:8 templates/result.html:15 msgid "code" msgstr "en" @@ -198,7 +194,9 @@ msgstr "." #: templates/about.html:19 msgid "stark_contact" -msgstr "Should you have any additional questions or require assistance with the tool, please contact kaja.dobrovoljc@ff.uni-lj.si." +msgstr "" +"Should you have any additional questions or require assistance with the " +"tool, please contact kaja.dobrovoljc@ff.uni-lj.si." #: templates/base.html:23 msgid "switch_link" @@ -236,19 +234,19 @@ msgstr "Input treebank" msgid "Upload a treebank" msgstr "Upload a treebank" -#: templates/index.html:12 templates/index.html:20 templates/index.html:160 -#: templates/index.html:167 +#: templates/index.html:12 templates/index.html:20 templates/index.html:171 +#: templates/index.html:178 msgid "in CONLL-U format" msgstr "in CONLL-U format" -#: templates/index.html:12 templates/index.html:41 templates/index.html:49 -#: templates/index.html:89 templates/index.html:104 templates/index.html:120 -#: templates/index.html:126 templates/index.html:132 templates/index.html:140 -#: templates/index.html:159 templates/index.html:160 +#: templates/index.html:12 templates/index.html:44 templates/index.html:48 +#: templates/index.html:94 templates/index.html:109 templates/index.html:125 +#: templates/index.html:131 templates/index.html:137 templates/index.html:143 +#: templates/index.html:151 templates/index.html:170 templates/index.html:171 msgid "Help" msgstr "Help" -#: templates/index.html:15 templates/index.html:163 +#: templates/index.html:15 templates/index.html:174 msgid "Browse" msgstr "Browse" @@ -256,15 +254,15 @@ msgstr "Browse" msgid "Upload" msgstr "Upload" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "Or" msgstr "Or" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "insert a URL link to a treebank in CONLL-U format" msgstr "insert a URL link to a treebank in CONLL-U format" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "Example" msgstr "Example" @@ -272,119 +270,131 @@ msgstr "Example" msgid "Tree specification" msgstr "Tree specification" -#: templates/index.html:41 +#: templates/index.html:44 msgid "Tree size" msgstr "Tree size" -#: templates/index.html:41 +#: templates/index.html:44 msgid "number of tokens in the tree" msgstr "number of tokens (words) in the tree" -#: templates/index.html:49 +#: templates/index.html:48 msgid "Node type" msgstr "Node type" -#: templates/index.html:49 +#: templates/index.html:48 msgid "token characteristics to consider" msgstr "token characteristics to consider" -#: templates/index.html:55 +#: templates/index.html:54 +msgid "No type" +msgstr "No type" + +#: templates/index.html:63 msgid "Part-of-speech" msgstr "Part-of-speech" -#: templates/index.html:64 +#: templates/index.html:69 msgid "Lemma" msgstr "Lemma" -#: templates/index.html:70 +#: templates/index.html:75 msgid "Form" msgstr "Form" -#: templates/index.html:84 +#: templates/index.html:89 msgid "Advanced settings" msgstr "Advanced settings" -#: templates/index.html:89 +#: templates/index.html:94 msgid "Labeled trees" msgstr "Labeled trees" -#: templates/index.html:89 +#: templates/index.html:94 msgid "include names of dependency relations" msgstr "include names of dependency relations" -#: templates/index.html:93 templates/index.html:108 templates/index.html:144 +#: templates/index.html:98 templates/index.html:113 templates/index.html:155 msgid "No" msgstr "No" -#: templates/index.html:96 templates/index.html:111 templates/index.html:147 +#: templates/index.html:101 templates/index.html:116 templates/index.html:158 msgid "Yes" msgstr "Yes" -#: templates/index.html:104 +#: templates/index.html:109 msgid "Fixed order" msgstr "Fixed order" -#: templates/index.html:104 +#: templates/index.html:109 msgid "differentiate trees based on surface word order" msgstr "differentiate trees based on surface word order" -#: templates/index.html:120 +#: templates/index.html:125 msgid "Head" msgstr "Head" -#: templates/index.html:120 +#: templates/index.html:125 msgid "specify potential restrictions on the head node" msgstr "specify potential restrictions on the head node" -#: templates/index.html:126 +#: templates/index.html:131 +msgid "Ignored labels" +msgstr "" + +#: templates/index.html:131 +msgid "specify the dependency labels of nodes to be ignored" +msgstr "" + +#: templates/index.html:137 msgid "Query" msgstr "" -#: templates/index.html:126 +#: templates/index.html:137 msgid "write a query. Note: Tree size attribute will be ignored!" msgstr "" -#: templates/index.html:132 +#: templates/index.html:143 msgid "Frequency threshold" msgstr "Frequency threshold" -#: templates/index.html:132 +#: templates/index.html:143 msgid "specify the minimum frequency of a tree in the treebank" msgstr "specify the minimum frequency of a tree in the treebank" -#: templates/index.html:140 +#: templates/index.html:151 msgid "Association measures" msgstr "Association measures" -#: templates/index.html:140 +#: templates/index.html:151 msgid "print MI, logDice and t-score" msgstr "print MI, logDice and t-score" -#: templates/index.html:155 +#: templates/index.html:166 msgid "Compare treebanks" msgstr "" -#: templates/index.html:159 +#: templates/index.html:170 msgid "" -"Select a reference treebank to identify key phenomena (prints the %DIFF, " +"Select a reference treebank to identify key phenomena (prints the frequency ration and the %DIFF, " "BIC and OR keyness scores)." msgstr "" "Select a reference treebank to identify key phenomena (prints the %DIFF, " "BIC and Odds Ratio scores)." -#: templates/index.html:160 templates/index.html:167 +#: templates/index.html:171 templates/index.html:178 msgid "Upload a compare corpus" msgstr "Upload a reference treebank" -#: templates/index.html:191 +#: templates/index.html:202 msgid "Submit" msgstr "Get trees" -#: templates/index.html:199 +#: templates/index.html:210 msgid "No results" msgstr "" -#: templates/index.html:200 +#: templates/index.html:211 msgid "Processing with your settings didnt produce any results!" msgstr "Processing with your settings did not produce any results." diff --git a/translations/sl/LC_MESSAGES/messages.po b/translations/sl/LC_MESSAGES/messages.po index 6f5c721..5db5744 100644 --- a/translations/sl/LC_MESSAGES/messages.po +++ b/translations/sl/LC_MESSAGES/messages.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2024-03-13 10:26+0100\n" +"POT-Creation-Date: 2024-07-04 11:51+0200\n" "PO-Revision-Date: 2024-02-14 14:36+0100\n" "Last-Translator: FULL NAME \n" "Language-Team: sl \n" @@ -47,74 +47,70 @@ msgid "Grew-match URL" msgstr "Povezava na Grew-match" #: app.py:115 -msgid "%DIFF" +msgid "Ratio" msgstr "" #: app.py:116 -msgid "OR" +msgid "%DIFF" msgstr "" #: app.py:117 -msgid "BIC" +msgid "OR" msgstr "" #: app.py:118 +msgid "BIC" +msgstr "" + +#: app.py:119 msgid "MI" msgstr "MI" -#: app.py:119 +#: app.py:120 msgid "logDice" msgstr "logDice" -#: app.py:120 +#: app.py:121 msgid "t-score" msgstr "t-test" -#: app.py:123 +#: app.py:124 msgid "Frequency in A" msgstr "Pogostost v A" -#: app.py:181 app.py:182 +#: app.py:188 app.py:189 msgid "Please insert either input url or file, not both of them." msgstr "Naložite datoteko ali vnesite povezavo URL, ne pa obojega." -#: app.py:192 app.py:287 +#: app.py:199 app.py:280 msgid "Incorrect URL!" msgstr "URL ni pravilne oblike." -#: app.py:194 app.py:195 +#: app.py:201 app.py:202 msgid "Please insert either input url or provide a file." msgstr "Naložite datoteko ali vnesite povezavo URL." -#: app.py:207 -msgid "Please provide information about minimum and maximum tree size." -msgstr "Določite najmanjše in največje število vozlišč v drevesu." - -#: app.py:211 -msgid "Tree size minimum should be smaller than tree size maximum." -msgstr "Najmanjše število vozlišč v drevesu ne sme biti večje od največjega." - -#: app.py:222 +#: app.py:210 msgid "Please select at least one node type." msgstr "Izberite vsaj eno možnost (npr. besedno vrsto)." -#: app.py:227 +#: app.py:215 msgid "Node option" msgstr "Vrsta vozlišč" -#: app.py:227 +#: app.py:215 msgid "is not supported. Please enter valid options." msgstr "vmesnik ne podpira. Vnesite eno izmed veljavnih možnosti." -#: app.py:275 app.py:276 +#: app.py:268 app.py:269 msgid "Please insert either compare url or file, not both of them." msgstr "Naložite datoteko ali vnesite povezavo URL, ne pa obojega." -#: app.py:299 +#: app.py:292 msgid "Please insert an Integer." msgstr "Vnesite celo število (npr. 3)." -#: app.py:324 +#: app.py:317 msgid "" "Processing failed! Please recheck your settings, e.g. input format or head " "node description." @@ -122,15 +118,15 @@ msgstr "" "Procesiranje ni bilo uspešno! Preverite nastavitve, kot sta format ali opis " "lastnosti jedra." -#: app.py:333 +#: app.py:326 msgid "Frequency " msgstr "Pogostost " -#: app.py:333 +#: app.py:326 msgid "Frequency in A " msgstr "Pogostost v A " -#: app.py:334 templates/base.html:20 templates/base.html:22 +#: app.py:327 templates/base.html:20 templates/base.html:22 #: templates/index.html:8 templates/result.html:15 msgid "code" msgstr "sl" @@ -199,7 +195,9 @@ msgstr ") nekoliko poenostavljen nabor nastavitev." #: templates/about.html:19 msgid "stark_contact" -msgstr "Za dodatna vprašanja ali pomoč pri uporabi orodja se obrnite na kaja.dobrovoljc@ff.uni-lj.si." +msgstr "" +"Za dodatna vprašanja ali pomoč pri uporabi orodja se obrnite na kaja." +"dobrovoljc@ff.uni-lj.si." #: templates/base.html:23 msgid "switch_link" @@ -237,19 +235,19 @@ msgstr "Vhodni podatki" msgid "Upload a treebank" msgstr "Naložite korpus" -#: templates/index.html:12 templates/index.html:20 templates/index.html:160 -#: templates/index.html:167 +#: templates/index.html:12 templates/index.html:20 templates/index.html:171 +#: templates/index.html:178 msgid "in CONLL-U format" msgstr "v formatu CONLL-U" -#: templates/index.html:12 templates/index.html:41 templates/index.html:49 -#: templates/index.html:89 templates/index.html:104 templates/index.html:120 -#: templates/index.html:126 templates/index.html:132 templates/index.html:140 -#: templates/index.html:159 templates/index.html:160 +#: templates/index.html:12 templates/index.html:44 templates/index.html:48 +#: templates/index.html:94 templates/index.html:109 templates/index.html:125 +#: templates/index.html:131 templates/index.html:137 templates/index.html:143 +#: templates/index.html:151 templates/index.html:170 templates/index.html:171 msgid "Help" msgstr "pomoč" -#: templates/index.html:15 templates/index.html:163 +#: templates/index.html:15 templates/index.html:174 msgid "Browse" msgstr "Izberi" @@ -257,15 +255,15 @@ msgstr "Izberi" msgid "Upload" msgstr "Naloži datoteko" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "Or" msgstr "Ali" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "insert a URL link to a treebank in CONLL-U format" msgstr "vnesite povezavo URL do korpusa v formatu CONLL-U" -#: templates/index.html:29 templates/index.html:177 +#: templates/index.html:29 templates/index.html:188 msgid "Example" msgstr "primer" @@ -273,121 +271,133 @@ msgstr "primer" msgid "Tree specification" msgstr "Opredelitev dreves" -#: templates/index.html:41 +#: templates/index.html:44 msgid "Tree size" msgstr "Velikost drevesa" -#: templates/index.html:41 +#: templates/index.html:44 msgid "number of tokens in the tree" msgstr "število vozlišč (besed) v drevesu" -#: templates/index.html:49 +#: templates/index.html:48 msgid "Node type" msgstr "Vrsta vozlišč" -#: templates/index.html:49 +#: templates/index.html:48 msgid "token characteristics to consider" msgstr "upoštevane lastnosti besed" -#: templates/index.html:55 +#: templates/index.html:54 +msgid "No type" +msgstr "Brez vrste" + +#: templates/index.html:63 msgid "Part-of-speech" msgstr "Besedna vrsta" -#: templates/index.html:64 +#: templates/index.html:69 msgid "Lemma" msgstr "Lema" -#: templates/index.html:70 +#: templates/index.html:75 msgid "Form" msgstr "Oblika" -#: templates/index.html:84 +#: templates/index.html:89 msgid "Advanced settings" msgstr "Napredne nastavitve" -#: templates/index.html:89 +#: templates/index.html:94 msgid "Labeled trees" msgstr "Označena drevesa" -#: templates/index.html:89 +#: templates/index.html:94 msgid "include names of dependency relations" msgstr "izpis vrste relacij med besedami" -#: templates/index.html:93 templates/index.html:108 templates/index.html:144 +#: templates/index.html:98 templates/index.html:113 templates/index.html:155 msgid "No" msgstr "Ne" -#: templates/index.html:96 templates/index.html:111 templates/index.html:147 +#: templates/index.html:101 templates/index.html:116 templates/index.html:158 msgid "Yes" msgstr "Da" -#: templates/index.html:104 +#: templates/index.html:109 msgid "Fixed order" msgstr "Nespremenljiv besedni red" -#: templates/index.html:104 +#: templates/index.html:109 msgid "differentiate trees based on surface word order" msgstr "ločevanje dreves glede na zaporedje besed v besedilu" -#: templates/index.html:120 +#: templates/index.html:125 msgid "Head" msgstr "Jedro" -#: templates/index.html:120 +#: templates/index.html:125 msgid "specify potential restrictions on the head node" msgstr "izpis dreves z vnaprej določenimi lastnostmi jedrne besede v drevesu" -#: templates/index.html:126 +#: templates/index.html:131 +msgid "Ignored labels" +msgstr "Nerelevantne relacije" + +#: templates/index.html:131 +msgid "specify the dependency labels of nodes to be ignored" +msgstr "seznam skladenjskih oznak vozlišč, ki se lahko pojavijo v drevesu, a niso prikazane v izpisu" + +#: templates/index.html:137 msgid "Query" msgstr "Iskalni pogoj" -#: templates/index.html:126 +#: templates/index.html:137 msgid "write a query. Note: Tree size attribute will be ignored!" msgstr "" "izpis dreves z vnaprej določeno strukturo (nastavitev velikosti drevesa se s " "tem ne upošteva.) " -#: templates/index.html:132 +#: templates/index.html:143 msgid "Frequency threshold" msgstr "Frekvenčni prag" -#: templates/index.html:132 +#: templates/index.html:143 msgid "specify the minimum frequency of a tree in the treebank" msgstr "najmanjše število pojavitev drevesa v korpusu" -#: templates/index.html:140 +#: templates/index.html:151 msgid "Association measures" msgstr "Mere povezovalnosti" -#: templates/index.html:140 +#: templates/index.html:151 msgid "print MI, logDice and t-score" msgstr "izračun vrednosti MI, logDice in t-test" -#: templates/index.html:155 +#: templates/index.html:166 msgid "Compare treebanks" msgstr "Primerjava korpusov" -#: templates/index.html:159 +#: templates/index.html:170 msgid "" "Select a reference treebank to identify key phenomena (prints the %DIFF, " "BIC and OR keyness scores)." msgstr "" -"Primerjava z rezultati v referenčnem korpusu (izračun vrednosti %DIFF, " +"Primerjava z rezultati v referenčnem korpusu (izračun razmerja frekvenc ter vrednosti %DIFF, " "BIC in Odds Ratio)" -#: templates/index.html:160 templates/index.html:167 +#: templates/index.html:171 templates/index.html:178 msgid "Upload a compare corpus" msgstr "Naložite referenčni korpus" -#: templates/index.html:191 +#: templates/index.html:202 msgid "Submit" msgstr "Poišči drevesa" -#: templates/index.html:199 +#: templates/index.html:210 msgid "No results" msgstr "Brez zadetkov" -#: templates/index.html:200 +#: templates/index.html:211 msgid "Processing with your settings didnt produce any results!" msgstr "Procesiranje z izbranimi nastavitvami ne vrača rezultatov." @@ -403,6 +413,13 @@ msgstr "Nazaj na izbrane nastavitve" msgid "Download complete results" msgstr "Prenesi datoteko s celotnimi rezultati" +#~ msgid "Please provide information about minimum and maximum tree size." +#~ msgstr "Določite najmanjše in največje število vozlišč v drevesu." + +#~ msgid "Tree size minimum should be smaller than tree size maximum." +#~ msgstr "" +#~ "Najmanjše število vozlišč v drevesu ne sme biti večje od največjega." + #~ msgid "intro_description" #~ msgstr "" #~ "Tukaj je opis na vstopni spletni strani, ki pa ga Kaja pripravi šele na "