You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 lines
155 KiB
1 lines
155 KiB
{"version":3,"sources":["../jssrc/lib/chibi.js","../jssrc/lib/keymaster.js","../jssrc/lib/polyfills.js","../jssrc/utils.js","../jssrc/modal.js","../jssrc/notif.js","../jssrc/appcommon.js","../jssrc/lang.js","../jssrc/wifi.js","../jssrc/term_conn.js","../jssrc/term_input.js","../jssrc/term_screen.js","../jssrc/term_upload.js","../jssrc/term.js","../jssrc/soft_keyboard.js"],"names":[],"mappings":"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","file":"app.js","sourcesContent":["/*!chibi 3.0.7, Copyright 2012-2016 Kyle Barrow, released under MIT license */\n\n// MODIFIED VERSION.\n(function () {\n\t'use strict';\n\n\tvar readyfn = [],\n\t\tloadedfn = [],\n\t\tdomready = false,\n\t\tpageloaded = false,\n\t\td = document,\n\t\tw = window;\n\n\t// Fire any function calls on ready event\n\tfunction fireReady() {\n\t\tvar i;\n\t\tdomready = true;\n\t\tfor (i = 0; i < readyfn.length; i += 1) {\n\t\t\treadyfn[i]();\n\t\t}\n\t\treadyfn = [];\n\t}\n\n\t// Fire any function calls on loaded event\n\tfunction fireLoaded() {\n\t\tvar i;\n\t\tpageloaded = true;\n\t\t// For browsers with no DOM loaded support\n\t\tif (!domready) {\n\t\t\tfireReady();\n\t\t}\n\t\tfor (i = 0; i < loadedfn.length; i += 1) {\n\t\t\tloadedfn[i]();\n\t\t}\n\t\tloadedfn = [];\n\t}\n\n\t// Check DOM ready, page loaded\n\tif (d.addEventListener) {\n\t\t// Standards\n\t\td.addEventListener('DOMContentLoaded', fireReady, false);\n\t\tw.addEventListener('load', fireLoaded, false);\n\t} else if (d.attachEvent) {\n\t\t// IE\n\t\td.attachEvent('onreadystatechange', fireReady);\n\t\t// IE < 9\n\t\tw.attachEvent('onload', fireLoaded);\n\t} else {\n\t\t// Anything else\n\t\tw.onload = fireLoaded;\n\t}\n\n\t// Utility functions\n\n\t// Loop through node array\n\tfunction nodeLoop(fn, nodes) {\n\t\tvar i;\n\t\t// Good idea to walk up the DOM\n\t\tfor (i = nodes.length - 1; i >= 0; i -= 1) {\n\t\t\tfn(nodes[i]);\n\t\t}\n\t}\n\n\t// Convert to camel case\n\tfunction cssCamel(property) {\n\t\treturn property.replace(/-\\w/g, function (result) {\n\t\t\treturn result.charAt(1).toUpperCase();\n\t\t});\n\t}\n\n\t// Get computed style\n\tfunction computeStyle(elm, property) {\n\t\t// IE, everything else or null\n\t\treturn (elm.currentStyle) ? elm.currentStyle[cssCamel(property)] : (w.getComputedStyle) ? w.getComputedStyle(elm, null).getPropertyValue(property) : null;\n\n\t}\n\n\t// Returns URI encoded query string pair\n\tfunction queryPair(name, value) {\n\t\treturn encodeURIComponent(name).replace(/%20/g, '+') + '=' + encodeURIComponent(value).replace(/%20/g, '+');\n\t}\n\n\t// Set CSS, important to wrap in try to prevent error thown on unsupported property\n\tfunction setCss(elm, property, value) {\n\t\ttry {\n\t\t\telm.style[cssCamel(property)] = value;\n\t\t} catch (e) {\n\t\t}\n\t}\n\n\t// Show CSS\n\tfunction showCss(elm) {\n\t\telm.style.display = '';\n\t\t// For elements still hidden by style block\n\t\tif (computeStyle(elm, 'display') === 'none') {\n\t\t\telm.style.display = 'block';\n\t\t}\n\t}\n\n\t// Serialize form & JSON values\n\tfunction serializeData(nodes) {\n\t\tvar querystring = '', subelm, i, j;\n\t\tif (nodes.constructor === Object) { // Serialize JSON data\n\t\t\tfor (subelm in nodes) {\n\t\t\t\tif (nodes.hasOwnProperty(subelm)) {\n\t\t\t\t\tif (nodes[subelm].constructor === Array) {\n\t\t\t\t\t\tfor (i = 0; i < nodes[subelm].length; i += 1) {\n\t\t\t\t\t\t\tquerystring += '&' + queryPair(subelm, nodes[subelm][i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tquerystring += '&' + queryPair(subelm, nodes[subelm]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else { // Serialize node data\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\tif (elm.nodeName === 'FORM') {\n\t\t\t\t\tfor (i = 0; i < elm.elements.length; i += 1) {\n\t\t\t\t\t\tsubelm = elm.elements[i];\n\n\t\t\t\t\t\tif (!subelm.disabled) {\n\t\t\t\t\t\t\tswitch (subelm.type) {\n\t\t\t\t\t\t\t\t// Ignore buttons, unsupported XHR 1 form fields\n\t\t\t\t\t\t\t\tcase 'button':\n\t\t\t\t\t\t\t\tcase 'image':\n\t\t\t\t\t\t\t\tcase 'file':\n\t\t\t\t\t\t\t\tcase 'submit':\n\t\t\t\t\t\t\t\tcase 'reset':\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 'select-one':\n\t\t\t\t\t\t\t\t\tif (subelm.length > 0) {\n\t\t\t\t\t\t\t\t\t\tquerystring += '&' + queryPair(subelm.name, subelm.value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 'select-multiple':\n\t\t\t\t\t\t\t\t\tfor (j = 0; j < subelm.length; j += 1) {\n\t\t\t\t\t\t\t\t\t\tif (subelm[j].selected) {\n\t\t\t\t\t\t\t\t\t\t\tquerystring += '&' + queryPair(subelm.name, subelm[j].value);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase 'checkbox':\n\t\t\t\t\t\t\t\tcase 'radio':\n\t\t\t\t\t\t\t\t\tif (subelm.checked) {\n\t\t\t\t\t\t\t\t\t\tquerystring += '&' + queryPair(subelm.name, subelm.value);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t// Everything else including shinny new HTML5 input types\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\tquerystring += '&' + queryPair(subelm.name, subelm.value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, nodes);\n\t\t}\n\t\t// Tidy up first &\n\t\treturn (querystring.length > 0) ? querystring.substring(1) : '';\n\t}\n\n\t// Class helper\n\tfunction classHelper(classes, action, nodes) {\n\t\tvar classarray, search, i, replace, has = false;\n\t\tif (classes) {\n\t\t\t// Trim any whitespace\n\t\t\tclassarray = classes.split(/\\s+/);\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\tfor (i = 0; i < classarray.length; i += 1) {\n\t\t\t\t\tvar clz = classarray[i];\n\t\t\t\t\tif (action === 'remove') {\n\t\t\t\t\t\telm.classList.remove(clz);\n\t\t\t\t\t}\n\t\t\t\t\telse if (action === 'add') {\n\t\t\t\t\t\telm.classList.add(clz);\n\t\t\t\t\t}\n\t\t\t\t\telse if (action === 'toggle') {\n\t\t\t\t\t\telm.classList.toggle(clz);\n\t\t\t\t\t}\n\t\t\t\t\telse if (action === 'has') {\n\t\t\t\t\t\tif (elm.classList.contains(clz)) {\n\t\t\t\t\t\t\thas = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// search = new RegExp('\\\\b' + classarray[i] + '\\\\b', 'g');\n\t\t\t\t\t// replace = new RegExp(' *' + classarray[i] + '\\\\b', 'g');\n\t\t\t\t\t// if (action === 'remove') {\n\t\t\t\t\t// \telm.className = elm.className.replace(search, '');\n\t\t\t\t\t// } else if (action === 'toggle') {\n\t\t\t\t\t// \telm.className = (elm.className.match(search)) ? elm.className.replace(replace, '') : elm.className + ' ' + classarray[i];\n\t\t\t\t\t// } else if (action === 'has') {\n\t\t\t\t\t// \tif (elm.className.match(search)) {\n\t\t\t\t\t// \t\thas = true;\n\t\t\t\t\t// \t\tbreak;\n\t\t\t\t\t// \t}\n\t\t\t\t\t// }\n\t\t\t\t}\n\t\t\t}, nodes);\n\t\t}\n\t\treturn has;\n\t}\n\n\t// HTML insertion helper\n\tfunction insertHtml(value, position, nodes) {\n\t\tvar tmpnodes, tmpnode;\n\t\tif (value) {\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\t// No insertAdjacentHTML support for FF < 8 and IE doesn't allow insertAdjacentHTML table manipulation, so use this instead\n\t\t\t\t// Convert string to node. We can't innerHTML on a document fragment\n\t\t\t\ttmpnodes = d.createElement('div');\n\t\t\t\ttmpnodes.innerHTML = value;\n\t\t\t\twhile ((tmpnode = tmpnodes.lastChild) !== null) {\n\t\t\t\t\t// Catch error in unlikely case elm has been removed\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (position === 'before') {\n\t\t\t\t\t\t\telm.parentNode.insertBefore(tmpnode, elm);\n\t\t\t\t\t\t} else if (position === 'after') {\n\t\t\t\t\t\t\telm.parentNode.insertBefore(tmpnode, elm.nextSibling);\n\t\t\t\t\t\t} else if (position === 'append') {\n\t\t\t\t\t\t\telm.appendChild(tmpnode);\n\t\t\t\t\t\t} else if (position === 'prepend') {\n\t\t\t\t\t\t\telm.insertBefore(tmpnode, elm.firstChild);\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, nodes);\n\t\t}\n\t}\n\n\t// Get nodes and return chibi\n\tfunction chibi(selector) {\n\t\tvar cb, nodes = [], json = false, nodelist, i;\n\n\t\tif (selector) {\n\n\t\t\t// Element node, would prefer to use (selector instanceof HTMLElement) but no IE support\n\t\t\tif (selector.nodeType && selector.nodeType === 1) {\n\t\t\t\tnodes = [selector]; // return element as node list\n\t\t\t} else if (typeof selector === 'object') {\n\t\t\t\t// JSON, document object or node list, would prefer to use (selector instanceof NodeList) but no IE support\n\t\t\t\tjson = (typeof selector.length !== 'number');\n\t\t\t\tnodes = selector;\n\t\t\t} else if (typeof selector === 'string') {\n\t\t\t\tnodelist = d.querySelectorAll(selector);\n\n\t\t\t\t// Convert node list to array so results have full access to array methods\n\t\t\t\t// Array.prototype.slice.call not supported in IE < 9 and often slower than loop anyway\n\t\t\t\tfor (i = 0; i < nodelist.length; i += 1) {\n\t\t\t\t\tnodes[i] = nodelist[i];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Only attach nodes if not JSON\n\t\tcb = json ? {} : nodes;\n\n\t\t// Public functions\n\n\t\t// Executes a function on nodes\n\t\tcb.each = function (fn) {\n\t\t\tif (typeof fn === 'function') {\n\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\t// <= IE 8 loses scope so need to apply\n\t\t\t\t\treturn fn.apply(elm, arguments);\n\t\t\t\t}, nodes);\n\t\t\t}\n\t\t\treturn cb;\n\t\t};\n\t\t// Find first\n\t\tcb.first = function () {\n\t\t\treturn chibi(nodes.shift());\n\t\t};\n\t\t// Find last\n\t\tcb.last = function () {\n\t\t\treturn chibi(nodes.pop());\n\t\t};\n\t\t// Find odd\n\t\tcb.odd = function () {\n\t\t\tvar odds = [], i;\n\t\t\tfor (i = 0; i < nodes.length; i += 2) {\n\t\t\t\todds.push(nodes[i]);\n\t\t\t}\n\t\t\treturn chibi(odds);\n\t\t};\n\t\t// Find even\n\t\tcb.even = function () {\n\t\t\tvar evens = [], i;\n\t\t\tfor (i = 1; i < nodes.length; i += 2) {\n\t\t\t\tevens.push(nodes[i]);\n\t\t\t}\n\t\t\treturn chibi(evens);\n\t\t};\n\t\t// Hide node\n\t\tcb.hide = function () {\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\telm.style.display = 'none';\n\t\t\t}, nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Show node\n\t\tcb.show = function () {\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\tshowCss(elm);\n\t\t\t}, nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Toggle node display\n\t\tcb.toggle = function (state) {\n\t\t\tif (typeof state != 'undefined') { // ADDED\n\t\t\t\tif (state)\n\t\t\t\t\tcb.show();\n\t\t\t\telse\n\t\t\t\t\tcb.hide();\n\t\t\t} else {\n\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\t// computeStyle instead of style.display == 'none' catches elements that are hidden via style block\n\t\t\t\t\tif (computeStyle(elm, 'display') === 'none') {\n\t\t\t\t\t\tshowCss(elm);\n\t\t\t\t\t} else {\n\t\t\t\t\t\telm.style.display = 'none';\n\t\t\t\t\t}\n\n\t\t\t\t}, nodes);\n\t\t\t}\n\t\t\treturn cb;\n\t\t};\n\t\t// Remove node\n\t\tcb.remove = function () {\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\t// Catch error in unlikely case elm has been removed\n\t\t\t\ttry {\n\t\t\t\t\telm.parentNode.removeChild(elm);\n\t\t\t\t} catch (e) {\n\t\t\t\t}\n\t\t\t}, nodes);\n\t\t\treturn chibi();\n\t\t};\n\t\t// Get/Set CSS\n\t\tcb.css = function (property, value) {\n\t\t\tif (property) {\n\t\t\t\tif (value || value === '') {\n\t\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\t\tsetCss(elm, property, value);\n\t\t\t\t\t}, nodes);\n\t\t\t\t\treturn cb;\n\t\t\t\t}\n\t\t\t\tif (nodes[0]) {\n\t\t\t\t\tif (nodes[0].style[cssCamel(property)]) {\n\t\t\t\t\t\treturn nodes[0].style[cssCamel(property)];\n\t\t\t\t\t}\n\t\t\t\t\tif (computeStyle(nodes[0], property)) {\n\t\t\t\t\t\treturn computeStyle(nodes[0], property);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\t// Get class(es)\n\t\tcb.getClass = function () {\n\t\t\tif (nodes[0] && nodes[0].className.length > 0) {\n\t\t\t\t// Weak IE trim support\n\t\t\t\treturn nodes[0].className.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '').replace(/\\s+/, ' ');\n\t\t\t}\n\t\t};\n\t\t// Set (replaces) classes\n\t\tcb.setClass = function (classes) {\n\t\t\tif (classes || classes === '') {\n\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\telm.className = classes;\n\t\t\t\t}, nodes);\n\t\t\t}\n\t\t\treturn cb;\n\t\t};\n\t\t// Add class\n\t\tcb.addClass = function (classes) {\n\t\t\tclassHelper(classes, 'add', nodes);\n\t\t\t// if (classes) {\n\t\t\t// \tnodeLoop(function (elm) {\n\t\t\t// \t\telm.className += ' ' + classes;\n\t\t\t// \t}, nodes);\n\t\t\t// }\n\t\t\treturn cb;\n\t\t};\n\t\t// Remove class\n\t\tcb.removeClass = function (classes) {\n\t\t\tclassHelper(classes, 'remove', nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Toggle class\n\t\tcb.toggleClass = function (classes, set) {\n\t\t\tvar method = ((typeof set === 'undefined') ? 'toggle' : (+set ? 'add' : 'remove'));\n\t\t\tclassHelper(classes, method, nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Has class\n\t\tcb.hasClass = function (classes) {\n\t\t\treturn classHelper(classes, 'has', nodes);\n\t\t};\n\t\t// Get/set HTML\n\t\tcb.html = function (value) {\n\t\t\tif (value || value === '') {\n\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\telm.innerHTML = value;\n\t\t\t\t}, nodes);\n\t\t\t\treturn cb;\n\t\t\t}\n\t\t\tif (nodes[0]) {\n\t\t\t\treturn nodes[0].innerHTML;\n\t\t\t}\n\t\t};\n\t\t// Insert HTML before selector\n\t\tcb.htmlBefore = function (value) {\n\t\t\tinsertHtml(value, 'before', nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Insert HTML after selector\n\t\tcb.htmlAfter = function (value) {\n\t\t\tinsertHtml(value, 'after', nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Insert HTML after selector innerHTML\n\t\tcb.htmlAppend = function (value) {\n\t\t\tinsertHtml(value, 'append', nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Insert HTML before selector innerHTML\n\t\tcb.htmlPrepend = function (value) {\n\t\t\tinsertHtml(value, 'prepend', nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Get/Set HTML attributes\n\t\tcb.attr = function (property, value) {\n\t\t\tif (property) {\n\t\t\t\tproperty = property.toLowerCase();\n\t\t\t\t// IE < 9 doesn't allow style or class via get/setAttribute so switch. cssText returns prettier CSS anyway\n\t\t\t\tif (typeof value !== 'undefined') {//FIXED BUG HERE\n\t\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\t\tif (property === 'style') {\n\t\t\t\t\t\t\telm.style.cssText = value;\n\t\t\t\t\t\t} else if (property === 'class') {\n\t\t\t\t\t\t\telm.className = value;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telm.setAttribute(property, value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, nodes);\n\t\t\t\t\treturn cb;\n\t\t\t\t}\n\t\t\t\tif (nodes[0]) {\n\t\t\t\t\tif (property === 'style') {\n\t\t\t\t\t\tif (nodes[0].style.cssText) {\n\t\t\t\t\t\t\treturn nodes[0].style.cssText;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (property === 'class') {\n\t\t\t\t\t\tif (nodes[0].className) {\n\t\t\t\t\t\t\treturn nodes[0].className;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (nodes[0].getAttribute(property)) {\n\t\t\t\t\t\t\treturn nodes[0].getAttribute(property);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\t// Get/Set HTML data property\n\t\tcb.data = function (key, value) {\n\t\t\tif (key) {\n\t\t\t\treturn cb.attr('data-' + key, value);\n\t\t\t}\n\t\t};\n\t\t// Get/Set form element values\n\t\tcb.val = function (value) {\n\t\t\tvar values, i, j;\n\t\t\tif (typeof value != 'undefined') { // FIXED A BUG HERE\n\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\tswitch (elm.nodeName) {\n\t\t\t\t\t\tcase 'SELECT':\n\t\t\t\t\t\t\tif (typeof value === 'string' || typeof value === 'number') {\n\t\t\t\t\t\t\t\tvalue = [value];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor (i = 0; i < elm.length; i += 1) {\n\t\t\t\t\t\t\t\t// Multiple select\n\t\t\t\t\t\t\t\tfor (j = 0; j < value.length; j += 1) {\n\t\t\t\t\t\t\t\t\telm[i].selected = '';\n\t\t\t\t\t\t\t\t\tif (elm[i].value === \"\"+value[j]) {\n\t\t\t\t\t\t\t\t\t\telm[i].selected = 'selected';\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'INPUT':\n\t\t\t\t\t\tcase 'TEXTAREA':\n\t\t\t\t\t\tcase 'BUTTON':\n\t\t\t\t\t\t\telm.value = value;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}, nodes);\n\n\t\t\t\treturn cb;\n\t\t\t}\n\t\t\tif (nodes[0]) {\n\t\t\t\tswitch (nodes[0].nodeName) {\n\t\t\t\t\tcase 'SELECT':\n\t\t\t\t\t\tvalues = [];\n\t\t\t\t\t\tfor (i = 0; i < nodes[0].length; i += 1) {\n\t\t\t\t\t\t\tif (nodes[0][i].selected) {\n\t\t\t\t\t\t\t\tvalues.push(nodes[0][i].value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (values.length > 1) ? values : values[0];\n\t\t\t\t\tcase 'INPUT':\n\t\t\t\t\tcase 'TEXTAREA':\n\t\t\t\t\tcase 'BUTTON':\n\t\t\t\t\t\treturn nodes[0].value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\t// Return matching checked checkbox or radios\n\t\tcb.checked = function (check) {\n\t\t\tif (typeof check === 'boolean') {\n\t\t\t\tnodeLoop(function (elm) {\n\t\t\t\t\tif (elm.nodeName === 'INPUT' && (elm.type === 'checkbox' || elm.type === 'radio')) {\n\t\t\t\t\t\telm.checked = check;\n\t\t\t\t\t}\n\t\t\t\t}, nodes);\n\t\t\t\treturn cb;\n\t\t\t}\n\t\t\tif (nodes[0] && nodes[0].nodeName === 'INPUT' && (nodes[0].type === 'checkbox' || nodes[0].type === 'radio')) {\n\t\t\t\treturn (!!nodes[0].checked);\n\t\t\t}\n\t\t};\n\t\t// Add event handler\n\t\tcb.on = function (event, fn) {\n\t\t\tif (selector === w || selector === d) {\n\t\t\t\tnodes = [selector];\n\t\t\t}\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\tif (d.addEventListener) {\n\t\t\t\t\telm.addEventListener(event, fn, false);\n\t\t\t\t} else if (d.attachEvent) {\n\t\t\t\t\t// <= IE 8 loses scope so need to apply, we add this to object so we can detach later (can't detach anonymous functions)\n\t\t\t\t\telm[event + fn] = function () {\n\t\t\t\t\t\treturn fn.apply(elm, arguments);\n\t\t\t\t\t};\n\t\t\t\t\telm.attachEvent('on' + event, elm[event + fn]);\n\t\t\t\t}\n\t\t\t}, nodes);\n\t\t\treturn cb;\n\t\t};\n\t\t// Remove event handler\n\t\tcb.off = function (event, fn) {\n\t\t\tif (selector === w || selector === d) {\n\t\t\t\tnodes = [selector];\n\t\t\t}\n\t\t\tnodeLoop(function (elm) {\n\t\t\t\tif (d.addEventListener) {\n\t\t\t\t\telm.removeEventListener(event, fn, false);\n\t\t\t\t} else if (d.attachEvent) {\n\t\t\t\t\telm.detachEvent('on' + event, elm[event + fn]);\n\t\t\t\t\t// Tidy up\n\t\t\t\t\telm[event + fn] = null;\n\t\t\t\t}\n\t\t\t}, nodes);\n\t\t\treturn cb;\n\t\t};\n\t\treturn cb;\n\t}\n\n\t// Basic XHR\n\tchibi.ajax = function (options) { // if options is a number, it's timeout in ms\n\t\tvar opts = extend({\n\t\t\tmethod: 'GET',\n\t\t\tnocache: true,\n\t\t\ttimeout: 5000,\n\t\t\tloader: true,\n\t\t\tcallback: null\n\t\t}, options);\n\t\topts.method = opts.method.toUpperCase();\n\n\t\tvar loaderFn = opts.loader ? chibi._loader : function(){};\n\t\tvar url = opts.url;\n\t\tvar method = opts.method;\n\t\tvar query = null;\n\n\t\tif (opts.data) {\n\t\t\tquery = serializeData(opts.data);\n\t\t}\n\n\t\tif (query && (method === 'GET')) {\n\t\t\turl += (url.indexOf('?') === -1) ? '?' + query : '&' + query;\n\t\t\tquery = null;\n\t\t}\n\n\t\tvar xhr = new XMLHttpRequest();\n\n\t\t// prevent caching\n\t\tif (opts.nocache) {\n\t\t\tvar ts = (+(new Date())).toString(36);\n\t\t\turl += ((url.indexOf('?') === -1) ? '?' : '&') + '_=' + ts;\n\t\t}\n\n\t\tloaderFn(true);\n\n\t\txhr.open(method, url, true);\n\t\txhr.timeout = opts.timeout;\n\n\t\t// Abort after given timeout\n\t\tvar abortTmeo = setTimeout(function () {\n\t\t\tconsole.error(\"XHR timed out.\");\n\t\t\txhr.abort();\n\t\t\tloaderFn(false);\n\t\t}, opts.timeout + 10);\n\n\t\txhr.onreadystatechange = function () {\n\t\t\tif (xhr.readyState === 4) {\n\t\t\t\tloaderFn(false);\n\n\t\t\t\topts.callback && opts.callback(xhr.responseText, xhr.status);\n\n\t\t\t\tclearTimeout(abortTmeo);\n\t\t\t}\n\t\t};\n\n\t\txhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n\t\tif (method === 'POST') {\n\t\t\txhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n\t\t}\n\n\t\txhr.send(query);\n\t\treturn xhr;\n\t};\n\n\tchibi._loader = function(){};\n\n\t// Alias to cb.ajax(url, 'get', callback)\n\tchibi.get = function (url, callback, opts) {\n\t\topts = opts || {};\n\t\topts.url = url;\n\t\topts.callback = callback;\n\t\topts.method = 'GET';\n\t\treturn chibi.ajax(opts);\n\t};\n\n\t// Alias to cb.ajax(url, 'post', callback)\n\tchibi.post = function (url, callback, opts) {\n\t\topts = opts || {};\n\t\topts.url = url;\n\t\topts.callback = callback;\n\t\topts.method = 'POST';\n\t\treturn chibi.ajax(opts);\n\t};\n\n\t// Fire on DOM ready\n\tchibi.ready = function (fn) {\n\t\tif (fn) {\n\t\t\tif (domready) {\n\t\t\t\tfn();\n\t\t\t\treturn chibi;\n\t\t\t} else {\n\t\t\t\treadyfn.push(fn);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Fire on page loaded\n\tchibi.loaded = function (fn) {\n\t\tif (fn) {\n\t\t\tif (pageloaded) {\n\t\t\t\tfn();\n\t\t\t\treturn chibi;\n\t\t\t} else {\n\t\t\t\tloadedfn.push(fn);\n\t\t\t}\n\t\t}\n\t};\n\n\tvar entityMap = {\n\t\t'&': '&',\n\t\t'<': '<',\n\t\t'>': '>',\n\t\t'\"': '"',\n\t\t\"'\": ''',\n\t\t'/': '/',\n\t\t'`': '`',\n\t\t'=': '='\n\t};\n\n\tchibi.htmlEscape = function(string) {\n\t\treturn String(string).replace(/[&<>\"'`=\\/]/g, function (s) {\n\t\t\treturn entityMap[s];\n\t\t});\n\t};\n\n\t// Set Chibi's global namespace here ($)\n\tw.$ = chibi;\n}());\n","// keymaster.js\n// (c) 2011-2013 Thomas Fuchs\n// keymaster.js may be freely distributed under the MIT license.\n\n;(function(global){\n var k,\n _handlers = {},\n _mods = { 16: false, 18: false, 17: false, 91: false },\n _scope = 'all',\n // modifier keys\n _MODIFIERS = {\n '⇧': 16, shift: 16,\n '⌥': 18, alt: 18, option: 18,\n '⌃': 17, ctrl: 17, control: 17,\n '⌘': 91, command: 91\n },\n // special keys\n _MAP = {\n backspace: 8, tab: 9, clear: 12,\n enter: 13, 'return': 13,\n esc: 27, escape: 27, space: 32,\n left: 37, up: 38,\n right: 39, down: 40,\n del: 46, 'delete': 46,\n home: 36, end: 35,\n pageup: 33, pagedown: 34,\n ',': 188, '.': 190, '/': 191,\n '`': 192, '-': 189, '=': 187,\n ';': 186, '\\'': 222,\n '[': 219, ']': 221, '\\\\': 220,\n // added:\n insert: 45,\n np_0: 96, np_1: 97, np_2: 98, np_3: 99, np_4: 100, np_5: 101,\n\t np_6: 102, np_7: 103, np_8: 104, np_9: 105, np_mul: 106,\n\t np_add: 107, np_sub: 109, np_point: 110, np_div: 111, numlock: 144,\n },\n code = function(x){\n return _MAP[x] || x.toUpperCase().charCodeAt(0);\n },\n _downKeys = [];\n\n for(k=1;k<20;k++) _MAP['f'+k] = 111+k;\n\n // IE doesn't support Array#indexOf, so have a simple replacement\n function index(array, item){\n var i = array.length;\n while(i--) if(array[i]===item) return i;\n return -1;\n }\n\n // for comparing mods before unassignment\n function compareArray(a1, a2) {\n if (a1.length != a2.length) return false;\n for (var i = 0; i < a1.length; i++) {\n if (a1[i] !== a2[i]) return false;\n }\n return true;\n }\n\n var modifierMap = {\n 16:'shiftKey',\n 18:'altKey',\n 17:'ctrlKey',\n 91:'metaKey'\n };\n function updateModifierKey(event) {\n for(k in _mods) _mods[k] = event[modifierMap[k]];\n };\n\n function isModifierPressed(mod) {\n if (mod=='control'||mod=='ctrl') return _mods[17];\n\tif (mod=='shift') return _mods[16];\n\tif (mod=='meta') return _mods[91];\n\tif (mod=='alt') return _mods[18];\n\treturn false;\n }\n\n // handle keydown event\n function dispatch(event) {\n var key, handler, k, i, modifiersMatch, scope;\n key = event.keyCode;\n\n if (index(_downKeys, key) == -1) {\n _downKeys.push(key);\n }\n\n // if a modifier key, set the key.<modifierkeyname> property to true and return\n if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko\n if(key in _mods) {\n _mods[key] = true;\n // 'assignKey' from inside this closure is exported to window.key\n for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;\n return;\n }\n updateModifierKey(event);\n\n // see if we need to ignore the keypress (filter() can can be overridden)\n // by default ignore key presses if a select, textarea, or input is focused\n if(!assignKey.filter.call(this, event)) return;\n\n // abort if no potentially matching shortcuts found\n if (!(key in _handlers)) return;\n\n scope = getScope();\n\n // for each potential shortcut\n for (i = 0; i < _handlers[key].length; i++) {\n handler = _handlers[key][i];\n\n // see if it's in the current scope\n if(handler.scope == scope || handler.scope == 'all'){\n // check if modifiers match if any\n modifiersMatch = handler.mods.length > 0;\n for(k in _mods)\n if((!_mods[k] && index(handler.mods, +k) > -1) ||\n (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;\n // call the handler and stop the event if neccessary\n if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){\n if(handler.method(event, handler)===false){\n if(event.preventDefault) event.preventDefault();\n else event.returnValue = false;\n if(event.stopPropagation) event.stopPropagation();\n if(event.cancelBubble) event.cancelBubble = true;\n }\n }\n }\n }\n };\n\n // unset modifier keys on keyup\n function clearModifier(event){\n var key = event.keyCode, k,\n i = index(_downKeys, key);\n\n // remove key from _downKeys\n if (i >= 0) {\n _downKeys.splice(i, 1);\n }\n\n if(key == 93 || key == 224) key = 91;\n if(key in _mods) {\n _mods[key] = false;\n for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;\n }\n };\n\n function resetModifiers() {\n for(k in _mods) _mods[k] = false;\n for(k in _MODIFIERS) assignKey[k] = false;\n };\n\n // parse and assign shortcut\n function assignKey(key, scope, method){\n var keys, mods;\n keys = getKeys(key);\n if (method === undefined) {\n method = scope;\n scope = 'all';\n }\n\n // for each shortcut\n for (var i = 0; i < keys.length; i++) {\n // set modifier keys if any\n mods = [];\n key = keys[i].split('+');\n if (key.length > 1){\n mods = getMods(key);\n key = [key[key.length-1]];\n }\n // convert to keycode and...\n key = key[0]\n key = code(key);\n // ...store handler\n if (!(key in _handlers)) _handlers[key] = [];\n _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });\n }\n };\n\n // unbind all handlers for given key in current scope\n function unbindKey(key, scope) {\n var multipleKeys, keys,\n mods = [],\n i, j, obj;\n\n multipleKeys = getKeys(key);\n\n for (j = 0; j < multipleKeys.length; j++) {\n keys = multipleKeys[j].split('+');\n\n if (keys.length > 1) {\n mods = getMods(keys);\n }\n\n key = keys[keys.length - 1];\n key = code(key);\n\n if (scope === undefined) {\n scope = getScope();\n }\n if (!_handlers[key]) {\n return;\n }\n for (i = 0; i < _handlers[key].length; i++) {\n obj = _handlers[key][i];\n // only clear handlers if correct scope and mods match\n if (obj.scope === scope && compareArray(obj.mods, mods)) {\n _handlers[key][i] = {};\n }\n }\n }\n };\n\n // Returns true if the key with code 'keyCode' is currently down\n // Converts strings into key codes.\n function isPressed(keyCode) {\n if (typeof(keyCode)=='string') {\n keyCode = code(keyCode);\n }\n return index(_downKeys, keyCode) != -1;\n }\n\n function getPressedKeyCodes() {\n return _downKeys.slice(0);\n }\n\n function filter(event){\n var tagName = (event.target || event.srcElement).tagName;\n // ignore keypressed in any elements that support keyboard data input\n return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');\n }\n\n // initialize key.<modifier> to false\n for(k in _MODIFIERS) assignKey[k] = false;\n\n // set current scope (default 'all')\n function setScope(scope){ _scope = scope || 'all' };\n function getScope(){ return _scope || 'all' };\n\n // delete all handlers for a given scope\n function deleteScope(scope){\n var key, handlers, i;\n\n for (key in _handlers) {\n handlers = _handlers[key];\n for (i = 0; i < handlers.length; ) {\n if (handlers[i].scope === scope) handlers.splice(i, 1);\n else i++;\n }\n }\n };\n\n // abstract key logic for assign and unassign\n function getKeys(key) {\n var keys;\n key = key.replace(/\\s/g, '');\n keys = key.split(',');\n if ((keys[keys.length - 1]) == '') {\n keys[keys.length - 2] += ',';\n }\n return keys;\n }\n\n // abstract mods logic for assign and unassign\n function getMods(key) {\n var mods = key.slice(0, key.length - 1);\n for (var mi = 0; mi < mods.length; mi++)\n mods[mi] = _MODIFIERS[mods[mi]];\n return mods;\n }\n\n // cross-browser events\n function addEvent(object, event, method) {\n if (object.addEventListener)\n object.addEventListener(event, method, false);\n else if(object.attachEvent)\n object.attachEvent('on'+event, function(){ method(window.event) });\n };\n\n // set the handlers globally on document\n addEvent(document, 'keydown', function(event) { dispatch(event) }); // Passing _scope to a callback to ensure it remains the same by execution. Fixes #48\n addEvent(document, 'keyup', clearModifier);\n\n // reset modifiers to false whenever the window is (re)focused.\n addEvent(window, 'focus', resetModifiers);\n\n // store previously defined key\n var previousKey = global.key;\n\n // restore previously defined key and return reference to our key object\n function noConflict() {\n var k = global.key;\n global.key = previousKey;\n return k;\n }\n\n // set window.key and window.key.set/get/deleteScope, and the default filter\n global.key = assignKey;\n global.key.setScope = setScope;\n global.key.getScope = getScope;\n global.key.deleteScope = deleteScope;\n global.key.filter = filter;\n global.key.isPressed = isPressed;\n global.key.isModifier = isModifierPressed;\n global.key.getPressedKeyCodes = getPressedKeyCodes;\n global.key.noConflict = noConflict;\n global.key.unbind = unbindKey;\n\n if(typeof module !== 'undefined') module.exports = assignKey;\n\n})(window);\n\n","/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */\nif (!String.fromCodePoint) {\n (function () {\n var defineProperty = (function () {\n // IE 8 only supports `Object.defineProperty` on DOM elements\n try {\n var object = {};\n var $defineProperty = Object.defineProperty;\n var result = $defineProperty(object, object, object) && $defineProperty;\n } catch (error) {\n }\n return result;\n }());\n var stringFromCharCode = String.fromCharCode;\n var floor = Math.floor;\n var fromCodePoint = function () {\n var MAX_SIZE = 0x4000;\n var codeUnits = [];\n var highSurrogate;\n var lowSurrogate;\n var index = -1;\n var length = arguments.length;\n if (!length) {\n return '';\n }\n var result = '';\n while (++index < length) {\n var codePoint = Number(arguments[index]);\n if (\n !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`\n codePoint < 0 || // not a valid Unicode code point\n codePoint > 0x10FFFF || // not a valid Unicode code point\n floor(codePoint) != codePoint // not an integer\n ) {\n throw RangeError('Invalid code point: ' + codePoint);\n }\n if (codePoint <= 0xFFFF) { // BMP code point\n codeUnits.push(codePoint);\n } else { // Astral code point; split in surrogate halves\n // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n codePoint -= 0x10000;\n highSurrogate = (codePoint >> 10) + 0xD800;\n lowSurrogate = (codePoint % 0x400) + 0xDC00;\n codeUnits.push(highSurrogate, lowSurrogate);\n }\n if (index + 1 == length || codeUnits.length > MAX_SIZE) {\n result += stringFromCharCode.apply(null, codeUnits);\n codeUnits.length = 0;\n }\n }\n return result;\n };\n if (defineProperty) {\n defineProperty(String, 'fromCodePoint', {\n 'value': fromCodePoint,\n 'configurable': true,\n 'writable': true\n });\n } else {\n String.fromCodePoint = fromCodePoint;\n }\n }());\n}\n","/** Make a node */\nfunction mk (e) {\n return document.createElement(e)\n}\n\n/** Find one by query */\nfunction qs (s) {\n return document.querySelector(s)\n}\n\n/** Find all by query */\nfunction qsa (s) {\n return document.querySelectorAll(s)\n}\n\n/** Convert any to bool safely */\nfunction bool (x) {\n return (x === 1 || x === '1' || x === true || x === 'true')\n}\n\n/**\n * Filter 'spacebar' and 'return' from keypress handler,\n * and when they're pressed, fire the callback.\n * use $(...).on('keypress', cr(handler))\n */\nfunction cr (hdl) {\n return function (e) {\n if (e.which === 10 || e.which === 13 || e.which === 32) {\n hdl()\n }\n }\n}\n\n/** Extend an objects with options */\nfunction extend (defaults, options) {\n let target = {}\n\n Object.keys(defaults).forEach(function (k) {\n target[k] = defaults[k]\n })\n\n Object.keys(options).forEach(function (k) {\n target[k] = options[k]\n })\n\n return target\n}\n\n/** Escape string for use as literal in RegExp */\nfunction rgxe (str) {\n return str.replace(/[-[\\]/{}()*+?.\\\\^$|]/g, '\\\\$&')\n}\n\n/** Format number to N decimal places, output as string */\nfunction numfmt (x, places) {\n const pow = Math.pow(10, places)\n return Math.round(x * pow) / pow\n}\n\n/** Get millisecond timestamp */\nfunction msNow () {\n return +(new Date())\n}\n\n/** Get ms elapsed since msNow() */\nfunction msElapsed (start) {\n return msNow() - start\n}\n\n/** Shim for log base 10 */\nMath.log10 = Math.log10 || function (x) {\n return Math.log(x) / Math.LN10\n}\n\n/** HTML escape */\nfunction esc (str) {\n return $.htmlEscape(str)\n}\n\n/** Check for undefined */\nfunction undef (x) {\n return typeof x == 'undefined'\n}\n\n/** Safe json parse */\nfunction jsp (str) {\n try {\n return JSON.parse(str)\n } catch (e) {\n console.error(e)\n return null\n }\n}\n\n/** Create a character from ASCII code */\nfunction Chr (n) {\n return String.fromCharCode(n)\n}\n\n/** Decode number from 2B encoding */\nfunction parse2B (s, i = 0) {\n return (s.charCodeAt(i++) - 1) + (s.charCodeAt(i) - 1) * 127\n}\n\n/** Decode number from 3B encoding */\nfunction parse3B (s, i = 0) {\n return (s.charCodeAt(i) - 1) + (s.charCodeAt(i + 1) - 1) * 127 + (s.charCodeAt(i + 2) - 1) * 127 * 127\n}\n\n/** Encode using 2B encoding, returns string. */\nfunction encode2B (n) {\n let lsb, msb\n lsb = (n % 127)\n n = ((n - lsb) / 127)\n lsb += 1\n msb = (n + 1)\n return Chr(lsb) + Chr(msb)\n}\n\n/** Encode using 3B encoding, returns string. */\nfunction encode3B (n) {\n let lsb, msb, xsb\n lsb = (n % 127)\n n = (n - lsb) / 127\n lsb += 1\n msb = (n % 127)\n n = (n - msb) / 127\n msb += 1\n xsb = (n + 1)\n return Chr(lsb) + Chr(msb) + Chr(xsb)\n}\n","/** Module for toggling a modal overlay */\n(function () {\n let modal = {}\n let curCloseCb = null\n\n modal.show = function (sel, closeCb) {\n let $m = $(sel)\n $m.removeClass('hidden visible')\n setTimeout(function () {\n $m.addClass('visible')\n }, 1)\n curCloseCb = closeCb\n }\n\n modal.hide = function (sel) {\n let $m = $(sel)\n $m.removeClass('visible')\n setTimeout(function () {\n $m.addClass('hidden')\n if (curCloseCb) curCloseCb()\n }, 500) // transition time\n }\n\n modal.init = function () {\n // close modal by click outside the dialog\n $('.Modal').on('click', function () {\n if ($(this).hasClass('no-close')) return // this is a no-close modal\n modal.hide(this)\n })\n\n $('.Dialog').on('click', function (e) {\n e.stopImmediatePropagation()\n })\n\n // Hide all modals on esc\n $(window).on('keydown', function (e) {\n if (e.which === 27) {\n modal.hide('.Modal')\n }\n })\n }\n\n window.Modal = modal\n})()\n","window.Notify = (function () {\n let nt = {}\n const sel = '#notif'\n\n let hideTmeo1 // timeout to start hiding (transition)\n let hideTmeo2 // timeout to add the hidden class\n\n nt.show = function (message, timeout) {\n $(sel).html(message)\n Modal.show(sel)\n\n clearTimeout(hideTmeo1)\n clearTimeout(hideTmeo2)\n\n if (undef(timeout)) timeout = 2500\n\n hideTmeo1 = setTimeout(nt.hide, timeout)\n }\n\n nt.hide = function () {\n let $m = $(sel)\n $m.removeClass('visible')\n hideTmeo2 = setTimeout(function () {\n $m.addClass('hidden')\n }, 250) // transition time\n }\n\n nt.init = function () {\n $(sel).on('click', function () {\n nt.hide(this)\n })\n }\n\n return nt\n})()\n","/** Global generic init */\n$.ready(function () {\n // Checkbox UI (checkbox CSS and hidden input with int value)\n $('.Row.checkbox').forEach(function (x) {\n let inp = x.querySelector('input')\n let box = x.querySelector('.box')\n\n $(box).toggleClass('checked', inp.value)\n\n let hdl = function () {\n inp.value = 1 - inp.value\n $(box).toggleClass('checked', inp.value)\n }\n\n $(x).on('click', hdl).on('keypress', cr(hdl))\n })\n\n // Expanding boxes on mobile\n $('.Box.mobcol,.Box.fold').forEach(function (x) {\n let h = x.querySelector('h2')\n\n let hdl = function () {\n $(x).toggleClass('expanded')\n }\n $(h).on('click', hdl).on('keypress', cr(hdl))\n })\n\n $('form').forEach(function (x) {\n $(x).on('keypress', function (e) {\n if ((e.keyCode === 10 || e.keyCode === 13) && e.ctrlKey) {\n x.submit()\n }\n })\n })\n\n // loader dots...\n setInterval(function () {\n $('.anim-dots').each(function (x) {\n let $x = $(x)\n let dots = $x.html() + '.'\n if (dots.length === 5) dots = '.'\n $x.html(dots)\n })\n }, 1000)\n\n // flipping number boxes with the mouse wheel\n $('input[type=number]').on('mousewheel', function (e) {\n let $this = $(this)\n let val = +$this.val()\n if (isNaN(val)) val = 1\n\n const step = +($this.attr('step') || 1)\n const min = +$this.attr('min')\n const max = +$this.attr('max')\n if (e.wheelDelta > 0) {\n val += step\n } else {\n val -= step\n }\n\n if (undef(min)) val = Math.max(val, +min)\n if (undef(max)) val = Math.min(val, +max)\n $this.val(val)\n\n if ('createEvent' in document) {\n let evt = document.createEvent('HTMLEvents')\n evt.initEvent('change', false, true)\n $this[0].dispatchEvent(evt)\n } else {\n $this[0].fireEvent('onchange')\n }\n\n e.preventDefault()\n })\n\n // populate the form errors box from GET arg ?err=...\n // (a way to pass errors back from server via redirect)\n let errAt = location.search.indexOf('err=')\n if (errAt !== -1 && qs('.Box.errors')) {\n let errs = location.search.substr(errAt + 4).split(',')\n let hres = []\n errs.forEach(function (er) {\n let lbl = qs('label[for=\"' + er + '\"]')\n if (lbl) {\n lbl.classList.add('error')\n hres.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, ''))\n } else {\n hres.push(er)\n }\n })\n\n qs('.Box.errors .list').innerHTML = hres.join(', ')\n qs('.Box.errors').classList.remove('hidden')\n }\n\n Modal.init()\n Notify.init()\n\n // remove tabindixes from h2 if wide\n if (window.innerWidth > 550) {\n $('.Box h2').forEach(function (x) {\n x.removeAttribute('tabindex')\n })\n\n // brand works as a link back to term in widescreen mode\n let br = qs('#brand')\n br && br.addEventListener('click', function () {\n location.href = '/' // go to terminal\n })\n }\n})\n\n// setup the ajax loader\n$._loader = function (vis) {\n $('#loader').toggleClass('show', vis)\n}\n\n// reveal content on load\nfunction showPage () {\n $('#content').addClass('load')\n}\n\n// Auto reveal pages other than the terminal (sets window.noAutoShow)\n$.ready(function () {\n if (window.noAutoShow !== true) {\n setTimeout(function () {\n showPage()\n }, 1)\n }\n})\n","// Generated from PHP locale file\nlet _tr = {\n \"wifi.connected_ip_is\": \"Connected, IP is \",\n \"wifi.not_conn\": \"Not connected.\",\n \"wifi.enter_passwd\": \"Enter password for \\\":ssid:\\\"\"\n};\n\nfunction tr (key) { return _tr[key] || '?' + key + '?' }\n","(function (w) {\n const authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2']\n let curSSID\n\n // Get XX % for a slider input\n function rangePt (inp) {\n return Math.round(((inp.value / inp.max) * 100)) + '%'\n }\n\n // Display selected STA SSID etc\n function selectSta (name, password, ip) {\n $('#sta_ssid').val(name)\n $('#sta_password').val(password)\n\n $('#sta-nw').toggleClass('hidden', name.length === 0)\n $('#sta-nw-nil').toggleClass('hidden', name.length > 0)\n\n $('#sta-nw .essid').html(esc(name))\n const nopw = undef(password) || password.length === 0\n $('#sta-nw .passwd').toggleClass('hidden', nopw)\n $('#sta-nw .nopasswd').toggleClass('hidden', !nopw)\n $('#sta-nw .ip').html(ip.length > 0 ? tr('wifi.connected_ip_is') + ip : tr('wifi.not_conn'))\n }\n\n /** Update display for received response */\n function onScan (resp, status) {\n // var ap_json = {\n // \"result\": {\n // \"inProgress\": \"0\",\n // \"APs\": [\n // {\"essid\": \"Chlivek\", \"bssid\": \"88:f7:c7:52:b3:99\", \"rssi\": \"204\", \"enc\": \"4\", \"channel\": \"1\"},\n // {\"essid\": \"TyNikdy\", \"bssid\": \"5c:f4:ab:0d:f1:1b\", \"rssi\": \"164\", \"enc\": \"3\", \"channel\": \"1\"},\n // ]\n // }\n // };\n\n if (status !== 200) {\n // bad response\n rescan(5000) // wait 5sm then retry\n return\n }\n\n try {\n resp = JSON.parse(resp)\n } catch (e) {\n console.log(e)\n rescan(5000)\n return\n }\n\n const done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0)\n rescan(done ? 15000 : 1000)\n if (!done) return // no redraw yet\n\n // clear the AP list\n let $list = $('#ap-list')\n // remove old APs\n $('#ap-list .AP').remove()\n\n $list.toggleClass('hidden', !done)\n $('#ap-loader').toggleClass('hidden', done)\n\n // scan done\n resp.result.APs.sort(function (a, b) {\n return b.rssi - a.rssi\n }).forEach(function (ap) {\n ap.enc = parseInt(ap.enc)\n\n if (ap.enc > 4) return // hide unsupported auths\n\n let item = mk('div')\n\n let $item = $(item)\n .data('ssid', ap.essid)\n .data('pwd', ap.enc)\n .attr('tabindex', 0)\n .addClass('AP')\n\n // mark current SSID\n if (ap.essid === curSSID) {\n $item.addClass('selected')\n }\n\n let inner = mk('div')\n let escapedSSID = $.htmlEscape(ap.essid)\n $(inner).addClass('inner')\n .htmlAppend(`<div class=\"rssi\">${ap.rssi_perc}</div>`)\n .htmlAppend(`<div class=\"essid\" title=\"${escapedSSID}\">${escapedSSID}</div>`)\n .htmlAppend(`<div class=\"auth\">${authStr[ap.enc]}</div>`)\n\n $item.on('click', function () {\n let $th = $(this)\n\n const conn_ssid = $th.data('ssid')\n let conn_pass = ''\n\n if (+$th.data('pwd')) {\n // this AP needs a password\n conn_pass = prompt(tr('wifi.enter_passwd').replace(':ssid:', conn_ssid))\n if (!conn_pass) return\n }\n\n $('#sta_password').val(conn_pass)\n $('#sta_ssid').val(conn_ssid)\n selectSta(conn_ssid, conn_pass, '')\n })\n\n item.appendChild(inner)\n $list[0].appendChild(item)\n })\n }\n\n function startScanning () {\n $('#ap-loader').removeClass('hidden')\n $('#ap-scan').addClass('hidden')\n $('#ap-loader .anim-dots').html('.')\n\n scanAPs()\n }\n\n /** Ask the CGI what APs are visible (async) */\n function scanAPs () {\n if (_demo) {\n onScan(_demo_aps, 200)\n } else {\n $.get('http://' + _root + '/cfg/wifi/scan', onScan)\n }\n }\n\n function rescan (time) {\n setTimeout(scanAPs, time)\n }\n\n /** Set up the WiFi page */\n function wifiInit (cfg) {\n // Update slider value displays\n $('.Row.range').forEach(function (x) {\n let inp = x.querySelector('input')\n let disp1 = x.querySelector('.x-disp1')\n let disp2 = x.querySelector('.x-disp2')\n let t = rangePt(inp)\n $(disp1).html(t)\n $(disp2).html(t)\n $(inp).on('input', function () {\n t = rangePt(inp)\n $(disp1).html(t)\n $(disp2).html(t)\n })\n })\n\n // Forget STA credentials\n $('#forget-sta').on('click', function () {\n selectSta('', '', '')\n return false\n })\n\n selectSta(cfg.sta_ssid, cfg.sta_password, cfg.sta_active_ip)\n curSSID = cfg.sta_active_ssid\n }\n\n w.init = wifiInit\n w.startScanning = startScanning\n})(window.WiFi = {})\n","/** Handle connections */\nwindow.Conn = (function () {\n let ws\n let heartbeatTout\n let pingIv\n let xoff = false\n let autoXoffTout\n let reconTout\n\n let pageShown = false\n\n function onOpen (evt) {\n console.log('CONNECTED')\n heartbeat()\n doSend('i')\n }\n\n function onClose (evt) {\n console.warn('SOCKET CLOSED, code ' + evt.code + '. Reconnecting...')\n clearTimeout(reconTout)\n reconTout = setTimeout(function () {\n init()\n }, 2000)\n // this happens when the buffer gets fucked up via invalid unicode.\n // we basically use polling instead of socket then\n }\n\n function onMessage (evt) {\n try {\n // . = heartbeat\n switch (evt.data.charAt(0)) {\n case '.':\n // heartbeat, no-op message\n break\n\n case '-':\n // console.log('xoff');\n xoff = true\n autoXoffTout = setTimeout(function () {\n xoff = false\n }, 250)\n break\n\n case '+':\n // console.log('xon');\n xoff = false\n clearTimeout(autoXoffTout)\n break\n\n default:\n Screen.load(evt.data)\n if (!pageShown) {\n showPage()\n pageShown = true\n }\n break\n }\n heartbeat()\n } catch (e) {\n console.error(e)\n }\n }\n\n function canSend () {\n return !xoff\n }\n\n function doSend (message) {\n if (_demo) {\n console.log('TX: ', message)\n return true // Simulate success\n }\n if (xoff) {\n // TODO queue\n console.log(\"Can't send, flood control.\")\n return false\n }\n\n if (!ws) return false // for dry testing\n if (ws.readyState !== 1) {\n console.error('Socket not ready')\n return false\n }\n if (typeof message != 'string') {\n message = JSON.stringify(message)\n }\n ws.send(message)\n return true\n }\n\n function init () {\n if (_demo) {\n console.log('Demo mode!')\n Screen.load(_demo_screen)\n showPage()\n return\n }\n\n clearTimeout(reconTout)\n clearTimeout(heartbeatTout)\n\n ws = new WebSocket('ws://' + _root + '/term/update.ws')\n ws.onopen = onOpen\n ws.onclose = onClose\n ws.onmessage = onMessage\n console.log('Opening socket.')\n heartbeat()\n }\n\n function heartbeat () {\n clearTimeout(heartbeatTout)\n heartbeatTout = setTimeout(heartbeatFail, 2000)\n }\n\n function heartbeatFail () {\n console.error('Heartbeat lost, probing server...')\n pingIv = setInterval(function () {\n console.log('> ping')\n $.get('http://' + _root + '/system/ping', function (resp, status) {\n if (status === 200) {\n clearInterval(pingIv)\n console.info('Server ready, reloading page...')\n location.reload()\n }\n }, {\n timeout: 100\n })\n }, 1000)\n }\n\n return {\n ws: null,\n init: init,\n send: doSend,\n canSend: canSend // check flood control\n }\n})()\n","/**\n * User input\n *\n * --- Rx messages: ---\n * S - screen content (binary encoding of the entire screen with simple compression)\n * T - text labels - Title and buttons, \\0x01-separated\n * B - beep\n * . - heartbeat\n *\n * --- Tx messages ---\n * s - string\n * b - action button\n * p - mb press\n * r - mb release\n * m - mouse move\n */\nwindow.Input = (function () {\n let opts = {\n np_alt: false,\n cu_alt: false,\n fn_alt: false,\n mt_click: false,\n mt_move: false,\n no_keys: false,\n crlf_mode: false\n }\n\n /** Send a literal message */\n function sendStrMsg (str) {\n return Conn.send('s' + str)\n }\n\n /** Send a button event */\n function sendBtnMsg (n) {\n Conn.send('b' + Chr(n))\n }\n\n /** Fn alt choice for key message */\n function fa (alt, normal) {\n return opts.fn_alt ? alt : normal\n }\n\n /** Cursor alt choice for key message */\n function ca (alt, normal) {\n return opts.cu_alt ? alt : normal\n }\n\n /** Numpad alt choice for key message */\n function na (alt, normal) {\n return opts.np_alt ? alt : normal\n }\n\n function _bindFnKeys () {\n const keymap = {\n 'tab': '\\x09',\n 'backspace': '\\x08',\n 'enter': opts.crlf_mode ? '\\x0d\\x0a' : '\\x0d',\n 'ctrl+enter': '\\x0a',\n 'esc': '\\x1b',\n 'up': ca('\\x1bOA', '\\x1b[A'),\n 'down': ca('\\x1bOB', '\\x1b[B'),\n 'right': ca('\\x1bOC', '\\x1b[C'),\n 'left': ca('\\x1bOD', '\\x1b[D'),\n 'home': ca('\\x1bOH', fa('\\x1b[H', '\\x1b[1~')),\n 'insert': '\\x1b[2~',\n 'delete': '\\x1b[3~',\n 'end': ca('\\x1bOF', fa('\\x1b[F', '\\x1b[4~')),\n 'pageup': '\\x1b[5~',\n 'pagedown': '\\x1b[6~',\n 'f1': fa('\\x1bOP', '\\x1b[11~'),\n 'f2': fa('\\x1bOQ', '\\x1b[12~'),\n 'f3': fa('\\x1bOR', '\\x1b[13~'),\n 'f4': fa('\\x1bOS', '\\x1b[14~'),\n 'f5': '\\x1b[15~', // note the disconnect\n 'f6': '\\x1b[17~',\n 'f7': '\\x1b[18~',\n 'f8': '\\x1b[19~',\n 'f9': '\\x1b[20~',\n 'f10': '\\x1b[21~', // note the disconnect\n 'f11': '\\x1b[23~',\n 'f12': '\\x1b[24~',\n 'shift+f1': fa('\\x1bO1;2P', '\\x1b[25~'),\n 'shift+f2': fa('\\x1bO1;2Q', '\\x1b[26~'), // note the disconnect\n 'shift+f3': fa('\\x1bO1;2R', '\\x1b[28~'),\n 'shift+f4': fa('\\x1bO1;2S', '\\x1b[29~'), // note the disconnect\n 'shift+f5': fa('\\x1b[15;2~', '\\x1b[31~'),\n 'shift+f6': fa('\\x1b[17;2~', '\\x1b[32~'),\n 'shift+f7': fa('\\x1b[18;2~', '\\x1b[33~'),\n 'shift+f8': fa('\\x1b[19;2~', '\\x1b[34~'),\n 'shift+f9': fa('\\x1b[20;2~', '\\x1b[35~'), // 35-38 are not standard - but what is?\n 'shift+f10': fa('\\x1b[21;2~', '\\x1b[36~'),\n 'shift+f11': fa('\\x1b[22;2~', '\\x1b[37~'),\n 'shift+f12': fa('\\x1b[23;2~', '\\x1b[38~'),\n 'np_0': na('\\x1bOp', '0'),\n 'np_1': na('\\x1bOq', '1'),\n 'np_2': na('\\x1bOr', '2'),\n 'np_3': na('\\x1bOs', '3'),\n 'np_4': na('\\x1bOt', '4'),\n 'np_5': na('\\x1bOu', '5'),\n 'np_6': na('\\x1bOv', '6'),\n 'np_7': na('\\x1bOw', '7'),\n 'np_8': na('\\x1bOx', '8'),\n 'np_9': na('\\x1bOy', '9'),\n 'np_mul': na('\\x1bOR', '*'),\n 'np_add': na('\\x1bOl', '+'),\n 'np_sub': na('\\x1bOS', '-'),\n 'np_point': na('\\x1bOn', '.'),\n 'np_div': na('\\x1bOQ', '/')\n // we don't implement numlock key (should change in numpad_alt mode, but it's even more useless than the rest)\n }\n\n for (let k in keymap) {\n if (keymap.hasOwnProperty(k)) {\n bind(k, keymap[k])\n }\n }\n }\n\n /** Bind a keystroke to message */\n function bind (combo, str) {\n // mac fix - allow also cmd\n if (combo.indexOf('ctrl+') !== -1) {\n combo += ',' + combo.replace('ctrl', 'command')\n }\n\n // unbind possible old binding\n key.unbind(combo)\n\n key(combo, function (e) {\n if (opts.no_keys) return\n e.preventDefault()\n sendStrMsg(str)\n })\n }\n\n /** Bind/rebind key messages */\n function _initKeys () {\n // This takes care of text characters typed\n window.addEventListener('keypress', function (evt) {\n if (opts.no_keys) return\n let str = ''\n if (evt.key) str = evt.key\n else if (evt.which) str = String.fromCodePoint(evt.which)\n if (str.length > 0 && str.charCodeAt(0) >= 32) {\n // console.log(\"Typed \", str);\n // prevent space from scrolling\n if (evt.which === 32) evt.preventDefault()\n sendStrMsg(str)\n }\n })\n\n // ctrl-letter codes are sent as simple low ASCII codes\n for (let i = 1; i <= 26; i++) {\n bind('ctrl+' + String.fromCharCode(96 + i), String.fromCharCode(i))\n }\n /* eslint-disable */\n bind('ctrl+]', '\\x1b') // alternate way to enter ESC\n bind('ctrl+\\\\', '\\x1c')\n bind('ctrl+[', '\\x1d')\n bind('ctrl+^', '\\x1e')\n bind('ctrl+_', '\\x1f')\n\n // extra ctrl-\n bind('ctrl+left', '\\x1f[1;5D')\n bind('ctrl+right', '\\x1f[1;5C')\n bind('ctrl+up', '\\x1f[1;5A')\n bind('ctrl+down', '\\x1f[1;5B')\n bind('ctrl+home', '\\x1f[1;5H')\n bind('ctrl+end', '\\x1f[1;5F')\n\n // extra shift-\n bind('shift+left', '\\x1f[1;2D')\n bind('shift+right', '\\x1f[1;2C')\n bind('shift+up', '\\x1f[1;2A')\n bind('shift+down', '\\x1f[1;2B')\n bind('shift+home', '\\x1f[1;2H')\n bind('shift+end', '\\x1f[1;2F')\n\n // macOS editing commands\n bind('⌥+left', '\\x1fb') // ⌥← to go back a word (^[b)\n bind('⌥+right', '\\x1ff') // ⌥→ to go forward one word (^[f)\n bind('⌘+left', '\\x01') // ⌘← to go to the beginning of a line (^A)\n bind('⌘+right', '\\x05') // ⌘→ to go to the end of a line (^E)\n bind('⌥+backspace', '\\x17') // ⌥⌫ to delete a word (^W, I think)\n bind('⌘+backspace', '\\x15') // ⌘⌫ to delete to the beginning of a line (possibly ^U)\n /* eslint-enable */\n\n _bindFnKeys()\n }\n\n // mouse button states\n let mb1 = 0\n let mb2 = 0\n let mb3 = 0\n\n /** Init the Input module */\n function init () {\n _initKeys()\n\n // Button presses\n $('#action-buttons button').forEach(function (s) {\n s.addEventListener('click', function () {\n sendBtnMsg(+this.dataset['n'])\n })\n })\n\n // global mouse state tracking - for motion reporting\n window.addEventListener('mousedown', function (evt) {\n if (evt.button === 0) mb1 = 1\n if (evt.button === 1) mb2 = 1\n if (evt.button === 2) mb3 = 1\n })\n\n window.addEventListener('mouseup', function (evt) {\n if (evt.button === 0) mb1 = 0\n if (evt.button === 1) mb2 = 0\n if (evt.button === 2) mb3 = 0\n })\n }\n\n /** Prepare modifiers byte for mouse message */\n function packModifiersForMouse () {\n return (key.isModifier('ctrl') ? 1 : 0) |\n (key.isModifier('shift') ? 2 : 0) |\n (key.isModifier('alt') ? 4 : 0) |\n (key.isModifier('meta') ? 8 : 0)\n }\n\n return {\n /** Init the Input module */\n init: init,\n\n /** Send a literal string message */\n sendString: sendStrMsg,\n\n /** Enable alternate key modes (cursors, numpad, fn) */\n setAlts: function (cu, np, fn, crlf) {\n if (opts.cu_alt !== cu || opts.np_alt !== np || opts.fn_alt !== fn || opts.crlf_mode !== crlf) {\n opts.cu_alt = cu\n opts.np_alt = np\n opts.fn_alt = fn\n opts.crlf_mode = crlf\n\n // rebind keys - codes have changed\n _bindFnKeys()\n }\n },\n\n setMouseMode: function (click, move) {\n opts.mt_click = click\n opts.mt_move = move\n },\n\n // Mouse events\n onMouseMove: function (x, y) {\n if (!opts.mt_move) return\n const b = mb1 ? 1 : mb2 ? 2 : mb3 ? 3 : 0\n const m = packModifiersForMouse()\n Conn.send('m' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n },\n\n onMouseDown: function (x, y, b) {\n if (!opts.mt_click) return\n if (b > 3 || b < 1) return\n const m = packModifiersForMouse()\n Conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n // console.log(\"B \",b,\" M \",m);\n },\n\n onMouseUp: function (x, y, b) {\n if (!opts.mt_click) return\n if (b > 3 || b < 1) return\n const m = packModifiersForMouse()\n Conn.send('r' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n // console.log(\"B \",b,\" M \",m);\n },\n\n onMouseWheel: function (x, y, dir) {\n if (!opts.mt_click) return\n // -1 ... btn 4 (away from user)\n // +1 ... btn 5 (towards user)\n const m = packModifiersForMouse()\n const b = (dir < 0 ? 4 : 5)\n Conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n // console.log(\"B \",b,\" M \",m);\n },\n\n mouseTracksClicks: function () {\n return opts.mt_click\n },\n\n blockKeys: function (yes) {\n opts.no_keys = yes\n }\n }\n})()\n","// Some non-bold Fraktur symbols are outside the contiguous block\nconst frakturExceptions = {\n 'C': '\\u212d',\n 'H': '\\u210c',\n 'I': '\\u2111',\n 'R': '\\u211c',\n 'Z': '\\u2128'\n}\n\n// constants for decoding the update blob\nconst SEQ_REPEAT = 2\nconst SEQ_SET_COLORS = 3\nconst SEQ_SET_ATTRS = 4\nconst SEQ_SET_FG = 5\nconst SEQ_SET_BG = 6\n\nconst SELECTION_BG = '#b2d7fe'\nconst SELECTION_FG = '#333'\n\nconst themes = [\n [ // Tango\n '#111213', '#CC0000', '#4E9A06', '#C4A000', '#3465A4', '#75507B', '#06989A', '#D3D7CF',\n '#555753', '#EF2929', '#8AE234', '#FCE94F', '#729FCF', '#AD7FA8', '#34E2E2', '#EEEEEC'\n ],\n [ // Linux\n '#000000', '#aa0000', '#00aa00', '#aa5500', '#0000aa', '#aa00aa', '#00aaaa', '#aaaaaa',\n '#555555', '#ff5555', '#55ff55', '#ffff55', '#5555ff', '#ff55ff', '#55ffff', '#ffffff'\n ],\n [ // xterm\n '#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000ee', '#cd00cd', '#00cdcd', '#e5e5e5',\n '#7f7f7f', '#ff0000', '#00ff00', '#ffff00', '#5c5cff', '#ff00ff', '#00ffff', '#ffffff'\n ],\n [ // rxvt\n '#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000cd', '#cd00cd', '#00cdcd', '#faebd7',\n '#404040', '#ff0000', '#00ff00', '#ffff00', '#0000ff', '#ff00ff', '#00ffff', '#ffffff'\n ],\n [ // Ambience\n '#2e3436', '#cc0000', '#4e9a06', '#c4a000', '#3465a4', '#75507b', '#06989a', '#d3d7cf',\n '#555753', '#ef2929', '#8ae234', '#fce94f', '#729fcf', '#ad7fa8', '#34e2e2', '#eeeeec'\n ],\n [ // Solarized\n '#073642', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#eee8d5',\n '#002b36', '#cb4b16', '#586e75', '#657b83', '#839496', '#6c71c4', '#93a1a1', '#fdf6e3'\n ]\n]\n\n// TODO move this to the initializer so it's not run on non-terminal pages\n\n// 256color lookup table\n// should not be used to look up 0-15 (will return transparent)\nconst colorTable256 = new Array(16).fill('rgba(0, 0, 0, 0)')\n\n// fill color table\n// colors 16-231 are a 6x6x6 color cube\nfor (let red = 0; red < 6; red++) {\n for (let green = 0; green < 6; green++) {\n for (let blue = 0; blue < 6; blue++) {\n let redValue = red * 40 + (red ? 55 : 0)\n let greenValue = green * 40 + (green ? 55 : 0)\n let blueValue = blue * 40 + (blue ? 55 : 0)\n colorTable256.push(`rgb(${redValue}, ${greenValue}, ${blueValue})`)\n }\n }\n}\n// colors 232-255 are a grayscale ramp, sans black and white\nfor (let gray = 0; gray < 24; gray++) {\n let value = gray * 10 + 8\n colorTable256.push(`rgb(${value}, ${value}, ${value})`)\n}\n\nclass TermScreen {\n constructor () {\n this.canvas = mk('canvas')\n this.ctx = this.canvas.getContext('2d')\n\n if ('AudioContext' in window || 'webkitAudioContext' in window) {\n this.audioCtx = new (window.AudioContext || window.webkitAudioContext)()\n } else {\n console.warn('No AudioContext!')\n }\n\n this.cursor = {\n x: 0,\n y: 0,\n fg: 7,\n bg: 0,\n attrs: 0,\n blinkOn: false,\n blinking: true,\n visible: true,\n hanging: false,\n style: 'block',\n blinkEnable: true,\n blinkInterval: 0\n }\n\n this._palette = null\n\n this._window = {\n width: 0,\n height: 0,\n devicePixelRatio: 1,\n fontFamily: '\"DejaVu Sans Mono\", \"Liberation Mono\", \"Inconsolata\", \"Menlo\", monospace',\n fontSize: 20,\n gridScaleX: 1.0,\n gridScaleY: 1.2,\n blinkStyleOn: true,\n blinkInterval: null,\n fitIntoWidth: 0,\n fitIntoHeight: 0,\n debug: false\n }\n\n // properties of this.window that require updating size and redrawing\n this.windowState = {\n width: 0,\n height: 0,\n devicePixelRatio: 0,\n gridScaleX: 0,\n gridScaleY: 0,\n fontFamily: '',\n fontSize: 0,\n fitIntoWidth: 0,\n fitIntoHeight: 0\n }\n\n // current selection\n this.selection = {\n // when false, this will prevent selection in favor of mouse events,\n // though alt can be held to override it\n selectable: true,\n\n start: [0, 0],\n end: [0, 0]\n }\n\n this.mouseMode = { clicks: false, movement: false }\n\n // event listeners\n this._listeners = {}\n\n const self = this\n this.window = new Proxy(this._window, {\n set (target, key, value, receiver) {\n target[key] = value\n self.scheduleSizeUpdate()\n self.scheduleDraw(`window:${key}=${value}`)\n return true\n }\n })\n\n this.blinkingCellCount = 0\n\n this.screen = []\n this.screenFG = []\n this.screenBG = []\n this.screenAttrs = []\n\n // used to determine if a cell should be redrawn\n this.drawnScreen = []\n this.drawnScreenFG = []\n this.drawnScreenBG = []\n this.drawnScreenAttrs = []\n\n this.resetBlink()\n this.resetCursorBlink()\n\n let selecting = false\n\n let selectStart = (x, y) => {\n if (selecting) return\n selecting = true\n this.selection.start = this.selection.end = this.screenToGrid(x, y)\n this.scheduleDraw('select-start')\n }\n\n let selectMove = (x, y) => {\n if (!selecting) return\n this.selection.end = this.screenToGrid(x, y)\n this.scheduleDraw('select-move')\n }\n\n let selectEnd = (x, y) => {\n if (!selecting) return\n selecting = false\n this.selection.end = this.screenToGrid(x, y)\n this.scheduleDraw('select-end')\n Object.assign(this.selection, this.getNormalizedSelection())\n }\n\n this.canvas.addEventListener('mousedown', e => {\n if ((this.selection.selectable || e.altKey) && e.button === 0) {\n selectStart(e.offsetX, e.offsetY)\n } else {\n Input.onMouseDown(...this.screenToGrid(e.offsetX, e.offsetY),\n e.button + 1)\n }\n })\n\n window.addEventListener('mousemove', e => {\n selectMove(e.offsetX, e.offsetY)\n })\n\n window.addEventListener('mouseup', e => {\n selectEnd(e.offsetX, e.offsetY)\n })\n\n let touchPosition = null\n let touchDownTime = 0\n let touchSelectMinTime = 500\n let touchDidMove = false\n\n let getTouchPositionOffset = touch => {\n let rect = this.canvas.getBoundingClientRect()\n return [touch.clientX - rect.left, touch.clientY - rect.top]\n }\n\n this.canvas.addEventListener('touchstart', e => {\n touchPosition = getTouchPositionOffset(e.touches[0])\n touchDidMove = false\n touchDownTime = Date.now()\n })\n\n this.canvas.addEventListener('touchmove', e => {\n touchPosition = getTouchPositionOffset(e.touches[0])\n\n if (!selecting && touchDidMove === false) {\n if (touchDownTime < Date.now() - touchSelectMinTime) {\n selectStart(...touchPosition)\n }\n } else if (selecting) {\n e.preventDefault()\n selectMove(...touchPosition)\n }\n\n touchDidMove = true\n })\n\n this.canvas.addEventListener('touchend', e => {\n if (e.touches[0]) {\n touchPosition = getTouchPositionOffset(e.touches[0])\n }\n\n if (selecting) {\n e.preventDefault()\n selectEnd(...touchPosition)\n\n let touchSelectMenu = qs('#touch-select-menu')\n touchSelectMenu.classList.add('open')\n let rect = touchSelectMenu.getBoundingClientRect()\n\n // use middle position for x and one line above for y\n let selectionPos = this.gridToScreen(\n (this.selection.start[0] + this.selection.end[0]) / 2,\n this.selection.start[1] - 1\n )\n selectionPos[0] -= rect.width / 2\n selectionPos[1] -= rect.height / 2\n touchSelectMenu.style.transform = `translate(${selectionPos[0]}px, ${\n selectionPos[1]}px)`\n }\n\n if (!touchDidMove) {\n this.emit('tap', Object.assign(e, {\n x: touchPosition[0],\n y: touchPosition[1]\n }))\n }\n\n touchPosition = null\n })\n\n this.on('tap', e => {\n if (this.selection.start[0] !== this.selection.end[0] ||\n this.selection.start[1] !== this.selection.end[1]) {\n // selection is not empty\n // reset selection\n this.selection.start = this.selection.end = [0, 0]\n qs('#touch-select-menu').classList.remove('open')\n this.scheduleDraw('select-reset')\n } else {\n e.preventDefault()\n this.emit('open-soft-keyboard')\n }\n })\n\n $.ready(() => {\n let copyButton = qs('#touch-select-copy-btn')\n if (copyButton) {\n copyButton.addEventListener('click', () => {\n this.copySelectionToClipboard()\n })\n }\n })\n\n this.canvas.addEventListener('mousemove', e => {\n if (!selecting) {\n Input.onMouseMove(...this.screenToGrid(e.offsetX, e.offsetY))\n }\n })\n\n this.canvas.addEventListener('mouseup', e => {\n if (!selecting) {\n Input.onMouseUp(...this.screenToGrid(e.offsetX, e.offsetY),\n e.button + 1)\n }\n })\n\n this.canvas.addEventListener('wheel', e => {\n if (this.mouseMode.clicks) {\n Input.onMouseWheel(...this.screenToGrid(e.offsetX, e.offsetY),\n e.deltaY > 0 ? 1 : -1)\n\n // prevent page scrolling\n e.preventDefault()\n }\n })\n\n this.canvas.addEventListener('contextmenu', e => {\n if (this.mouseMode.clicks) {\n // prevent mouse keys getting stuck\n e.preventDefault()\n }\n selectEnd(e.offsetX, e.offsetY)\n })\n\n // bind ctrl+shift+c to copy\n key('⌃+⇧+c', e => {\n e.preventDefault()\n this.copySelectionToClipboard()\n })\n }\n\n on (event, listener) {\n if (!this._listeners[event]) this._listeners[event] = []\n this._listeners[event].push({ listener })\n }\n\n once (event, listener) {\n if (!this._listeners[event]) this._listeners[event] = []\n this._listeners[event].push({ listener, once: true })\n }\n\n off (event, listener) {\n let listeners = this._listeners[event]\n if (listeners) {\n for (let i in listeners) {\n if (listeners[i].listener === listener) {\n listeners.splice(i, 1)\n break\n }\n }\n }\n }\n\n emit (event, ...args) {\n let listeners = this._listeners[event]\n if (listeners) {\n let remove = []\n for (let listener of listeners) {\n try {\n listener.listener(...args)\n if (listener.once) remove.push(listener)\n } catch (err) {\n console.error(err)\n }\n }\n\n // this needs to be done in this roundabout way because for loops\n // do not like arrays with changing lengths\n for (let listener of remove) {\n listeners.splice(listeners.indexOf(listener), 1)\n }\n }\n }\n\n get palette () {\n return this._palette || themes[0]\n }\n\n set palette (palette) {\n if (this._palette !== palette) {\n this._palette = palette\n this.scheduleDraw('palette')\n }\n }\n\n getColor (i) {\n // return palette color if it exists\n if (this.palette[i]) return this.palette[i]\n\n // -1 for selection foreground, -2 for selection background\n if (i === -1) return SELECTION_FG\n if (i === -2) return SELECTION_BG\n\n // 256 color\n if (i > 15 && i < 256) return colorTable256[i]\n\n // true color, encoded as (hex) + 256 (such that #000 == 256)\n if (i > 255) {\n i -= 256\n let red = (i >> 16) & 0xFF\n let green = (i >> 8) & 0xFF\n let blue = i & 0xFF\n return `rgb(${red}, ${green}, ${blue})`\n }\n\n // default to transparent\n return 'rgba(0, 0, 0, 0)'\n }\n\n // schedule a size update in the next tick\n scheduleSizeUpdate () {\n clearTimeout(this._scheduledSizeUpdate)\n this._scheduledSizeUpdate = setTimeout(() => this.updateSize(), 1)\n }\n\n // schedule a draw in the next tick\n scheduleDraw (why, aggregateTime = 1) {\n clearTimeout(this._scheduledDraw)\n this._scheduledDraw = setTimeout(() => this.draw(why), aggregateTime)\n }\n\n getFont (modifiers = {}) {\n let fontStyle = modifiers.style || 'normal'\n let fontWeight = modifiers.weight || 'normal'\n return `${fontStyle} normal ${fontWeight} ${this.window.fontSize}px ${this.window.fontFamily}`\n }\n\n getCharSize () {\n this.ctx.font = this.getFont()\n\n return {\n width: Math.floor(this.ctx.measureText(' ').width),\n height: this.window.fontSize\n }\n }\n\n getCellSize () {\n let charSize = this.getCharSize()\n\n return {\n width: Math.ceil(charSize.width * this.window.gridScaleX),\n height: Math.ceil(charSize.height * this.window.gridScaleY)\n }\n }\n\n updateSize () {\n this._window.devicePixelRatio = window.devicePixelRatio || 1\n\n let didChange = false\n for (let key in this.windowState) {\n if (this.windowState.hasOwnProperty(key) && this.windowState[key] !== this.window[key]) {\n didChange = true\n this.windowState[key] = this.window[key]\n }\n }\n\n if (didChange) {\n const {\n width,\n height,\n devicePixelRatio,\n gridScaleX,\n gridScaleY,\n fitIntoWidth,\n fitIntoHeight\n } = this.window\n const cellSize = this.getCellSize()\n\n // real height of the canvas element in pixels\n let realWidth = width * cellSize.width\n let realHeight = height * cellSize.height\n\n if (fitIntoWidth && fitIntoHeight) {\n if (realWidth > fitIntoWidth || realHeight > fitIntoHeight) {\n let terminalAspect = realWidth / realHeight\n let fitAspect = fitIntoWidth / fitIntoHeight\n\n if (terminalAspect < fitAspect) {\n // align heights\n realHeight = fitIntoHeight\n realWidth = realHeight * terminalAspect\n } else {\n // align widths\n realWidth = fitIntoWidth\n realHeight = realWidth / terminalAspect\n }\n }\n } else if (fitIntoWidth && realWidth > fitIntoWidth) {\n realHeight = fitIntoWidth / (realWidth / realHeight)\n realWidth = fitIntoWidth\n } else if (fitIntoHeight && realHeight > fitIntoHeight) {\n realWidth = fitIntoHeight * (realWidth / realHeight)\n realHeight = fitIntoHeight\n }\n\n this.canvas.width = width * devicePixelRatio * cellSize.width\n this.canvas.style.width = `${realWidth}px`\n this.canvas.height = height * devicePixelRatio * cellSize.height\n this.canvas.style.height = `${realHeight}px`\n\n // the screen has been cleared (by changing canvas width)\n this.drawnScreen = []\n this.drawnScreenFG = []\n this.drawnScreenBG = []\n this.drawnScreenAttrs = []\n\n // draw immediately; the canvas shouldn't flash\n this.draw('init')\n }\n }\n\n resetCursorBlink () {\n this.cursor.blinkOn = true\n clearInterval(this.cursor.blinkInterval)\n this.cursor.blinkInterval = setInterval(() => {\n this.cursor.blinkOn = this.cursor.blinking\n ? !this.cursor.blinkOn\n : true\n if (this.cursor.blinking) this.scheduleDraw('cursor-blink')\n }, 500)\n }\n\n resetBlink () {\n this.window.blinkStyleOn = true\n clearInterval(this.window.blinkInterval)\n let intervals = 0\n this.window.blinkInterval = setInterval(() => {\n if (this.blinkingCellCount <= 0) return\n\n intervals++\n if (intervals >= 4 && this.window.blinkStyleOn) {\n this.window.blinkStyleOn = false\n intervals = 0\n } else if (intervals >= 1 && !this.window.blinkStyleOn) {\n this.window.blinkStyleOn = true\n intervals = 0\n }\n }, 200)\n }\n\n getNormalizedSelection () {\n let { start, end } = this.selection\n // if the start line is after the end line, or if they're both on the same\n // line but the start column comes after the end column, swap\n if (start[1] > end[1] || (start[1] === end[1] && start[0] > end[0])) {\n [start, end] = [end, start]\n }\n return { start, end }\n }\n\n isInSelection (col, line) {\n let { start, end } = this.getNormalizedSelection()\n let colAfterStart = start[0] <= col\n let colBeforeEnd = col < end[0]\n let onStartLine = line === start[1]\n let onEndLine = line === end[1]\n\n if (onStartLine && onEndLine) return colAfterStart && colBeforeEnd\n else if (onStartLine) return colAfterStart\n else if (onEndLine) return colBeforeEnd\n else return start[1] < line && line < end[1]\n }\n\n getSelectedText () {\n const screenLength = this.window.width * this.window.height\n let lines = []\n let previousLineIndex = -1\n\n for (let cell = 0; cell < screenLength; cell++) {\n let x = cell % this.window.width\n let y = Math.floor(cell / this.window.width)\n\n if (this.isInSelection(x, y)) {\n if (previousLineIndex !== y) {\n previousLineIndex = y\n lines.push('')\n }\n lines[lines.length - 1] += this.screen[cell]\n }\n }\n\n return lines.join('\\n')\n }\n\n copySelectionToClipboard () {\n let selectedText = this.getSelectedText()\n // don't copy anything if nothing is selected\n if (!selectedText) return\n let textarea = mk('textarea')\n document.body.appendChild(textarea)\n textarea.value = selectedText\n textarea.select()\n if (document.execCommand('copy')) {\n Notify.show('Copied to clipboard')\n } else {\n Notify.show('Failed to copy')\n }\n document.body.removeChild(textarea)\n }\n\n screenToGrid (x, y) {\n let cellSize = this.getCellSize()\n\n return [\n Math.floor((x + cellSize.width / 2) / cellSize.width),\n Math.floor(y / cellSize.height)\n ]\n }\n\n gridToScreen (x, y) {\n let cellSize = this.getCellSize()\n\n return [ x * cellSize.width, y * cellSize.height ]\n }\n\n drawCellBackground ({ x, y, cellWidth, cellHeight, bg }) {\n const ctx = this.ctx\n ctx.fillStyle = this.getColor(bg)\n ctx.clearRect(x * cellWidth, y * cellHeight, Math.ceil(cellWidth), Math.ceil(cellHeight))\n ctx.fillRect(x * cellWidth, y * cellHeight, Math.ceil(cellWidth), Math.ceil(cellHeight))\n }\n\n drawCell ({ x, y, charSize, cellWidth, cellHeight, text, fg, bg, attrs }) {\n if (!text) return\n\n const ctx = this.ctx\n\n let underline = false\n let strike = false\n let overline = false\n if (attrs & (1 << 1)) ctx.globalAlpha = 0.5\n if (attrs & (1 << 3)) underline = true\n if (attrs & (1 << 5)) text = TermScreen.alphaToFraktur(text)\n if (attrs & (1 << 6)) strike = true\n if (attrs & (1 << 7)) overline = true\n\n ctx.fillStyle = this.getColor(fg)\n ctx.fillText(text, (x + 0.5) * cellWidth, (y + 0.5) * cellHeight)\n\n if (underline || strike || overline) {\n ctx.strokeStyle = this.getColor(fg)\n ctx.lineWidth = 1\n ctx.lineCap = 'round'\n ctx.beginPath()\n\n if (underline) {\n let lineY = Math.round(y * cellHeight + charSize.height) + 0.5\n ctx.moveTo(x * cellWidth, lineY)\n ctx.lineTo((x + 1) * cellWidth, lineY)\n }\n\n if (strike) {\n let lineY = Math.round((y + 0.5) * cellHeight) + 0.5\n ctx.moveTo(x * cellWidth, lineY)\n ctx.lineTo((x + 1) * cellWidth, lineY)\n }\n\n if (overline) {\n let lineY = Math.round(y * cellHeight) + 0.5\n ctx.moveTo(x * cellWidth, lineY)\n ctx.lineTo((x + 1) * cellWidth, lineY)\n }\n\n ctx.stroke()\n }\n\n ctx.globalAlpha = 1\n }\n\n getAdjacentCells (cell, radius = 1) {\n const { width, height } = this.window\n const screenLength = width * height\n\n let cells = []\n\n for (let x = -radius; x <= radius; x++) {\n for (let y = -radius; y <= radius; y++) {\n if (x === 0 && y === 0) continue\n cells.push(cell + x + y * width)\n }\n }\n\n return cells.filter(cell => cell >= 0 && cell < screenLength)\n }\n\n draw (why) {\n const ctx = this.ctx\n const {\n width,\n height,\n devicePixelRatio,\n gridScaleX,\n gridScaleY\n } = this.window\n\n const charSize = this.getCharSize()\n const { width: cellWidth, height: cellHeight } = this.getCellSize()\n const screenWidth = width * cellWidth\n const screenHeight = height * cellHeight\n const screenLength = width * height\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0)\n\n if (this.window.debug) {\n // differentiate static cells from updated cells\n ctx.fillStyle = 'rgba(255, 0, 255, 0.3)'\n ctx.fillRect(0, 0, screenWidth, screenHeight)\n console.log(`draw: ${why}`)\n }\n\n ctx.font = this.getFont()\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n\n // bits in the attr value that affect the font\n const FONT_MASK = 0b101\n\n // Map of (attrs & FONT_MASK) -> Array of cell indices\n let fontGroups = new Map()\n\n // Map of (cell index) -> boolean, whether or not a cell has updated\n let updateMap = new Map()\n\n for (let cell = 0; cell < screenLength; cell++) {\n let x = cell % width\n let y = Math.floor(cell / width)\n let isCursor = !this.cursor.hanging &&\n this.cursor.x === x &&\n this.cursor.y === y\n\n let invertForCursor = isCursor && this.cursor.blinkOn &&\n this.cursor.style === 'block'\n\n let inSelection = this.isInSelection(x, y)\n\n let text = this.screen[cell]\n let fg = invertForCursor ? this.screenBG[cell] : this.screenFG[cell]\n let bg = invertForCursor ? this.screenFG[cell] : this.screenBG[cell]\n let attrs = this.screenAttrs[cell]\n\n if (attrs & (1 << 4) && !this.window.blinkStyleOn) {\n // blinking is enabled and blink style is off\n // set text to nothing so drawCell doesn't draw anything\n text = ''\n }\n\n // HACK: ensure cursor is visible\n if (invertForCursor && fg === bg) bg = fg === 0 ? 7 : 0\n\n if (inSelection) {\n fg = -1\n bg = -2\n }\n\n let didUpdate = text !== this.drawnScreen[cell] ||\n fg !== this.drawnScreenFG[cell] ||\n bg !== this.drawnScreenBG[cell] ||\n attrs !== this.drawnScreenAttrs[cell] ||\n isCursor\n\n let font = attrs & FONT_MASK\n if (!fontGroups.has(font)) fontGroups.set(font, [])\n\n fontGroups.get(font).push([cell, x, y, text, fg, bg, attrs, isCursor])\n updateMap.set(cell, didUpdate)\n }\n\n // Map of (cell index) -> boolean, whether or not a cell should be redrawn\n const redrawMap = new Map()\n\n let isTextWide = text =>\n text !== ' ' && ctx.measureText(text).width >= (cellWidth + 0.05)\n\n // decide for each cell if it should be redrawn\n let updateRedrawMapAt = cell => {\n let shouldUpdate = updateMap.get(cell) || redrawMap.get(cell)\n\n // TODO: fonts (necessary?)\n let text = this.screen[cell]\n let isWideCell = isTextWide(text)\n let checkRadius = isWideCell ? 2 : 1\n\n if (!shouldUpdate) {\n // check adjacent cells\n let adjacentDidUpdate = false\n\n for (let adjacentCell of this.getAdjacentCells(cell, checkRadius)) {\n if (updateMap.get(adjacentCell)) {\n adjacentDidUpdate = true\n break\n }\n }\n\n if (adjacentDidUpdate) shouldUpdate = true\n }\n\n if (shouldUpdate) {\n if (isWideCell) {\n // set redraw for adjacent cells\n for (let adjacentCell of this.getAdjacentCells(cell)) {\n redrawMap.set(adjacentCell, true)\n }\n\n // update previous wide cells as well\n let index = cell - 1\n while (index > 0) {\n let text = this.screen[index]\n let isWide = isTextWide(text)\n\n if (redrawMap.get(index - 1)) break\n\n // might be out of bounds but that doesn't matter\n redrawMap.set(index - width, true)\n redrawMap.set(index + width, true)\n redrawMap.set(index--, true)\n\n if (!isWide) break\n }\n }\n }\n\n redrawMap.set(cell, shouldUpdate)\n }\n\n for (let cell of updateMap.keys()) updateRedrawMapAt(cell)\n\n // pass 1: backgrounds\n for (let font of fontGroups.keys()) {\n for (let data of fontGroups.get(font)) {\n let [cell, x, y, text, fg, bg, attrs, isCursor] = data\n\n if (redrawMap.get(cell)) {\n this.drawCellBackground({ x, y, cellWidth, cellHeight, bg })\n }\n }\n }\n\n // pass 2: characters\n for (let font of fontGroups.keys()) {\n // set font once because in Firefox, this is a really slow action for some\n // reason\n let modifiers = {}\n if (font & 1) modifiers.weight = 'bold'\n if (font & 1 << 2) modifiers.style = 'italic'\n ctx.font = this.getFont(modifiers)\n\n for (let data of fontGroups.get(font)) {\n let [cell, x, y, text, fg, bg, attrs, isCursor] = data\n\n if (redrawMap.get(cell)) {\n this.drawCell({\n x, y, charSize, cellWidth, cellHeight, text, fg, bg, attrs\n })\n\n this.drawnScreen[cell] = text\n this.drawnScreenFG[cell] = fg\n this.drawnScreenBG[cell] = bg\n this.drawnScreenAttrs[cell] = attrs\n\n if (this.window.debug) {\n // add cell data\n ctx.save()\n ctx.fillStyle = '#0f0'\n ctx.font = '6px monospace'\n ctx.textAlign = 'left'\n ctx.textBaseline = 'top'\n ctx.fillText(+isTextWide(text), x * cellWidth, y * cellHeight)\n ctx.fillText(+updateMap.get(cell), x * cellWidth, y * cellHeight + 6)\n ctx.restore()\n }\n }\n\n if (isCursor && this.cursor.blinkOn && this.cursor.style !== 'block') {\n ctx.save()\n ctx.beginPath()\n if (this.cursor.style === 'bar') {\n // vertical bar\n let barWidth = 2\n ctx.rect(x * cellWidth, y * cellHeight, barWidth, cellHeight)\n } else if (this.cursor.style === 'line') {\n // underline\n let lineHeight = 2\n ctx.rect(x * cellWidth, y * cellHeight + charSize.height,\n cellWidth, lineHeight)\n }\n ctx.clip()\n\n // swap foreground/background\n fg = this.screenBG[cell]\n bg = this.screenFG[cell]\n // HACK: ensure cursor is visible\n if (fg === bg) bg = fg === 0 ? 7 : 0\n\n this.drawCell({\n x, y, charSize, cellWidth, cellHeight, text, fg, bg, attrs\n })\n ctx.restore()\n }\n }\n }\n }\n\n loadContent (str) {\n // current index\n let i = 0\n\n // window size\n const newHeight = parse2B(str, i)\n const newWidth = parse2B(str, i + 2)\n const resized = (this.window.height !== newHeight) || (this.window.width !== newWidth)\n this.window.height = newHeight\n this.window.width = newWidth\n i += 4\n\n // cursor position\n let [cursorY, cursorX] = [parse2B(str, i), parse2B(str, i + 2)]\n i += 4\n let cursorMoved = (cursorX !== this.cursor.x || cursorY !== this.cursor.y)\n this.cursor.x = cursorX\n this.cursor.y = cursorY\n\n if (cursorMoved) {\n this.resetCursorBlink()\n this.emit('cursor-moved')\n }\n\n // attributes\n let attributes = parse3B(str, i)\n i += 3\n\n this.cursor.visible = !!(attributes & 1)\n this.cursor.hanging = !!(attributes & (1 << 1))\n\n Input.setAlts(\n !!(attributes & (1 << 2)), // cursors alt\n !!(attributes & (1 << 3)), // numpad alt\n !!(attributes & (1 << 4)), // fn keys alt\n !!(attributes & (1 << 12)) // crlf mode\n )\n\n let trackMouseClicks = !!(attributes & (1 << 5))\n let trackMouseMovement = !!(attributes & (1 << 6))\n\n // 0 - Block blink 2 - Block steady (1 is unused)\n // 3 - Underline blink 4 - Underline steady\n // 5 - I-bar blink 6 - I-bar steady\n let cursorShape = (attributes >> 9) & 0x07\n\n // if it's not zero, decrement such that the two most significant bits\n // are the type and the least significant bit is the blink state\n if (cursorShape > 0) cursorShape--\n\n let cursorStyle = cursorShape >> 1\n let cursorBlinking = !(cursorShape & 1)\n\n if (cursorStyle === 0) this.cursor.style = 'block'\n else if (cursorStyle === 1) this.cursor.style = 'line'\n else if (cursorStyle === 2) this.cursor.style = 'bar'\n\n if (this.cursor.blinking !== cursorBlinking) {\n this.cursor.blinking = cursorBlinking\n this.resetCursorBlink()\n }\n\n Input.setMouseMode(trackMouseClicks, trackMouseMovement)\n this.selection.selectable = !trackMouseMovement\n $(this.canvas).toggleClass('selectable', !trackMouseMovement)\n this.mouseMode = {\n clicks: trackMouseClicks,\n movement: trackMouseMovement\n }\n\n let showButtons = !!(attributes & (1 << 7))\n let showConfigLinks = !!(attributes & (1 << 8))\n\n $('.x-term-conf-btn').toggleClass('hidden', !showConfigLinks)\n $('#action-buttons').toggleClass('hidden', !showButtons)\n\n // content\n let fg = 7\n let bg = 0\n let attrs = 0\n let cell = 0 // cell index\n let lastChar = ' '\n let screenLength = this.window.width * this.window.height\n\n if (resized) {\n this.updateSize()\n this.blinkingCellCount = 0\n this.screen = new Array(screenLength).fill(' ')\n this.screenFG = new Array(screenLength).fill(' ')\n this.screenBG = new Array(screenLength).fill(' ')\n this.screenAttrs = new Array(screenLength).fill(' ')\n }\n\n let strArray = !undef(Array.from) ? Array.from(str) : str.split('')\n\n const MASK_LINE_ATTR = 0xC8\n const MASK_BLINK = 1 << 4\n\n let setCellContent = () => {\n // Remove blink attribute if it wouldn't have any effect\n let myAttrs = attrs\n if ((myAttrs & MASK_BLINK) !== 0 &&\n ((lastChar === ' ' && ((myAttrs & MASK_LINE_ATTR) === 0)) || // no line styles\n fg === bg // invisible text\n )\n ) {\n myAttrs ^= MASK_BLINK\n }\n // update blinking cells counter if blink state changed\n if ((this.screenAttrs[cell] & MASK_BLINK) !== (myAttrs & MASK_BLINK)) {\n if (myAttrs & MASK_BLINK) this.blinkingCellCount++\n else this.blinkingCellCount--\n }\n\n this.screen[cell] = lastChar\n this.screenFG[cell] = fg\n this.screenBG[cell] = bg\n this.screenAttrs[cell] = myAttrs\n }\n\n while (i < strArray.length && cell < screenLength) {\n let character = strArray[i++]\n let charCode = character.codePointAt(0)\n\n let data\n switch (charCode) {\n case SEQ_REPEAT:\n let count = parse2B(strArray[i] + strArray[i + 1])\n i += 2\n for (let j = 0; j < count; j++) {\n setCellContent(cell)\n if (++cell > screenLength) break\n }\n break\n\n case SEQ_SET_COLORS:\n data = parse3B(strArray[i] + strArray[i + 1] + strArray[i + 2])\n i += 3\n fg = data & 0xFF\n bg = (data >> 8) & 0xFF\n break\n\n case SEQ_SET_ATTRS:\n data = parse2B(strArray[i] + strArray[i + 1])\n i += 2\n attrs = data & 0xFF\n break\n\n case SEQ_SET_FG:\n data = parse2B(strArray[i] + strArray[i + 1])\n i += 2\n fg = data & 0xFF\n break\n\n case SEQ_SET_BG:\n data = parse2B(strArray[i] + strArray[i + 1])\n i += 2\n bg = data & 0xFF\n break\n\n default:\n if (charCode < 32) character = '\\ufffd'\n lastChar = character\n setCellContent(cell)\n cell++\n }\n }\n\n if (this.window.debug) console.log(`Blinky cells = ${this.blinkingCellCount}`)\n\n this.scheduleDraw('load', 16)\n this.emit('load')\n }\n\n /** Apply labels to buttons and screen title (leading T removed already) */\n loadLabels (str) {\n let pieces = str.split('\\x01')\n qs('h1').textContent = pieces[0]\n $('#action-buttons button').forEach((button, i) => {\n let label = pieces[i + 1].trim()\n // if empty string, use the \"dim\" effect and put nbsp instead to\n // stretch the button vertically\n button.innerHTML = label ? esc(label) : ' '\n button.style.opacity = label ? 1 : 0.2\n })\n }\n\n showNotification (text) {\n console.info(`Notification: ${text}`)\n if (Notification && Notification.permission === 'granted') {\n let notification = new Notification('ESPTerm', {\n body: text\n })\n notification.addEventListener('click', () => window.focus())\n } else {\n if (Notification && Notification.permission !== 'denied') {\n Notification.requestPermission()\n } else {\n // Fallback using the built-in notification balloon\n Notify.show(text)\n }\n }\n }\n\n load (str, theme = -1) {\n const content = str.substr(1)\n if (theme >= 0 && theme < themes.length) {\n Screen.palette = themes[theme]\n }\n\n switch (str[0]) {\n case 'S':\n this.loadContent(content)\n break\n\n case 'T':\n this.loadLabels(content)\n break\n\n case 'B':\n this.beep()\n break\n\n case 'G':\n this.showNotification(content)\n break\n\n default:\n console.warn(`Bad data message type; ignoring.\\n${JSON.stringify(str)}`)\n }\n }\n\n beep () {\n const audioCtx = this.audioCtx\n if (!audioCtx) return\n\n // prevent screeching\n if (this._lastBeep && this._lastBeep > Date.now() - 50) return\n this._lastBeep = Date.now()\n\n let osc, gain\n\n // main beep\n osc = audioCtx.createOscillator()\n gain = audioCtx.createGain()\n osc.connect(gain)\n gain.connect(audioCtx.destination)\n gain.gain.value = 0.5\n osc.frequency.value = 750\n osc.type = 'sine'\n osc.start()\n osc.stop(audioCtx.currentTime + 0.05)\n\n // surrogate beep (making it sound like 'oops')\n osc = audioCtx.createOscillator()\n gain = audioCtx.createGain()\n osc.connect(gain)\n gain.connect(audioCtx.destination)\n gain.gain.value = 0.2\n osc.frequency.value = 400\n osc.type = 'sine'\n osc.start(audioCtx.currentTime + 0.05)\n osc.stop(audioCtx.currentTime + 0.08)\n }\n\n static alphaToFraktur (character) {\n if (character >= 'a' && character <= 'z') {\n character = String.fromCodePoint(0x1d51e - 0x61 + character.charCodeAt(0))\n } else if (character >= 'A' && character <= 'Z') {\n character = frakturExceptions[character] || String.fromCodePoint(\n 0x1d504 - 0x41 + character.charCodeAt(0))\n }\n return character\n }\n}\n\nconst Screen = new TermScreen()\n\nScreen.once('load', () => {\n qs('#screen').appendChild(Screen.canvas)\n})\n\nlet fitScreen = false\nfunction fitScreenIfNeeded () {\n Screen.window.fitIntoWidth = fitScreen ? window.innerWidth - 20 : 0\n Screen.window.fitIntoHeight = fitScreen ? window.innerHeight : 0\n}\nfitScreenIfNeeded()\nwindow.addEventListener('resize', fitScreenIfNeeded)\n\nwindow.toggleFitScreen = function () {\n fitScreen = !fitScreen\n const resizeButtonIcon = qs('#resize-button-icon')\n if (fitScreen) {\n resizeButtonIcon.classList.remove('icn-resize-small')\n resizeButtonIcon.classList.add('icn-resize-full')\n } else {\n resizeButtonIcon.classList.remove('icn-resize-full')\n resizeButtonIcon.classList.add('icn-resize-small')\n }\n fitScreenIfNeeded()\n}\n","/** File upload utility */\nwindow.TermUpl = (function () {\n let lines, // array of lines without newlines\n line_i, // current line index\n fuTout, // timeout handle for line sending\n send_delay_ms, // delay between lines (ms)\n nl_str, // newline string to use\n curLine, // current line (when using fuOil)\n inline_pos // Offset in line (for long lines)\n\n // lines longer than this are split to chunks\n // sending a super-ling string through the socket is not a good idea\n const MAX_LINE_LEN = 128\n\n function fuOpen () {\n fuStatus('Ready...')\n Modal.show('#fu_modal', onClose)\n $('#fu_form').toggleClass('busy', false)\n Input.blockKeys(true)\n }\n\n function onClose () {\n console.log('Upload modal closed.')\n clearTimeout(fuTout)\n line_i = 0\n Input.blockKeys(false)\n }\n\n function fuStatus (msg) {\n qs('#fu_prog').textContent = msg\n }\n\n function fuSend () {\n let v = qs('#fu_text').value\n if (!v.length) {\n fuClose()\n return\n }\n\n lines = v.split('\\n')\n line_i = 0\n inline_pos = 0 // offset in line\n send_delay_ms = qs('#fu_delay').value\n\n // sanitize - 0 causes overflows\n if (send_delay_ms < 0) {\n send_delay_ms = 0\n qs('#fu_delay').value = send_delay_ms\n }\n\n nl_str = {\n 'CR': '\\r',\n 'LF': '\\n',\n 'CRLF': '\\r\\n'\n }[qs('#fu_crlf').value]\n\n $('#fu_form').toggleClass('busy', true)\n fuStatus('Starting...')\n fuSendLine()\n }\n\n function fuSendLine () {\n if (!$('#fu_modal').hasClass('visible')) {\n // Modal is closed, cancel\n return\n }\n\n if (!Conn.canSend()) {\n // postpone\n fuTout = setTimeout(fuSendLine, 1)\n return\n }\n\n if (inline_pos === 0) {\n curLine = lines[line_i++] + nl_str\n }\n\n let chunk\n if ((curLine.length - inline_pos) <= MAX_LINE_LEN) {\n chunk = curLine.substr(inline_pos, MAX_LINE_LEN)\n inline_pos = 0\n } else {\n chunk = curLine.substr(inline_pos, MAX_LINE_LEN)\n inline_pos += MAX_LINE_LEN\n }\n\n if (!Input.sendString(chunk)) {\n fuStatus('FAILED!')\n return\n }\n\n let all = lines.length\n\n fuStatus(line_i + ' / ' + all + ' (' + (Math.round((line_i / all) * 1000) / 10) + '%)')\n\n if (lines.length > line_i || inline_pos > 0) {\n fuTout = setTimeout(fuSendLine, send_delay_ms)\n } else {\n closeWhenReady()\n }\n }\n\n function closeWhenReady () {\n if (!Conn.canSend()) {\n // stuck in XOFF still, wait to process...\n fuStatus('Waiting for Tx buffer...')\n setTimeout(closeWhenReady, 100)\n } else {\n fuStatus('Done.')\n // delay to show it\n setTimeout(function () {\n fuClose()\n }, 100)\n }\n }\n\n function fuClose () {\n Modal.hide('#fu_modal')\n }\n\n return {\n init: function () {\n qs('#fu_file').addEventListener('change', function (evt) {\n let reader = new FileReader()\n let file = evt.target.files[0]\n console.log('Selected file type: ' + file.type)\n if (!file.type.match(/text\\/.*|application\\/(json|csv|.*xml.*|.*script.*)/)) {\n // Deny load of blobs like img - can crash browser and will get corrupted anyway\n if (!confirm('This does not look like a text file: ' + file.type + '\\nReally load?')) {\n qs('#fu_file').value = ''\n return\n }\n }\n reader.onload = function (e) {\n const txt = e.target.result.replace(/[\\r\\n]+/, '\\n')\n qs('#fu_text').value = txt\n }\n console.log('Loading file...')\n reader.readAsText(file)\n }, false)\n },\n close: fuClose,\n start: fuSend,\n open: fuOpen\n }\n})()\n","/** Init the terminal sub-module - called from HTML */\nwindow.termInit = function (labels, theme) {\n Conn.init()\n Input.init()\n TermUpl.init()\n Screen.load(labels, theme) // populate labels\n}\n","$.ready(() => {\n const input = qs('#softkb-input')\n if (!input) return // abort, we're not on the terminal page\n\n let keyboardOpen = false\n\n let updateInputPosition = function () {\n if (!keyboardOpen) return\n\n let [x, y] = Screen.gridToScreen(Screen.cursor.x, Screen.cursor.y)\n input.style.transform = `translate(${x}px, ${y}px)`\n }\n\n input.addEventListener('focus', () => {\n keyboardOpen = true\n updateInputPosition()\n })\n\n input.addEventListener('blur', () => (keyboardOpen = false))\n\n Screen.on('cursor-moved', updateInputPosition)\n\n window.kbOpen = function openSoftKeyboard (open) {\n keyboardOpen = open\n updateInputPosition()\n if (open) input.focus()\n else input.blur()\n }\n\n let lastCompositionString = ''\n let compositing = false\n\n let sendInputDelta = function (newValue) {\n let resend = false\n if (newValue.length > lastCompositionString.length) {\n if (newValue.startsWith(lastCompositionString)) {\n // characters have been added at the end\n Input.sendString(newValue.substr(lastCompositionString.length))\n } else resend = true\n } else if (newValue.length < lastCompositionString.length) {\n if (lastCompositionString.startsWith(newValue)) {\n // characters have been removed at the end\n Input.sendString('\\b'.repeat(lastCompositionString.length -\n newValue.length))\n } else resend = true\n } else if (newValue !== lastCompositionString) resend = true\n\n if (resend) {\n // the entire string changed; resend everything\n Input.sendString('\\b'.repeat(lastCompositionString.length) +\n newValue)\n }\n lastCompositionString = newValue\n }\n\n input.addEventListener('keydown', e => {\n if (e.key === 'Unidentified') return\n\n e.preventDefault()\n input.value = ''\n\n if (e.key === 'Backspace') Input.sendString('\\b')\n else if (e.key === 'Enter') Input.sendString('\\x0d')\n })\n\n input.addEventListener('input', e => {\n e.stopPropagation()\n\n if (e.isComposing) {\n sendInputDelta(e.data)\n } else {\n if (e.data) Input.sendString(e.data)\n else if (e.inputType === 'deleteContentBackward') {\n lastCompositionString = ''\n sendInputDelta('')\n }\n }\n })\n\n input.addEventListener('compositionstart', e => {\n lastCompositionString = ''\n compositing = true\n })\n\n input.addEventListener('compositionend', e => {\n lastCompositionString = ''\n compositing = false\n input.value = ''\n })\n\n Screen.on('open-soft-keyboard', () => input.focus())\n})\n"]} |