{"version":3,"sources":["webpack:///app.4a032ee-en.js","webpack:///webpack/bootstrap 5f19c49887263bc447b9","webpack:///./js/utils.js","webpack:///./js/lib/chibi.js","webpack:///./js/modal.js","webpack:///./js/notif.js","webpack:///./node_modules/events/events.js","webpack:///./js/term/themes.js","webpack:///./js/term/demo.js","webpack:///./js/lib/color_utils.js","webpack:///./js/lang.js","webpack:///./js/index.js","webpack:///./js/lib/polyfills.js","webpack:///./js/appcommon.js","webpack:///./js/wifi.js","webpack:///./lang/en.php","webpack:///./js/term/index.js","webpack:///./js/term/screen.js","webpack:///./js/term/screen_parser.js","webpack:///./js/term/screen_renderer.js","webpack:///./js/term/connection.js","webpack:///./js/term/input.js","webpack:///./js/term/upload.js","webpack:///./js/term/soft_keyboard.js","webpack:///./js/term/debug_screen.js","webpack:///./js/term/buttons.js","webpack:///./js/term_conf.js","webpack:///./js/lib/colortriangle.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","mk","e","document","createElement","qs","querySelector","qsa","querySelectorAll","cr","hdl","which","parse2B","arguments","length","undefined","charCodeAt","parse3B","encode2B","lsb","msb","String","fromCharCode","encode3B","xsb","_typeof","Symbol","iterator","obj","constructor","fireReady","domready","readyfn","fireLoaded","pageloaded","loadedfn","nodeLoop","fn","nodes","cssCamel","replace","result","charAt","toUpperCase","computeStyle","elm","currentStyle","w","getComputedStyle","getPropertyValue","queryPair","value","encodeURIComponent","setCss","style","showCss","display","serializeData","subelm","j","querystring","Array","nodeName","elements","disabled","type","selected","checked","substring","classHelper","classes","action","classarray","has","split","clz","classList","remove","add","toggle","contains","insertHtml","position","tmpnodes","tmpnode","innerHTML","lastChild","parentNode","insertBefore","nextSibling","appendChild","firstChild","chibi","selector","cb","nodelist","json","nodeType","each","apply","first","shift","last","pop","odd","odds","push","even","evens","hide","show","state","removeChild","css","getClass","className","setClass","addClass","removeClass","toggleClass","set","hasClass","html","htmlBefore","htmlAfter","htmlAppend","htmlPrepend","attr","toLowerCase","cssText","setAttribute","getAttribute","data","key","val","values","check","on","event","addEventListener","attachEvent","off","removeEventListener","detachEvent","window","onload","ajax","options","opts","assign","method","nocache","timeout","loader","callback","loaderFn","_loader","url","query","indexOf","xhr","XMLHttpRequest","ts","Date","toString","open","abortTmeo","setTimeout","console","error","abort","onreadystatechange","readyState","responseText","status","clearTimeout","setRequestHeader","send","post","ready","loaded","entityMap","&","<",">","\"","'","/","`","=","htmlEscape","string","$","modal","curCloseCb","sel","closeCb","$m","init","this","stopImmediatePropagation","nt","$balloon","timerHideBegin","timerHideEnd","canCancel","stopTimeouts","message","isError","EventEmitter","_events","_maxListeners","isFunction","arg","isNumber","isObject","isUndefined","defaultMaxListeners","setMaxListeners","isNaN","TypeError","emit","er","handler","len","args","listeners","Error","err","context","slice","addListener","listener","newListener","warned","trace","once","g","removeListener","fired","list","splice","removeAllListeners","listenerCount","evlistener","emitter","_require","rgb255ToHex","themes","fgbgThemes","colorTable256","buildColorTable","fill","red","green","blue","redValue","greenValue","blueValue","gray","SELECTION_FG","SELECTION_BG","themePreview","themeN","forEach","elem","shade","dataset","fg","test","toHex","color","bg","backgroundColor","_toConsumableArray","arr","isArray","arr2","from","_possibleConstructorReturn","self","ReferenceError","_inherits","subClass","superClass","create","writable","setPrototypeOf","__proto__","_classCallCheck","instance","Constructor","_get","receiver","Function","desc","getOwnPropertyDescriptor","parent","getPrototypeOf","_createClass","defineProperties","target","props","descriptor","protoProps","staticProps","_require2","encodeAsCodePoint","fromCodePoint","ANSIParser","reset","joinChunks","currentSequence","sequence","content","numbers","map","numOr1","number","mode","r","b","text","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_step","_iterator","next","done","character","code","codePointAt","match","parseSequence","return","TERM_DEFAULT_STYLE","getRainbowColor","t","Math","floor","sin","PI","ScrollingTerminal","screen","_this","width","height","termScreen","parser","handleParsed","buttonLabels","_lastLoad","now","loadTimer","showPage","cursor","x","y","visible","trackMouse","theme","rainbow","superRainbow","clear","scroll","newLine","max","moveBack","min","writeChar","deleteForward","insertBlanks","load","clampCursor","write","attributes","join","serialized","lastStyle","index","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_iterator2","cell","foreground","background","setForeground","setBackground","setAttributes","encodeColor","topicData","screenOpts","getScreenOpts","title","getTitle","buttons","getButtons","getCursor","serializeScreen","_screenOpts","_title","_buttons","_cursor","_screen","_this2","clearInterval","_loadTimer","setInterval","update","getUpdate","Process","_EventEmitter","demoData","mouseReceiver","demoshIndex","Clear","_Process","destroy","screenfetch","Screenfetch","_Process2","_this6","image","location","hostname","devicePixelRatio","filter","line","trim","chars","loop","substr","local-echo","_Process3","LocalEcho","_len","_key","includes","info","_Process4","Info","_this9","_len2","_key2","fast","showSplash","then","printText","_this10","splash","levels"," ",".","-","*","#","characters","repeat","cursorX","cursorY","moveTo","moveX","moveY","abs","drawCell","level","Promise","resolve","reject","cycles","dx","parts","colors","PrintColors","_Process5","ls","ListCommands","_Process6","SetTheme","shell","_this13","_Process7","maxnum","Number","isFinite","terminal","drawnScreenFG","ShowThemes","_Process8","hex","parseInt","col","SetCursor","_Process9","_len3","_key3","steady","ToggleRainbow","_this16","su","_Process10","_didWarnRainbow","mouse","ShowMouse","_this17","_Process11","label","randomData","highlighted","random","scrollOffset","render","lineData","button","sudo","Sudo","_this18","didDestroy","_Process12","_this19","_len4","_key4","child","setButtons","run","make","Make","_this20","_Process14","_len5","_key5","h","pwd","cd","whoami","navigator","userAgent","uname","mkdir","rm","cp","mv","ln","touch","exit","github","GoToGithub","_Process15","autocompleteIndex","DemoShell","printInfo","_this22","history","historyIndex","cursorPos","lastInputLength","prompt","success","unshift","current","visual","input","prefix","startsWith","newInput","copyFromHistoryIndex","completed","getCompleted","words","moveForward","rest","parse","command","inQuote","_iteratorNormalCompletion3","_didIteratorError3","_iteratorError3","_step3","_iterator3","spawn","_this23","_child","writeChars","demoInterface","onButtonPress","row","column","modifiers","mouseMove","mouseDown","mouseUp","didInit","pad","M","TAU","hue2rgb","v1","v2","hsl2rgb","var_1","var_2","rgb2hsl","d_r","d_g","d_b","hex2rgb","groups","bytes","pow","rgb2hex","round","termInit","TermConf","$defineProperty","stringFromCharCode","highSurrogate","lowSurrogate","codeUnits","codePoint","RangeError","pageShown","notify","menuOpen","inp","box","keyCode","ctrlKey","submit","$x","dots","$this","step","deltaY","evt","createEvent","initEvent","dispatchEvent","fireEvent","preventDefault","errAt","search","errs","decodeURIComponent","humanReadableErrors","lbls","lbl","childNodes","textContent","msgAt","msg","innerWidth","removeAttribute","br","href","vis","noAutoShow","bnr","id","tr","calc_dBm","toFixed","selectSta","password","ip","hasPassword","onScan","resp","rescan","JSON","log","inProgress","APs","$list","sort","a","rssi","ap","enc","item","$item","essid","curSSID","inner","escapedSSID","rssi_perc","authTypes","$th","conn_ssid","conn_pass","startScanning","scanAPs","_demo","_demo_aps","_root","time","wifiInit","cfg","disp1","disp2","sta_ssid","sta_password","sta_active_ip","sta_active_ssid","WiFi","wifi.connected_ip_is","wifi.not_conn","wifi.enter_passwd","term_nav.fullscreen","term_conn.connecting","term_conn.waiting_content","term_conn.disconnected","term_conn.waiting_server","term_conn.reconnecting","localize","Notify","TermScreen","TermConnection","TermInput","TermUpload","initSoftKeyboard","attachDebugScreen","initButtons","conn","termUpload","labels","_buttons$labels","concat","showSplashTimeout","delay","statusScreen","loading","screenFG","screenBG","screenAttrs","onerror","errorMsg","file","canvas","fullscreenIcon","isFullscreen","properFullscreen","fitScreen","screenPadding","padding","fitScreenIfNeeded","fitIntoWidth","fitIntoHeight","innerHeight","toggleFitScreen","resizeButtonIcon","Element","requestFullscreen","webkitRequestFullscreen","checkForFullscreen","body","updateSize","span","termUpl","ScreenParser","ScreenRenderer","ctx","getContext","renderer","_debug","audioCtx","AudioContext","webkitAudioContext","warn","Proxy","blinking","hanging","_window","fontFamily","fontSize","gridScaleX","gridScaleY","debug","graphics","_windowScale","_padding","windowState","selection","selectable","start","end","mouseMode","clicks","movement","scheduleSizeUpdate","scheduleDraw","bracketedPaste","blinkingCellCount","reverseVideo","selecting","selectStart","screenToGrid","selectMove","selectEnd","getNormalizedSelection","altKey","offsetX","offsetY","_this$input","onMouseDown","touchPosition","touchDownTime","touchDidMove","getTouchPositionOffset","rect","getBoundingClientRect","clientX","left","clientY","top","touches","passive","touchSelectMenu","selectionPos","gridToScreen","transform","copyButton","copySelectionToClipboard","_this$input2","onMouseMove","_this$input3","onMouseUp","aggregateWheelDelta","wheelDeltaY","_this$input4","onMouseWheel","_this$input5","_scheduledSizeUpdate","weight","rounded","cellSize","getCellSize","_this3","withScale","v","font","getFont","measureText","charSize","getCharSize","ceil","didChange","realWidth","realHeight","originalWidth","terminalAspect","resetDrawn","draw","_selection","_ref","_getNormalizedSelecti","colAfterStart","colBeforeEnd","onStartLine","onEndLine","screenLength","lines","previousLineIndex","isInSelection","selectedText","getSelectedText","textarea","select","execCommand","Notification","permission","focus","requestPermission","_lastBeep","_convolver","createConvolver","impulseLength","sampleRate","impulse","createBuffer","getChannelData","buffer","connect","destination","mainOsc","createOscillator","mainGain","createGain","gain","frequency","surrOsc","surrGain","startTime","currentTime","stop","requestAnimationFrame","_parser","du","str","num","contentLoaded","errmsg","ci","strArray","resized","topics","topic","newHeight","newWidth","defFg","defBg","loadTheme","setDefaultColors","setAlts","trackMouseClicks","trackMouseMovement","cursorShape","cursorStyle","cursorBlinking","resetCursorBlink","setMouseMode","showButtons","showConfigLinks","cursorMoved","count","beep","flags","cursorAttrs","regionStart","regionEnd","charsetGx","charsetG0","charsetG1","freeHeap","clientCount","frameY","frameX","frameHeight","frameWidth","pushFrame","attrs","lastChar","frameLength","pushCell","myAttrs","hasFG","hasBG","cellFG","cellBG","ATTR_UNDERLINE","cellXInFrame","cellYInFrame","charCode","hideLoadFailedMsg","loadUpdate","showNotification","stringify","frakturExceptions","C","H","I","R","Z","_palette","defaultBgNum","defaultFgNum","blinkStyleOn","blinkInterval","cursorBlinkOn","cursorBlinkInterval","resetBlink","drawnScreen","drawnScreenBG","drawnScreenAttrs","drawnCursor","palette","why","aggregateTime","_scheduledDraw","intervals","cellWidth","cellHeight","_screen$window","fillStyle","getColor","screenX","screenY","right","bottom","clearRect","fillRect","_ref2","underline","strike","overline","globalAlpha","alphaToFraktur","beginPath","cw","ch","c2w","c2h","offset","dotSpacingX","dotSpacingY","dotSize","alignRight","dy","dotSizeY","lineTo","strokeStyle","stroke","fillText","lineWidth","lineCap","lineY","radius","_screen$window2","cells","_this4","_screen$window3","drawStatus","startDrawLoop","stopDrawLoop","_screen$getCellSize","setTransform","drawStart","textAlign","textBaseline","fontGroups","Map","updateMap","isCursor","wasCursor","inSelection","_ref3","_ref4","didUpdate","ATTR_BOLD","redrawMap","isTextWide","keys","shouldUpdate","isWideCell","checkRadius","adjacentDidUpdate","getAdjacentCells","adjacentCell","save","redrawing","clipRect","clip","_iteratorNormalCompletion5","_didIteratorError5","_iteratorError5","_step5","_iterator5","drawBackground","setCell","_iteratorNormalCompletion4","_didIteratorError4","_iteratorError4","_step4","_iterator4","_iteratorNormalCompletion6","_didIteratorError6","_iteratorError6","_step6","_iterator6","drawCharacter","_ref5","restore","drawEnd","_screen$window4","screenWidth","screenHeight","translate","rotate","_drawTimerThread","threadID","drawTimerLoop","_this5","demo","ws","heartbeatTimeout","pingInterval","xoff","autoXoffTimeout","reconnTimeout","forceClosing","blobReader","FileReader","onDecodedWSMessage","disconnectTimeout","hidden","closeSocket","heartbeat","readAsText","onWSMessage","close","alert","WebSocket","onWSOpen","onWSClose","onHeartbeatFail","_this7","_this8","sendPing","sendString","sendButton","initKeys","allFn","shouldAcceptEvent","metaKey","handleKeyDown","clipboardData","setData","getData","setContent","all_fn","mb1","mb2","mb3","packModifiersForMouse","KEY_NAMES","3","6","8","9","12","13","16","17","18","19","20","27","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","58","59","60","61","62","63","64","91","92","93","106","107","109","110","111","144","145","160","161","162","163","164","165","166","167","168","169","170","171","172","173","174","175","176","186","187","188","189","190","192","194","219","220","221","222","224","np_alt","cu_alt","fn_alt","mt_click","mt_move","no_keys","crlf_mode","fa","alt","normal","ca","na","keymap","Backspace","Tab","Enter","Control+Enter","Escape","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Home","Insert","Delete","End","PageUp","PageDown","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12","Shift+F1","Shift+F2","Shift+F3","Shift+F4","Shift+F5","Shift+F6","Shift+F7","Shift+F8","Shift+F9","Shift+F10","Shift+F11","Shift+F12","Numpad0","Numpad1","Numpad2","Numpad3","Numpad4","Numpad5","Numpad6","Numpad7","Numpad8","Numpad9","Numpad*","Numpad+","Numpad-","Numpad.","Numpad/","Control+]","Control+\\","Control+[","Control+^","Control+_","Control+ArrowLeft","Control+ArrowRight","Control+ArrowUp","Control+ArrowDown","Control+Home","Control+End","Shift+ArrowLeft","Shift+ArrowRight","Shift+ArrowUp","Shift+ArrowDown","Shift+Home","Shift+End","Alt+ArrowLeft","Alt+ArrowRight","Meta+ArrowLeft","Meta+ArrowRight","Alt+Backspace","Meta+Backspace","Control+Shift+C","Control+Insert","Control+F12","activeElement","HTMLTextAreaElement","keyBlacklist","softModifiers","ctrl","meta","shiftKey","binding","itemModifiers","cu","np","crlf","click","move","dir","blockKeys","yes","openUploadDialog","updateStatus","onDialogClose","fuTout","line_i","startUpload","fuClose","inline_pos","send_delay_ms","nl_str","CR","LF","CRLF","uploadLine","canSend","curLine","maxChunk","MAX_LINE_LEN","chunk","pt","closeWhenReady","reader","files","ftype","confirm","txt","_slicedToArray","sliceIterator","_arr","_n","_d","_e","_s","_i","keyInput","shortcutBar","keyboardOpen","updateInputPosition","_screen$gridToScreen","_screen$gridToScreen2","lastCompositionString","sendInputDelta","newValue","resend","stopPropagation","isComposing","inputType","shortcuts","Control","Esc","←","↓","↑","→","touchMoved","shortcut","fakeEvent","debugCanvas","mouseHoverCell","updateToolbar","startDrawing","onMouseOut","addCanvas","removeCanvas","updateCanvasSize","drawInfo","endTime","lastReason","clippedRects","updateFrames","reason","frame","clipPattern","patternCanvas","pctx","createPattern","isDrawing","lastDrawTime","drawLoop","dt","activeCells","_cells$get","_cells$get2","timestamp","elapsedTime","strokeRect","didDrawUpdateFrames","framesToDelete","elapsed","lineJoin","setLineDash","lineDashOffset","toolbar","toolbarAttached","dataDisplay","internalDisplay","redraw","fancyGraphics","attachToolbar","detachToolbar","displayCellAttrs","formatColor","getCellData","cellAttrs","fgText","bgText","cellCode","hexcode","setFormattedText","node","pushSpan","internalInfo","container","pushButton","popButton","selectedTheme","showColor","ex","ColorTriangle","uppercase","trianglePointerSize","size","parseColor","initInput","$presets","thm","tit","xfg","xbg","nextTheme","selectedIndex","prevTheme","times","win","doc","triangleSize","wheelPointerColor1","wheelPointerColor2","trianglePointerColor1","trianglePointerColor2","pixelRatio","setOptions","calculateProperties","createContainer","createTriangle","createWheel","createWheelPointer","createTrianglePointer","attachEvents","setHEX","innerSize","wheelThickness","wheelPointerSize","wheelRadius","triangleRadius","triangleSideLength","sqrt","hue","third","saturation","lightness","hx","cos","hy","sx","sy","vx","vy","mx","my","boxShadow","borderRadius","wheel","margin","drawWheel","arc","triangle","triangleCtx","closePath","grad0","createLinearGradient","hsla","addColorStop","grad1","globalCompositeOperation","wheelPointer","drawPointer","trianglePointer","color1","color2","getRGB","setRGB","getHSL","setHSL","initColor","calculatePositions","moveWheelPointer","drawTriangle","moveTrianglePointer","down","mousedown","mousemove","mouseup","xy","getRelativeCoordinates","x0","y0","rad","atan2","rad0","rad1","tan","maxR","rad2","atan","widthShare","dflt","ct","openColorTriangle","offsetWidth","getHEX","fireChangeEvent","offsetTop","offsetHeight","el","getElement","offsetLeft","zIndex","inject","closeColorTriangle","dispose"],"mappings":"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","file":"app.4a032ee-en.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 9);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/** Make a node */\nexports.mk = function mk(e) {\n return document.createElement(e);\n};\n\n/** Find one by query */\nexports.qs = function qs(s) {\n return document.querySelector(s);\n};\n\n/** Find all by query */\nexports.qsa = function qsa(s) {\n return document.querySelectorAll(s);\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 */\nexports.cr = function cr(hdl) {\n return function (e) {\n if (e.which === 10 || e.which === 13 || e.which === 32) {\n hdl();\n }\n };\n};\n\n/** Decode number from 2B encoding */\nexports.parse2B = function parse2B(s) {\n var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n\n return s.charCodeAt(i++) - 1 + (s.charCodeAt(i) - 1) * 127;\n};\n\n/** Decode number from 3B encoding */\nexports.parse3B = function parse3B(s) {\n var i = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n\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. */\nexports.encode2B = function encode2B(n) {\n var lsb = void 0,\n msb = void 0;\n lsb = n % 127;\n n = (n - lsb) / 127;\n lsb += 1;\n msb = n + 1;\n return String.fromCharCode(lsb) + String.fromCharCode(msb);\n};\n\n/** Encode using 3B encoding, returns string. */\nexports.encode3B = function encode3B(n) {\n var lsb = void 0,\n msb = void 0,\n xsb = void 0;\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 String.fromCharCode(lsb) + String.fromCharCode(msb) + String.fromCharCode(xsb);\n};\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/*!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 loadedfn = [],\n\t domready = false,\n\t pageloaded = false,\n\t d = document,\n\t w = 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\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}\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 = '',\n\t\t subelm,\n\t\t i,\n\t\t j;\n\t\tif (nodes.constructor === Object) {\n\t\t\t// 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 {\n\t\t\t// 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,\n\t\t search,\n\t\t i,\n\t\t replace,\n\t\t 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} else if (action === 'add') {\n\t\t\t\t\t\telm.classList.add(clz);\n\t\t\t\t\t} else if (action === 'toggle') {\n\t\t\t\t\t\telm.classList.toggle(clz);\n\t\t\t\t\t} else 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,\n\t\t nodes = [],\n\t\t json = false,\n\t\t nodelist,\n\t\t 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 === 'undefined' ? 'undefined' : _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 = [],\n\t\t\t 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 = [],\n\t\t\t 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') {\n\t\t\t\t// ADDED\n\t\t\t\tif (state) cb.show();else cb.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\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}, 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') {\n\t\t\t\t\t//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') {\n\t\t\t\t// 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) {\n\t\t// if options is a number, it's timeout in ms\n\t\tvar opts = Object.assign({\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\tmodule.exports = chibi;\n})();\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\n\n/** Module for toggling a modal overlay */\nvar modal = {};\nvar curCloseCb = null;\n\nmodal.show = function (sel, closeCb) {\n var $m = $(sel);\n $m.removeClass('hidden visible');\n setTimeout(function () {\n $m.addClass('visible');\n }, 1);\n curCloseCb = closeCb;\n};\n\nmodal.hide = function (sel) {\n var $m = $(sel);\n $m.removeClass('visible');\n setTimeout(function () {\n $m.addClass('hidden');\n if (curCloseCb) curCloseCb();\n }, 500); // transition time\n};\n\nmodal.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\nmodule.exports = modal;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\nvar modal = __webpack_require__(2);\n\nvar nt = {};\nvar sel = '#notif';\nvar $balloon = void 0;\n\nvar timerHideBegin = void 0; // timeout to start hiding (transition)\nvar timerHideEnd = void 0; // timeout to add the hidden class\nvar canCancel = false;\n\nvar stopTimeouts = function stopTimeouts() {\n clearTimeout(timerHideBegin);\n clearTimeout(timerHideEnd);\n};\n\nnt.show = function (message, timeout, isError) {\n $balloon.toggleClass('error', isError === true);\n $balloon.html(message);\n modal.show($balloon);\n stopTimeouts();\n\n if (!timeout || timeout <= 0) {\n timeout = 2500;\n }\n\n timerHideBegin = setTimeout(nt.hide, timeout);\n\n canCancel = false;\n setTimeout(function () {\n canCancel = true;\n }, 500);\n};\n\nnt.hide = function () {\n var $m = $(sel);\n $m.removeClass('visible');\n timerHideEnd = setTimeout(function () {\n $m.addClass('hidden');\n }, 250); // transition time\n};\n\nnt.init = function () {\n $balloon = $(sel);\n\n // close by click outside\n $(document).on('click', function () {\n if (!canCancel) return;\n nt.hide(this);\n });\n\n // click caused by selecting, prevent it from bubbling\n $balloon.on('click', function (e) {\n e.stopImmediatePropagation();\n return false;\n });\n\n // stop fading if moused\n $balloon.on('mouseenter', function () {\n stopTimeouts();\n $balloon.removeClass('hidden').addClass('visible');\n });\n};\n\nmodule.exports = nt;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(7),\n rgb255ToHex = _require.rgb255ToHex;\n\nvar themes = exports.themes = [[// 0 - Tango - terminator\n'#111213', '#CC0000', '#4E9A06', '#C4A000', '#3465A4', '#75507B', '#06989A', '#D3D7CF', '#555753', '#EF2929', '#8AE234', '#FCE94F', '#729FCF', '#AD7FA8', '#34E2E2', '#EEEEEC'], [// 1 - Linux (CGA) - terminator\n'#000000', '#aa0000', '#00aa00', '#aa5500', '#0000aa', '#aa00aa', '#00aaaa', '#aaaaaa', '#555555', '#ff5555', '#55ff55', '#ffff55', '#5555ff', '#ff55ff', '#55ffff', '#ffffff'], [// 2 - xterm - terminator\n'#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000ee', '#cd00cd', '#00cdcd', '#e5e5e5', '#7f7f7f', '#ff0000', '#00ff00', '#ffff00', '#5c5cff', '#ff00ff', '#00ffff', '#ffffff'], [// 3 - rxvt - terminator\n'#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000cd', '#cd00cd', '#00cdcd', '#faebd7', '#404040', '#ff0000', '#00ff00', '#ffff00', '#0000ff', '#ff00ff', '#00ffff', '#ffffff'], [// 4 - Ambience - terminator\n'#2e3436', '#cc0000', '#4e9a06', '#c4a000', '#3465a4', '#75507b', '#06989a', '#d3d7cf', '#555753', '#ef2929', '#8ae234', '#fce94f', '#729fcf', '#ad7fa8', '#34e2e2', '#eeeeec'], [// 5 - Solarized Dark - terminator\n'#073642', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#eee8d5', '#002b36', '#cb4b16', '#586e75', '#657b83', '#839496', '#6c71c4', '#93a1a1', '#fdf6e3'], [// 6 - CGA NTSC - wikipedia\n'#000000', '#69001A', '#117800', '#769100', '#1A00A6', '#8019AB', '#289E76', '#A4A4A4', '#484848', '#C54E76', '#6DD441', '#D2ED46', '#765BFF', '#DC75FF', '#84FAD2', '#FFFFFF'], [// 7 - ZX Spectrum - wikipedia\n'#000000', '#aa0000', '#00aa00', '#aaaa00', '#0000aa', '#aa00aa', '#00aaaa', '#aaaaaa', '#000000', '#ff0000', '#00FF00', '#ffff00', '#0000ff', '#ff00ff', '#00ffff', '#ffffff'], [// 8 - Apple II - wikipedia\n'#000000', '#722640', '#0E5940', '#808080', '#40337F', '#E434FE', '#1B9AFE', '#BFB3FF', '#404C00', '#E46501', '#1BCB01', '#BFCC80', '#808080', '#F1A6BF', '#8DD9BF', '#ffffff'], [// 9 - Commodore - wikipedia\n'#000000', '#8D3E37', '#55A049', '#AAB95D', '#40318D', '#80348B', '#72C1C8', '#D59F74', '#8B5429', '#B86962', '#94E089', '#FFFFB2', '#8071CC', '#AA5FB6', '#87D6DD', '#ffffff'], [// 10 - Solarized Light - https://github.com/sgerrand/xfce4-terminal-colors-solarized\n'#eee8d5', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#073642', '#fdf6e3', '#cb4b16', '#93a1a1', '#839496', '#657b83', '#6c71c4', '#586e75', '#002b36'], [// 11 - Solarized Dark High contrast - https://github.com/sgerrand/xfce4-terminal-colors-solarized\n'#073642', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#fdf6e3', '#002b36', '#cb4b16', '#657b83', '#839496', '#93a1a1', '#6c71c4', '#eee8d5', '#fdf6e3']];\n\nexports.fgbgThemes = [['#AAAAAA', '#000000', 'Lnx', 'Linux'], ['#FFFFFF', '#000000', 'W+K', 'White on Black'], ['#00FF00', '#000000', 'Lim', 'Lime'], ['#E53C00', '#000000', 'Nix', 'Nixie'], ['#EFF0F1', '#31363B', 'Brz', 'Breeze'], ['#FFFFFF', '#300A24', 'Amb', 'Ambiance'], ['#839496', '#002B36', 'SoD', 'Solarized Dark'], ['#93a1a1', '#002b36', 'SoH', 'Solarized Dark (High Contrast)'], ['#657B83', '#FDF6E3', 'SoL', 'Solarized Light'], ['#000000', '#FFD75F', 'Wsp', 'Wasp'], ['#000000', '#FFFFDD', 'K+Y', 'Black on Yellow'], ['#000000', '#FFFFFF', 'K+W', 'Black on White']];\n\nvar colorTable256 = null;\n\nexports.buildColorTable = function () {\n if (colorTable256 !== null) return colorTable256;\n\n // 256color lookup table\n // should not be used to look up 0-15 (will return transparent)\n colorTable256 = new Array(16).fill('#000000');\n\n // fill color table\n // colors 16-231 are a 6x6x6 color cube\n for (var red = 0; red < 6; red++) {\n for (var green = 0; green < 6; green++) {\n for (var blue = 0; blue < 6; blue++) {\n var redValue = red * 40 + (red ? 55 : 0);\n var greenValue = green * 40 + (green ? 55 : 0);\n var blueValue = blue * 40 + (blue ? 55 : 0);\n colorTable256.push(rgb255ToHex(redValue, greenValue, blueValue));\n }\n }\n }\n // colors 232-255 are a grayscale ramp, sans black and white\n for (var gray = 0; gray < 24; gray++) {\n var value = gray * 10 + 8;\n colorTable256.push(rgb255ToHex(value, value, value));\n }\n\n return colorTable256;\n};\n\nexports.SELECTION_FG = '#333';\nexports.SELECTION_BG = '#b2d7fe';\n\nexports.themePreview = function (themeN) {\n $('[data-fg]').forEach(function (elem) {\n var shade = elem.dataset.fg;\n if (/^\\d+$/.test(shade)) shade = exports.toHex(shade, themeN);\n elem.style.color = shade;\n });\n $('[data-bg]').forEach(function (elem) {\n var shade = elem.dataset.bg;\n if (/^\\d+$/.test(shade)) shade = exports.toHex(shade, themeN);\n elem.style.backgroundColor = shade;\n });\n};\n\nexports.toHex = function (shade, themeN) {\n if (/^\\d+$/.test(shade)) {\n shade = +shade;\n if (shade < 16) shade = themes[themeN][shade];else {\n shade = exports.buildColorTable()[shade];\n }\n }\n return shade;\n};\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if (\"value\" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar EventEmitter = __webpack_require__(4);\n\nvar _require = __webpack_require__(0),\n parse2B = _require.parse2B;\n\nvar _require2 = __webpack_require__(5),\n themes = _require2.themes;\n\nvar encodeAsCodePoint = function encodeAsCodePoint(i) {\n return String.fromCodePoint(i + (i >= 0xD800 ? 0x801 : 1));\n};\n\nvar ANSIParser = function () {\n function ANSIParser(handler) {\n _classCallCheck(this, ANSIParser);\n\n this.reset();\n this.handler = handler;\n this.joinChunks = true;\n }\n\n _createClass(ANSIParser, [{\n key: 'reset',\n value: function reset() {\n this.currentSequence = 0;\n this.sequence = '';\n }\n }, {\n key: 'parseSequence',\n value: function parseSequence(sequence) {\n if (sequence[0] === '[') {\n var type = sequence[sequence.length - 1];\n var content = sequence.substring(1, sequence.length - 1);\n\n var numbers = content ? content.split(';').map(function (i) {\n return +i.replace(/\\D/g, '');\n }) : [];\n var numOr1 = numbers.length ? numbers[0] : 1;\n if (type === 'H') {\n this.handler('set-cursor', (numbers[0] | 0) - 1, (numbers[1] | 0) - 1);\n } else if (type >= 'A' && type <= 'D') {\n this.handler('move-cursor-' + (type <= 'B' ? 'y' : 'x'), (type === 'B' || type === 'C' ? 1 : -1) * numOr1);\n } else if (type === 'E' || type === 'F') {\n this.handler('move-cursor-line', (type === 'E' ? 1 : -1) * numOr1);\n } else if (type === 'G') {\n this.handler('set-cursor-x', numOr1 - 1);\n } else if (type === 'J') {\n var number = numbers.length ? numbers[0] : 2;\n if (number === 2) this.handler('clear');\n } else if (type === 'P') {\n this.handler('delete', numOr1);\n } else if (type === '@') {\n this.handler('insert-blanks', numOr1);\n } else if (type === 'q') this.handler('set-cursor-style', numOr1);else if (type === 'm') {\n if (!numbers.length) {\n this.handler('reset-style');\n return;\n }\n var _type = void 0;\n while (_type = numbers.shift()) {\n if (_type === 0) this.handler('reset-style');else if (_type === 1) this.handler('add-attrs', 1 << 2); // bold\n else if (_type === 2) this.handler('add-attrs', 1 << 9); // faint\n else if (_type === 3) this.handler('add-attrs', 1 << 6); // italic\n else if (_type === 4) this.handler('add-attrs', 1 << 3); // underline\n else if (_type === 5 || _type === 6) this.handler('add-attrs', 1 << 5); // blink\n else if (_type === 7) this.handler('add-attrs', 1 << 4); // invert\n else if (_type === 9) this.handler('add-attrs', 1 << 7); // strike\n else if (_type === 20) this.handler('add-attrs', 1 << 10); // fraktur\n else if (_type >= 30 && _type <= 37) this.handler('set-color-fg', _type % 10);else if (_type >= 40 && _type <= 47) this.handler('set-color-bg', _type % 10);else if (_type === 39) this.handler('reset-color-fg');else if (_type === 49) this.handler('reset-color-bg');else if (_type >= 90 && _type <= 98) this.handler('set-color-fg', _type % 10 + 8);else if (_type >= 100 && _type <= 108) this.handler('set-color-bg', _type % 10 + 8);else if (_type === 38 || _type === 48) {\n var mode = numbers.shift();\n if (mode === 2) {\n var r = numbers.shift();\n var g = numbers.shift();\n var b = numbers.shift();\n var color = (r << 16 | g << 8 | b) + 256;\n if (_type === 38) this.handler('set-color-fg', color);\n if (_type === 48) this.handler('set-color-bg', color);\n } else if (mode === 5) {\n var _color = (numbers.shift() | 0) & 0xFF;\n if (_type === 38) this.handler('set-color-fg', _color);\n if (_type === 48) this.handler('set-color-bg', _color);\n }\n }\n }\n } else if (type === 'h' || type === 'l') {\n if (content === '?25') {\n if (type === 'h') this.handler('show-cursor');else if (type === 'l') this.handler('hide-cursor');\n }\n }\n }\n }\n }, {\n key: 'write',\n value: function write(text) {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = text.toString()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var character = _step.value;\n\n var code = character.codePointAt(0);\n if (code === 0x1b) this.currentSequence = 1;else if (this.currentSequence === 1 && character === '[') {\n this.currentSequence = 2;\n this.sequence += '[';\n } else if (this.currentSequence && character.match(/[\\x40-\\x7e]/)) {\n this.parseSequence(this.sequence + character);\n this.currentSequence = 0;\n this.sequence = '';\n } else if (this.currentSequence > 1) this.sequence += character;else if (this.currentSequence === 1) {\n // something something nothing\n this.currentSequence = 0;\n this.handler('write', character);\n } else if (code < 0x03) this.handler('_null');else if (code === 0x03) this.handler('sigint');else if (code <= 0x06) this.handler('_null');else if (code === 0x07) this.handler('bell');else if (code === 0x08) this.handler('back');else if (code === 0x09) this.handler('tab');else if (code === 0x0a) this.handler('new-line');else if (code === 0x0d) this.handler('return');else if (code === 0x15) this.handler('delete-line');else if (code === 0x17) this.handler('delete-word');else this.handler('write', character);\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n if (!this.joinChunks) this.reset();\n }\n }]);\n\n return ANSIParser;\n}();\n\nvar TERM_DEFAULT_STYLE = [0, 0, 0];\n\nvar getRainbowColor = function getRainbowColor(t) {\n var r = Math.floor(Math.sin(t) * 2.5 + 2.5);\n var g = Math.floor(Math.sin(t + 2 / 3 * Math.PI) * 2.5 + 2.5);\n var b = Math.floor(Math.sin(t + 4 / 3 * Math.PI) * 2.5 + 2.5);\n return 16 + 36 * r + 6 * g + b;\n};\n\nvar ScrollingTerminal = function () {\n function ScrollingTerminal(screen) {\n var _this = this;\n\n _classCallCheck(this, ScrollingTerminal);\n\n this.width = 80;\n this.height = 25;\n this.termScreen = screen;\n this.parser = new ANSIParser(function () {\n return _this.handleParsed.apply(_this, arguments);\n });\n this.buttonLabels = [];\n\n this.reset();\n\n this._lastLoad = Date.now();\n this.loadTimer();\n\n window.showPage();\n }\n\n _createClass(ScrollingTerminal, [{\n key: 'reset',\n value: function reset() {\n this.style = TERM_DEFAULT_STYLE.slice();\n this.cursor = { x: 0, y: 0, style: 1, visible: true };\n this.trackMouse = false;\n this.theme = 0;\n this.rainbow = this.superRainbow = false;\n this.parser.reset();\n this.clear();\n }\n }, {\n key: 'clear',\n value: function clear() {\n this.screen = [];\n for (var i = 0; i < this.width * this.height; i++) {\n this.screen.push([' ', this.style.slice()]);\n }\n }\n }, {\n key: 'scroll',\n value: function scroll() {\n this.screen.splice(0, this.width);\n for (var i = 0; i < this.width; i++) {\n this.screen.push([' ', TERM_DEFAULT_STYLE.slice()]);\n }\n this.cursor.y--;\n }\n }, {\n key: 'newLine',\n value: function newLine() {\n this.cursor.y++;\n if (this.cursor.y >= this.height) this.scroll();\n }\n }, {\n key: 'writeChar',\n value: function writeChar(character) {\n this.screen[this.cursor.y * this.width + this.cursor.x] = [character, this.style.slice()];\n this.cursor.x++;\n if (this.cursor.x >= this.width) {\n this.cursor.x = 0;\n this.newLine();\n }\n }\n }, {\n key: 'moveBack',\n value: function moveBack() {\n var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n\n for (var i = 0; i < n; i++) {\n this.cursor.x--;\n if (this.cursor.x < 0) {\n if (this.cursor.y > 0) this.cursor.x = this.width - 1;else this.cursor.x = 0;\n this.cursor.y = Math.max(0, this.cursor.y - 1);\n }\n }\n }\n }, {\n key: 'moveForward',\n value: function moveForward() {\n var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n\n for (var i = 0; i < n; i++) {\n this.cursor.x++;\n if (this.cursor.x >= this.width) {\n this.cursor.x = 0;\n this.cursor.y++;\n if (this.cursor.y >= this.height) this.scroll();\n }\n }\n }\n }, {\n key: 'deleteChar',\n value: function deleteChar() {\n // FIXME unused?\n this.moveBack();\n this.screen.splice((this.cursor.y + 1) * this.width, 0, [' ', TERM_DEFAULT_STYLE.slice()]);\n this.screen.splice(this.cursor.y * this.width + this.cursor.x, 1);\n }\n }, {\n key: 'deleteForward',\n value: function deleteForward(n) {\n n = Math.min(this.width, n);\n for (var i = 0; i < n; i++) {\n this.screen.splice((this.cursor.y + 1) * this.width, 0, [' ', TERM_DEFAULT_STYLE.slice()]);\n }this.screen.splice(this.cursor.y * this.width + this.cursor.x, n);\n }\n }, {\n key: 'clampCursor',\n value: function clampCursor() {\n if (this.cursor.x < 0) this.cursor.x = 0;\n if (this.cursor.y < 0) this.cursor.y = 0;\n if (this.cursor.x > this.width - 1) this.cursor.x = this.width - 1;\n if (this.cursor.y > this.height - 1) this.cursor.y = this.height - 1;\n }\n }, {\n key: 'handleParsed',\n value: function handleParsed(action) {\n if (action === 'write') {\n this.writeChar(arguments.length <= 1 ? undefined : arguments[1]);\n } else if (action === 'delete') {\n this.deleteForward(arguments.length <= 1 ? undefined : arguments[1]);\n } else if (action === 'insert-blanks') {\n this.insertBlanks(arguments.length <= 1 ? undefined : arguments[1]); // FIXME undefined?\n } else if (action === 'clear') {\n this.clear();\n } else if (action === 'bell') {\n this.termScreen.load('U\\x01B');\n } else if (action === 'back') {\n this.moveBack();\n } else if (action === 'new-line') {\n this.newLine();\n this.cursor.x = 0;\n } else if (action === 'return') {\n this.cursor.x = 0;\n } else if (action === 'set-cursor') {\n this.cursor.x = arguments.length <= 2 ? undefined : arguments[2];\n this.cursor.y = arguments.length <= 1 ? undefined : arguments[1];\n this.clampCursor();\n } else if (action === 'move-cursor-y') {\n this.cursor.y += arguments.length <= 1 ? undefined : arguments[1];\n this.clampCursor();\n } else if (action === 'move-cursor-x') {\n this.cursor.x += arguments.length <= 1 ? undefined : arguments[1];\n this.clampCursor();\n } else if (action === 'move-cursor-line') {\n this.cursor.x = 0;\n this.cursor.y += arguments.length <= 1 ? undefined : arguments[1];\n this.clampCursor();\n } else if (action === 'set-cursor-x') {\n this.cursor.x = arguments.length <= 1 ? undefined : arguments[1];\n } else if (action === 'set-cursor-style') {\n this.cursor.style = Math.max(0, Math.min(6, arguments.length <= 1 ? undefined : arguments[1]));\n } else if (action === 'reset-style') {\n this.style = TERM_DEFAULT_STYLE.slice();\n } else if (action === 'add-attrs') {\n this.style[2] |= arguments.length <= 1 ? undefined : arguments[1];\n } else if (action === 'set-color-fg') {\n this.style[0] = arguments.length <= 1 ? undefined : arguments[1];\n this.style[2] |= 1;\n } else if (action === 'set-color-bg') {\n this.style[1] = arguments.length <= 1 ? undefined : arguments[1];\n this.style[2] |= 1 << 1;\n } else if (action === 'reset-color-fg') {\n this.style[0] = 0;\n if (this.style[2] & 1) this.style[2] ^= 1;\n } else if (action === 'reset-color-bg') {\n this.style[1] = 0;\n if (this.style[2] & 1 << 1) this.style[2] ^= 1 << 1;\n } else if (action === 'hide-cursor') {\n this.cursor.visible = false;\n } else if (action === 'show-cursor') {\n this.cursor.visible = true;\n }\n }\n }, {\n key: 'write',\n value: function write(text) {\n this.parser.write(text);\n }\n }, {\n key: 'getScreenOpts',\n value: function getScreenOpts() {\n var data = 'O';\n data += encodeAsCodePoint(25);\n data += encodeAsCodePoint(80);\n data += encodeAsCodePoint(this.theme);\n data += encodeAsCodePoint(7);\n data += encodeAsCodePoint(0);\n data += encodeAsCodePoint(0);\n data += encodeAsCodePoint(0);\n var attributes = +this.cursor.visible;\n attributes |= (3 << 5) * +this.trackMouse; // track mouse controls both\n attributes |= 3 << 7; // buttons/links always visible\n attributes |= this.cursor.style << 9;\n data += encodeAsCodePoint(attributes);\n return data;\n }\n }, {\n key: 'getButtons',\n value: function getButtons() {\n var data = 'B';\n data += encodeAsCodePoint(this.buttonLabels.length);\n data += this.buttonLabels.map(function (x) {\n return x + '\\x01';\n }).join('');\n return data;\n }\n }, {\n key: 'getTitle',\n value: function getTitle() {\n return 'TESPTerm Web UI Demo\\x01';\n }\n }, {\n key: 'getCursor',\n value: function getCursor() {\n var data = 'C';\n data += encodeAsCodePoint(this.cursor.y);\n data += encodeAsCodePoint(this.cursor.x);\n data += encodeAsCodePoint(0);\n return data;\n }\n }, {\n key: 'encodeColor',\n value: function encodeColor(color) {\n if (color < 256) {\n return encodeAsCodePoint(color);\n } else {\n color -= 256;\n return encodeAsCodePoint(color & 0xFFF | 0x10000) + encodeAsCodePoint(color >> 12);\n }\n }\n }, {\n key: 'serializeScreen',\n value: function serializeScreen() {\n var serialized = 'S';\n serialized += encodeAsCodePoint(0) + encodeAsCodePoint(0);\n serialized += encodeAsCodePoint(this.height) + encodeAsCodePoint(this.width);\n\n var lastStyle = [null, null, null];\n var index = 0;\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = this.screen[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var cell = _step2.value;\n\n var style = cell[1].slice();\n if (this.rainbow) {\n var x = index % this.width;\n var y = Math.floor(index / this.width);\n // C instead of F in mask and 1 << 8 in attrs to change attr bits 1 and 2\n var t = (x + y) / 10 + Date.now() / 1000;\n if (this.superRainbow) {\n t = (x * y + Date.now()) / 100 + Date.now() / 1000;\n }\n style[0] = getRainbowColor(t);\n style[1] = 0;\n if (this.superRainbow) style[1] = getRainbowColor(t / 10);\n style[2] = style[2] | 1;\n if (!this.superRainbow && style[2] & 1 << 1) style[2] ^= 1 << 1;\n index++;\n }\n\n var foreground = style[0];\n var background = style[1];\n var attributes = style[2];\n var setForeground = foreground !== lastStyle[0];\n var setBackground = background !== lastStyle[1];\n var setAttributes = attributes !== lastStyle[2];\n\n if (setForeground && setBackground) {\n if (foreground < 256 && background < 256) {\n serialized += '\\x03' + encodeAsCodePoint(background << 8 | foreground);\n } else {\n serialized += '\\x05' + this.encodeColor(foreground);\n serialized += '\\x06' + this.encodeColor(background);\n }\n } else if (setForeground) serialized += '\\x05' + this.encodeColor(foreground);else if (setBackground) serialized += '\\x06' + this.encodeColor(background);\n if (setAttributes) serialized += '\\x04' + encodeAsCodePoint(attributes);\n lastStyle = style;\n\n serialized += cell[0];\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n return serialized;\n }\n }, {\n key: 'getUpdate',\n value: function getUpdate() {\n var topics = 0;\n var topicData = [];\n var screenOpts = this.getScreenOpts();\n var title = this.getTitle();\n var buttons = this.getButtons();\n var cursor = this.getCursor();\n var screen = this.serializeScreen();\n if (this._screenOpts !== screenOpts) {\n this._screenOpts = screenOpts;\n topicData.push(screenOpts);\n }\n if (this._title !== title) {\n this._title = title;\n topicData.push(title);\n }\n if (this._buttons !== buttons) {\n this._buttons = buttons;\n topicData.push(buttons);\n }\n if (this._cursor !== cursor) {\n this._cursor = cursor;\n topicData.push(cursor);\n }\n if (this._screen !== screen) {\n this._screen = screen;\n topicData.push(screen);\n }\n if (!topicData.length) return '';\n return 'U' + encodeAsCodePoint(topics) + topicData.join('');\n }\n }, {\n key: 'loadTimer',\n value: function loadTimer() {\n var _this2 = this;\n\n clearInterval(this._loadTimer);\n this._loadTimer = setInterval(function () {\n var update = _this2.getUpdate();\n if (update) _this2.termScreen.load(update);\n }, 30);\n }\n }]);\n\n return ScrollingTerminal;\n}();\n\nvar Process = function (_EventEmitter) {\n _inherits(Process, _EventEmitter);\n\n function Process() {\n _classCallCheck(this, Process);\n\n return _possibleConstructorReturn(this, (Process.__proto__ || Object.getPrototypeOf(Process)).apply(this, arguments));\n }\n\n _createClass(Process, [{\n key: 'write',\n value: function write(data) {\n this.emit('in', data);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n // death.\n this.emit('exit', 0);\n }\n }, {\n key: 'run',\n value: function run() {\n // noop\n }\n }]);\n\n return Process;\n}(EventEmitter);\n\nvar demoData = {\n buttons: [],\n mouseReceiver: null\n};\n\nvar demoshIndex = {\n clear: function (_Process) {\n _inherits(Clear, _Process);\n\n function Clear() {\n _classCallCheck(this, Clear);\n\n return _possibleConstructorReturn(this, (Clear.__proto__ || Object.getPrototypeOf(Clear)).apply(this, arguments));\n }\n\n _createClass(Clear, [{\n key: 'run',\n value: function run() {\n this.emit('write', '\\x1b[2J\\x1b[1;1H');\n this.destroy();\n }\n }]);\n\n return Clear;\n }(Process),\n screenfetch: function (_Process2) {\n _inherits(Screenfetch, _Process2);\n\n function Screenfetch() {\n _classCallCheck(this, Screenfetch);\n\n return _possibleConstructorReturn(this, (Screenfetch.__proto__ || Object.getPrototypeOf(Screenfetch)).apply(this, arguments));\n }\n\n _createClass(Screenfetch, [{\n key: 'run',\n value: function run() {\n var _this6 = this;\n\n var image = ('\\n ###. ESPTerm Demo\\n \\'###. Hostname: ' + window.location.hostname + '\\n \\'###. Shell: ESPTerm Demo Shell\\n \\'###. Resolution: 80x25@' + window.devicePixelRatio + 'x\\n :###-\\n .###\\'\\n .###\\'\\n .###\\' ###############\\n ###\\' ###############\\n ').split('\\n').filter(function (line) {\n return line.trim();\n });\n\n var chars = '';\n for (var y = 0; y < image.length; y++) {\n for (var x = 0; x < 80; x++) {\n if (image[y][x]) {\n chars += '\\x1B[38;5;' + getRainbowColor((x + y) / 10) + 'm' + image[y][x];\n } else chars += ' ';\n }\n }\n\n this.emit('write', '\\r\\n\\x1b[?25l');\n var loop = function loop() {\n _this6.emit('write', chars.substr(0, 80));\n chars = chars.substr(80);\n if (chars.length) setTimeout(loop, 50);else {\n _this6.emit('write', '\\r\\n\\x1b[?25h');\n _this6.destroy();\n }\n };\n loop();\n }\n }]);\n\n return Screenfetch;\n }(Process),\n 'local-echo': function (_Process3) {\n _inherits(LocalEcho, _Process3);\n\n function LocalEcho() {\n _classCallCheck(this, LocalEcho);\n\n return _possibleConstructorReturn(this, (LocalEcho.__proto__ || Object.getPrototypeOf(LocalEcho)).apply(this, arguments));\n }\n\n _createClass(LocalEcho, [{\n key: 'run',\n value: function run() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n if (!args.includes('--suppress-note')) {\n this.emit('write', '\\x1b[38;5;239mNote: not all terminal features are supported or and may not work as expected in this demo\\x1b[0m\\r\\n');\n }\n }\n }, {\n key: 'write',\n value: function write(data) {\n this.emit('write', data);\n }\n }]);\n\n return LocalEcho;\n }(Process),\n 'info': function (_Process4) {\n _inherits(Info, _Process4);\n\n function Info() {\n _classCallCheck(this, Info);\n\n return _possibleConstructorReturn(this, (Info.__proto__ || Object.getPrototypeOf(Info)).apply(this, arguments));\n }\n\n _createClass(Info, [{\n key: 'run',\n value: function run() {\n var _this9 = this;\n\n for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n args[_key2] = arguments[_key2];\n }\n\n var fast = args.includes('--fast');\n this.showSplash().then(function () {\n _this9.printText(fast);\n });\n }\n }, {\n key: 'showSplash',\n value: function showSplash() {\n var _this10 = this;\n\n var splash = '\\n -#####- -###*..#####- ######-\\n -#* -#- .## .##. *#-\\n -##### .-###*..#####- *#- -*##*- #*-#--#**#-*##-\\n -#* -#-.##. *#- *##@#* ##. -#* *# .#*\\n -#####--####- .##. *#- -*#@@- ##. -#* *# .#*\\n '.split('\\n').filter(function (line) {\n return line.trim();\n });\n var levels = {\n ' ': -231,\n '.': 4,\n '-': 8,\n '*': 17,\n '#': 24\n };\n var characters = {\n ' ': ' ',\n '.': '░',\n '-': '▒',\n '*': '▓',\n '#': '█'\n };\n for (var i in splash) {\n if (splash[i].length < 79) splash[i] += ' '.repeat(79 - splash[i].length);\n }\n this.emit('write', '\\r\\n'.repeat(splash.length + 1));\n this.emit('write', '\\x1b[A'.repeat(splash.length));\n this.emit('write', '\\x1b[?25l');\n\n var cursorX = 0;\n var cursorY = 0;\n var moveTo = function moveTo(x, y) {\n var moveX = x - cursorX;\n var moveY = y - cursorY;\n _this10.emit('write', '\\x1B[' + Math.abs(moveX) + (moveX > 0 ? 'C' : 'D'));\n _this10.emit('write', '\\x1B[' + Math.abs(moveY) + (moveY > 0 ? 'B' : 'A'));\n cursorX = x;\n cursorY = y;\n };\n var drawCell = function drawCell(x, y) {\n moveTo(x, y);\n if (splash[y][x] === '@') {\n _this10.emit('write', '\\x1b[48;5;238m\\x1b[38;5;255m▄\\b');\n } else {\n var level = 231 + levels[splash[y][x]];\n var character = characters[splash[y][x]];\n _this10.emit('write', '\\x1B[48;5;' + level + 'm\\x1B[38;5;' + level + 'm' + character + '\\b');\n }\n };\n return new Promise(function (resolve, reject) {\n var self = _this10;\n var x = 13;\n var cycles = 0;\n var loop = function loop() {\n for (var y = 0; y < splash.length; y++) {\n var dx = x - y;\n if (dx > 0) drawCell(dx, y);\n }\n\n if (++x < 70) {\n if (++cycles >= 3) {\n setTimeout(loop, 50);\n cycles = 0;\n } else loop();\n } else {\n moveTo(0, splash.length);\n self.emit('write', '\\x1b[m\\x1b[?25h');\n resolve();\n }\n };\n loop();\n });\n }\n }, {\n key: 'printText',\n value: function printText() {\n var fast = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n\n // lots of printing\n var parts = ['', ' ESPTerm is a VT100-like terminal emulator running on the ESP8266 WiFi chip.', '', ' \\x1b[93mThis is an online demo of the web user interface, simulating a simple ', ' terminal in your browser.\\x1b[m', '', ' Type \\x1b[92mls\\x1b[m to list available commands.', ' Use the \\x1b[94mlinks\\x1b[m below this screen for a demo of the options and more info.', ''];\n\n if (fast) {\n this.emit('write', parts.join('\\r\\n') + '\\r\\n');\n this.destroy();\n } else {\n var self = this;\n var loop = function loop() {\n self.emit('write', parts.shift() + '\\r\\n');\n if (parts.length) setTimeout(loop, 17);else self.destroy();\n };\n loop();\n }\n }\n }]);\n\n return Info;\n }(Process),\n colors: function (_Process5) {\n _inherits(PrintColors, _Process5);\n\n function PrintColors() {\n _classCallCheck(this, PrintColors);\n\n return _possibleConstructorReturn(this, (PrintColors.__proto__ || Object.getPrototypeOf(PrintColors)).apply(this, arguments));\n }\n\n _createClass(PrintColors, [{\n key: 'run',\n value: function run() {\n this.emit('write', '\\r\\n');\n var fgtext = 'foreground-color';\n this.emit('write', ' ');\n for (var i = 0; i < 16; i++) {\n this.emit('write', '\\x1b[' + (i < 8 ? '3' + i : '9' + (i - 8)) + 'm');\n this.emit('write', fgtext[i] + ' ');\n }\n this.emit('write', '\\r\\n ');\n for (var _i = 0; _i < 16; _i++) {\n this.emit('write', '\\x1b[' + (_i < 8 ? '4' + _i : '10' + (_i - 8)) + 'm ');\n }\n this.emit('write', '\\x1b[m\\r\\n');\n for (var r = 0; r < 6; r++) {\n this.emit('write', ' ');\n for (var g = 0; g < 6; g++) {\n for (var b = 0; b < 6; b++) {\n this.emit('write', '\\x1B[48;5;' + (16 + r * 36 + g * 6 + b) + 'm ');\n }\n this.emit('write', '\\x1b[m');\n }\n this.emit('write', '\\r\\n');\n }\n this.emit('write', ' ');\n for (var _g = 0; _g < 24; _g++) {\n this.emit('write', '\\x1B[48;5;' + (232 + _g) + 'm ');\n }\n this.emit('write', '\\x1b[m\\r\\n\\n');\n this.destroy();\n }\n }]);\n\n return PrintColors;\n }(Process),\n ls: function (_Process6) {\n _inherits(ListCommands, _Process6);\n\n function ListCommands() {\n _classCallCheck(this, ListCommands);\n\n return _possibleConstructorReturn(this, (ListCommands.__proto__ || Object.getPrototypeOf(ListCommands)).apply(this, arguments));\n }\n\n _createClass(ListCommands, [{\n key: 'run',\n value: function run() {\n this.emit('write', '\\x1b[92mList of demo commands\\x1b[m\\r\\n');\n for (var i in demoshIndex) {\n if (typeof demoshIndex[i] === 'string') continue;\n this.emit('write', i + '\\r\\n');\n }\n this.destroy();\n }\n }]);\n\n return ListCommands;\n }(Process),\n theme: function (_Process7) {\n _inherits(SetTheme, _Process7);\n\n function SetTheme(shell) {\n _classCallCheck(this, SetTheme);\n\n var _this13 = _possibleConstructorReturn(this, (SetTheme.__proto__ || Object.getPrototypeOf(SetTheme)).call(this));\n\n _this13.shell = shell;\n return _this13;\n }\n\n _createClass(SetTheme, [{\n key: 'run',\n value: function run() {\n var theme = +(arguments.length <= 0 ? undefined : arguments[0]) | 0;\n var maxnum = themes.length;\n if (!arguments.length || !Number.isFinite(theme) || theme < 0 || theme >= maxnum) {\n this.emit('write', '\\x1B[31mUsage: theme [0\\u2013' + (maxnum - 1) + ']\\n');\n this.destroy();\n return;\n }\n this.shell.terminal.theme = theme;\n // HACK: reset drawn screen to prevent only partly redrawn screen\n this.shell.terminal.termScreen.drawnScreenFG = [];\n this.emit('write', '');\n this.destroy();\n }\n }]);\n\n return SetTheme;\n }(Process),\n themes: function (_Process8) {\n _inherits(ShowThemes, _Process8);\n\n function ShowThemes() {\n _classCallCheck(this, ShowThemes);\n\n return _possibleConstructorReturn(this, (ShowThemes.__proto__ || Object.getPrototypeOf(ShowThemes)).apply(this, arguments));\n }\n\n _createClass(ShowThemes, [{\n key: 'color',\n value: function color(hex) {\n hex = parseInt(hex.substr(1), 16);\n var r = hex >> 16;\n var g = hex >> 8 & 0xFF;\n var b = hex & 0xFF;\n this.emit('write', '\\x1B[48;2;' + r + ';' + g + ';' + b + 'm');\n if ((r + g + b) / 3 > 127) {\n this.emit('write', '\\x1b[38;5;16m');\n } else {\n this.emit('write', '\\x1b[38;5;255m');\n }\n }\n }, {\n key: 'run',\n value: function run() {\n for (var i in themes) {\n var theme = themes[i];\n\n var name = (' ' + i).substr(-2);\n\n this.emit('write', 'Theme ' + name + ': ');\n\n for (var col = 0; col < 16; col++) {\n var text = (' ' + col).substr(-2);\n this.color(theme[col]);\n this.emit('write', text);\n this.emit('write', '\\x1b[m ');\n }\n\n this.emit('write', '\\n');\n }\n\n this.destroy();\n }\n }]);\n\n return ShowThemes;\n }(Process),\n cursor: function (_Process9) {\n _inherits(SetCursor, _Process9);\n\n function SetCursor() {\n _classCallCheck(this, SetCursor);\n\n return _possibleConstructorReturn(this, (SetCursor.__proto__ || Object.getPrototypeOf(SetCursor)).apply(this, arguments));\n }\n\n _createClass(SetCursor, [{\n key: 'run',\n value: function run() {\n for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n args[_key3] = arguments[_key3];\n }\n\n var steady = args.includes('--steady');\n if (args.includes('block')) {\n this.emit('write', '\\x1B[' + 2 * steady + ' q');\n } else if (args.includes('line')) {\n this.emit('write', '\\x1B[' + (3 + steady) + ' q');\n } else if (args.includes('bar') || args.includes('beam')) {\n this.emit('write', '\\x1B[' + (5 + steady) + ' q');\n } else {\n this.emit('write', '\\x1b[31mUsage: cursor [block|line|bar] [--steady]\\r\\n');\n }\n this.destroy();\n }\n }]);\n\n return SetCursor;\n }(Process),\n rainbow: function (_Process10) {\n _inherits(ToggleRainbow, _Process10);\n\n function ToggleRainbow(shell) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n _classCallCheck(this, ToggleRainbow);\n\n var _this16 = _possibleConstructorReturn(this, (ToggleRainbow.__proto__ || Object.getPrototypeOf(ToggleRainbow)).call(this));\n\n _this16.shell = shell;\n _this16.su = options.su;\n _this16.abort = false;\n return _this16;\n }\n\n _createClass(ToggleRainbow, [{\n key: 'write',\n value: function write(data) {\n var newLine = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n if (data === 'y') {\n this.shell.terminal.rainbow = !this.shell.terminal.rainbow;\n this.shell.terminal.superRainbow = true;\n demoData._didWarnRainbow = true;\n } else {\n this.emit('write', data);\n }\n if (newLine) this.emit('write', '\\x1b[0;32m\\x1b[G\\x1b[79PRainbow!\\n');\n this.destroy();\n }\n }, {\n key: 'run',\n value: function run() {\n if (this.su && !this.shell.terminal.rainbow) {\n if (!demoData._didWarnRainbow) {\n this.emit('write', '\\x1b[31;1mWarning: flashy colors. Continue? [y/N] ');\n } else {\n this.write('y', false);\n }\n } else {\n this.shell.terminal.rainbow = !this.shell.terminal.rainbow;\n this.shell.terminal.superRainbow = false;\n this.destroy();\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.abort = true;\n _get(ToggleRainbow.prototype.__proto__ || Object.getPrototypeOf(ToggleRainbow.prototype), 'destroy', this).call(this);\n }\n }]);\n\n return ToggleRainbow;\n }(Process),\n mouse: function (_Process11) {\n _inherits(ShowMouse, _Process11);\n\n function ShowMouse(shell) {\n _classCallCheck(this, ShowMouse);\n\n var _this17 = _possibleConstructorReturn(this, (ShowMouse.__proto__ || Object.getPrototypeOf(ShowMouse)).call(this));\n\n _this17.shell = shell;\n return _this17;\n }\n\n _createClass(ShowMouse, [{\n key: 'run',\n value: function run() {\n this.emit('buttons', [{\n label: 'Exit',\n action: function action(shell) {\n shell.write('\\x03');\n }\n }]);\n\n this.shell.terminal.trackMouse = true;\n demoData.mouseReceiver = this;\n this.randomData = [];\n this.highlighted = {};\n var characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n for (var i = 0; i < 23; i++) {\n var line = '';\n for (var j = 0; j < 79; j++) {\n line += characters[Math.floor(characters.length * Math.random())];\n }\n this.randomData.push(line);\n }\n this.scrollOffset = 0;\n this.render();\n }\n }, {\n key: 'render',\n value: function render() {\n this.emit('write', '\\x1b[m\\x1b[2J\\x1b[1;1H');\n this.emit('write', '\\x1b[97m\\x1b[1mMouse Demo\\r\\n\\x1b[mMouse movement, clicking, and scrolling!');\n\n // render random data for scrolling\n for (var y = 0; y < 23; y++) {\n var index = y + this.scrollOffset;\n // proper modulo:\n index = (index % this.randomData.length + this.randomData.length) % this.randomData.length;\n var line = this.randomData[index];\n var lineData = '\\x1B[' + (3 + y) + ';1H\\x1B[38;5;239m';\n for (var x in line) {\n if (this.highlighted[(y + 2) * 80 + +x]) lineData += '\\x1b[97m';\n lineData += line[x];\n if (this.highlighted[(y + 2) * 80 + +x]) lineData += '\\x1b[38;5;239m';\n }\n this.emit('write', lineData);\n }\n\n // move cursor to mouse\n if (this.mouse) {\n this.emit('write', '\\x1B[' + (this.mouse.y + 1) + ';' + (this.mouse.x + 1) + 'H');\n }\n }\n }, {\n key: 'mouseMove',\n value: function mouseMove(x, y) {\n this.mouse = { x: x, y: y };\n this.render();\n }\n }, {\n key: 'mouseDown',\n value: function mouseDown(x, y, button) {\n if (button === 4) this.scrollOffset--;else if (button === 5) this.scrollOffset++;else this.highlighted[y * 80 + x] = !this.highlighted[y * 80 + x];\n this.render();\n }\n }, {\n key: 'mouseUp',\n value: function mouseUp(x, y, button) {}\n }, {\n key: 'destroy',\n value: function destroy() {\n this.shell.terminal.write('\\x1b[2J\\x1b[1;1H');\n this.shell.terminal.trackMouse = false;\n if (demoData.mouseReceiver === this) demoData.mouseReceiver = null;\n _get(ShowMouse.prototype.__proto__ || Object.getPrototypeOf(ShowMouse.prototype), 'destroy', this).call(this);\n }\n }]);\n\n return ShowMouse;\n }(Process),\n sudo: function (_Process12) {\n _inherits(Sudo, _Process12);\n\n function Sudo(shell) {\n _classCallCheck(this, Sudo);\n\n var _this18 = _possibleConstructorReturn(this, (Sudo.__proto__ || Object.getPrototypeOf(Sudo)).call(this));\n\n _this18.shell = shell;\n _this18.didDestroy = false;\n return _this18;\n }\n\n _createClass(Sudo, [{\n key: 'run',\n value: function run() {\n var _this19 = this;\n\n for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n\n if (args.length === 0) {\n this.emit('write', '\\x1b[31mUsage: sudo [command]\\x1b[m\\r\\n');\n this.destroy();\n } else {\n var name = args.shift();\n if (this.shell.index[name]) {\n var _Process13 = this.shell.index[name];\n if (_Process13 instanceof Function) {\n var child = this.child = new _Process13(this.shell, { su: true });\n this.on('in', function (data) {\n return child.write(data);\n });\n var write = function write(data) {\n return _this19.emit('write', data);\n };\n var setButtons = function setButtons(buttons) {\n return _this19.emit('buttons', buttons);\n };\n child.on('write', write);\n child.on('buttons', setButtons);\n child.on('exit', function (code) {\n child.removeListener('write', write);\n child.removeListener('buttons', setButtons);\n _this19.destroy();\n });\n child.run.apply(child, args);\n } else {\n this.emit('write', _Process13);\n this.destroy();\n }\n } else {\n this.emit('write', 'sudo: ' + name + ': command not found\\r\\n');\n this.destroy();\n }\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n if (this.didDestroy) return;\n this.didDestroy = true;\n if (this.child) this.child.destroy();\n _get(Sudo.prototype.__proto__ || Object.getPrototypeOf(Sudo.prototype), 'destroy', this).call(this);\n }\n }]);\n\n return Sudo;\n }(Process),\n make: function (_Process14) {\n _inherits(Make, _Process14);\n\n function Make(shell) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n _classCallCheck(this, Make);\n\n var _this20 = _possibleConstructorReturn(this, (Make.__proto__ || Object.getPrototypeOf(Make)).call(this));\n\n _this20.su = options.su;\n return _this20;\n }\n\n _createClass(Make, [{\n key: 'run',\n value: function run() {\n for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {\n args[_key5] = arguments[_key5];\n }\n\n if (args.length === 0) this.emit('write', '\\x1b[31mmake: *** No targets specified. Stop.\\x1b[0m\\r\\n');else if (args.length === 3 && args.join(' ').toLowerCase() === 'me a sandwich') {\n if (this.su) {\n var b = '\\x1b[33m';\n var r = '\\x1b[0m';\n var l = '\\x1b[32m';\n var c = '\\x1b[38;5;229m';\n var h = '\\x1b[38;5;225m';\n this.emit('write', ' ' + b + '_.---._\\r\\n' + ' _.-~ ~-._\\r\\n' + ' _.-~ ~-._\\r\\n' + ' _.-~ ~---._\\r\\n' + ' _.-~ ~\\\\\\r\\n' + ' .-~ _.;\\r\\n' + ' :-._ _.-~ ./\\r\\n' + ' `-._~-._ _..__.-~ _.-~\\r\\n' + (' ' + c + '/ ' + b + '~-._~-._ / .__..--' + c + '~-' + l + '---._\\r\\n') + (c + ' \\\\_____(_' + b + ';-._\\\\. _.-~_/' + c + ' ~)' + l + '.. . \\\\\\r\\n') + (l + ' /(_____ ' + b + '\\\\`--...--~_.-~' + c + '______..-+' + l + '_______)\\r\\n') + (l + ' .(_________/' + b + '`--...--~/' + l + ' _/ ' + h + ' ' + b + '/\\\\\\r\\n') + (b + ' /-._' + h + ' \\\\_ ' + l + '(___./_..-~' + h + '__.....' + b + '__..-~./\\r\\n') + (b + ' `-._~-._' + h + ' ~\\\\--------~ .-~' + b + '_..__.-~ _.-~\\r\\n') + (b + ' ~-._~-._ ' + h + '~---------` ' + b + '/ .__..--~\\r\\n') + (b + ' ~-._\\\\. _.-~_/\\r\\n') + (b + ' \\\\`--...--~_.-~\\r\\n') + (b + ' `--...--~' + r + '\\r\\n'));\n } else {\n this.emit('write', '\\x1b[31mmake: me a sandwich : Permission denied\\x1b[0m\\r\\n');\n }\n } else {\n this.emit('write', '\\x1B[31mmake: *** No rule to make target \\'' + args.join(' ').toLowerCase() + '\\'. Stop.\\x1B[0m\\r\\n');\n }\n this.destroy();\n }\n }]);\n\n return Make;\n }(Process),\n pwd: '/this/is/a/demo\\r\\n',\n cd: '\\x1b[38;5;239mNo directories to change to\\r\\n',\n whoami: window.navigator.userAgent + '\\r\\n',\n hostname: '' + window.location.hostname,\n uname: 'ESPTerm Demo\\r\\n',\n mkdir: '\\x1b[38;5;239mDid not create a directory because this is a demo.\\r\\n',\n rm: '\\x1b[38;5;239mDid not delete anything because this is a demo.\\r\\n',\n cp: '\\x1b[38;5;239mNothing to copy because this is a demo.\\r\\n',\n mv: '\\x1b[38;5;239mNothing to move because this is a demo.\\r\\n',\n ln: '\\x1b[38;5;239mNothing to link because this is a demo.\\r\\n',\n touch: '\\x1b[38;5;239mNothing to touch\\r\\n',\n exit: '\\x1b[38;5;239mNowhere to go\\r\\n',\n github: function (_Process15) {\n _inherits(GoToGithub, _Process15);\n\n function GoToGithub() {\n _classCallCheck(this, GoToGithub);\n\n return _possibleConstructorReturn(this, (GoToGithub.__proto__ || Object.getPrototypeOf(GoToGithub)).apply(this, arguments));\n }\n\n _createClass(GoToGithub, [{\n key: 'run',\n value: function run() {\n window.open('https://github.com/espterm/espterm-firmware');\n this.destroy();\n }\n }]);\n\n return GoToGithub;\n }(Process)\n};\nvar autocompleteIndex = {\n 'local-echo': 'local-echo [--suppress-note]',\n theme: 'theme [n]',\n cursor: 'cursor [block|line|bar] [--steady]',\n sudo: 'sudo [command]'\n};\n\nvar DemoShell = function () {\n function DemoShell(terminal, printInfo) {\n var _this22 = this;\n\n _classCallCheck(this, DemoShell);\n\n this.terminal = terminal;\n this.terminal.reset();\n this.parser = new ANSIParser(function () {\n return _this22.handleParsed.apply(_this22, arguments);\n });\n this.history = [];\n this.historyIndex = 0;\n this.cursorPos = 0;\n this.lastInputLength = 0;\n this.child = null;\n this.index = demoshIndex;\n\n if (printInfo) this.run('info');else this.prompt();\n }\n\n _createClass(DemoShell, [{\n key: 'write',\n value: function write(text) {\n if (this.child) {\n if (text.codePointAt(0) === 3) this.child.destroy();else this.child.write(text);\n } else this.parser.write(text);\n }\n }, {\n key: 'prompt',\n value: function prompt() {\n var success = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n if (this.terminal.cursor.x !== 0) this.terminal.write('\\x1b[m\\x1b[38;5;238m⏎\\r\\n');\n this.terminal.write('\\x1b[34;1mdemosh \\x1b[m');\n if (!success) this.terminal.write('\\x1b[31m');\n this.terminal.write('$ \\x1b[m');\n this.history.unshift('');\n this.cursorPos = 0;\n\n this.setButtons();\n }\n }, {\n key: 'copyFromHistoryIndex',\n value: function copyFromHistoryIndex() {\n if (!this.historyIndex) return;\n var current = this.history[this.historyIndex];\n this.history[0] = current;\n this.historyIndex = 0;\n }\n }, {\n key: 'getCompleted',\n value: function getCompleted() {\n var visual = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n\n if (this.history[0]) {\n var input = this.history[0];\n var prefix = '';\n if (input.startsWith('sudo ')) {\n var newInput = input.replace(/^(sudo\\s+)+/, '');\n prefix = input.substr(0, input.length - newInput.length);\n input = newInput;\n }\n for (var name in this.index) {\n if (name.startsWith(input) && name !== input) {\n if (visual && name in autocompleteIndex) return prefix + autocompleteIndex[name];\n return prefix + name;\n }\n }\n return null;\n }\n return null;\n }\n }, {\n key: 'handleParsed',\n value: function handleParsed(action) {\n this.terminal.write('\\x1B[' + (this.lastInputLength - this.cursorPos) + 'P');\n this.terminal.write('\\b\\x1b[P'.repeat(this.cursorPos));\n\n if (action === 'write') {\n this.copyFromHistoryIndex();\n this.history[0] = this.history[0].substr(0, this.cursorPos) + (arguments.length <= 1 ? undefined : arguments[1]) + this.history[0].substr(this.cursorPos);\n this.cursorPos++;\n } else if (action === 'back') {\n this.copyFromHistoryIndex();\n this.history[0] = this.history[0].substr(0, this.cursorPos - 1) + this.history[0].substr(this.cursorPos);\n this.cursorPos--;\n if (this.cursorPos < 0) this.cursorPos = 0;\n } else if (action === 'tab') {\n var _completed = this.getCompleted();\n if (_completed) {\n this.history[0] = _completed;\n this.cursorPos = this.history[0].length;\n }\n } else if (action === 'move-cursor-x') {\n this.cursorPos = Math.max(0, Math.min(this.history[this.historyIndex].length, this.cursorPos + (arguments.length <= 1 ? undefined : arguments[1])));\n } else if (action === 'delete-line') {\n this.copyFromHistoryIndex();\n this.history[0] = '';\n this.cursorPos = 0;\n } else if (action === 'delete-word') {\n this.copyFromHistoryIndex();\n var words = this.history[0].substr(0, this.cursorPos).split(' ');\n words.pop();\n this.history[0] = words.join(' ') + this.history[0].substr(this.cursorPos);\n this.cursorPos = words.join(' ').length;\n } else if (action === 'move-cursor-y') {\n this.historyIndex -= arguments.length <= 1 ? undefined : arguments[1];\n if (this.historyIndex < 0) this.historyIndex = 0;\n if (this.historyIndex >= this.history.length) this.historyIndex = this.history.length - 1;\n this.cursorPos = this.history[this.historyIndex].length;\n }\n\n this.terminal.write(this.history[this.historyIndex]);\n this.terminal.write('\\b'.repeat(this.history[this.historyIndex].length));\n this.terminal.moveForward(this.cursorPos);\n\n this.lastInputLength = this.cursorPos;\n\n var completed = this.getCompleted(true);\n if (this.historyIndex === 0 && completed && action !== 'return') {\n // show closest match faintly\n var rest = completed.substr(this.history[0].length);\n this.terminal.write('\\x1B[2m' + rest + '\\x1B[m' + '\\b'.repeat(rest.length));\n this.lastInputLength += rest.length;\n }\n\n if (action === 'return') {\n this.terminal.write('\\n');\n this.parse(this.history[this.historyIndex]);\n }\n }\n }, {\n key: 'parse',\n value: function parse(input) {\n if (input === 'help') input = 'info';\n // TODO: basic chaining (i.e. semicolon)\n if (input) this.run(input);else this.prompt();\n }\n }, {\n key: 'run',\n value: function run(command) {\n var parts = [''];\n\n var inQuote = false;\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = command.trim()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var character = _step3.value;\n\n if (inQuote && character !== inQuote) {\n parts[parts.length - 1] += character;\n } else if (inQuote) {\n inQuote = false;\n } else if (character === '\"' || character === \"'\") {\n inQuote = character;\n } else if (character.match(/\\s/)) {\n if (parts[parts.length - 1]) parts.push('');\n } else parts[parts.length - 1] += character;\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n var name = parts.shift();\n\n if (name in this.index) {\n this.spawn(name, parts);\n } else {\n this.terminal.write('demosh: Unknown command: ' + name + '\\r\\n');\n this.prompt(false);\n }\n }\n }, {\n key: 'spawn',\n value: function spawn(name) {\n var _this23 = this;\n\n var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n var Process = this.index[name];\n if (Process instanceof Function) {\n var _child;\n\n this.setButtons([]);\n this.child = new Process(this);\n var write = function write(data) {\n return _this23.terminal.write(data);\n };\n var setButtons = function setButtons(buttons) {\n return _this23.setButtons(buttons);\n };\n this.child.on('write', write);\n this.child.on('buttons', setButtons);\n this.child.on('exit', function (code) {\n if (_this23.child) {\n _this23.child.removeListener('write', write);\n _this23.child.removeListener('buttons', setButtons);\n }\n _this23.child = null;\n _this23.prompt(!code);\n });\n (_child = this.child).run.apply(_child, _toConsumableArray(args));\n } else {\n this.terminal.write(Process);\n this.prompt();\n }\n }\n }, {\n key: 'setButtons',\n value: function setButtons(buttons) {\n if (!buttons) {\n var shell = this;\n var writeChars = function writeChars(chars) {\n var loop = function loop() {\n shell.write(chars[0]);\n chars = chars.substr(1);\n if (chars) setTimeout(loop, 100);\n };\n setTimeout(loop, 200);\n };\n\n buttons = [{\n label: 'Open GitHub',\n action: function action(shell) {\n if (shell.child) shell.child.destroy();\n writeChars('github\\r');\n }\n }, {\n label: 'Help',\n action: function action(shell) {\n if (shell.child) shell.child.destroy();\n writeChars('info\\r');\n }\n }];\n }\n if (!buttons.length) buttons.push({ label: '', action: function action() {}\n });\n this.buttons = buttons;\n this.terminal.buttonLabels = buttons.map(function (x) {\n return x.label;\n });\n }\n }, {\n key: 'onButtonPress',\n value: function onButtonPress(index) {\n var button = this.buttons[index];\n if (!button) return;\n button.action(this, this.terminal);\n }\n }]);\n\n return DemoShell;\n}();\n\nwindow.demoInterface = module.exports = {\n input: function input(data) {\n var type = data[0];\n var content = data.substr(1);\n\n if (type === 's') {\n this.shell.write(content);\n } else if (type === 'b') {\n var button = content.charCodeAt(0);\n this.shell.onButtonPress(button - 1);\n } else if (type === 'm' || type === 'p' || type === 'r') {\n var row = parse2B(content, 0);\n var column = parse2B(content, 2);\n var _button = parse2B(content, 4);\n var modifiers = parse2B(content, 6);\n\n if (demoData.mouseReceiver) {\n if (type === 'm') demoData.mouseReceiver.mouseMove(column, row, _button, modifiers);else if (type === 'p') demoData.mouseReceiver.mouseDown(column, row, _button, modifiers);else if (type === 'r') demoData.mouseReceiver.mouseUp(column, row, _button, modifiers);\n }\n }\n },\n\n didInit: false,\n init: function init(screen) {\n if (this.didInit) return;\n this.didInit = true;\n this.terminal = new ScrollingTerminal(screen);\n this.shell = new DemoShell(this.terminal, true);\n }\n};\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/*\n * Copyright (c) 2010 Tim Baumann\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// NOTE:\n// Extracted from ColorTriangle and\n// Converted to ES6 by MightyPork (2017)\n\n/*******************\n * Color conversion *\n *******************/\n\nvar M = Math;\nvar TAU = 2 * M.PI;\n\nexports.hue2rgb = function (v1, v2, h) {\n if (h < 0) h += 1;\n if (h > 1) h -= 1;\n\n if (6 * h < 1) return v1 + (v2 - v1) * 6 * h;\n if (2 * h < 1) return v2;\n if (3 * h < 2) return v1 + (v2 - v1) * (2 / 3 - h) * 6;\n return v1;\n};\n\nexports.hsl2rgb = function (h, s, l) {\n h /= TAU;\n var r = void 0,\n g = void 0,\n b = void 0;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n var var_1 = void 0,\n var_2 = void 0;\n\n if (l < 0.5) var_2 = l * (1 + s);else var_2 = l + s - s * l;\n\n var_1 = 2 * l - var_2;\n\n r = exports.hue2rgb(var_1, var_2, h + 1 / 3);\n g = exports.hue2rgb(var_1, var_2, h);\n b = exports.hue2rgb(var_1, var_2, h - 1 / 3);\n }\n return [r, g, b];\n};\n\nexports.rgb2hsl = function (r, g, b) {\n var min = M.min(r, g, b);\n var max = M.max(r, g, b);\n var d = max - min; // delta\n\n var h = void 0,\n s = void 0,\n l = void 0;\n\n l = (max + min) / 2;\n\n if (d === 0) {\n // gray\n h = s = 0; // HSL results from 0 to 1\n } else {\n // chroma\n if (l < 0.5) s = d / (max + min);else s = d / (2 - max - min);\n\n var d_r = ((max - r) / 6 + d / 2) / d;\n var d_g = ((max - g) / 6 + d / 2) / d;\n var d_b = ((max - b) / 6 + d / 2) / d; // deltas\n\n if (r === max) h = d_b - d_g;else if (g === max) h = 1 / 3 + d_r - d_b;else if (b === max) h = 2 / 3 + d_g - d_r;\n\n if (h < 0) h += 1;else if (h > 1) h -= 1;\n }\n h *= TAU;\n return [h, s, l];\n};\n\nexports.hex2rgb = function (hex) {\n var groups = hex.match(/^#([\\da-f]{3,6})$/i);\n if (groups) {\n hex = groups[1];\n var bytes = hex.length / 3;\n var max = Math.pow(16, bytes) - 1;\n return [0, 1, 2].map(function (x) {\n return parseInt(hex.slice(x * bytes, (x + 1) * bytes), 16) / max;\n });\n }\n return [0, 0, 0];\n};\n\nfunction pad(n) {\n return ('00' + n).substr(-2);\n}\n\nexports.rgb255ToHex = function (r, g, b) {\n return '#' + [r, g, b].map(function (x) {\n return pad(x.toString(16));\n }).join('');\n};\n\nexports.rgb2hex = function (r, g, b) {\n return '#' + [r, g, b].map(function (x) {\n return pad(Math.round(x * 255).toString(16));\n }).join('');\n};\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar data = __webpack_require__(13);\n\nmodule.exports = function localize(key) {\n return data[key] || '?' + key + '?';\n};\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n__webpack_require__(10);\n__webpack_require__(2);\n__webpack_require__(3);\n__webpack_require__(11);\ntry {\n __webpack_require__(6);\n} catch (err) {}\n__webpack_require__(12);\n\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n qs = _require.qs;\n\n/* Export stuff to the global scope for inline scripts */\n\n\nwindow.termInit = __webpack_require__(14);\nwindow.$ = $;\nwindow.qs = qs;\n\nwindow.themes = __webpack_require__(5);\n\nwindow.TermConf = __webpack_require__(24);\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\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 return result;\n }();\n var stringFromCharCode = String.fromCharCode;\n var floor = Math.floor;\n var fromCodePoint = function fromCodePoint() {\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 (!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) {\n // BMP code point\n codeUnits.push(codePoint);\n } else {\n // 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\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n mk = _require.mk,\n qs = _require.qs,\n qsa = _require.qsa,\n cr = _require.cr;\n\nvar modal = __webpack_require__(2);\nvar notify = __webpack_require__(3);\n\n/** Global generic init */\n$.ready(function () {\n // Opening menu on mobile / narrow screen\n function menuOpen() {\n $('#menu').toggleClass('expanded');\n }\n $('#brand').on('click', menuOpen).on('keypress', cr(menuOpen));\n\n // Checkbox UI (checkbox CSS and hidden input with int value)\n $('.Row.checkbox').forEach(function (x) {\n var inp = x.querySelector('input');\n var box = x.querySelector('.box');\n\n $(box).toggleClass('checked', inp.value);\n\n var hdl = function hdl() {\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 var h = x.querySelector('h2');\n\n var hdl = function hdl() {\n if ($(x).hasClass('d-expanded')) {\n $(x).removeClass('d-expanded');\n } else {\n $(x).toggleClass('expanded');\n }\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 var $x = $(x);\n var 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('wheel', function (e) {\n var $this = $(this);\n var val = +$this.val();\n if (isNaN(val)) val = 1;\n\n var step = +($this.attr('step') || 1);\n var min = +$this.attr('min');\n var max = +$this.attr('max');\n if (e.deltaY > 0) {\n val += step;\n } else {\n val -= step;\n }\n\n if (Number.isFinite(min)) val = Math.max(val, +min);\n if (Number.isFinite(max)) val = Math.min(val, +max);\n $this.val(val);\n\n if ('createEvent' in document) {\n var 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 var errAt = window.location.search.indexOf('err=');\n if (errAt !== -1 && qs('.Box.errors')) {\n var errs = decodeURIComponent(window.location.search.substr(errAt + 4)).split(',');\n var humanReadableErrors = [];\n errs.forEach(function (er) {\n var lbls = qsa('label[for=\"' + er + '\"]');\n if (lbls) {\n for (var i = 0; i < lbls.length; i++) {\n var lbl = lbls[i];\n lbl.classList.add('error');\n if (i === 0) humanReadableErrors.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, ''));\n }\n } else {\n humanReadableErrors.push(er);\n }\n });\n\n qs('.Box.errors .list').innerHTML = humanReadableErrors.join(', ');\n qs('.Box.errors').classList.remove('hidden');\n }\n\n var msgAt = window.location.search.indexOf('msg=');\n if (msgAt !== -1 && qs('.Box.message')) {\n var msg = decodeURIComponent(window.location.search.substr(msgAt + 4));\n var box = qs('.Box.message');\n box.innerHTML = msg;\n box.classList.remove('hidden');\n setTimeout(function () {\n box.classList.add('hiding');\n setTimeout(function () {\n box.classList.add('hidden');\n }, 1000);\n }, 2000);\n }\n\n modal.init();\n notify.init();\n\n // remove tabindices 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 var br = qs('#brand');\n br && br.addEventListener('click', function () {\n window.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\nvar pageShown = false;\n// reveal content on load\nfunction showPage() {\n pageShown = true;\n $('#content').addClass('load');\n}\n// HACKITY HACK: fix this later\nwindow.showPage = showPage;\n\n// Auto reveal pages other than the terminal (sets window.noAutoShow)\n$.ready(function () {\n if (window.noAutoShow === true) {\n setTimeout(function () {\n if (!pageShown) {\n var bnr = mk('P');\n bnr.id = 'load-failed';\n bnr.innerHTML = 'Server connection failed! Trying again' + '.';\n qs('#screen').appendChild(bnr);\n showPage();\n }\n }, 2000);\n } else {\n setTimeout(function () {\n showPage();\n }, 1);\n }\n});\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n mk = _require.mk;\n\nvar tr = __webpack_require__(8);\n\n{\n\n // Get XX % for a slider input\n var calc_dBm = function calc_dBm(inp) {\n return '+' + (inp.value * 0.25).toFixed(2) + ' dBm';\n };\n\n // Display selected STA SSID etc\n\n\n var selectSta = 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($.htmlEscape(name));\n var hasPassword = !!password;\n\n // (the following is kind of confusing with the double-double negations,\n // but it works)\n $('#sta-nw .passwd').toggleClass('hidden', !hasPassword);\n $('#sta-nw .nopasswd').toggleClass('hidden', hasPassword);\n\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\n\n var onScan = 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 5s 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 var done = !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 var $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 var item = mk('div');\n\n var $item = $(item).data('ssid', ap.essid).data('pwd', ap.enc).attr('tabindex', 0).addClass('AP');\n\n // mark current SSID\n if (ap.essid === curSSID) {\n $item.addClass('selected');\n }\n\n var inner = mk('div');\n var escapedSSID = $.htmlEscape(ap.essid);\n $(inner).addClass('inner').htmlAppend('
' + ap.rssi_perc + '
').htmlAppend('
' + escapedSSID + '
').htmlAppend('
' + authTypes[ap.enc] + '
');\n\n $item.on('click', function () {\n var $th = $(this);\n\n var conn_ssid = $th.data('ssid');\n var conn_pass = '';\n\n if (+$th.data('pwd')) {\n // this AP needs a password\n conn_pass = window.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 var startScanning = 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\n\n var scanAPs = function scanAPs() {\n if (window._demo) {\n onScan(window._demo_aps, 200);\n } else {\n $.get('http://' + window._root + '/cfg/wifi/scan', onScan);\n }\n };\n\n var rescan = function rescan(time) {\n setTimeout(scanAPs, time);\n };\n\n /** Set up the WiFi page */\n\n\n var wifiInit = function wifiInit(cfg) {\n // Update slider value displays\n $('.Row.range').forEach(function (x) {\n var inp = x.querySelector('input');\n var disp1 = x.querySelector('.x-disp1');\n var disp2 = x.querySelector('.x-disp2');\n var t = calc_dBm(inp);\n $(disp1).html(t);\n $(disp2).html(t);\n $(inp).on('input', function () {\n t = calc_dBm(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 var w = window.WiFi = {};\n\n var authTypes = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];\n var curSSID = void 0;\n\n w.init = wifiInit;\n w.startScanning = startScanning;\n}\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports) {\n\n/* Generated language file */\nmodule.exports={\"wifi.connected_ip_is\":\"Connected, IP is \",\"wifi.not_conn\":\"Not connected.\",\"wifi.enter_passwd\":\"Enter password for \\\":ssid:\\\"\",\"term_nav.fullscreen\":\"Fullscreen\",\"term_conn.connecting\":\"Connecting\",\"term_conn.waiting_content\":\"Waiting for content\",\"term_conn.disconnected\":\"Disconnected\",\"term_conn.waiting_server\":\"Waiting for server\",\"term_conn.reconnecting\":\"Reconnecting\"}\n\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar _require = __webpack_require__(0),\n qs = _require.qs,\n mk = _require.mk;\n\nvar localize = __webpack_require__(8);\nvar Notify = __webpack_require__(3);\nvar TermScreen = __webpack_require__(15);\nvar TermConnection = __webpack_require__(18);\nvar TermInput = __webpack_require__(19);\nvar TermUpload = __webpack_require__(20);\nvar initSoftKeyboard = __webpack_require__(21);\nvar attachDebugScreen = __webpack_require__(22);\nvar initButtons = __webpack_require__(23);\n\n/** Init the terminal sub-module - called from HTML */\nmodule.exports = function (opts) {\n var screen = new TermScreen();\n var conn = new TermConnection(screen);\n var input = TermInput(conn, screen);\n var termUpload = TermUpload(conn, input, screen);\n screen.input = input;\n screen.conn = conn;\n input.termUpload = termUpload;\n\n var buttons = initButtons(input);\n screen.on('button-labels', function (labels) {\n var _buttons$labels;\n\n // TODO: don't use pointers for this\n (_buttons$labels = buttons.labels).splice.apply(_buttons$labels, [0, buttons.labels.length].concat(_toConsumableArray(labels)));\n buttons.update();\n });\n\n var showSplashTimeout = null;\n var showSplash = function showSplash(obj) {\n var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 250;\n\n clearTimeout(showSplashTimeout);\n showSplashTimeout = setTimeout(function () {\n screen.window.statusScreen = obj;\n }, delay);\n };\n\n conn.on('open', function () {\n // console.log('*open')\n showSplash({ title: localize('term_conn.connecting'), loading: true });\n });\n conn.on('connect', function () {\n // console.log('*connect')\n showSplash({ title: localize('term_conn.waiting_content'), loading: true });\n });\n conn.on('load', function () {\n // console.log('*load')\n clearTimeout(showSplashTimeout);\n if (screen.window.statusScreen) screen.window.statusScreen = null;\n });\n conn.on('disconnect', function () {\n // console.log('*disconnect')\n showSplash({ title: localize('term_conn.disconnected') }, 500);\n screen.screen = [];\n screen.screenFG = [];\n screen.screenBG = [];\n screen.screenAttrs = [];\n });\n conn.on('silence', function () {\n // console.log('*silence')\n showSplash({ title: localize('term_conn.waiting_server'), loading: true }, 0);\n });\n // conn.on('ping-fail', () => { screen.window.statusScreen = { title: 'Disconnected' } })\n conn.on('ping-success', function () {\n // console.log('*ping-success')\n showSplash({ title: localize('term_conn.reconnecting'), loading: true }, 0);\n });\n\n conn.init();\n input.init(opts);\n termUpload.init();\n Notify.init();\n\n window.onerror = function (errorMsg, file, line, col) {\n Notify.show('JS ERROR!
' + errorMsg + '
at ' + file + ':' + line + ':' + col, 10000, true);\n return false;\n };\n\n qs('#screen').appendChild(screen.canvas);\n\n initSoftKeyboard(screen, input);\n if (attachDebugScreen) attachDebugScreen(screen);\n\n var fullscreenIcon = {}; // dummy\n var isFullscreen = false;\n var properFullscreen = false;\n var fitScreen = false;\n var screenPadding = screen.window.padding;\n var fitScreenIfNeeded = function fitScreenIfNeeded() {\n if (isFullscreen) {\n fullscreenIcon.className = 'icn-resize-small';\n if (properFullscreen) {\n screen.window.fitIntoWidth = window.screen.width;\n screen.window.fitIntoHeight = window.screen.height;\n screen.window.padding = 0;\n } else {\n screen.window.fitIntoWidth = window.innerWidth;\n if (qs('#term-nav').classList.contains('hidden')) {\n screen.window.fitIntoHeight = window.innerHeight;\n } else {\n screen.window.fitIntoHeight = window.innerHeight - 24;\n }\n screen.window.padding = 0;\n }\n } else {\n fullscreenIcon.className = 'icn-resize-full';\n screen.window.fitIntoWidth = fitScreen ? window.innerWidth - 4 : 0;\n screen.window.fitIntoHeight = fitScreen ? window.innerHeight : 0;\n screen.window.padding = screenPadding;\n }\n };\n fitScreenIfNeeded();\n window.addEventListener('resize', fitScreenIfNeeded);\n\n var toggleFitScreen = function toggleFitScreen() {\n fitScreen = !fitScreen;\n var 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\n qs('#term-fit-screen').addEventListener('click', function () {\n toggleFitScreen();\n return false;\n });\n\n // add fullscreen mode & button\n if (window.Element.prototype.requestFullscreen || window.Element.prototype.webkitRequestFullscreen) {\n properFullscreen = true;\n\n var checkForFullscreen = function checkForFullscreen() {\n // document.fullscreenElement is not really supported yet, so here's a hack\n if (isFullscreen && (window.innerWidth !== window.screen.width || window.innerHeight !== window.screen.height)) {\n isFullscreen = false;\n fitScreenIfNeeded();\n }\n };\n setInterval(checkForFullscreen, 500);\n }\n\n // (why are the buttons anchors?)\n var button = mk('a');\n button.id = 'fullscreen-button';\n button.href = '#';\n button.addEventListener('click', function (e) {\n e.preventDefault();\n\n if (document.body.classList.contains('pseudo-fullscreen')) {\n document.body.classList.remove('pseudo-fullscreen');\n isFullscreen = false;\n fitScreenIfNeeded();\n return;\n }\n\n isFullscreen = true;\n fitScreenIfNeeded();\n screen.updateSize();\n\n if (properFullscreen) {\n if (screen.canvas.requestFullscreen) screen.canvas.requestFullscreen();else screen.canvas.webkitRequestFullscreen();\n } else {\n document.body.classList.add('pseudo-fullscreen');\n }\n });\n fullscreenIcon = mk('i');\n fullscreenIcon.className = 'icn-resize-full';\n button.appendChild(fullscreenIcon);\n var span = mk('span');\n span.textContent = localize('term_nav.fullscreen');\n button.appendChild(span);\n qs('#term-nav').insertBefore(button, qs('#term-nav').firstChild);\n\n // for debugging\n window.termScreen = screen;\n window.conn = conn;\n window.input = input;\n window.termUpl = termUpload;\n};\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar EventEmitter = __webpack_require__(4);\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n mk = _require.mk,\n qs = _require.qs;\n\nvar notify = __webpack_require__(3);\nvar ScreenParser = __webpack_require__(16);\nvar ScreenRenderer = __webpack_require__(17);\n\nmodule.exports = function (_EventEmitter) {\n _inherits(TermScreen, _EventEmitter);\n\n function TermScreen() {\n _classCallCheck(this, TermScreen);\n\n var _this = _possibleConstructorReturn(this, (TermScreen.__proto__ || Object.getPrototypeOf(TermScreen)).call(this));\n\n _this.canvas = mk('canvas');\n _this.ctx = _this.canvas.getContext('2d');\n\n _this.parser = new ScreenParser(_this);\n _this.renderer = new ScreenRenderer(_this);\n\n // debug screen handle\n _this._debug = null;\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 // dummy. Handle for Input\n _this.input = new Proxy({}, {\n get: function get() {\n return function () {\n return console.warn('TermScreen#input not set!');\n };\n }\n });\n // dummy. Handle for Conn\n _this.conn = new Proxy({}, {\n get: function get() {\n return function () {\n return console.warn('TermScreen#conn not set!');\n };\n },\n set: function set(a, b) {\n return function () {\n return console.warn('TermScreen#conn not set!');\n };\n }\n });\n\n _this.cursor = {\n x: 0,\n y: 0,\n blinking: true,\n visible: true,\n hanging: false,\n style: 'block'\n };\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 padding: 6,\n gridScaleX: 1.0,\n gridScaleY: 1.2,\n fitIntoWidth: 0,\n fitIntoHeight: 0,\n debug: false,\n graphics: 0,\n statusScreen: null\n\n // scaling caused by fitIntoWidth/fitIntoHeight\n };_this._windowScale = 1;\n\n // actual padding, as it may be disabled by fullscreen mode etc.\n _this._padding = 0;\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 padding: 0,\n gridScaleX: 0,\n gridScaleY: 0,\n fontFamily: '',\n fontSize: 0,\n fitIntoWidth: 0,\n fitIntoHeight: 0\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 // selection start and end (x, y) tuples\n start: [0, 0],\n end: [0, 0]\n\n // mouse features\n };_this.mouseMode = { clicks: false, movement: false\n\n // make writing to window update size and draw\n };var self = _this;\n _this.window = new Proxy(_this._window, {\n set: function set(target, key, value, receiver) {\n if (target[key] !== value) {\n target[key] = value;\n self.scheduleSizeUpdate();\n self.renderer.scheduleDraw('window:' + key + '=' + value);\n self.emit('update-window:' + key, value);\n }\n return true;\n }\n });\n\n _this.bracketedPaste = false;\n _this.blinkingCellCount = 0;\n _this.reverseVideo = false;\n\n _this.screen = [];\n _this.screenFG = [];\n _this.screenBG = [];\n _this.screenAttrs = [];\n\n var selecting = false;\n\n var selectStart = function selectStart(x, y) {\n if (selecting) return;\n selecting = true;\n _this.selection.start = _this.selection.end = _this.screenToGrid(x, y, true);\n _this.renderer.scheduleDraw('select-start');\n };\n\n var selectMove = function selectMove(x, y) {\n if (!selecting) return;\n _this.selection.end = _this.screenToGrid(x, y, true);\n _this.renderer.scheduleDraw('select-move');\n };\n\n var selectEnd = function selectEnd(x, y) {\n if (!selecting) return;\n selecting = false;\n _this.selection.end = _this.screenToGrid(x, y, true);\n _this.renderer.scheduleDraw('select-end');\n Object.assign(_this.selection, _this.getNormalizedSelection());\n };\n\n // bind event listeners\n\n _this.canvas.addEventListener('mousedown', function (e) {\n if ((_this.selection.selectable || e.altKey) && e.button === 0) {\n selectStart(e.offsetX, e.offsetY);\n } else {\n var _this$input;\n\n (_this$input = _this.input).onMouseDown.apply(_this$input, _toConsumableArray(_this.screenToGrid(e.offsetX, e.offsetY)).concat([e.button + 1]));\n }\n });\n\n window.addEventListener('mousemove', function (e) {\n selectMove(e.offsetX, e.offsetY);\n });\n\n window.addEventListener('mouseup', function (e) {\n selectEnd(e.offsetX, e.offsetY);\n });\n\n // touch event listeners\n\n var touchPosition = null;\n var touchDownTime = 0;\n var touchSelectMinTime = 500;\n var touchDidMove = false;\n\n var getTouchPositionOffset = function getTouchPositionOffset(touch) {\n var rect = _this.canvas.getBoundingClientRect();\n return [touch.clientX - rect.left, touch.clientY - rect.top];\n };\n\n _this.canvas.addEventListener('touchstart', function (e) {\n touchPosition = getTouchPositionOffset(e.touches[0]);\n touchDidMove = false;\n touchDownTime = Date.now();\n }, { passive: true });\n\n _this.canvas.addEventListener('touchmove', function (e) {\n touchPosition = getTouchPositionOffset(e.touches[0]);\n\n if (!selecting && touchDidMove === false) {\n if (touchDownTime < Date.now() - touchSelectMinTime) {\n selectStart.apply(undefined, _toConsumableArray(touchPosition));\n }\n } else if (selecting) {\n e.preventDefault();\n selectMove.apply(undefined, _toConsumableArray(touchPosition));\n }\n\n touchDidMove = true;\n });\n\n _this.canvas.addEventListener('touchend', function (e) {\n if (e.touches[0]) {\n touchPosition = getTouchPositionOffset(e.touches[0]);\n }\n\n if (selecting) {\n e.preventDefault();\n selectEnd.apply(undefined, _toConsumableArray(touchPosition));\n\n // selection ended; show touch select menu\n var touchSelectMenu = qs('#touch-select-menu');\n touchSelectMenu.classList.add('open');\n var rect = touchSelectMenu.getBoundingClientRect();\n\n // use middle position for x and one line above for y\n var selectionPos = _this.gridToScreen((_this.selection.start[0] + _this.selection.end[0]) / 2, _this.selection.start[1] - 1);\n selectionPos[0] -= rect.width / 2;\n selectionPos[1] -= rect.height / 2;\n touchSelectMenu.style.transform = 'translate(' + selectionPos[0] + 'px, ' + selectionPos[1] + 'px)';\n }\n\n if (!touchDidMove && !_this.mouseMode.clicks) {\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', function (e) {\n if (_this.selection.start[0] !== _this.selection.end[0] || _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.renderer.scheduleDraw('select-reset');\n } else {\n e.preventDefault();\n _this.emit('open-soft-keyboard');\n }\n });\n\n $.ready(function () {\n var copyButton = qs('#touch-select-copy-btn');\n if (copyButton) {\n copyButton.addEventListener('click', function () {\n _this.copySelectionToClipboard();\n });\n }\n });\n\n _this.canvas.addEventListener('mousemove', function (e) {\n if (!selecting) {\n var _this$input2;\n\n (_this$input2 = _this.input).onMouseMove.apply(_this$input2, _toConsumableArray(_this.screenToGrid(e.offsetX, e.offsetY)));\n }\n });\n\n _this.canvas.addEventListener('mouseup', function (e) {\n if (!selecting) {\n var _this$input3;\n\n (_this$input3 = _this.input).onMouseUp.apply(_this$input3, _toConsumableArray(_this.screenToGrid(e.offsetX, e.offsetY)).concat([e.button + 1]));\n }\n });\n\n var aggregateWheelDelta = 0;\n _this.canvas.addEventListener('wheel', function (e) {\n if (_this.mouseMode.clicks) {\n if (Math.abs(e.wheelDeltaY) === 120) {\n var _this$input4;\n\n // mouse wheel scrolling\n (_this$input4 = _this.input).onMouseWheel.apply(_this$input4, _toConsumableArray(_this.screenToGrid(e.offsetX, e.offsetY)).concat([e.deltaY > 0 ? 1 : -1]));\n } else {\n // smooth scrolling\n aggregateWheelDelta -= e.wheelDeltaY;\n if (Math.abs(aggregateWheelDelta) >= 40) {\n var _this$input5;\n\n (_this$input5 = _this.input).onMouseWheel.apply(_this$input5, _toConsumableArray(_this.screenToGrid(e.offsetX, e.offsetY)).concat([aggregateWheelDelta > 0 ? 1 : -1]));\n aggregateWheelDelta = 0;\n }\n }\n\n // prevent page scrolling\n e.preventDefault();\n }\n });\n\n _this.canvas.addEventListener('contextmenu', function (e) {\n if (_this.mouseMode.clicks) {\n // prevent mouse keys getting stuck\n e.preventDefault();\n }\n selectEnd(e.offsetX, e.offsetY);\n });\n return _this;\n }\n\n /**\n * Schedule a size update in the next millisecond\n */\n\n\n _createClass(TermScreen, [{\n key: 'scheduleSizeUpdate',\n value: function scheduleSizeUpdate() {\n var _this2 = this;\n\n clearTimeout(this._scheduledSizeUpdate);\n this._scheduledSizeUpdate = setTimeout(function () {\n return _this2.updateSize();\n }, 1);\n }\n\n /**\n * Returns a CSS font string with this TermScreen's font settings and the\n * font modifiers.\n * @param {Object} modifiers\n * @param {string} [modifiers.style] - the font style\n * @param {string} [modifiers.weight] - the font weight\n * @returns {string} a CSS font string\n */\n\n }, {\n key: 'getFont',\n value: function getFont() {\n var modifiers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n var fontStyle = modifiers.style || 'normal';\n var fontWeight = modifiers.weight || 'normal';\n return fontStyle + ' normal ' + fontWeight + ' ' + this.window.fontSize + 'px ' + this.window.fontFamily;\n }\n\n /**\n * Converts screen coordinates to grid coordinates.\n * @param {number} x - x in pixels\n * @param {number} y - y in pixels\n * @param {boolean} rounded - whether to round the coord, used for select highlighting\n * @returns {number[]} a tuple of (x, y) in cells\n */\n\n }, {\n key: 'screenToGrid',\n value: function screenToGrid(x, y) {\n var rounded = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var cellSize = this.getCellSize();\n\n x = x / this._windowScale - this._padding;\n y = y / this._windowScale - this._padding;\n x = Math.floor((x + (rounded ? cellSize.width / 2 : 0)) / cellSize.width);\n y = Math.floor(y / cellSize.height);\n x = Math.max(0, Math.min(this.window.width - 1, x));\n y = Math.max(0, Math.min(this.window.height - 1, y));\n\n return [x, y];\n }\n\n /**\n * Converts grid coordinates to screen coordinates.\n * @param {number} x - x in cells\n * @param {number} y - y in cells\n * @param {boolean} [withScale] - when true, will apply window scale\n * @returns {number[]} a tuple of (x, y) in pixels\n */\n\n }, {\n key: 'gridToScreen',\n value: function gridToScreen(x, y) {\n var _this3 = this;\n\n var withScale = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var cellSize = this.getCellSize();\n\n return [x * cellSize.width, y * cellSize.height].map(function (v) {\n return _this3._padding + (withScale ? v * _this3._windowScale : v);\n });\n }\n\n /**\n * The character size, used for calculating the cell size. The space character\n * is used for measuring.\n * @returns {Object} the character size with `width` and `height` in pixels\n */\n\n }, {\n key: 'getCharSize',\n value: function 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 /**\n * The cell size, which is the character size multiplied by the grid scale.\n * @returns {Object} the cell size with `width` and `height` in pixels\n */\n\n }, {\n key: 'getCellSize',\n value: function getCellSize() {\n var 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 /**\n * Updates the canvas size if it changed\n */\n\n }, {\n key: 'updateSize',\n value: function updateSize() {\n // see below (this is just updating it)\n this._window.devicePixelRatio = Math.ceil(this._windowScale * (window.devicePixelRatio || 1));\n\n var didChange = false;\n for (var 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 var _window = this.window,\n width = _window.width,\n height = _window.height,\n fitIntoWidth = _window.fitIntoWidth,\n fitIntoHeight = _window.fitIntoHeight,\n padding = _window.padding;\n\n var cellSize = this.getCellSize();\n\n // real height of the canvas element in pixels\n var realWidth = width * cellSize.width;\n var realHeight = height * cellSize.height;\n var originalWidth = realWidth;\n\n if (fitIntoWidth && fitIntoHeight) {\n var terminalAspect = realWidth / realHeight;\n var fitAspect = fitIntoWidth / fitIntoHeight;\n\n if (terminalAspect < fitAspect) {\n // align heights\n realHeight = fitIntoHeight - 2 * padding;\n realWidth = realHeight * terminalAspect;\n } else {\n // align widths\n realWidth = fitIntoWidth - 2 * padding;\n realHeight = realWidth / terminalAspect;\n }\n }\n\n // store new window scale\n this._windowScale = realWidth / originalWidth;\n\n realWidth += 2 * padding;\n realHeight += 2 * padding;\n\n // store padding\n this._padding = padding * (originalWidth / realWidth);\n\n // the DPR must be rounded to a very nice value to prevent gaps between cells\n var devicePixelRatio = this._window.devicePixelRatio = Math.ceil(this._windowScale * (window.devicePixelRatio || 1));\n\n this.canvas.width = (width * cellSize.width + 2 * Math.round(this._padding)) * devicePixelRatio;\n this.canvas.style.width = realWidth + 'px';\n this.canvas.height = (height * cellSize.height + 2 * Math.round(this._padding)) * devicePixelRatio;\n this.canvas.style.height = realHeight + 'px';\n\n // the screen has been cleared (by changing canvas width)\n this.renderer.resetDrawn();\n\n // draw immediately; the canvas shouldn't flash\n this.renderer.draw('update-size');\n }\n }\n\n /**\n * Returns a normalized version of the current selection, such that `start`\n * is always before `end`.\n * @returns {Object} the normalized selection, with `start` and `end`\n */\n\n }, {\n key: 'getNormalizedSelection',\n value: function getNormalizedSelection() {\n var _selection = this.selection,\n start = _selection.start,\n end = _selection.end;\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\n if (start[1] > end[1] || start[1] === end[1] && start[0] > end[0]) {\n var _ref = [end, start];\n start = _ref[0];\n end = _ref[1];\n }\n return { start: start, end: end };\n }\n\n /**\n * Returns whether or not a given cell is in the current selection.\n * @param {number} col - the column (x)\n * @param {number} line - the line (y)\n * @returns {boolean}\n */\n\n }, {\n key: 'isInSelection',\n value: function isInSelection(col, line) {\n var _getNormalizedSelecti = this.getNormalizedSelection(),\n start = _getNormalizedSelecti.start,\n end = _getNormalizedSelecti.end;\n\n var colAfterStart = start[0] <= col;\n var colBeforeEnd = col < end[0];\n var onStartLine = line === start[1];\n var onEndLine = line === end[1];\n\n if (onStartLine && onEndLine) return colAfterStart && colBeforeEnd;else if (onStartLine) return colAfterStart;else if (onEndLine) return colBeforeEnd;else return start[1] < line && line < end[1];\n }\n\n /**\n * Sweeps for selected cells and joins them in a multiline string.\n * @returns {string} the selection\n */\n\n }, {\n key: 'getSelectedText',\n value: function getSelectedText() {\n var screenLength = this.window.width * this.window.height;\n var lines = [];\n var previousLineIndex = -1;\n\n for (var cell = 0; cell < screenLength; cell++) {\n var x = cell % this.window.width;\n var 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 /**\n * Copies the selection to clipboard and creates a notification balloon.\n */\n\n }, {\n key: 'copySelectionToClipboard',\n value: function copySelectionToClipboard() {\n var selectedText = this.getSelectedText();\n // don't copy anything if nothing is selected\n if (!selectedText) return;\n var 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 /**\n * Shows an actual notification (if possible) or a notification balloon.\n * @param {string} text - the notification content\n */\n\n }, {\n key: 'showNotification',\n value: function showNotification(text) {\n console.info('Notification: ' + text);\n if (window.Notification && window.Notification.permission === 'granted') {\n var notification = new window.Notification('ESPTerm', {\n body: text\n });\n notification.addEventListener('click', function () {\n return window.focus();\n });\n } else {\n if (window.Notification && window.Notification.permission !== 'denied') {\n window.Notification.requestPermission();\n } else {\n // Fallback using the built-in notification balloon\n notify.show(text);\n }\n }\n }\n\n /**\n * Creates a beep sound.\n */\n\n }, {\n key: 'beep',\n value: function beep() {\n var 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 if (!this._convolver) {\n this._convolver = audioCtx.createConvolver();\n var impulseLength = audioCtx.sampleRate * 0.8;\n var impulse = audioCtx.createBuffer(2, impulseLength, audioCtx.sampleRate);\n for (var i = 0; i < impulseLength; i++) {\n impulse.getChannelData(0)[i] = Math.pow(1 - i / impulseLength, 7 + Math.random());\n impulse.getChannelData(1)[i] = Math.pow(1 - i / impulseLength, 7 + Math.random());\n }\n this._convolver.buffer = impulse;\n this._convolver.connect(audioCtx.destination);\n }\n\n // main beep\n var mainOsc = audioCtx.createOscillator();\n var mainGain = audioCtx.createGain();\n mainOsc.connect(mainGain);\n mainGain.gain.value = 4;\n mainOsc.frequency.value = 750;\n mainOsc.type = 'sine';\n\n // surrogate beep (making it sound like 'oops')\n var surrOsc = audioCtx.createOscillator();\n var surrGain = audioCtx.createGain();\n surrOsc.connect(surrGain);\n surrGain.gain.value = 2;\n surrOsc.frequency.value = 400;\n surrOsc.type = 'sine';\n\n mainGain.connect(this._convolver);\n surrGain.connect(this._convolver);\n\n var startTime = audioCtx.currentTime;\n mainOsc.start();\n mainOsc.stop(startTime + 0.5);\n surrOsc.start(startTime + 0.05);\n surrOsc.stop(startTime + 0.8);\n\n var loop = function loop() {\n if (audioCtx.currentTime < startTime + 0.8) window.requestAnimationFrame(loop);\n mainGain.gain.value *= 0.8;\n surrGain.gain.value *= 0.8;\n };\n loop();\n }\n }, {\n key: 'load',\n value: function load() {\n var _parser;\n\n (_parser = this.parser).load.apply(_parser, arguments);\n }\n }]);\n\n return TermScreen;\n}(EventEmitter);\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n qs = _require.qs;\n\n// constants for decoding the update blob\n\n\nvar SEQ_SKIP = 1;\nvar SEQ_REPEAT = 2;\nvar SEQ_SET_COLORS = 3;\nvar SEQ_SET_ATTRS = 4;\nvar SEQ_SET_FG = 5;\nvar SEQ_SET_BG = 6;\nvar SEQ_SET_ATTR_0 = 7;\n\nfunction du(str) {\n var num = str.codePointAt(0);\n if (num > 0xDFFF) num -= 0x800;\n return num - 1;\n}\n\n/* eslint-disable no-multi-spaces */\nvar TOPIC_SCREEN_OPTS = 'O';\nvar TOPIC_CONTENT = 'S';\nvar TOPIC_TITLE = 'T';\nvar TOPIC_BUTTONS = 'B';\nvar TOPIC_CURSOR = 'C';\nvar TOPIC_INTERNAL = 'D';\nvar TOPIC_BELL = '!';\n\nvar OPT_CURSOR_VISIBLE = 1 << 0;\nvar OPT_DEBUGBAR = 1 << 1;\nvar OPT_CURSORS_ALT_MODE = 1 << 2;\nvar OPT_NUMPAD_ALT_MODE = 1 << 3;\nvar OPT_FN_ALT_MODE = 1 << 4;\nvar OPT_CLICK_TRACKING = 1 << 5;\nvar OPT_MOVE_TRACKING = 1 << 6;\nvar OPT_SHOW_BUTTONS = 1 << 7;\nvar OPT_SHOW_CONFIG_LINKS = 1 << 8;\n// const OPT_CURSOR_SHAPE = (7 << 9)\nvar OPT_CRLF_MODE = 1 << 12;\nvar OPT_BRACKETED_PASTE = 1 << 13;\nvar OPT_REVERSE_VIDEO = 1 << 14;\n\nvar ATTR_FG = 1 << 0; // 1 if not using default background color (ignore cell bg) - color extension bit\nvar ATTR_BG = 1 << 1; // 1 if not using default foreground color (ignore cell fg) - color extension bit\nvar ATTR_BOLD = 1 << 2; // Bold font\nvar ATTR_UNDERLINE = 1 << 3; // Underline decoration\nvar ATTR_INVERSE = 1 << 4; // Invert colors - this is useful so we can clear then with SGR manipulation commands\nvar ATTR_BLINK = 1 << 5; // Blinking\nvar ATTR_ITALIC = 1 << 6; // Italic font\nvar ATTR_STRIKE = 1 << 7; // Strike-through decoration\nvar ATTR_OVERLINE = 1 << 8; // Over-line decoration\nvar ATTR_FAINT = 1 << 9; // Faint foreground color (reduced alpha)\nvar ATTR_FRAKTUR = 1 << 10; // Fraktur font (unicode substitution)\n/* eslint-enable no-multi-spaces */\n\nmodule.exports = function () {\n function ScreenParser(screen) {\n _classCallCheck(this, ScreenParser);\n\n this.screen = screen;\n\n // true if TermScreen#load was called at least once\n this.contentLoaded = false;\n }\n\n /**\n * Hide the warning message about failed data load\n */\n\n\n _createClass(ScreenParser, [{\n key: 'hideLoadFailedMsg',\n value: function hideLoadFailedMsg() {\n if (!this.contentLoaded) {\n var errmsg = qs('#load-failed');\n if (errmsg) errmsg.parentNode.removeChild(errmsg);\n this.contentLoaded = true;\n }\n }\n }, {\n key: 'loadUpdate',\n value: function loadUpdate(str) {\n var _this = this;\n\n // console.log(`update ${str}`)\n // current index\n var ci = 0;\n var strArray = Array.from ? Array.from(str) : str.split('');\n\n var text = void 0;\n var resized = false;\n var topics = du(strArray[ci++]);\n // this.screen.cursor.hanging = !!(attributes & (1 << 1))\n\n while (ci < strArray.length) {\n var topic = strArray[ci++];\n\n if (topic === TOPIC_SCREEN_OPTS) {\n var newHeight = du(strArray[ci++]);\n var newWidth = du(strArray[ci++]);\n var theme = du(strArray[ci++]);\n var defFg = du(strArray[ci++]) & 0xFFFF | (du(strArray[ci++]) & 0xFFFF) << 16;\n var defBg = du(strArray[ci++]) & 0xFFFF | (du(strArray[ci++]) & 0xFFFF) << 16;\n var attributes = du(strArray[ci++]);\n\n // theming\n this.screen.renderer.loadTheme(theme);\n this.screen.renderer.setDefaultColors(defFg, defBg);\n\n // apply size\n resized = this.screen.window.height !== newHeight || this.screen.window.width !== newWidth;\n this.screen.window.height = newHeight;\n this.screen.window.width = newWidth;\n\n // process attributes\n this.screen.cursor.visible = !!(attributes & OPT_CURSOR_VISIBLE);\n\n this.screen.input.setAlts(!!(attributes & OPT_CURSORS_ALT_MODE), !!(attributes & OPT_NUMPAD_ALT_MODE), !!(attributes & OPT_FN_ALT_MODE), !!(attributes & OPT_CRLF_MODE));\n\n var trackMouseClicks = !!(attributes & OPT_CLICK_TRACKING);\n var trackMouseMovement = !!(attributes & OPT_MOVE_TRACKING);\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 var cursorShape = attributes >> 9 & 0x07;\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 var cursorStyle = cursorShape >> 1;\n var cursorBlinking = !(cursorShape & 1);\n if (cursorStyle === 0) this.screen.cursor.style = 'block';else if (cursorStyle === 1) this.screen.cursor.style = 'line';else if (cursorStyle === 2) this.screen.cursor.style = 'bar';\n if (this.screen.cursor.blinking !== cursorBlinking) {\n this.screen.cursor.blinking = cursorBlinking;\n this.screen.renderer.resetCursorBlink();\n }\n\n this.screen.input.setMouseMode(trackMouseClicks, trackMouseMovement);\n this.screen.selection.selectable = !trackMouseClicks && !trackMouseMovement;\n $(this.screen.canvas).toggleClass('selectable', this.screen.selection.selectable);\n this.screen.mouseMode = {\n clicks: trackMouseClicks,\n movement: trackMouseMovement\n };\n\n var showButtons = !!(attributes & OPT_SHOW_BUTTONS);\n var showConfigLinks = !!(attributes & OPT_SHOW_CONFIG_LINKS);\n\n $('.x-term-conf-btn').toggleClass('hidden', !showConfigLinks);\n $('#action-buttons').toggleClass('hidden', !showButtons);\n\n this.screen.bracketedPaste = !!(attributes & OPT_BRACKETED_PASTE);\n this.screen.reverseVideo = !!(attributes & OPT_REVERSE_VIDEO);\n\n var debugbar = !!(attributes & OPT_DEBUGBAR);\n // TODO do something with debugbar\n } else if (topic === TOPIC_CURSOR) {\n\n // cursor position\n var cursorY = du(strArray[ci++]);\n var cursorX = du(strArray[ci++]);\n var hanging = du(strArray[ci++]);\n\n var cursorMoved = hanging !== this.screen.cursor.hanging || cursorX !== this.screen.cursor.x || cursorY !== this.screen.cursor.y;\n\n this.screen.cursor.x = cursorX;\n this.screen.cursor.y = cursorY;\n\n this.screen.cursor.hanging = !!hanging;\n\n if (cursorMoved) {\n this.screen.renderer.resetCursorBlink();\n this.screen.emit('cursor-moved');\n }\n\n this.screen.renderer.scheduleDraw('cursor-moved');\n } else if (topic === TOPIC_TITLE) {\n\n // TODO optimize this\n text = '';\n while (ci < strArray.length) {\n var c = strArray[ci++];\n if (c !== '\\x01') {\n text += c;\n } else {\n break;\n }\n }\n\n qs('#screen-title').textContent = text;\n if (text.length === 0) text = 'Terminal';\n qs('title').textContent = text + ' :: ESPTerm';\n } else if (topic === TOPIC_BUTTONS) {\n var count = du(strArray[ci++]);\n\n var labels = [];\n for (var j = 0; j < count; j++) {\n text = '';\n while (ci < strArray.length) {\n var _c = strArray[ci++];\n if (_c === '\\x01') break;\n text += _c;\n }\n labels.push(text);\n }\n\n this.screen.emit('button-labels', labels);\n } else if (topic === TOPIC_BELL) {\n\n this.screen.beep();\n } else if (topic === TOPIC_INTERNAL) {\n // debug info\n\n var flags = du(strArray[ci++]);\n var cursorAttrs = du(strArray[ci++]);\n var regionStart = du(strArray[ci++]);\n var regionEnd = du(strArray[ci++]);\n var charsetGx = du(strArray[ci++]);\n var charsetG0 = strArray[ci++];\n var charsetG1 = strArray[ci++];\n var freeHeap = du(strArray[ci++]);\n var clientCount = du(strArray[ci++]);\n\n this.screen.emit('internal', {\n flags: flags,\n cursorAttrs: cursorAttrs,\n regionStart: regionStart,\n regionEnd: regionEnd,\n charsetGx: charsetGx,\n charsetG0: charsetG0,\n charsetG1: charsetG1,\n freeHeap: freeHeap,\n clientCount: clientCount\n });\n } else if (topic === TOPIC_CONTENT) {\n (function () {\n // set screen content\n\n var frameY = du(strArray[ci++]);\n var frameX = du(strArray[ci++]);\n var frameHeight = du(strArray[ci++]);\n var frameWidth = du(strArray[ci++]);\n\n if (_this.screen._debug && _this.screen.window.debug) {\n _this.screen._debug.pushFrame([frameX, frameY, frameWidth, frameHeight]);\n }\n\n // content\n var fg = 7;\n var bg = 0;\n var attrs = 0;\n var cell = 0; // cell index\n var lastChar = ' ';\n var frameLength = frameWidth * frameHeight;\n var screenLength = _this.screen.window.width * _this.screen.window.height;\n\n if (resized) {\n _this.screen.updateSize();\n _this.screen.blinkingCellCount = 0;\n _this.screen.screen = new Array(screenLength).fill(' ');\n _this.screen.screenFG = new Array(screenLength).fill(' ');\n _this.screen.screenBG = new Array(screenLength).fill(' ');\n _this.screen.screenAttrs = new Array(screenLength).fill(0);\n }\n\n var MASK_LINE_ATTR = ATTR_UNDERLINE | ATTR_OVERLINE | ATTR_STRIKE;\n var MASK_BLINK = ATTR_BLINK;\n\n var pushCell = function pushCell() {\n // Remove blink attribute if it wouldn't have any effect\n var myAttrs = attrs;\n var hasFG = attrs & ATTR_FG;\n var hasBG = attrs & ATTR_BG;\n var cellFG = fg;\n var cellBG = bg;\n\n // use 0,0 if no fg/bg. this is to match back-end implementation\n // and allow leaving out fg/bg setting for cells with none\n if (!hasFG) cellFG = 0;\n if (!hasBG) cellBG = 0;\n\n if ((myAttrs & MASK_BLINK) !== 0 && (lastChar === ' ' && (myAttrs & MASK_LINE_ATTR) === 0 || // no line styles\n fg === bg && hasFG && hasBG // invisible text\n )) {\n myAttrs ^= MASK_BLINK;\n }\n // update blinking cells counter if blink state changed\n if ((_this.screen.screenAttrs[cell] & MASK_BLINK) !== (myAttrs & MASK_BLINK)) {\n if (myAttrs & MASK_BLINK) _this.screen.blinkingCellCount++;else _this.screen.blinkingCellCount--;\n }\n\n var cellXInFrame = cell % frameWidth;\n var cellYInFrame = Math.floor(cell / frameWidth);\n var index = (frameY + cellYInFrame) * _this.screen.window.width + frameX + cellXInFrame;\n\n // 8 dark system colors turn bright when bold\n if (myAttrs & ATTR_BOLD && !(myAttrs & ATTR_FAINT) && hasFG && cellFG < 8) {\n cellFG += 8;\n }\n\n _this.screen.screen[index] = lastChar;\n _this.screen.screenFG[index] = cellFG;\n _this.screen.screenBG[index] = cellBG;\n _this.screen.screenAttrs[index] = myAttrs;\n };\n\n while (ci < strArray.length && cell < frameLength) {\n var character = strArray[ci++];\n var charCode = character.codePointAt(0);\n\n var data = void 0,\n _count = void 0;\n switch (charCode) {\n case SEQ_REPEAT:\n _count = du(strArray[ci++]);\n for (var _j = 0; _j < _count; _j++) {\n pushCell();\n if (++cell > frameLength) break;\n }\n break;\n\n case SEQ_SKIP:\n cell += du(strArray[ci++]);\n break;\n\n case SEQ_SET_COLORS:\n data = du(strArray[ci++]);\n fg = data & 0xFF;\n bg = data >> 8 & 0xFF;\n break;\n\n case SEQ_SET_ATTRS:\n data = du(strArray[ci++]);\n attrs = data & 0xFFFF;\n break;\n\n case SEQ_SET_ATTR_0:\n attrs = 0;\n break;\n\n case SEQ_SET_FG:\n data = du(strArray[ci++]);\n if (data & 0x10000) {\n data &= 0xFFF;\n data |= (du(strArray[ci++]) & 0xFFF) << 12;\n data += 256;\n }\n fg = data;\n break;\n\n case SEQ_SET_BG:\n data = du(strArray[ci++]);\n if (data & 0x10000) {\n data &= 0xFFF;\n data |= (du(strArray[ci++]) & 0xFFF) << 12;\n data += 256;\n }\n bg = data;\n break;\n\n default:\n if (charCode < 32) character = '\\uFFFD';\n lastChar = character;\n pushCell();\n cell++;\n }\n }\n\n if (_this.screen.window.debug) console.log('Blinky cells: ' + _this.screen.blinkingCellCount);\n\n _this.screen.renderer.scheduleDraw('load', 16);\n _this.screen.conn.emit('load');\n })();\n }\n\n if ((topics & 0x3B) !== 0) this.hideLoadFailedMsg();\n }\n }\n\n /**\n * Loads a message from the server, and optionally a theme.\n * @param {string} str - the message\n */\n\n }, {\n key: 'load',\n value: function load(str) {\n var content = str.substr(1);\n\n // This is a good place for debugging the message\n // console.log(str)\n\n switch (str[0]) {\n case 'U':\n this.loadUpdate(content);\n break;\n\n case 'G':\n this.screen.showNotification(content);\n break;\n\n default:\n console.warn('Bad data message type; ignoring.\\n' + JSON.stringify(str));\n }\n }\n }]);\n\n return ScreenParser;\n}();\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar _require = __webpack_require__(5),\n themes = _require.themes,\n buildColorTable = _require.buildColorTable,\n SELECTION_FG = _require.SELECTION_FG,\n SELECTION_BG = _require.SELECTION_BG;\n\n// Some non-bold Fraktur symbols are outside the contiguous block\n\n\nvar frakturExceptions = {\n 'C': '\\u212D',\n 'H': '\\u210C',\n 'I': '\\u2111',\n 'R': '\\u211C',\n 'Z': '\\u2128'\n\n // TODO do not repeat - this is also defined in screen_parser ...\n /* eslint-disable no-multi-spaces */\n};var ATTR_FG = 1 << 0; // 1 if not using default background color (ignore cell bg) - color extension bit\nvar ATTR_BG = 1 << 1; // 1 if not using default foreground color (ignore cell fg) - color extension bit\nvar ATTR_BOLD = 1 << 2; // Bold font\nvar ATTR_UNDERLINE = 1 << 3; // Underline decoration\nvar ATTR_INVERSE = 1 << 4; // Invert colors - this is useful so we can clear then with SGR manipulation commands\nvar ATTR_BLINK = 1 << 5; // Blinking\nvar ATTR_ITALIC = 1 << 6; // Italic font\nvar ATTR_STRIKE = 1 << 7; // Strike-through decoration\nvar ATTR_OVERLINE = 1 << 8; // Over-line decoration\nvar ATTR_FAINT = 1 << 9; // Faint foreground color (reduced alpha)\nvar ATTR_FRAKTUR = 1 << 10; // Fraktur font (unicode substitution)\n/* eslint-enable no-multi-spaces */\n\nmodule.exports = function () {\n function ScreenRenderer(screen) {\n _classCallCheck(this, ScreenRenderer);\n\n this.screen = screen;\n this.ctx = screen.ctx;\n\n this._palette = null; // colors 0-15\n this.defaultBgNum = 0;\n this.defaultFgNum = 7;\n\n // 256color lookup table\n // should not be used to look up 0-15 (will return transparent)\n this.colorTable256 = buildColorTable();\n\n this.resetDrawn();\n\n this.blinkStyleOn = false;\n this.blinkInterval = null;\n this.cursorBlinkOn = false;\n this.cursorBlinkInterval = null;\n\n // start blink timers\n this.resetBlink();\n this.resetCursorBlink();\n }\n\n _createClass(ScreenRenderer, [{\n key: 'resetDrawn',\n value: function resetDrawn() {\n // used to determine if a cell should be redrawn; storing the current state\n // as it is on screen\n if (this.screen.window && this.screen.window.debug) {\n console.log('Resetting drawn screen');\n }\n this.drawnScreen = [];\n this.drawnScreenFG = [];\n this.drawnScreenBG = [];\n this.drawnScreenAttrs = [];\n this.drawnCursor = [-1, -1, ''];\n }\n\n /**\n * The color palette. Should define 16 colors in an array.\n * @type {string[]}\n */\n\n }, {\n key: 'loadTheme',\n value: function loadTheme(i) {\n if (i in themes) this.palette = themes[i];\n }\n }, {\n key: 'setDefaultColors',\n value: function setDefaultColors(fg, bg) {\n if (fg !== this.defaultFgNum || bg !== this.defaultBgNum) {\n this.resetDrawn();\n this.defaultFgNum = fg;\n this.defaultBgNum = bg;\n this.scheduleDraw('default-colors');\n }\n }\n\n /**\n * Schedule a draw in the next millisecond\n * @param {string} why - the reason why the draw occured (for debugging)\n * @param {number} [aggregateTime] - time to wait for more scheduleDraw calls\n * to occur. 1 ms by default.\n */\n\n }, {\n key: 'scheduleDraw',\n value: function scheduleDraw(why) {\n var _this = this;\n\n var aggregateTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n\n clearTimeout(this._scheduledDraw);\n this._scheduledDraw = setTimeout(function () {\n return _this.draw(why);\n }, aggregateTime);\n }\n\n /**\n * Returns the specified color. If `i` is in the palette, it will return the\n * palette color. If `i` is between 16 and 255, it will return the 256color\n * value. If `i` is larger than 255, it will return an RGB color value. If `i`\n * is -1 (foreground) or -2 (background), it will return the selection colors.\n * @param {number} i - the color\n * @returns {string} the CSS color\n */\n\n }, {\n key: 'getColor',\n value: function getColor(i) {\n // return palette color if it exists\n if (i < 16 && i in this.palette) 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 this.colorTable256[i];\n\n // true color, encoded as (hex) + 256 (such that #000 == 256)\n if (i > 255) {\n i -= 256;\n var red = i >> 16 & 0xFF;\n var green = i >> 8 & 0xFF;\n var blue = i & 0xFF;\n return 'rgb(' + red + ', ' + green + ', ' + blue + ')';\n }\n\n // return error color\n return Date.now() / 1000 % 2 === 0 ? '#f0f' : '#0f0';\n }\n\n /**\n * Resets the cursor blink to on and restarts the timer\n */\n\n }, {\n key: 'resetCursorBlink',\n value: function resetCursorBlink() {\n var _this2 = this;\n\n this.cursorBlinkOn = true;\n clearInterval(this.cursorBlinkInterval);\n this.cursorBlinkInterval = setInterval(function () {\n _this2.cursorBlinkOn = _this2.screen.cursor.blinking ? !_this2.cursorBlinkOn : true;\n if (_this2.screen.cursor.blinking) _this2.scheduleDraw('cursor-blink');\n }, 500);\n }\n\n /**\n * Resets the blink style to on and restarts the timer\n */\n\n }, {\n key: 'resetBlink',\n value: function resetBlink() {\n var _this3 = this;\n\n this.blinkStyleOn = true;\n clearInterval(this.blinkInterval);\n var intervals = 0;\n this.blinkInterval = setInterval(function () {\n if (_this3.screen.blinkingCellCount <= 0) return;\n\n intervals++;\n if (intervals >= 4 && _this3.blinkStyleOn) {\n _this3.blinkStyleOn = false;\n intervals = 0;\n _this3.scheduleDraw('blink-style');\n } else if (intervals >= 1 && !_this3.blinkStyleOn) {\n _this3.blinkStyleOn = true;\n intervals = 0;\n _this3.scheduleDraw('blink-style');\n }\n }, 200);\n }\n\n /**\n * Draws a cell's background with the given parameters.\n * @param {Object} options\n * @param {number} options.x - x in cells\n * @param {number} options.y - y in cells\n * @param {number} options.cellWidth - cell width in pixels\n * @param {number} options.cellHeight - cell height in pixels\n * @param {number} options.bg - the background color\n */\n\n }, {\n key: 'drawBackground',\n value: function drawBackground(_ref) {\n var x = _ref.x,\n y = _ref.y,\n cellWidth = _ref.cellWidth,\n cellHeight = _ref.cellHeight,\n bg = _ref.bg;\n\n var ctx = this.ctx;\n var _screen$window = this.screen.window,\n width = _screen$window.width,\n height = _screen$window.height;\n\n var padding = Math.round(this.screen._padding);\n ctx.fillStyle = this.getColor(bg);\n var screenX = x * cellWidth + padding;\n var screenY = y * cellHeight + padding;\n var isBorderCell = x === 0 || y === 0 || x === width - 1 || y === height - 1;\n if (isBorderCell) {\n var left = screenX;\n var top = screenY;\n var right = screenX + cellWidth;\n var bottom = screenY + cellHeight;\n if (x === 0) left -= padding;else if (x === width - 1) right += padding;\n if (y === 0) top -= padding;else if (y === height - 1) bottom += padding;\n ctx.clearRect(left, top, right - left, bottom - top);\n ctx.fillRect(left, top, right - left, bottom - top);\n } else {\n ctx.clearRect(screenX, screenY, cellWidth, cellHeight);\n ctx.fillRect(screenX, screenY, cellWidth, cellHeight);\n }\n }\n\n /**\n * Draws a cell's character with the given parameters. Won't do anything if\n * text is an empty string.\n * @param {Object} options\n * @param {number} options.x - x in cells\n * @param {number} options.y - y in cells\n * @param {Object} options.charSize - the character size, an object with\n * `width` and `height` in pixels\n * @param {number} options.cellWidth - cell width in pixels\n * @param {number} options.cellHeight - cell height in pixels\n * @param {string} options.text - the cell content\n * @param {number} options.fg - the foreground color\n * @param {number} options.attrs - the cell's attributes\n */\n\n }, {\n key: 'drawCharacter',\n value: function drawCharacter(_ref2) {\n var x = _ref2.x,\n y = _ref2.y,\n charSize = _ref2.charSize,\n cellWidth = _ref2.cellWidth,\n cellHeight = _ref2.cellHeight,\n text = _ref2.text,\n fg = _ref2.fg,\n attrs = _ref2.attrs;\n\n if (!text) return;\n\n var ctx = this.ctx;\n var padding = Math.round(this.screen._padding);\n\n var underline = false;\n var strike = false;\n var overline = false;\n if (attrs & ATTR_FAINT) ctx.globalAlpha = 0.5;\n if (attrs & ATTR_UNDERLINE) underline = true;\n if (attrs & ATTR_FRAKTUR) text = ScreenRenderer.alphaToFraktur(text);\n if (attrs & ATTR_STRIKE) strike = true;\n if (attrs & ATTR_OVERLINE) overline = true;\n\n ctx.fillStyle = this.getColor(fg);\n\n var screenX = x * cellWidth + padding;\n var screenY = y * cellHeight + padding;\n\n var codePoint = text.codePointAt(0);\n if (codePoint >= 0x2580 && codePoint <= 0x259F) {\n // block elements\n ctx.beginPath();\n var left = screenX;\n var top = screenY;\n var cw = cellWidth;\n var ch = cellHeight;\n var c2w = cellWidth / 2;\n var c2h = cellHeight / 2;\n\n // http://www.fileformat.info/info/unicode/block/block_elements/utf8test.htm\n // 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F\n // 0x2580 ▀ ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▉ ▊ ▋ ▌ ▍ ▎ ▏\n // 0x2590 ▐ ░ ▒ ▓ ▔ ▕ ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▞ ▟\n\n if (codePoint === 0x2580) {\n // upper half block >▀<\n ctx.rect(left, top, cw, c2h);\n } else if (codePoint <= 0x2588) {\n // lower n eighth block (increasing) >▁< to >█<\n var offset = (1 - (codePoint - 0x2580) / 8) * ch;\n ctx.rect(left, top + offset, cw, ch - offset);\n } else if (codePoint <= 0x258F) {\n // left n eighth block (decreasing) >▉< to >▏<\n var _offset = (codePoint - 0x2588) / 8 * cw;\n ctx.rect(left, top, cw - _offset, ch);\n } else if (codePoint === 0x2590) {\n // right half block >▐<\n ctx.rect(left + c2w, top, c2w, ch);\n } else if (codePoint <= 0x2593) {\n // shading >░< >▒< >▓<\n\n // dot spacing by dividing cell size by a constant. This could be\n // reworked to always return a whole number, but that would require\n // prime factorization, and doing that without a loop would let you\n // take over the world, which is not within the scope of this project.\n var dotSpacingX = void 0,\n dotSpacingY = void 0,\n dotSize = void 0;\n if (codePoint === 0x2591) {\n dotSpacingX = cw / 4;\n dotSpacingY = ch / 10;\n dotSize = 1;\n } else if (codePoint === 0x2592) {\n dotSpacingX = cw / 6;\n dotSpacingY = cw / 10;\n dotSize = 1;\n } else if (codePoint === 0x2593) {\n dotSpacingX = cw / 4;\n dotSpacingY = cw / 7;\n dotSize = 2;\n }\n\n var alignRight = false;\n for (var dy = 0; dy < ch; dy += dotSpacingY) {\n for (var dx = 0; dx < cw; dx += dotSpacingX) {\n // prevent overflow\n var dotSizeY = Math.min(dotSize, ch - dy);\n ctx.rect(left + (alignRight ? cw - dx - dotSize : dx), top + dy, dotSize, dotSizeY);\n }\n alignRight = !alignRight;\n }\n } else if (codePoint === 0x2594) {\n // upper one eighth block >▔<\n ctx.rect(left, top, cw, ch / 8);\n } else if (codePoint === 0x2595) {\n // right one eighth block >▕<\n ctx.rect(left + 7 / 8 * cw, top, cw / 8, ch);\n } else if (codePoint === 0x2596) {\n // left bottom quadrant >▖<\n ctx.rect(left, top + c2h, c2w, c2h);\n } else if (codePoint === 0x2597) {\n // right bottom quadrant >▗<\n ctx.rect(left + c2w, top + c2h, c2w, c2h);\n } else if (codePoint === 0x2598) {\n // left top quadrant >▘<\n ctx.rect(left, top, c2w, c2h);\n } else if (codePoint === 0x2599) {\n // left chair >▙<\n ctx.rect(left, top, c2w, ch);\n ctx.rect(left + c2w, top + c2h, c2w, c2h);\n } else if (codePoint === 0x259A) {\n // quadrants lt rb >▚<\n ctx.rect(left, top, c2w, c2h);\n ctx.rect(left + c2w, top + c2h, c2w, c2h);\n } else if (codePoint === 0x259B) {\n // left chair upside down >▛<\n ctx.rect(left, top, c2w, ch);\n ctx.rect(left + c2w, top, c2w, c2h);\n } else if (codePoint === 0x259C) {\n // right chair upside down >▜<\n ctx.rect(left, top, cw, c2h);\n ctx.rect(left + c2w, top + c2h, c2w, c2h);\n } else if (codePoint === 0x259D) {\n // right top quadrant >▝<\n ctx.rect(left + c2w, top, c2w, c2h);\n } else if (codePoint === 0x259E) {\n // quadrants lb rt >▞<\n ctx.rect(left, top + c2h, c2w, c2h);\n ctx.rect(left + c2w, top, c2w, c2h);\n } else if (codePoint === 0x259F) {\n // right chair upside down >▟<\n ctx.rect(left, top + c2h, c2w, c2h);\n ctx.rect(left + c2w, top, c2w, ch);\n }\n\n ctx.fill();\n } else if (codePoint >= 0xE0B0 && codePoint <= 0xE0B3) {\n // powerline symbols, except branch, line, and lock. Basically, just the triangles\n ctx.beginPath();\n\n if (codePoint === 0xE0B0 || codePoint === 0xE0B1) {\n // right-pointing triangle\n ctx.moveTo(screenX, screenY);\n ctx.lineTo(screenX + cellWidth, screenY + cellHeight / 2);\n ctx.lineTo(screenX, screenY + cellHeight);\n } else if (codePoint === 0xE0B2 || codePoint === 0xE0B3) {\n // left-pointing triangle\n ctx.moveTo(screenX + cellWidth, screenY);\n ctx.lineTo(screenX, screenY + cellHeight / 2);\n ctx.lineTo(screenX + cellWidth, screenY + cellHeight);\n }\n\n if (codePoint % 2 === 0) {\n // triangle\n ctx.fill();\n } else {\n // chevron\n ctx.strokeStyle = ctx.fillStyle;\n ctx.stroke();\n }\n } else {\n // Draw other characters using the text renderer\n ctx.fillText(text, screenX + 0.5 * cellWidth, screenY + 0.5 * cellHeight);\n }\n\n // -- line drawing - a reference for a possible future rect/line implementation ---\n // http://www.fileformat.info/info/unicode/block/box_drawing/utf8test.htm\n // 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F\n // 0x2500 ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏\n // 0x2510 ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟\n // 0x2520 ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯\n // 0x2530 ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿\n // 0x2540 ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏\n // 0x2550 ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟\n // 0x2560 ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯\n // 0x2570 ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿\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 var lineY = Math.round(screenY + charSize.height) + 0.5;\n ctx.moveTo(screenX, lineY);\n ctx.lineTo(screenX + cellWidth, lineY);\n }\n\n if (strike) {\n var _lineY = Math.round(screenY + 0.5 * cellHeight) + 0.5;\n ctx.moveTo(screenX, _lineY);\n ctx.lineTo(screenX + cellWidth, _lineY);\n }\n\n if (overline) {\n var _lineY2 = Math.round(screenY) + 0.5;\n ctx.moveTo(screenX, _lineY2);\n ctx.lineTo(screenX + cellWidth, _lineY2);\n }\n\n ctx.stroke();\n }\n\n ctx.globalAlpha = 1;\n }\n\n /**\n * Returns all adjacent cell indices given a radius.\n * @param {number} cell - the center cell index\n * @param {number} [radius] - the radius. 1 by default\n * @returns {number[]} an array of cell indices\n */\n\n }, {\n key: 'getAdjacentCells',\n value: function getAdjacentCells(cell) {\n var radius = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n var _screen$window2 = this.screen.window,\n width = _screen$window2.width,\n height = _screen$window2.height;\n\n var screenLength = width * height;\n\n var cells = [];\n\n for (var x = -radius; x <= radius; x++) {\n for (var 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(function (cell) {\n return cell >= 0 && cell < screenLength;\n });\n }\n\n /**\n * Updates the screen.\n * @param {string} why - the draw reason (for debugging)\n */\n\n }, {\n key: 'draw',\n value: function draw(why) {\n var _this4 = this;\n\n var ctx = this.ctx;\n var _screen$window3 = this.screen.window,\n width = _screen$window3.width,\n height = _screen$window3.height,\n devicePixelRatio = _screen$window3.devicePixelRatio,\n statusScreen = _screen$window3.statusScreen;\n\n\n if (statusScreen) {\n // draw status screen instead\n this.drawStatus(statusScreen);\n this.startDrawLoop();\n return;\n } else this.stopDrawLoop();\n\n var charSize = this.screen.getCharSize();\n\n var _screen$getCellSize = this.screen.getCellSize(),\n cellWidth = _screen$getCellSize.width,\n cellHeight = _screen$getCellSize.height;\n\n var screenLength = width * height;\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n\n if (this.screen.window.debug && this.screen._debug) this.screen._debug.drawStart(why);\n\n ctx.font = this.screen.getFont();\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n\n // bits in the attr value that affect the font\n var FONT_MASK = ATTR_BOLD | ATTR_ITALIC;\n\n // Map of (attrs & FONT_MASK) -> Array of cell indices\n var fontGroups = new Map();\n\n // Map of (cell index) -> boolean, whether or not a cell has updated\n var updateMap = new Map();\n\n for (var cell = 0; cell < screenLength; cell++) {\n var x = cell % width;\n var y = Math.floor(cell / width);\n var isCursor = this.cursorBlinkOn && this.screen.cursor.x === x && this.screen.cursor.y === y && this.screen.cursor.visible;\n\n var wasCursor = x === this.drawnCursor[0] && y === this.drawnCursor[1];\n\n var inSelection = this.screen.isInSelection(x, y);\n\n var text = this.screen.screen[cell];\n var fg = this.screen.screenFG[cell] | 0;\n var bg = this.screen.screenBG[cell] | 0;\n var attrs = this.screen.screenAttrs[cell] | 0;\n\n if (!(attrs & ATTR_FG)) fg = this.defaultFgNum;\n if (!(attrs & ATTR_BG)) bg = this.defaultBgNum;\n\n if (attrs & ATTR_INVERSE) {\n ;var _ref3 = [bg, fg];\n fg = _ref3[0];\n bg = _ref3[1];\n } // swap - reversed character colors\n if (this.screen.reverseVideo) {\n ;var _ref4 = [bg, fg];\n fg = _ref4[0];\n bg = _ref4[1];\n } // swap - reversed all screen\n\n if (attrs & ATTR_BLINK && !this.blinkStyleOn) {\n // blinking is enabled and blink style is off\n // set text to nothing so drawCharacter doesn't draw anything\n text = '';\n }\n\n if (inSelection) {\n fg = -1;\n bg = -2;\n }\n\n var didUpdate = text !== this.drawnScreen[cell] || // text updated\n fg !== this.drawnScreenFG[cell] || // foreground updated, and this cell has text\n bg !== this.drawnScreenBG[cell] || // background updated\n attrs !== this.drawnScreenAttrs[cell] || // attributes updated\n isCursor !== wasCursor || // cursor blink/position updated\n isCursor && this.screen.cursor.style !== this.drawnCursor[2] || // cursor style updated\n isCursor && this.screen.cursor.hanging !== this.drawnCursor[3]; // cursor hanging updated\n\n var font = attrs & FONT_MASK;\n if (!fontGroups.has(font)) fontGroups.set(font, []);\n\n fontGroups.get(font).push({ cell: cell, x: x, y: y, text: text, fg: fg, bg: bg, attrs: attrs, isCursor: isCursor, inSelection: inSelection });\n updateMap.set(cell, didUpdate);\n }\n\n // Map of (cell index) -> boolean, whether or not a cell should be redrawn\n var redrawMap = new Map();\n\n var isTextWide = function isTextWide(text) {\n return text !== ' ' && ctx.measureText(text).width >= cellWidth + 0.05;\n };\n\n // decide for each cell if it should be redrawn\n var updateRedrawMapAt = function updateRedrawMapAt(cell) {\n var shouldUpdate = updateMap.get(cell) || redrawMap.get(cell) || false;\n\n // TODO: fonts (necessary?)\n var text = _this4.screen.screen[cell];\n var isWideCell = isTextWide(text);\n var checkRadius = isWideCell ? 2 : 1;\n\n if (!shouldUpdate) {\n // check adjacent cells\n var adjacentDidUpdate = false;\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _this4.getAdjacentCells(cell, checkRadius)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var adjacentCell = _step.value;\n\n // update this cell if:\n // - the adjacent cell updated (For now, this'll always be true because characters can be slightly larger than they say they are)\n // - the adjacent cell updated and this cell or the adjacent cell is wide\n if (updateMap.get(adjacentCell) && (_this4.screen.window.graphics < 2 || isWideCell || isTextWide(_this4.screen.screen[adjacentCell]))) {\n adjacentDidUpdate = true;\n break;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n if (adjacentDidUpdate) shouldUpdate = true;\n }\n\n redrawMap.set(cell, shouldUpdate);\n };\n\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = updateMap.keys()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var _cell = _step2.value;\n updateRedrawMapAt(_cell);\n } // mask to redrawing regions only\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n if (this.screen.window.graphics >= 1) {\n var debug = this.screen.window.debug && this.screen._debug;\n var padding = Math.round(this.screen._padding);\n ctx.save();\n ctx.beginPath();\n for (var _y = 0; _y < height; _y++) {\n var regionStart = null;\n for (var _x3 = 0; _x3 < width; _x3++) {\n var _cell2 = _y * width + _x3;\n var redrawing = redrawMap.get(_cell2);\n if (redrawing && regionStart === null) regionStart = _x3;\n if (!redrawing && regionStart !== null) {\n ctx.rect(padding + regionStart * cellWidth, padding + _y * cellHeight, (_x3 - regionStart) * cellWidth, cellHeight);\n if (debug) this.screen._debug.clipRect(regionStart * cellWidth, _y * cellHeight, (_x3 - regionStart) * cellWidth, cellHeight);\n regionStart = null;\n }\n }\n if (regionStart !== null) {\n ctx.rect(padding + regionStart * cellWidth, padding + _y * cellHeight, (width - regionStart) * cellWidth, cellHeight);\n if (debug) this.screen._debug.clipRect(regionStart * cellWidth, _y * cellHeight, (width - regionStart) * cellWidth, cellHeight);\n }\n }\n ctx.clip();\n }\n\n // pass 1: backgrounds\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = fontGroups.keys()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var _font = _step3.value;\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = fontGroups.get(_font)[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var data = _step5.value;\n var _cell3 = data.cell,\n _x4 = data.x,\n _y2 = data.y,\n _text = data.text,\n _bg = data.bg;\n\n\n if (redrawMap.get(_cell3)) {\n this.drawBackground({ x: _x4, y: _y2, cellWidth: cellWidth, cellHeight: cellHeight, bg: _bg });\n\n if (this.screen.window.debug && this.screen._debug) {\n // set cell flags\n var flags = +redrawMap.get(_cell3);\n flags |= +updateMap.get(_cell3) << 1;\n flags |= +isTextWide(_text) << 2;\n this.screen._debug.setCell(_cell3, flags);\n }\n }\n }\n } catch (err) {\n _didIteratorError5 = true;\n _iteratorError5 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion5 && _iterator5.return) {\n _iterator5.return();\n }\n } finally {\n if (_didIteratorError5) {\n throw _iteratorError5;\n }\n }\n }\n }\n\n // reset drawn cursor\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n this.drawnCursor = [-1, -1, -1];\n\n // pass 2: characters\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = fontGroups.keys()[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n var _font2 = _step4.value;\n\n // set font once because in Firefox, this is a really slow action for some\n // reason\n var modifiers = {};\n if (_font2 & ATTR_BOLD) modifiers.weight = 'bold';\n if (_font2 & ATTR_ITALIC) modifiers.style = 'italic';\n ctx.font = this.screen.getFont(modifiers);\n\n var _iteratorNormalCompletion6 = true;\n var _didIteratorError6 = false;\n var _iteratorError6 = undefined;\n\n try {\n for (var _iterator6 = fontGroups.get(_font2)[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {\n var _data = _step6.value;\n var _cell4 = _data.cell,\n _x5 = _data.x,\n _y3 = _data.y,\n _text2 = _data.text,\n _fg = _data.fg,\n _bg2 = _data.bg,\n _attrs = _data.attrs,\n _isCursor = _data.isCursor,\n _inSelection = _data.inSelection;\n\n\n if (redrawMap.get(_cell4)) {\n this.drawCharacter({\n x: _x5, y: _y3, charSize: charSize, cellWidth: cellWidth, cellHeight: cellHeight, text: _text2, fg: _fg, attrs: _attrs\n });\n\n this.drawnScreen[_cell4] = _text2;\n this.drawnScreenFG[_cell4] = _fg;\n this.drawnScreenBG[_cell4] = _bg2;\n this.drawnScreenAttrs[_cell4] = _attrs;\n\n if (_isCursor) this.drawnCursor = [_x5, _y3, this.screen.cursor.style, this.screen.cursor.hanging];\n\n // draw cursor\n if (_isCursor && !_inSelection) {\n ctx.save();\n ctx.beginPath();\n\n var cursorX = _x5;\n var cursorY = _y3;\n\n if (this.screen.cursor.hanging) {\n // draw hanging cursor in the margin\n cursorX += 1;\n }\n\n var screenX = cursorX * cellWidth + this.screen._padding;\n var screenY = cursorY * cellHeight + this.screen._padding;\n if (this.screen.cursor.style === 'block') {\n // block\n ctx.rect(screenX, screenY, cellWidth, cellHeight);\n } else if (this.screen.cursor.style === 'bar') {\n // vertical bar\n var barWidth = 2;\n ctx.rect(screenX, screenY, barWidth, cellHeight);\n } else if (this.screen.cursor.style === 'line') {\n // underline\n var lineHeight = 2;\n ctx.rect(screenX, screenY + charSize.height, cellWidth, lineHeight);\n }\n ctx.clip()\n\n // swap foreground/background\n ;\n\n // HACK: ensure cursor is visible\n var _ref5 = [_bg2, _fg];\n _fg = _ref5[0];\n _bg2 = _ref5[1];\n if (_fg === _bg2) _bg2 = _fg === 0 ? 7 : 0;\n\n this.drawBackground({ x: cursorX, y: cursorY, cellWidth: cellWidth, cellHeight: cellHeight, bg: _bg2 });\n this.drawCharacter({\n x: cursorX, y: cursorY, charSize: charSize, cellWidth: cellWidth, cellHeight: cellHeight, text: _text2, fg: _fg, attrs: _attrs\n });\n ctx.restore();\n }\n }\n }\n } catch (err) {\n _didIteratorError6 = true;\n _iteratorError6 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion6 && _iterator6.return) {\n _iterator6.return();\n }\n } finally {\n if (_didIteratorError6) {\n throw _iteratorError6;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError4 = true;\n _iteratorError4 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion4 && _iterator4.return) {\n _iterator4.return();\n }\n } finally {\n if (_didIteratorError4) {\n throw _iteratorError4;\n }\n }\n }\n\n if (this.screen.window.graphics >= 1) ctx.restore();\n\n if (this.screen.window.debug && this.screen._debug) this.screen._debug.drawEnd();\n\n this.screen.emit('draw', why);\n }\n }, {\n key: 'drawStatus',\n value: function drawStatus(statusScreen) {\n var ctx = this.ctx;\n var _screen$window4 = this.screen.window,\n fontFamily = _screen$window4.fontFamily,\n width = _screen$window4.width,\n height = _screen$window4.height,\n devicePixelRatio = _screen$window4.devicePixelRatio;\n\n // reset drawnScreen to force redraw when statusScreen is disabled\n\n this.drawnScreen = [];\n\n var cellSize = this.screen.getCellSize();\n var screenWidth = width * cellSize.width + 2 * this.screen._padding;\n var screenHeight = height * cellSize.height + 2 * this.screen._padding;\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n ctx.fillStyle = this.getColor(this.defaultBgNum);\n ctx.fillRect(0, 0, screenWidth, screenHeight);\n\n ctx.font = '24px ' + fontFamily;\n ctx.fillStyle = this.getColor(this.defaultFgNum);\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText(statusScreen.title || '', screenWidth / 2, screenHeight / 2 - 50);\n\n if (statusScreen.loading) {\n // show loading spinner\n ctx.save();\n ctx.translate(screenWidth / 2, screenHeight / 2 + 20);\n\n ctx.strokeStyle = this.getColor(this.defaultFgNum);\n ctx.lineWidth = 5;\n ctx.lineCap = 'round';\n\n var t = Date.now() / 1000;\n\n for (var i = 0; i < 12; i++) {\n ctx.rotate(Math.PI / 6);\n var offset = (t * 12 - i) % 12;\n ctx.globalAlpha = Math.max(0.2, 1 - offset / 3);\n ctx.beginPath();\n ctx.moveTo(0, 15);\n ctx.lineTo(0, 30);\n ctx.stroke();\n }\n\n ctx.restore();\n }\n }\n }, {\n key: 'startDrawLoop',\n value: function startDrawLoop() {\n if (this._drawTimerThread) return;\n var threadID = Math.random().toString(36);\n this._drawTimerThread = threadID;\n this.drawTimerLoop(threadID);\n }\n }, {\n key: 'stopDrawLoop',\n value: function stopDrawLoop() {\n this._drawTimerThread = null;\n }\n }, {\n key: 'drawTimerLoop',\n value: function drawTimerLoop(threadID) {\n var _this5 = this;\n\n if (!threadID || threadID !== this._drawTimerThread) return;\n window.requestAnimationFrame(function () {\n return _this5.drawTimerLoop(threadID);\n });\n this.draw('draw-loop');\n }\n\n /**\n * Converts an alphabetic character to its fraktur variant.\n * @param {string} character - the character\n * @returns {string} the converted character\n */\n\n }, {\n key: 'palette',\n get: function get() {\n return this._palette || themes[0];\n }\n\n /** @type {string[]} */\n ,\n set: function set(palette) {\n if (this._palette !== palette) {\n this._palette = palette;\n this.resetDrawn();\n this.scheduleDraw('palette');\n }\n }\n }], [{\n key: 'alphaToFraktur',\n value: function 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(0x1d504 - 0x41 + character.charCodeAt(0));\n }\n return character;\n }\n }]);\n\n return ScreenRenderer;\n}();\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar EventEmitter = __webpack_require__(4);\nvar $ = __webpack_require__(1);\nvar demo = void 0;\ntry {\n demo = __webpack_require__(6);\n} catch (err) {}\n\nvar RECONN_DELAY = 2000;\nvar HEARTBEAT_TIME = 3000;\n\n/** Handle connections */\nmodule.exports = function (_EventEmitter) {\n _inherits(TermConnection, _EventEmitter);\n\n function TermConnection(screen) {\n _classCallCheck(this, TermConnection);\n\n var _this = _possibleConstructorReturn(this, (TermConnection.__proto__ || Object.getPrototypeOf(TermConnection)).call(this));\n\n _this.screen = screen;\n _this.ws = null;\n _this.heartbeatTimeout = null;\n _this.pingInterval = null;\n _this.xoff = false;\n _this.autoXoffTimeout = null;\n _this.reconnTimeout = null;\n _this.forceClosing = false;\n\n try {\n _this.blobReader = new FileReader();\n _this.blobReader.onload = function (evt) {\n _this.onDecodedWSMessage(_this.blobReader.result);\n };\n _this.blobReader.onerror = function (evt) {\n console.error(evt);\n };\n } catch (e) {\n _this.blobReader = null;\n }\n\n _this.pageShown = false;\n\n _this.disconnectTimeout = null;\n\n document.addEventListener('visibilitychange', function () {\n if (document.hidden === true) {\n console.info('Window lost focus, freeing socket');\n // Delayed, avoid disconnecting if the background time is short\n _this.disconnectTimeout = setTimeout(function () {\n _this.closeSocket();\n clearTimeout(_this.heartbeatTimeout);\n }, 1000);\n } else {\n clearTimeout(_this.disconnectTimeout);\n console.info('Window got focus, re-connecting');\n _this.init();\n }\n }, false);\n return _this;\n }\n\n _createClass(TermConnection, [{\n key: 'onWSOpen',\n value: function onWSOpen(evt) {\n console.log('CONNECTED');\n this.heartbeat();\n this.send('i');\n this.forceClosing = false;\n\n this.emit('connect');\n }\n }, {\n key: 'onWSClose',\n value: function onWSClose(evt) {\n var _this2 = this;\n\n if (this.forceClosing) {\n this.forceClosing = false;\n return;\n }\n console.warn('SOCKET CLOSED, code ' + evt.code + '. Reconnecting...');\n if (evt.code < 1000) {\n console.error('Bad code from socket!');\n // this sometimes happens for unknown reasons, code < 1000 is invalid\n // location.reload()\n }\n\n clearTimeout(this.reconnTimeout);\n this.reconnTimeout = setTimeout(function () {\n return _this2.init();\n }, RECONN_DELAY);\n\n this.emit('disconnect', evt.code);\n }\n }, {\n key: 'onDecodedWSMessage',\n value: function onDecodedWSMessage(str) {\n var _this3 = this;\n\n switch (str.charAt(0)) {\n case '.':\n console.log(str);\n // heartbeat, no-op message\n break;\n\n case '-':\n // console.log('xoff');\n this.xoff = true;\n this.autoXoffTimeout = setTimeout(function () {\n _this3.xoff = false;\n }, 250);\n break;\n\n case '+':\n // console.log('xon');\n this.xoff = false;\n clearTimeout(this.autoXoffTimeout);\n break;\n\n default:\n this.screen.load(str);\n if (!this.pageShown) {\n window.showPage();\n this.pageShown = true;\n }\n break;\n }\n this.heartbeat();\n }\n }, {\n key: 'onWSMessage',\n value: function onWSMessage(evt) {\n var _this4 = this;\n\n if (typeof evt.data === 'string') this.onDecodedWSMessage(evt.data);else {\n if (!this.blobReader) {\n console.error('No FileReader!');\n return;\n }\n\n if (this.blobReader.readyState !== 1) {\n this.blobReader.readAsText(evt.data);\n } else {\n setTimeout(function () {\n _this4.onWSMessage(evt);\n }, 1);\n }\n }\n }\n }, {\n key: 'canSend',\n value: function canSend() {\n return !this.xoff;\n }\n }, {\n key: 'send',\n value: function send(message) {\n if (window._demo) {\n if (typeof window.demoInterface !== 'undefined') {\n demo.input(message);\n } else {\n console.log('TX: ' + JSON.stringify(message));\n }\n return true; // Simulate success\n }\n if (this.xoff) {\n // TODO queue\n console.log(\"Can't send, flood control.\");\n return false;\n }\n\n if (!this.ws) return false; // for dry testing\n if (this.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 this.ws.send(message);\n return true;\n }\n\n /** Safely close the socket */\n\n }, {\n key: 'closeSocket',\n value: function closeSocket() {\n if (this.ws) {\n this.forceClosing = true;\n if (this.ws.readyState === 1) this.ws.close();\n this.ws = null;\n }\n }\n }, {\n key: 'init',\n value: function init() {\n var _this5 = this;\n\n if (window._demo) {\n if (typeof window.demoInterface === 'undefined') {\n window.alert('Demoing non-demo build!'); // this will catch mistakes when deploying to the website\n } else {\n demo.init(this.screen);\n }\n return;\n }\n\n clearTimeout(this.reconnTimeout);\n clearTimeout(this.heartbeatTimeout);\n\n this.closeSocket();\n\n this.ws = new window.WebSocket('ws://' + window._root + '/term/update.ws');\n this.ws.addEventListener('open', function () {\n return _this5.onWSOpen.apply(_this5, arguments);\n });\n this.ws.addEventListener('close', function () {\n return _this5.onWSClose.apply(_this5, arguments);\n });\n this.ws.addEventListener('message', function () {\n return _this5.onWSMessage.apply(_this5, arguments);\n });\n console.log('Opening socket.');\n this.heartbeat();\n\n this.emit('open');\n }\n }, {\n key: 'heartbeat',\n value: function heartbeat() {\n var _this6 = this;\n\n clearTimeout(this.heartbeatTimeout);\n this.heartbeatTimeout = setTimeout(function () {\n return _this6.onHeartbeatFail();\n }, HEARTBEAT_TIME);\n }\n }, {\n key: 'sendPing',\n value: function sendPing() {\n var _this7 = this;\n\n console.log('> ping');\n this.emit('ping');\n $.get('http://' + window._root + '/api/v1/ping', function (resp, status) {\n if (status === 200) {\n clearInterval(_this7.pingInterval);\n console.info('Server ready, opening socket…');\n _this7.emit('ping-success');\n _this7.init();\n // location.reload()\n } else _this7.emit('ping-fail', status);\n }, {\n timeout: 100,\n loader: false // we have loader on-screen\n });\n }\n }, {\n key: 'onHeartbeatFail',\n value: function onHeartbeatFail() {\n var _this8 = this;\n\n this.closeSocket();\n this.emit('silence');\n console.error('Heartbeat lost, probing server...');\n clearInterval(this.pingInterval);\n this.pingInterval = setInterval(function () {\n _this8.sendPing();\n }, 1000);\n\n // first ping, if this gets through, it'll will reduce delay\n setTimeout(function () {\n _this8.sendPing();\n }, 200);\n }\n }]);\n\n return TermConnection;\n}(EventEmitter);\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n encode2B = _require.encode2B;\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 */\n\n\nmodule.exports = function (conn, screen) {\n // handle for input object\n var input = void 0;\n\n var KEY_NAMES = {\n 0x03: 'Cancel',\n 0x06: 'Help',\n 0x08: 'Backspace',\n 0x09: 'Tab',\n 0x0C: 'Clear',\n 0x0D: 'Enter',\n 0x10: 'Shift',\n 0x11: 'Control',\n 0x12: 'Alt',\n 0x13: 'Pause',\n 0x14: 'CapsLock',\n 0x1B: 'Escape',\n 0x20: ' ',\n 0x21: 'PageUp',\n 0x22: 'PageDown',\n 0x23: 'End',\n 0x24: 'Home',\n 0x25: 'ArrowLeft',\n 0x26: 'ArrowUp',\n 0x27: 'ArrowRight',\n 0x28: 'ArrowDown',\n 0x29: 'Select',\n 0x2A: 'Print',\n 0x2B: 'Execute',\n 0x2C: 'PrintScreen',\n 0x2D: 'Insert',\n 0x2E: 'Delete',\n 0x3A: ':',\n 0x3B: ';',\n 0x3C: '<',\n 0x3D: '=',\n 0x3E: '>',\n 0x3F: '?',\n 0x40: '@',\n 0x5B: 'Meta',\n 0x5C: 'Meta',\n 0x5D: 'ContextMenu',\n 0x6A: 'Numpad*',\n 0x6B: 'Numpad+',\n 0x6D: 'Numpad-',\n 0x6E: 'Numpad.',\n 0x6F: 'Numpad/',\n 0x90: 'NumLock',\n 0x91: 'ScrollLock',\n 0xA0: '^',\n 0xA1: '!',\n 0xA2: '\"',\n 0xA3: '#',\n 0xA4: '$',\n 0xA5: '%',\n 0xA6: '&',\n 0xA7: '_',\n 0xA8: '(',\n 0xA9: ')',\n 0xAA: '*',\n 0xAB: '+',\n 0xAC: '|',\n 0xAD: '-',\n 0xAE: '{',\n 0xAF: '}',\n 0xB0: '~',\n 0xBA: ';',\n 0xBB: '=',\n 0xBC: 'Numpad,',\n 0xBD: '-',\n 0xBE: 'Numpad,',\n 0xC0: '`',\n 0xC2: 'Numpad,',\n 0xDB: '[',\n 0xDC: '\\\\',\n 0xDD: ']',\n 0xDE: \"'\",\n 0xE0: 'Meta'\n // numbers 0-9\n };for (var i = 0x30; i <= 0x39; i++) {\n KEY_NAMES[i] = String.fromCharCode(i);\n } // characters A-Z\n for (var _i = 0x41; _i <= 0x5A; _i++) {\n KEY_NAMES[_i] = String.fromCharCode(_i);\n } // function F1-F20\n for (var _i2 = 0x70; _i2 <= 0x83; _i2++) {\n KEY_NAMES[_i2] = 'F' + (_i2 - 0x70 + 1);\n } // numpad 0-9\n for (var _i3 = 0x60; _i3 <= 0x69; _i3++) {\n KEY_NAMES[_i3] = 'Numpad' + (_i3 - 0x60);\n }var cfg = {\n np_alt: false, // Application Numpad Mode\n cu_alt: false, // Application Cursors Mode\n fn_alt: false, // SS3 function keys mode\n mt_click: false, // Mouse click tracking\n mt_move: false, // Mouse move tracking\n no_keys: false, // Suppress any key / clipboard event intercepting\n crlf_mode: false, // Enter sends CR LF\n all_fn: false // Capture also F5, F11 and F12\n\n\n /** Fn alt choice for key message */\n };var fa = function fa(alt, normal) {\n return cfg.fn_alt ? alt : normal;\n };\n\n /** Cursor alt choice for key message */\n var ca = function ca(alt, normal) {\n return cfg.cu_alt ? alt : normal;\n };\n\n /** Numpad alt choice for key message */\n var na = function na(alt, normal) {\n return cfg.np_alt ? alt : normal;\n };\n\n var keymap = {\n /* eslint-disable key-spacing */\n 'Backspace': '\\x08',\n 'Tab': '\\x09',\n 'Enter': function Enter() {\n return cfg.crlf_mode ? '\\x0d\\x0a' : '\\x0d';\n },\n 'Control+Enter': '\\x0a',\n 'Escape': '\\x1b',\n 'ArrowUp': function ArrowUp() {\n return ca('\\x1bOA', '\\x1b[A');\n },\n 'ArrowDown': function ArrowDown() {\n return ca('\\x1bOB', '\\x1b[B');\n },\n 'ArrowRight': function ArrowRight() {\n return ca('\\x1bOC', '\\x1b[C');\n },\n 'ArrowLeft': function ArrowLeft() {\n return ca('\\x1bOD', '\\x1b[D');\n },\n 'Home': function Home() {\n return ca('\\x1bOH', fa('\\x1b[H', '\\x1b[1~'));\n },\n 'Insert': '\\x1b[2~',\n 'Delete': '\\x1b[3~',\n 'End': function End() {\n return ca('\\x1bOF', fa('\\x1b[F', '\\x1b[4~'));\n },\n 'PageUp': '\\x1b[5~',\n 'PageDown': '\\x1b[6~',\n 'F1': function F1() {\n return fa('\\x1bOP', '\\x1b[11~');\n },\n 'F2': function F2() {\n return fa('\\x1bOQ', '\\x1b[12~');\n },\n 'F3': function F3() {\n return fa('\\x1bOR', '\\x1b[13~');\n },\n 'F4': function F4() {\n return fa('\\x1bOS', '\\x1b[14~');\n },\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': function ShiftF1() {\n return fa('\\x1bO1;2P', '\\x1b[25~');\n },\n 'Shift+F2': function ShiftF2() {\n return fa('\\x1bO1;2Q', '\\x1b[26~');\n }, // note the disconnect\n 'Shift+F3': function ShiftF3() {\n return fa('\\x1bO1;2R', '\\x1b[28~');\n },\n 'Shift+F4': function ShiftF4() {\n return fa('\\x1bO1;2S', '\\x1b[29~');\n }, // note the disconnect\n 'Shift+F5': function ShiftF5() {\n return fa('\\x1b[15;2~', '\\x1b[31~');\n },\n 'Shift+F6': function ShiftF6() {\n return fa('\\x1b[17;2~', '\\x1b[32~');\n },\n 'Shift+F7': function ShiftF7() {\n return fa('\\x1b[18;2~', '\\x1b[33~');\n },\n 'Shift+F8': function ShiftF8() {\n return fa('\\x1b[19;2~', '\\x1b[34~');\n },\n 'Shift+F9': function ShiftF9() {\n return fa('\\x1b[20;2~', '\\x1b[35~');\n }, // 35-38 are not standard - but what is?\n 'Shift+F10': function ShiftF10() {\n return fa('\\x1b[21;2~', '\\x1b[36~');\n },\n 'Shift+F11': function ShiftF11() {\n return fa('\\x1b[22;2~', '\\x1b[37~');\n },\n 'Shift+F12': function ShiftF12() {\n return fa('\\x1b[23;2~', '\\x1b[38~');\n },\n 'Numpad0': function Numpad0() {\n return na('\\x1bOp', '0');\n },\n 'Numpad1': function Numpad1() {\n return na('\\x1bOq', '1');\n },\n 'Numpad2': function Numpad2() {\n return na('\\x1bOr', '2');\n },\n 'Numpad3': function Numpad3() {\n return na('\\x1bOs', '3');\n },\n 'Numpad4': function Numpad4() {\n return na('\\x1bOt', '4');\n },\n 'Numpad5': function Numpad5() {\n return na('\\x1bOu', '5');\n },\n 'Numpad6': function Numpad6() {\n return na('\\x1bOv', '6');\n },\n 'Numpad7': function Numpad7() {\n return na('\\x1bOw', '7');\n },\n 'Numpad8': function Numpad8() {\n return na('\\x1bOx', '8');\n },\n 'Numpad9': function Numpad9() {\n return na('\\x1bOy', '9');\n },\n 'Numpad*': function Numpad() {\n return na('\\x1bOR', '*');\n },\n 'Numpad+': function Numpad() {\n return na('\\x1bOl', '+');\n },\n 'Numpad-': function Numpad() {\n return na('\\x1bOS', '-');\n },\n 'Numpad.': function Numpad() {\n return na('\\x1bOn', '.');\n },\n 'Numpad/': function Numpad() {\n return na('\\x1bOQ', '/');\n },\n // we don't implement numlock key (should change in numpad_alt mode,\n // but it's even more useless than the rest and also has the side\n // effect of changing the user's numlock state)\n\n // shortcuts\n 'Control+]': '\\x1b', // alternate way to enter ESC\n 'Control+\\\\': '\\x1c',\n 'Control+[': '\\x1d',\n 'Control+^': '\\x1e',\n 'Control+_': '\\x1f',\n\n // extra controls\n 'Control+ArrowLeft': '\\x1f[1;5D',\n 'Control+ArrowRight': '\\x1f[1;5C',\n 'Control+ArrowUp': '\\x1f[1;5A',\n 'Control+ArrowDown': '\\x1f[1;5B',\n 'Control+Home': '\\x1f[1;5H',\n 'Control+End': '\\x1f[1;5F',\n\n // extra shift controls\n 'Shift+ArrowLeft': '\\x1f[1;2D',\n 'Shift+ArrowRight': '\\x1f[1;2C',\n 'Shift+ArrowUp': '\\x1f[1;2A',\n 'Shift+ArrowDown': '\\x1f[1;2B',\n 'Shift+Home': '\\x1f[1;2H',\n 'Shift+End': '\\x1f[1;2F',\n\n // macOS text editing commands\n 'Alt+ArrowLeft': '\\x1bb', // ⌥← to go back a word (^[b)\n 'Alt+ArrowRight': '\\x1bf', // ⌥→ to go forward one word (^[f)\n 'Meta+ArrowLeft': '\\x01', // ⌘← to go to the beginning of a line (^A)\n 'Meta+ArrowRight': '\\x05', // ⌘→ to go to the end of a line (^E)\n 'Alt+Backspace': '\\x17', // ⌥⌫ to delete a word (^W)\n 'Meta+Backspace': '\\x15', // ⌘⌫ to delete to the beginning of a line (^U)\n\n // copy to clipboard\n 'Control+Shift+C': function ControlShiftC() {\n screen.copySelectionToClipboard();\n },\n 'Control+Insert': function ControlInsert() {\n screen.copySelectionToClipboard();\n },\n\n\n // toggle debug mode\n 'Control+F12': function ControlF12() {\n screen.window.debug ^= 1;\n }\n /* eslint-enable key-spacing */\n\n };\n\n // ctrl+[A-Z] sent as simple low ASCII codes\n for (var _i4 = 1; _i4 <= 26; _i4++) {\n keymap['Control+' + String.fromCharCode(0x40 + _i4)] = String.fromCharCode(_i4);\n }\n\n /** Send a literal message */\n function sendString(str) {\n return conn.send('s' + str);\n }\n\n /** Send a button event */\n function sendButton(index) {\n conn.send('b' + String.fromCharCode(index + 1));\n }\n\n var shouldAcceptEvent = function shouldAcceptEvent() {\n if (cfg.no_keys) return false;\n if (document.activeElement instanceof window.HTMLTextAreaElement) return false;\n return true;\n };\n\n var keyBlacklist = ['F5', 'F11', 'F12', 'Shift+F5'];\n\n var softModifiers = {\n alt: false,\n ctrl: false,\n meta: false,\n shift: false\n };\n\n var handleKeyDown = function handleKeyDown(e) {\n if (!shouldAcceptEvent()) return;\n\n var modifiers = [];\n // sorted alphabetically\n if (e.altKey || softModifiers.alt) modifiers.push('Alt');\n if (e.ctrlKey || softModifiers.ctrl) modifiers.push('Control');\n if (e.metaKey || softModifiers.meta) modifiers.push('Meta');\n if (e.shiftKey || softModifiers.shift) modifiers.push('Shift');\n\n var key = KEY_NAMES[e.which] || e.key;\n\n // ignore clipboard events\n if ((e.ctrlKey || e.metaKey) && key === 'V') return;\n\n var binding = null;\n\n for (var name in keymap) {\n var itemModifiers = name.split('+');\n var itemKey = itemModifiers.pop();\n\n if (itemKey === key && itemModifiers.sort().join() === modifiers.join()) {\n if (keyBlacklist.includes(name) && !cfg.all_fn) continue;\n binding = keymap[name];\n break;\n }\n }\n\n if (binding) {\n if (binding instanceof Function) binding = binding();\n e.preventDefault();\n if (typeof binding === 'string') {\n sendString(binding);\n }\n }\n };\n\n /** Bind/rebind key messages */\n function initKeys(_ref) {\n var allFn = _ref.allFn;\n\n // This takes care of text characters typed\n window.addEventListener('keypress', function (evt) {\n if (!shouldAcceptEvent()) return;\n if (evt.ctrlKey || evt.metaKey) return;\n\n var str = '';\n if (evt.key && evt.key.length === 1) str = evt.key;else if (evt.which && evt.which !== 229) str = String.fromCodePoint(evt.which);\n\n if (str.length > 0 && str.charCodeAt(0) >= 32) {\n // prevent space from scrolling\n if (evt.which === 32) evt.preventDefault();\n sendString(str);\n }\n });\n\n window.addEventListener('keydown', handleKeyDown);\n window.addEventListener('copy', function (e) {\n if (!shouldAcceptEvent()) return;\n var selectedText = screen.getSelectedText();\n if (selectedText) {\n e.preventDefault();\n e.clipboardData.setData('text/plain', selectedText);\n }\n });\n window.addEventListener('paste', function (e) {\n if (!shouldAcceptEvent()) return;\n e.preventDefault();\n var string = e.clipboardData.getData('text/plain');\n if (string.includes('\\n') || string.length > 90) {\n if (!input.termUpload) console.error('input.termUpload is undefined');\n input.termUpload.setContent(string);\n input.termUpload.open();\n } else {\n // simple string, just paste it\n if (screen.bracketedPaste) string = '\\x1B[200~' + string + '\\x1B[201~';\n sendString(string);\n }\n });\n\n cfg.all_fn = allFn;\n }\n\n // mouse button states\n var mb1 = 0;\n var mb2 = 0;\n var mb3 = 0;\n\n /** Init the Input module */\n function init(opts) {\n initKeys(opts);\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 // record modifier keys\n // bits: Meta, Alt, Shift, Ctrl\n var modifiers = 0;\n\n window.addEventListener('keydown', function (e) {\n if (e.ctrlKey) modifiers |= 1;\n if (e.shiftKey) modifiers |= 2;\n if (e.altKey) modifiers |= 4;\n if (e.metaKey) modifiers |= 8;\n });\n window.addEventListener('keyup', function (e) {\n modifiers = 0;\n if (e.ctrlKey) modifiers |= 1;\n if (e.shiftKey) modifiers |= 2;\n if (e.altKey) modifiers |= 4;\n if (e.metaKey) modifiers |= 8;\n });\n\n /** Prepare modifiers byte for mouse message */\n function packModifiersForMouse() {\n return modifiers;\n }\n\n input = {\n /** Init the Input module */\n init: init,\n\n /** Send a literal string message */\n sendString: sendString,\n sendButton: sendButton,\n\n /** Enable alternate key modes (cursors, numpad, fn) */\n setAlts: function setAlts(cu, np, fn, crlf) {\n if (cfg.cu_alt !== cu || cfg.np_alt !== np || cfg.fn_alt !== fn || cfg.crlf_mode !== crlf) {\n cfg.cu_alt = cu;\n cfg.np_alt = np;\n cfg.fn_alt = fn;\n cfg.crlf_mode = crlf;\n }\n },\n\n setMouseMode: function setMouseMode(click, move) {\n cfg.mt_click = click;\n cfg.mt_move = move;\n },\n\n\n // Mouse events\n onMouseMove: function onMouseMove(x, y) {\n if (!cfg.mt_move) return;\n var b = mb1 ? 1 : mb2 ? 2 : mb3 ? 3 : 0;\n var m = packModifiersForMouse();\n conn.send('m' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m));\n },\n onMouseDown: function onMouseDown(x, y, b) {\n if (!cfg.mt_click) return;\n if (b > 3 || b < 1) return;\n var m = packModifiersForMouse();\n conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m));\n },\n onMouseUp: function onMouseUp(x, y, b) {\n if (!cfg.mt_click) return;\n if (b > 3 || b < 1) return;\n var m = packModifiersForMouse();\n conn.send('r' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m));\n // console.log(\"B \",b,\" M \",m);\n },\n onMouseWheel: function onMouseWheel(x, y, dir) {\n if (!cfg.mt_click) return;\n // -1 ... btn 4 (away from user)\n // +1 ... btn 5 (towards user)\n var m = packModifiersForMouse();\n var 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\n /**\n * Prevent capturing keys. This is used for text input\n * modals on the terminal screen\n */\n blockKeys: function blockKeys(yes) {\n cfg.no_keys = yes;\n },\n\n\n handleKeyDown: handleKeyDown,\n softModifiers: softModifiers\n };\n return input;\n};\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n qs = _require.qs;\n\nvar modal = __webpack_require__(2);\n\n/** File upload utility */\nmodule.exports = function (conn, input, screen) {\n var lines = void 0,\n // array of lines without newlines\n line_i = void 0,\n // current line index\n fuTout = void 0,\n // timeout handle for line sending\n send_delay_ms = void 0,\n // delay between lines (ms)\n nl_str = void 0,\n // newline string to use\n curLine = void 0,\n // current line (when using fuOil)\n inline_pos = void 0; // 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 var MAX_LINE_LEN = 128;\n\n function openUploadDialog() {\n updateStatus('Ready...');\n modal.show('#fu_modal', onDialogClose);\n $('#fu_form').toggleClass('busy', false);\n input.blockKeys(true);\n }\n\n function onDialogClose() {\n console.log('Upload modal closed.');\n clearTimeout(fuTout);\n line_i = 0;\n input.blockKeys(false);\n }\n\n function updateStatus(msg) {\n qs('#fu_prog').textContent = msg;\n }\n\n function startUpload() {\n var 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 updateStatus('Starting...');\n uploadLine();\n }\n\n function uploadLine() {\n if (!$('#fu_modal').hasClass('visible')) {\n // Modal is closed, cancel\n return;\n }\n\n if (!conn.canSend()) {\n // postpone\n fuTout = setTimeout(uploadLine, 1);\n return;\n }\n\n if (inline_pos === 0) {\n curLine = '';\n if (line_i === 0) {\n if (screen.bracketedPaste) {\n curLine = '\\x1b[200~';\n }\n }\n\n curLine += lines[line_i++] + nl_str;\n\n if (line_i === lines.length) {\n if (screen.bracketedPaste) {\n curLine += '\\x1b[201~';\n }\n }\n }\n\n var maxChunk = +qs('#fu_chunk').value;\n if (maxChunk === 0 || maxChunk > MAX_LINE_LEN) {\n maxChunk = MAX_LINE_LEN;\n }\n\n var chunk = void 0;\n if (curLine.length - inline_pos <= maxChunk) {\n chunk = curLine.substr(inline_pos, maxChunk);\n inline_pos = 0;\n } else {\n chunk = curLine.substr(inline_pos, maxChunk);\n inline_pos += maxChunk;\n }\n\n if (!input.sendString(chunk)) {\n updateStatus('FAILED!');\n return;\n }\n\n var pt = Math.round(line_i / lines.length * 1000) / 10;\n updateStatus(line_i + ' / ' + lines.length + ' (' + pt + '%)');\n\n if (lines.length > line_i || inline_pos > 0) {\n fuTout = setTimeout(uploadLine, 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 updateStatus('Waiting for Tx buffer...');\n setTimeout(closeWhenReady, 100);\n } else {\n updateStatus('Done.');\n // delay to show it\n fuClose();\n }\n }\n\n function fuClose() {\n modal.hide('#fu_modal');\n }\n\n return {\n init: function init() {\n qs('#fu_file').addEventListener('change', function (evt) {\n var reader = new window.FileReader();\n var file = evt.target.files[0];\n var ftype = file.type || 'application/octet-stream';\n console.log('Selected file type: ' + ftype);\n if (!ftype.match(/text\\/.*|application\\/(json|csv|.*xml.*|.*script.*|x-php)/)) {\n // Deny load of blobs like img - can crash browser and will get corrupted anyway\n if (!window.confirm('This does not look like a text file: ' + ftype + '\\nReally load?')) {\n qs('#fu_file').value = '';\n return;\n }\n }\n reader.onload = function (e) {\n var 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 qs('#term-fu-open').addEventListener('click', function (e) {\n e.preventDefault();\n openUploadDialog();\n });\n\n qs('#term-fu-start').addEventListener('click', function (e) {\n e.preventDefault();\n startUpload();\n });\n\n qs('#term-fu-close').addEventListener('click', function (e) {\n e.preventDefault();\n fuClose();\n });\n },\n open: openUploadDialog,\n setContent: function setContent(content) {\n qs('#fu_text').value = content;\n }\n };\n};\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar _require = __webpack_require__(0),\n qs = _require.qs;\n\nmodule.exports = function (screen, input) {\n var keyInput = qs('#softkb-input');\n if (!keyInput) return; // abort, we're not on the terminal page\n\n var shortcutBar = document.createElement('div');\n shortcutBar.id = 'keyboard-shortcut-bar';\n if (navigator.userAgent.match(/iPad|iPhone|iPod/)) {\n qs('#screen').appendChild(shortcutBar);\n }\n\n var keyboardOpen = false;\n\n // moves the input to where the cursor is on the canvas.\n // this is because most browsers will always scroll to wherever the focused\n // input is\n var updateInputPosition = function updateInputPosition() {\n if (!keyboardOpen) return;\n\n var _screen$gridToScreen = screen.gridToScreen(screen.cursor.x, screen.cursor.y, true),\n _screen$gridToScreen2 = _slicedToArray(_screen$gridToScreen, 2),\n x = _screen$gridToScreen2[0],\n y = _screen$gridToScreen2[1];\n\n keyInput.style.transform = 'translate(' + x + 'px, ' + y + 'px)';\n };\n\n keyInput.addEventListener('focus', function () {\n keyboardOpen = true;\n updateInputPosition();\n shortcutBar.classList.add('open');\n });\n\n keyInput.addEventListener('blur', function () {\n keyboardOpen = false;\n shortcutBar.classList.remove('open');\n });\n\n screen.on('cursor-moved', updateInputPosition);\n\n qs('#term-kb-open').addEventListener('click', function (e) {\n e.preventDefault();\n keyInput.focus();\n });\n\n // Chrome for Android doesn't send proper keydown/keypress events with\n // real key values instead of 229 “Unidentified,” so here's a workaround\n // that deals with the input composition events.\n\n var lastCompositionString = '';\n\n // sends the difference between the last and the new composition string\n var sendInputDelta = function sendInputDelta(newValue) {\n if (newValue === null) newValue = ''; // this sometimes happens, why?\n var 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 - 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) + newValue);\n }\n lastCompositionString = newValue;\n };\n\n keyInput.addEventListener('keydown', function (e) {\n if (e.key === 'Unidentified') return;\n\n keyInput.value = '';\n\n e.stopPropagation();\n input.handleKeyDown(e);\n });\n\n keyInput.addEventListener('keypress', function (e) {\n // prevent key duplication on iOS (because Safari *does* send proper events)\n e.stopPropagation();\n });\n\n keyInput.addEventListener('input', function (e) {\n e.stopPropagation();\n\n if (e.isComposing && 'data' in e) {\n sendInputDelta(e.data);\n } else if (e.isComposing) {\n // Firefox Mobile doesn't support InputEvent#data, so here's a hack\n // that just takes the input value and uses that\n sendInputDelta(keyInput.value);\n } else {\n if (e.inputType === 'insertCompositionText') input.sendString(e.data);else if (e.inputType === 'deleteContentBackward') {\n lastCompositionString = '';\n sendInputDelta('');\n } else if (e.inputType === 'insertText') {\n input.sendString(e.data);\n }\n }\n });\n\n keyInput.addEventListener('compositionstart', function (e) {\n lastCompositionString = '';\n });\n\n keyInput.addEventListener('compositionend', function (e) {\n lastCompositionString = '';\n keyInput.value = '';\n });\n\n screen.on('open-soft-keyboard', function () {\n return keyInput.focus();\n });\n\n // shortcut bar\n var shortcuts = {\n Control: 'ctrl',\n Esc: 0x1b,\n Tab: 0x09,\n '←': 0x25,\n '↓': 0x28,\n '↑': 0x26,\n '→': 0x27\n };\n\n var touchMoved = false;\n\n var _loop = function _loop(shortcut) {\n var button = document.createElement('button');\n button.classList.add('shortcut-button');\n button.textContent = shortcut;\n shortcutBar.appendChild(button);\n\n var key = shortcuts[shortcut];\n if (typeof key === 'string') button.classList.add('modifier');\n button.addEventListener('touchstart', function (e) {\n touchMoved = false;\n if (typeof key === 'string') {\n // modifier button\n input.softModifiers[key] = true;\n button.classList.add('enabled');\n\n // prevent default. This prevents scrolling, but also prevents the\n // selection popup\n e.preventDefault();\n }\n });\n window.addEventListener('touchmove', function (e) {\n touchMoved = true;\n });\n button.addEventListener('touchend', function (e) {\n e.preventDefault();\n if (typeof key === 'number') {\n if (touchMoved) return;\n var fakeEvent = { which: key, preventDefault: function preventDefault() {} };\n input.handleKeyDown(fakeEvent);\n } else if (typeof key === 'string') {\n button.classList.remove('enabled');\n input.softModifiers[key] = false;\n }\n });\n };\n\n for (var shortcut in shortcuts) {\n _loop(shortcut);\n }\n};\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar _require = __webpack_require__(0),\n mk = _require.mk;\n\nmodule.exports = function attachDebugScreen(screen) {\n var debugCanvas = mk('canvas');\n var ctx = debugCanvas.getContext('2d');\n\n debugCanvas.classList.add('debug-canvas');\n\n var mouseHoverCell = null;\n var updateToolbar = void 0;\n\n var onMouseMove = function onMouseMove(e) {\n mouseHoverCell = screen.screenToGrid(e.offsetX, e.offsetY);\n startDrawing();\n updateToolbar();\n };\n var onMouseOut = function onMouseOut() {\n return mouseHoverCell = null;\n };\n\n var addCanvas = function addCanvas() {\n if (!debugCanvas.parentNode) {\n screen.canvas.parentNode.appendChild(debugCanvas);\n screen.canvas.addEventListener('mousemove', onMouseMove);\n screen.canvas.addEventListener('mouseout', onMouseOut);\n }\n };\n var removeCanvas = function removeCanvas() {\n if (debugCanvas.parentNode) {\n debugCanvas.parentNode.removeChild(debugCanvas);\n screen.canvas.removeEventListener('mousemove', onMouseMove);\n screen.canvas.removeEventListener('mouseout', onMouseOut);\n onMouseOut();\n }\n };\n var updateCanvasSize = function updateCanvasSize() {\n var _screen$window = screen.window,\n width = _screen$window.width,\n height = _screen$window.height,\n devicePixelRatio = _screen$window.devicePixelRatio;\n\n var cellSize = screen.getCellSize();\n debugCanvas.width = width * cellSize.width * devicePixelRatio;\n debugCanvas.height = height * cellSize.height * devicePixelRatio;\n debugCanvas.style.width = width * cellSize.width + 'px';\n debugCanvas.style.height = height * cellSize.height + 'px';\n };\n\n var drawInfo = mk('div');\n drawInfo.classList.add('draw-info');\n\n var startTime = void 0,\n endTime = void 0,\n lastReason = void 0;\n var cells = new Map();\n var clippedRects = [];\n var updateFrames = [];\n\n var startDrawing = void 0;\n\n screen._debug = {\n drawStart: function drawStart(reason) {\n lastReason = reason;\n startTime = Date.now();\n clippedRects = [];\n },\n drawEnd: function drawEnd() {\n endTime = Date.now();\n console.log(drawInfo.textContent = 'Draw: ' + lastReason + ' (' + (endTime - startTime) + ' ms) with graphics=' + screen.window.graphics);\n startDrawing();\n },\n setCell: function setCell(cell, flags) {\n cells.set(cell, [flags, Date.now()]);\n },\n clipRect: function clipRect() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n clippedRects.push(args);\n },\n pushFrame: function pushFrame(frame) {\n frame.push(Date.now());\n updateFrames.push(frame);\n startDrawing();\n }\n };\n\n var clipPattern = void 0;\n {\n var patternCanvas = document.createElement('canvas');\n patternCanvas.width = patternCanvas.height = 12;\n var pctx = patternCanvas.getContext('2d');\n pctx.lineWidth = 1;\n pctx.strokeStyle = '#00f';\n pctx.beginPath();\n pctx.moveTo(0, 0);\n pctx.lineTo(0 - 4, 12);\n pctx.moveTo(4, 0);\n pctx.lineTo(4 - 4, 12);\n pctx.moveTo(8, 0);\n pctx.lineTo(8 - 4, 12);\n pctx.moveTo(12, 0);\n pctx.lineTo(12 - 4, 12);\n pctx.moveTo(16, 0);\n pctx.lineTo(16 - 4, 12);\n pctx.stroke();\n clipPattern = ctx.createPattern(patternCanvas, 'repeat');\n }\n\n var isDrawing = false;\n var lastDrawTime = 0;\n var t = 0;\n\n var drawLoop = function drawLoop() {\n if (isDrawing) window.requestAnimationFrame(drawLoop);\n\n var dt = (Date.now() - lastDrawTime) / 1000;\n lastDrawTime = Date.now();\n t += dt;\n\n var _screen$window2 = screen.window,\n devicePixelRatio = _screen$window2.devicePixelRatio,\n width = _screen$window2.width,\n height = _screen$window2.height;\n\n var _screen$getCellSize = screen.getCellSize(),\n cellWidth = _screen$getCellSize.width,\n cellHeight = _screen$getCellSize.height;\n\n var screenLength = width * height;\n var now = Date.now();\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n ctx.clearRect(0, 0, width * cellWidth, height * cellHeight);\n\n var activeCells = 0;\n for (var cell = 0; cell < screenLength; cell++) {\n if (!cells.has(cell) || cells.get(cell)[0] === 0) continue;\n\n var _cells$get = cells.get(cell),\n _cells$get2 = _slicedToArray(_cells$get, 2),\n flags = _cells$get2[0],\n timestamp = _cells$get2[1];\n\n var elapsedTime = (now - timestamp) / 1000;\n\n if (elapsedTime > 1) continue;\n\n activeCells++;\n ctx.globalAlpha = 0.5 * Math.max(0, 1 - elapsedTime);\n\n var x = cell % width;\n var y = Math.floor(cell / width);\n\n if (flags & 1) {\n // redrawn\n ctx.fillStyle = '#f0f';\n }\n if (flags & 2) {\n // updated\n ctx.fillStyle = '#0f0';\n }\n\n ctx.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);\n\n if (flags & 4) {\n // wide cell\n ctx.lineWidth = 2;\n ctx.strokeStyle = '#f00';\n ctx.strokeRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);\n }\n }\n\n if (clippedRects.length) {\n ctx.globalAlpha = 0.5;\n ctx.beginPath();\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = clippedRects[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var rect = _step.value;\n\n ctx.rect.apply(ctx, _toConsumableArray(rect));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n ctx.fillStyle = clipPattern;\n ctx.fill();\n }\n\n var didDrawUpdateFrames = false;\n if (updateFrames.length) {\n var framesToDelete = [];\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = updateFrames[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var frame = _step2.value;\n\n var time = frame[4];\n var elapsed = Date.now() - time;\n if (elapsed > 1000) framesToDelete.push(frame);else {\n didDrawUpdateFrames = true;\n ctx.globalAlpha = 1 - elapsed / 1000;\n ctx.strokeStyle = '#ff0';\n ctx.lineWidth = 2;\n ctx.strokeRect(frame[0] * cellWidth, frame[1] * cellHeight, frame[2] * cellWidth, frame[3] * cellHeight);\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = framesToDelete[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var _frame = _step3.value;\n\n updateFrames.splice(updateFrames.indexOf(_frame), 1);\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n }\n\n if (mouseHoverCell) {\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.lineWidth = 1 + 0.5 * Math.sin(t * 10);\n ctx.strokeStyle = '#fff';\n ctx.lineJoin = 'round';\n ctx.setLineDash([2, 2]);\n ctx.lineDashOffset = t * 10;\n ctx.strokeRect(mouseHoverCell[0] * cellWidth, mouseHoverCell[1] * cellHeight, cellWidth, cellHeight);\n ctx.lineDashOffset += 2;\n ctx.strokeStyle = '#000';\n ctx.strokeRect(mouseHoverCell[0] * cellWidth, mouseHoverCell[1] * cellHeight, cellWidth, cellHeight);\n ctx.restore();\n }\n\n if (activeCells === 0 && !mouseHoverCell && !didDrawUpdateFrames) {\n isDrawing = false;\n removeCanvas();\n }\n };\n\n startDrawing = function startDrawing() {\n if (isDrawing) return;\n addCanvas();\n updateCanvasSize();\n isDrawing = true;\n lastDrawTime = Date.now();\n drawLoop();\n };\n\n // debug toolbar\n var toolbar = mk('div');\n toolbar.classList.add('debug-toolbar');\n var toolbarAttached = false;\n var dataDisplay = mk('div');\n dataDisplay.classList.add('data-display');\n toolbar.appendChild(dataDisplay);\n var internalDisplay = mk('div');\n internalDisplay.classList.add('internal-display');\n toolbar.appendChild(internalDisplay);\n toolbar.appendChild(drawInfo);\n var buttons = mk('div');\n buttons.classList.add('toolbar-buttons');\n toolbar.appendChild(buttons);\n\n {\n var redraw = mk('button');\n redraw.textContent = 'Redraw';\n redraw.addEventListener('click', function (e) {\n screen.renderer.resetDrawn();\n screen.renderer.draw('debug-redraw');\n });\n buttons.appendChild(redraw);\n\n var fancyGraphics = mk('button');\n fancyGraphics.textContent = 'Toggle Graphics';\n fancyGraphics.addEventListener('click', function (e) {\n screen.window.graphics = +!screen.window.graphics;\n });\n buttons.appendChild(fancyGraphics);\n }\n\n var attachToolbar = function attachToolbar() {\n screen.canvas.parentNode.appendChild(toolbar);\n };\n var detachToolbar = function detachToolbar() {\n toolbar.parentNode.removeChild(toolbar);\n };\n\n screen.on('update-window:debug', function (debug) {\n if (debug !== toolbarAttached) {\n toolbarAttached = debug;\n if (debug) attachToolbar();else {\n detachToolbar();\n removeCanvas();\n }\n }\n });\n\n var displayCellAttrs = function displayCellAttrs(attrs) {\n var result = attrs.toString(16);\n if (attrs & 1 || attrs & 2) {\n result += ':has(';\n if (attrs & 1) result += 'fg';\n if (attrs & 2) result += (attrs & 1 ? ',' : '') + 'bg';\n result += ')';\n }\n var attributes = [];\n if (attrs & 1 << 2) attributes.push('\\\\[bold]bold\\\\()');\n if (attrs & 1 << 3) attributes.push('\\\\[underline]underln\\\\()');\n if (attrs & 1 << 4) attributes.push('\\\\[invert]invert\\\\()');\n if (attrs & 1 << 5) attributes.push('blink');\n if (attrs & 1 << 6) attributes.push('\\\\[italic]italic\\\\()');\n if (attrs & 1 << 7) attributes.push('\\\\[strike]strike\\\\()');\n if (attrs & 1 << 8) attributes.push('\\\\[overline]overln\\\\()');\n if (attrs & 1 << 9) attributes.push('\\\\[faint]faint\\\\()');\n if (attrs & 1 << 10) attributes.push('fraktur');\n if (attributes.length) result += ':' + attributes.join();\n return result.trim();\n };\n\n var formatColor = function formatColor(color) {\n return color < 256 ? color : '#' + ('000000' + (color - 256).toString(16)).substr(-6);\n };\n var getCellData = function getCellData(cell) {\n if (cell < 0 || cell > screen.screen.length) return '(-)';\n var cellAttrs = screen.renderer.drawnScreenAttrs[cell] | 0;\n var cellFG = screen.renderer.drawnScreenFG[cell] | 0;\n var cellBG = screen.renderer.drawnScreenBG[cell] | 0;\n var fgText = formatColor(cellFG);\n var bgText = formatColor(cellBG);\n fgText += '\\\\[color=' + screen.renderer.getColor(cellFG).replace(/ /g, '') + ']\\u25CF\\\\[]';\n bgText += '\\\\[color=' + screen.renderer.getColor(cellBG).replace(/ /g, '') + ']\\u25CF\\\\[]';\n var cellCode = (screen.renderer.drawnScreen[cell] || '').codePointAt(0) | 0;\n var hexcode = cellCode.toString(16).toUpperCase();\n if (hexcode.length < 4) hexcode = ('0000' + hexcode).substr(-4);\n hexcode = 'U+' + hexcode;\n var x = cell % screen.window.width;\n var y = Math.floor(cell / screen.window.width);\n return '((' + y + ',' + x + ')=' + cell + ':\\\\[bold]' + hexcode + '\\\\[]:F' + fgText + ':B' + bgText + ':A(' + displayCellAttrs(cellAttrs) + '))';\n };\n\n var setFormattedText = function setFormattedText(node, text) {\n node.innerHTML = '';\n\n var match = void 0;\n var attrs = {};\n\n var pushSpan = function pushSpan(content) {\n var span = mk('span');\n node.appendChild(span);\n span.textContent = content;\n for (var key in attrs) {\n span[key] = attrs[key];\n }\n };\n\n while (match = text.match(/\\\\\\[(.*?)\\]/)) {\n if (match.index > 0) pushSpan(text.substr(0, match.index));\n\n attrs = { style: '' };\n var data = match[1].split(' ');\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = data[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n var attr = _step4.value;\n\n if (!attr) continue;\n var key = void 0,\n value = void 0;\n if (attr.indexOf('=') > -1) {\n key = attr.substr(0, attr.indexOf('='));\n value = attr.substr(attr.indexOf('=') + 1);\n } else {\n key = attr;\n value = true;\n }\n\n if (key === 'color') console.log(value);\n\n if (key === 'bold') attrs.style += 'font-weight:bold;';\n if (key === 'italic') attrs.style += 'font-style:italic;';\n if (key === 'underline') attrs.style += 'text-decoration:underline;';\n if (key === 'invert') attrs.style += 'background:#000;filter:invert(1);';\n if (key === 'strike') attrs.style += 'text-decoration:line-through;';\n if (key === 'overline') attrs.style += 'text-decoration:overline;';\n if (key === 'faint') attrs.style += 'opacity:0.5;';else if (key === 'color') attrs.style += 'color:' + value + ';';else attrs[key] = value;\n }\n } catch (err) {\n _didIteratorError4 = true;\n _iteratorError4 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion4 && _iterator4.return) {\n _iterator4.return();\n }\n } finally {\n if (_didIteratorError4) {\n throw _iteratorError4;\n }\n }\n }\n\n text = text.substr(match.index + match[0].length);\n }\n\n if (text) pushSpan(text);\n };\n\n var internalInfo = {};\n\n updateToolbar = function updateToolbar() {\n if (!toolbarAttached) return;\n var text = 'C((' + screen.cursor.y + ',' + screen.cursor.x + '),hang:' + screen.cursor.hanging + ',vis:' + screen.cursor.visible + ')';\n if (mouseHoverCell) {\n text += ' m' + getCellData(mouseHoverCell[1] * screen.window.width + mouseHoverCell[0]);\n }\n setFormattedText(dataDisplay, text);\n\n if ('flags' in internalInfo) {\n // we got ourselves some internal data\n var _text = ' ';\n _text += ' flags:' + internalInfo.flags.toString(2);\n _text += ' curAttrs:' + internalInfo.cursorAttrs.toString(2);\n _text += ' Region:' + internalInfo.regionStart + '->' + internalInfo.regionEnd;\n _text += ' Charset:' + internalInfo.charsetGx + ' (0:' + internalInfo.charsetG0 + ',1:' + internalInfo.charsetG1 + ')';\n _text += ' Heap:' + internalInfo.freeHeap;\n _text += ' Clients:' + internalInfo.clientCount;\n setFormattedText(internalDisplay, _text);\n }\n };\n\n screen.on('draw', updateToolbar);\n screen.on('internal', function (data) {\n internalInfo = data;\n updateToolbar();\n });\n};\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _require = __webpack_require__(0),\n qs = _require.qs;\n\nmodule.exports = function initButtons(input) {\n var container = qs('#action-buttons');\n\n // button labels\n var labels = [];\n\n // button elements\n var buttons = [];\n\n // add a button element\n var pushButton = function pushButton() {\n var button = document.createElement('button');\n button.classList.add('action-button');\n button.setAttribute('data-n', buttons.length);\n buttons.push(button);\n container.appendChild(button);\n\n button.addEventListener('click', function (e) {\n // might as well use the attribute ¯\\_(ツ)_/¯\n var index = +button.getAttribute('data-n');\n input.sendButton(index);\n });\n\n return button;\n };\n\n // remove a button element\n var popButton = function popButton() {\n var button = buttons.pop();\n button.parentNode.removeChild(button);\n };\n\n // sync with DOM\n var update = function updateButtons() {\n if (labels.length > buttons.length) {\n for (var i = buttons.length; i < labels.length; i++) {\n pushButton();\n }\n } else if (buttons.length > labels.length) {\n for (var _i = labels.length; _i <= buttons.length; _i++) {\n popButton();\n }\n }\n\n for (var _i2 = 0; _i2 < labels.length; _i2++) {\n var label = labels[_i2].trim();\n var button = buttons[_i2];\n button.textContent = label || '\\xA0'; // label or nbsp\n if (!label) button.classList.add('inactive');else button.classList.remove('inactive');\n }\n };\n\n return { update: update, labels: labels };\n};\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar ColorTriangle = __webpack_require__(25);\nvar $ = __webpack_require__(1);\nvar themes = __webpack_require__(5);\n\nvar _require = __webpack_require__(0),\n qs = _require.qs;\n\nfunction selectedTheme() {\n return +$('#theme').val();\n}\n\nexports.init = function () {\n $('#theme').on('change', showColor);\n\n $('#default_fg').on('input', showColor);\n $('#default_bg').on('input', showColor);\n\n var opts = {\n padding: 10,\n event: 'drag',\n uppercase: true,\n trianglePointerSize: 20,\n // wheelPointerSize: 12,\n size: 200,\n parseColor: function parseColor(color) {\n return themes.toHex(color, selectedTheme());\n }\n };\n\n ColorTriangle.initInput(qs('#default_fg'), opts);\n ColorTriangle.initInput(qs('#default_bg'), opts);\n\n $('.colorprev.bg span').on('click', function () {\n var bg = this.dataset.bg;\n if (typeof bg != 'undefined') $('#default_bg').val(bg);\n showColor();\n });\n\n $('.colorprev.fg span').on('click', function () {\n var fg = this.dataset.fg;\n if (typeof fg != 'undefined') $('#default_fg').val(fg);\n showColor();\n });\n\n var $presets = $('#fgbg_presets');\n for (var i = 0; i < themes.fgbgThemes.length; i++) {\n var thm = themes.fgbgThemes[i];\n var fg = thm[0];\n var bg = thm[1];\n var lbl = thm[2];\n var tit = thm[3];\n $presets.htmlAppend(' ' + lbl + ' ');\n\n if ((i + 1) % 5 === 0) $presets.htmlAppend('
');\n }\n\n $('.preset').on('click', function () {\n $('#default_fg').val(this.dataset.xfg);\n $('#default_bg').val(this.dataset.xbg);\n showColor();\n });\n\n showColor();\n};\n\nfunction showColor() {\n var ex = qs('.color-example');\n var fg = $('#default_fg').val();\n var bg = $('#default_bg').val();\n\n if (/^\\d+$/.test(fg)) {\n fg = +fg;\n } else if (!/^#[\\da-f]{6}$/i.test(fg)) {\n fg = 'black';\n }\n\n if (/^\\d+$/.test(bg)) {\n bg = +bg;\n } else if (!/^#[\\da-f]{6}$/i.test(bg)) {\n bg = 'black';\n }\n\n var themeN = selectedTheme();\n ex.dataset.fg = fg;\n ex.dataset.bg = bg;\n\n themes.themePreview(themeN);\n\n $('.colorprev.fg span').css('background', themes.toHex(bg, themeN));\n}\n\nexports.nextTheme = function () {\n var sel = qs('#theme');\n var i = sel.selectedIndex;\n sel.options[++i % sel.options.length].selected = true;\n showColor();\n};\n\nexports.prevTheme = function () {\n var sel = qs('#theme');\n var i = sel.selectedIndex;\n sel.options[(sel.options.length + --i) % sel.options.length].selected = true;\n showColor();\n};\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n/*\n * Copyright (c) 2010 Tim Baumann\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// NOTE: Converted to ES6 by MightyPork (2017)\n// Modified for ESPTerm\n\nvar EventEmitter = __webpack_require__(4);\n\nvar _require = __webpack_require__(7),\n rgb2hex = _require.rgb2hex,\n hex2rgb = _require.hex2rgb,\n hsl2rgb = _require.hsl2rgb,\n rgb2hsl = _require.rgb2hsl;\n\nvar win = window;\nvar doc = document;\nvar M = Math;\nvar TAU = 2 * M.PI;\n\nfunction times(i, fn) {\n for (var j = 0; j < i; j++) {\n fn(j);\n }\n}\n\nfunction each(obj, fn) {\n if (obj.length) {\n times(obj.length, function (i) {\n fn(obj[i], i);\n });\n } else {\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n fn(obj[key], key);\n }\n }\n }\n}\n\nmodule.exports = function (_EventEmitter) {\n _inherits(ColorTriangle, _EventEmitter);\n\n /****************\n * ColorTriangle *\n ****************/\n\n // Constructor function:\n function ColorTriangle(color, options) {\n _classCallCheck(this, ColorTriangle);\n\n var _this = _possibleConstructorReturn(this, (ColorTriangle.__proto__ || Object.getPrototypeOf(ColorTriangle)).call(this));\n\n _this.options = {\n size: 150,\n padding: 8,\n triangleSize: 0.8,\n wheelPointerColor1: '#444',\n wheelPointerColor2: '#eee',\n trianglePointerSize: 16,\n // wheelPointerSize: 16,\n trianglePointerColor1: '#eee',\n trianglePointerColor2: '#444',\n background: 'transparent'\n };\n\n _this.pixelRatio = window.devicePixelRatio;\n\n _this.setOptions(options);\n _this.calculateProperties();\n\n _this.createContainer();\n _this.createTriangle();\n _this.createWheel();\n _this.createWheelPointer();\n _this.createTrianglePointer();\n _this.attachEvents();\n\n color = color || '#f00';\n if (typeof color == 'string') {\n _this.setHEX(color);\n }\n return _this;\n }\n\n _createClass(ColorTriangle, [{\n key: 'calculateProperties',\n value: function calculateProperties() {\n var opts = this.options;\n\n this.padding = opts.padding;\n this.innerSize = opts.size - opts.padding * 2;\n this.triangleSize = opts.triangleSize * this.innerSize;\n this.wheelThickness = (this.innerSize - this.triangleSize) / 2;\n this.wheelPointerSize = opts.wheelPointerSize || this.wheelThickness;\n\n this.wheelRadius = this.innerSize / 2;\n this.triangleRadius = this.triangleSize / 2;\n this.triangleSideLength = M.sqrt(3) * this.triangleRadius;\n }\n }, {\n key: 'calculatePositions',\n value: function calculatePositions() {\n var r = this.triangleRadius;\n var hue = this.hue;\n var third = TAU / 3;\n var s = this.saturation;\n var l = this.lightness;\n\n // Colored point\n var hx = this.hx = M.cos(hue) * r;\n var hy = this.hy = -M.sin(hue) * r;\n // Black point\n var sx = this.sx = M.cos(hue - third) * r;\n var sy = this.sy = -M.sin(hue - third) * r;\n // White point\n var vx = this.vx = M.cos(hue + third) * r;\n var vy = this.vy = -M.sin(hue + third) * r;\n // Current point\n var mx = (sx + vx) / 2;\n var my = (sy + vy) / 2;\n var a = (1 - 2 * M.abs(l - 0.5)) * s;\n this.x = sx + (vx - sx) * l + (hx - mx) * a;\n this.y = sy + (vy - sy) * l + (hy - my) * a;\n }\n }, {\n key: 'createContainer',\n value: function createContainer() {\n var c = this.container = doc.createElement('div');\n c.className = 'color-triangle';\n\n c.style.display = 'block';\n c.style.padding = this.padding + 'px';\n c.style.position = 'relative';\n c.style.boxShadow = '0 1px 10px black';\n c.style.borderRadius = '5px';\n c.style.width = c.style.height = this.innerSize + 2 * this.padding + 'px';\n c.style.background = this.options.background;\n }\n }, {\n key: 'createWheel',\n value: function createWheel() {\n var c = this.wheel = doc.createElement('canvas');\n c.width = c.height = this.innerSize * this.pixelRatio;\n c.style.width = c.style.height = this.innerSize + 'px';\n c.style.position = 'absolute';\n c.style.margin = c.style.padding = '0';\n c.style.left = c.style.top = this.padding + 'px';\n\n this.drawWheel(c.getContext('2d'));\n this.container.appendChild(c);\n }\n }, {\n key: 'drawWheel',\n value: function drawWheel(ctx) {\n var s = void 0,\n i = void 0;\n\n ctx.save();\n ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);\n ctx.translate(this.wheelRadius, this.wheelRadius);\n s = this.wheelRadius - this.triangleRadius;\n // Draw a circle for every color\n for (i = 0; i < 360; i++) {\n ctx.rotate(TAU / -360); // rotate one degree\n ctx.beginPath();\n ctx.fillStyle = 'hsl(' + i + ', 100%, 50%)';\n ctx.arc(this.wheelRadius - s / 2, 0, s / 2, 0, TAU, true);\n ctx.fill();\n }\n ctx.restore();\n }\n }, {\n key: 'createTriangle',\n value: function createTriangle() {\n var c = this.triangle = doc.createElement('canvas');\n\n c.width = c.height = this.innerSize * this.pixelRatio;\n c.style.width = c.style.height = this.innerSize + 'px';\n c.style.position = 'absolute';\n c.style.margin = c.style.padding = '0';\n c.style.left = c.style.top = this.padding + 'px';\n\n this.triangleCtx = c.getContext('2d');\n\n this.container.appendChild(c);\n }\n }, {\n key: 'drawTriangle',\n value: function drawTriangle() {\n var hx = this.hx;\n var hy = this.hy;\n var sx = this.sx;\n var sy = this.sy;\n var vx = this.vx;\n var vy = this.vy;\n var size = this.innerSize;\n\n var ctx = this.triangleCtx;\n\n // clear\n ctx.clearRect(0, 0, size * this.pixelRatio, size * this.pixelRatio);\n\n ctx.save();\n ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);\n ctx.translate(this.wheelRadius, this.wheelRadius);\n\n // make a triangle\n ctx.beginPath();\n ctx.moveTo(hx, hy);\n ctx.lineTo(sx, sy);\n ctx.lineTo(vx, vy);\n ctx.closePath();\n ctx.clip();\n\n ctx.fillStyle = '#000';\n ctx.fillRect(-this.wheelRadius, -this.wheelRadius, size, size);\n // => black triangle\n\n // create gradient from hsl(hue, 1, 1) to transparent\n var grad0 = ctx.createLinearGradient(hx, hy, (sx + vx) / 2, (sy + vy) / 2);\n var hsla = 'hsla(' + M.round(this.hue * (360 / TAU)) + ', 100%, 50%, ';\n grad0.addColorStop(0, hsla + '1)');\n grad0.addColorStop(1, hsla + '0)');\n ctx.fillStyle = grad0;\n ctx.fillRect(-this.wheelRadius, -this.wheelRadius, size, size);\n // => gradient: one side of the triangle is black, the opponent angle is $color\n\n // create color gradient from white to transparent\n var grad1 = ctx.createLinearGradient(vx, vy, (hx + sx) / 2, (hy + sy) / 2);\n grad1.addColorStop(0, '#fff');\n grad1.addColorStop(1, 'rgba(255, 255, 255, 0)');\n ctx.globalCompositeOperation = 'lighter';\n ctx.fillStyle = grad1;\n ctx.fillRect(-this.wheelRadius, -this.wheelRadius, size, size);\n // => white angle\n\n ctx.restore();\n }\n\n // The two pointers\n\n }, {\n key: 'createWheelPointer',\n value: function createWheelPointer() {\n var c = this.wheelPointer = doc.createElement('canvas');\n var size = this.wheelPointerSize;\n c.width = c.height = size * this.pixelRatio;\n c.style.width = c.style.height = size + 'px';\n c.style.position = 'absolute';\n c.style.margin = c.style.padding = '0';\n this.drawPointer(c.getContext('2d'), size / 2, this.options.wheelPointerColor1, this.options.wheelPointerColor2);\n this.container.appendChild(c);\n }\n }, {\n key: 'moveWheelPointer',\n value: function moveWheelPointer() {\n var r = this.wheelPointerSize / 2;\n var s = this.wheelPointer.style;\n s.top = this.padding + this.wheelRadius - M.sin(this.hue) * (this.triangleRadius + this.wheelThickness / 2) - r + 'px';\n s.left = this.padding + this.wheelRadius + M.cos(this.hue) * (this.triangleRadius + this.wheelThickness / 2) - r + 'px';\n }\n }, {\n key: 'createTrianglePointer',\n value: function createTrianglePointer() {\n // create pointer in the triangle\n var c = this.trianglePointer = doc.createElement('canvas');\n var size = this.options.trianglePointerSize;\n\n c.width = c.height = size * this.pixelRatio;\n c.style.width = c.style.height = size + 'px';\n c.style.position = 'absolute';\n c.style.margin = c.style.padding = '0';\n this.drawPointer(c.getContext('2d'), size / 2, this.options.trianglePointerColor1, this.options.trianglePointerColor2);\n this.container.appendChild(c);\n }\n }, {\n key: 'moveTrianglePointer',\n value: function moveTrianglePointer(x, y) {\n var s = this.trianglePointer.style;\n var r = this.options.trianglePointerSize / 2;\n s.top = this.y + this.wheelRadius + this.padding - r + 'px';\n s.left = this.x + this.wheelRadius + this.padding - r + 'px';\n }\n }, {\n key: 'drawPointer',\n value: function drawPointer(ctx, r, color1, color2) {\n ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);\n ctx.fillStyle = color2;\n ctx.beginPath();\n ctx.arc(r, r, r, 0, TAU, true);\n ctx.fill(); // => black circle\n ctx.fillStyle = color1;\n ctx.beginPath();\n ctx.arc(r, r, r - 2, 0, TAU, true);\n ctx.fill(); // => white circle with 1px black border\n ctx.fillStyle = color2;\n ctx.beginPath();\n ctx.arc(r, r, r / 4 + 2, 0, TAU, true);\n ctx.fill(); // => black circle with big white border and a small black border\n ctx.globalCompositeOperation = 'destination-out';\n ctx.beginPath();\n ctx.arc(r, r, r / 4, 0, TAU, true);\n ctx.fill(); // => transparent center\n }\n\n // The Element and the DOM\n\n }, {\n key: 'inject',\n value: function inject(parent) {\n parent.appendChild(this.container);\n }\n }, {\n key: 'getRelativeCoordinates',\n value: function getRelativeCoordinates(evt) {\n var elem = this.triangle;\n var rect = elem.getBoundingClientRect();\n\n return {\n x: evt.clientX - rect.x,\n y: evt.clientY - rect.y\n };\n }\n }, {\n key: 'dispose',\n value: function dispose() {\n var parent = this.container.parentNode;\n if (parent) {\n parent.removeChild(this.container);\n }\n }\n }, {\n key: 'getElement',\n value: function getElement() {\n return this.container;\n }\n\n // Color accessors\n\n }, {\n key: 'getCSS',\n value: function getCSS() {\n var h = Math.round(this.hue * (360 / TAU));\n var s = Math.round(this.saturation * 100);\n var l = Math.round(this.lightness * 100);\n\n return 'hsl(' + h + ', ' + s + '%, ' + l + '%)';\n }\n }, {\n key: 'getHEX',\n value: function getHEX() {\n return rgb2hex.apply(undefined, _toConsumableArray(this.getRGB()));\n }\n }, {\n key: 'setHEX',\n value: function setHEX(hex) {\n this.setRGB.apply(this, _toConsumableArray(hex2rgb(hex)));\n }\n }, {\n key: 'getRGB',\n value: function getRGB() {\n return hsl2rgb.apply(undefined, _toConsumableArray(this.getHSL()));\n }\n }, {\n key: 'setRGB',\n value: function setRGB(r, g, b) {\n this.setHSL.apply(this, _toConsumableArray(rgb2hsl(r, g, b)));\n }\n }, {\n key: 'getHSL',\n value: function getHSL() {\n return [this.hue, this.saturation, this.lightness];\n }\n }, {\n key: 'setHSL',\n value: function setHSL(h, s, l) {\n this.hue = h;\n this.saturation = s;\n this.lightness = l;\n\n this.initColor();\n }\n }, {\n key: 'initColor',\n value: function initColor() {\n this.calculatePositions();\n this.moveWheelPointer();\n this.drawTriangle();\n this.moveTrianglePointer();\n }\n\n // Mouse event handling\n\n }, {\n key: 'attachEvents',\n value: function attachEvents() {\n var _this2 = this;\n\n this.down = null;\n\n var mousedown = function mousedown(evt) {\n evt.stopPropagation();\n evt.preventDefault();\n\n doc.body.addEventListener('mousemove', mousemove, false);\n doc.body.addEventListener('mouseup', mouseup, false);\n\n var xy = _this2.getRelativeCoordinates(evt);\n _this2.map(xy.x, xy.y);\n };\n\n var mousemove = function mousemove(evt) {\n var xy = _this2.getRelativeCoordinates(evt);\n _this2.move(xy.x, xy.y);\n };\n\n var mouseup = function mouseup(evt) {\n if (_this2.down) {\n _this2.down = null;\n _this2.emit('dragend');\n }\n doc.body.removeEventListener('mousemove', mousemove, false);\n doc.body.removeEventListener('mouseup', mouseup, false);\n };\n\n this.container.addEventListener('mousedown', mousedown, false);\n this.container.addEventListener('mousemove', mousemove, false);\n }\n }, {\n key: 'map',\n value: function map(x, y) {\n var x0 = x;\n var y0 = y;\n x -= this.wheelRadius;\n y -= this.wheelRadius;\n\n var r = M.sqrt(x * x + y * y); // Pythagoras\n if (r > this.triangleRadius && r < this.wheelRadius) {\n // Wheel\n this.down = 'wheel';\n this.emit('dragstart');\n this.move(x0, y0);\n } else if (r < this.triangleRadius) {\n // Inner circle\n this.down = 'triangle';\n this.emit('dragstart');\n this.move(x0, y0);\n }\n }\n }, {\n key: 'move',\n value: function move(x, y) {\n if (!this.down) {\n return;\n }\n\n x -= this.wheelRadius;\n y -= this.wheelRadius;\n\n var rad = M.atan2(-y, x);\n if (rad < 0) {\n rad += TAU;\n }\n\n if (this.down === 'wheel') {\n this.hue = rad;\n this.initColor();\n this.emit('drag');\n } else if (this.down === 'triangle') {\n // get radius and max radius\n var rad0 = (rad + TAU - this.hue) % TAU;\n var rad1 = rad0 % (TAU / 3) - TAU / 6;\n var a = 0.5 * this.triangleRadius;\n var b = M.tan(rad1) * a;\n var r = M.sqrt(x * x + y * y); // Pythagoras\n var maxR = M.sqrt(a * a + b * b); // Pythagoras\n\n if (r > maxR) {\n var dx = M.tan(rad1) * r;\n var rad2 = M.atan(dx / maxR);\n if (rad2 > TAU / 6) {\n rad2 = TAU / 6;\n } else if (rad2 < -TAU / 6) {\n rad2 = -TAU / 6;\n }\n rad += rad2 - rad1;\n\n rad0 = (rad + TAU - this.hue) % TAU;\n rad1 = rad0 % (TAU / 3) - TAU / 6;\n b = M.tan(rad1) * a;\n r = maxR = M.sqrt(a * a + b * b); // Pythagoras\n }\n\n x = M.round(M.cos(rad) * r);\n y = M.round(-M.sin(rad) * r);\n\n var l = this.lightness = M.sin(rad0) * r / this.triangleSideLength + 0.5;\n\n var widthShare = 1 - M.abs(l - 0.5) * 2;\n var s = this.saturation = (M.cos(rad0) * r + this.triangleRadius / 2) / (1.5 * this.triangleRadius) / widthShare;\n s = M.max(0, s); // cannot be lower than 0\n s = M.min(1, s); // cannot be greater than 1\n\n this.lightness = l;\n this.saturation = s;\n\n this.x = x;\n this.y = y;\n this.moveTrianglePointer();\n\n this.emit('drag');\n }\n }\n\n /***************\n * Init helpers *\n ***************/\n\n }, {\n key: 'setOptions',\n\n\n /*******************\n * Helper functions *\n *******************/\n\n value: function setOptions(opts) {\n opts = opts || {};\n var dflt = this.options;\n var options = this.options = {};\n\n each(dflt, function (val, key) {\n options[key] = opts.hasOwnProperty(key) ? opts[key] : val;\n });\n }\n }], [{\n key: 'initInput',\n value: function initInput(input, options) {\n options = options || {};\n\n var ct = void 0;\n var openColorTriangle = function openColorTriangle() {\n var hex = input.value;\n if (options.parseColor) hex = options.parseColor(hex);\n if (!ct) {\n options.size = options.size || input.offsetWidth;\n options.background = win.getComputedStyle(input, null).backgroundColor;\n options.margin = options.margin || 10;\n options.event = options.event || 'dragend';\n\n ct = new ColorTriangle(hex, options);\n ct.on(options.event, function () {\n var hex = ct.getHEX();\n input.value = options.uppercase ? hex.toUpperCase() : hex;\n fireChangeEvent();\n });\n } else {\n ct.setHEX(hex);\n }\n\n var top = input.offsetTop;\n if (win.innerHeight - input.getBoundingClientRect().top > input.offsetHeight + options.margin + options.size) {\n top += input.offsetHeight + options.margin; // below\n } else {\n top -= options.margin + options.size; // above\n }\n\n var el = ct.getElement();\n el.style.position = 'absolute';\n el.style.left = input.offsetLeft + 'px';\n el.style.top = top + 'px';\n el.style.zIndex = '1338'; // above everything\n\n ct.inject(input.parentNode);\n };\n\n var closeColorTriangle = function closeColorTriangle() {\n if (ct) {\n ct.dispose();\n }\n };\n\n var fireChangeEvent = function fireChangeEvent() {\n var evt = doc.createEvent('HTMLEvents');\n evt.initEvent('input', true, false); // bubbles = true, cancable = false\n input.dispatchEvent(evt); // fire event\n };\n\n input.addEventListener('focus', openColorTriangle, false);\n input.addEventListener('blur', closeColorTriangle, false);\n input.addEventListener('keyup', function () {\n var val = input.value;\n if (val.match(/^#((?:[0-9A-Fa-f]{3})|(?:[0-9A-Fa-f]{6}))$/)) {\n openColorTriangle();\n fireChangeEvent();\n } else {\n closeColorTriangle();\n }\n }, false);\n }\n }]);\n\n return ColorTriangle;\n}(EventEmitter);\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// app.4a032ee-en.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 9);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 5f19c49887263bc447b9","/** Make a node */\nexports.mk = function mk (e) {\n return document.createElement(e)\n}\n\n/** Find one by query */\nexports.qs = function qs (s) {\n return document.querySelector(s)\n}\n\n/** Find all by query */\nexports.qsa = function qsa (s) {\n return document.querySelectorAll(s)\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 */\nexports.cr = function cr (hdl) {\n return function (e) {\n if (e.which === 10 || e.which === 13 || e.which === 32) {\n hdl()\n }\n }\n}\n\n/** Decode number from 2B encoding */\nexports.parse2B = function parse2B (s, i = 0) {\n return (s.charCodeAt(i++) - 1) + (s.charCodeAt(i) - 1) * 127\n}\n\n/** Decode number from 3B encoding */\nexports.parse3B = function 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. */\nexports.encode2B = function encode2B (n) {\n let lsb, msb\n lsb = (n % 127)\n n = ((n - lsb) / 127)\n lsb += 1\n msb = (n + 1)\n return String.fromCharCode(lsb) + String.fromCharCode(msb)\n}\n\n/** Encode using 3B encoding, returns string. */\nexports.encode3B = function 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 String.fromCharCode(lsb) + String.fromCharCode(msb) + String.fromCharCode(xsb)\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/utils.js","/*!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 = Object.assign({\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\tmodule.exports = chibi;\n}());\n\n\n\n// WEBPACK FOOTER //\n// ./js/lib/chibi.js","const $ = require('./lib/chibi')\n\n/** Module for toggling a modal overlay */\nlet modal = {}\nlet curCloseCb = null\n\nmodal.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\nmodal.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\nmodal.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\nmodule.exports = modal\n\n\n\n// WEBPACK FOOTER //\n// ./js/modal.js","const $ = require('./lib/chibi')\nconst modal = require('./modal')\n\nlet nt = {}\nconst sel = '#notif'\nlet $balloon\n\nlet timerHideBegin // timeout to start hiding (transition)\nlet timerHideEnd // timeout to add the hidden class\nlet canCancel = false\n\nlet stopTimeouts = function () {\n clearTimeout(timerHideBegin)\n clearTimeout(timerHideEnd)\n}\n\nnt.show = function (message, timeout, isError) {\n $balloon.toggleClass('error', isError === true)\n $balloon.html(message)\n modal.show($balloon)\n stopTimeouts()\n\n if (!timeout || timeout <= 0) {\n timeout = 2500\n }\n\n timerHideBegin = setTimeout(nt.hide, timeout)\n\n canCancel = false\n setTimeout(() => {\n canCancel = true\n }, 500)\n}\n\nnt.hide = function () {\n let $m = $(sel)\n $m.removeClass('visible')\n timerHideEnd = setTimeout(function () {\n $m.addClass('hidden')\n }, 250) // transition time\n}\n\nnt.init = function () {\n $balloon = $(sel)\n\n // close by click outside\n $(document).on('click', function () {\n if (!canCancel) return\n nt.hide(this)\n })\n\n // click caused by selecting, prevent it from bubbling\n $balloon.on('click', function (e) {\n e.stopImmediatePropagation()\n return false\n })\n\n // stop fading if moused\n $balloon.on('mouseenter', function () {\n stopTimeouts()\n $balloon.removeClass('hidden').addClass('visible')\n })\n}\n\nmodule.exports = nt\n\n\n\n// WEBPACK FOOTER //\n// ./js/notif.js","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./node_modules/events/events.js\n// module id = 4\n// module chunks = 0","const $ = require('../lib/chibi')\nconst { rgb255ToHex } = require('../lib/color_utils')\n\nconst themes = exports.themes = [\n [ // 0 - Tango - terminator\n '#111213', '#CC0000', '#4E9A06', '#C4A000', '#3465A4', '#75507B', '#06989A', '#D3D7CF',\n '#555753', '#EF2929', '#8AE234', '#FCE94F', '#729FCF', '#AD7FA8', '#34E2E2', '#EEEEEC'\n ],\n [ // 1 - Linux (CGA) - terminator\n '#000000', '#aa0000', '#00aa00', '#aa5500', '#0000aa', '#aa00aa', '#00aaaa', '#aaaaaa',\n '#555555', '#ff5555', '#55ff55', '#ffff55', '#5555ff', '#ff55ff', '#55ffff', '#ffffff'\n ],\n [ // 2 - xterm - terminator\n '#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000ee', '#cd00cd', '#00cdcd', '#e5e5e5',\n '#7f7f7f', '#ff0000', '#00ff00', '#ffff00', '#5c5cff', '#ff00ff', '#00ffff', '#ffffff'\n ],\n [ // 3 - rxvt - terminator\n '#000000', '#cd0000', '#00cd00', '#cdcd00', '#0000cd', '#cd00cd', '#00cdcd', '#faebd7',\n '#404040', '#ff0000', '#00ff00', '#ffff00', '#0000ff', '#ff00ff', '#00ffff', '#ffffff'\n ],\n [ // 4 - Ambience - terminator\n '#2e3436', '#cc0000', '#4e9a06', '#c4a000', '#3465a4', '#75507b', '#06989a', '#d3d7cf',\n '#555753', '#ef2929', '#8ae234', '#fce94f', '#729fcf', '#ad7fa8', '#34e2e2', '#eeeeec'\n ],\n [ // 5 - Solarized Dark - terminator\n '#073642', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#eee8d5',\n '#002b36', '#cb4b16', '#586e75', '#657b83', '#839496', '#6c71c4', '#93a1a1', '#fdf6e3'\n ],\n [ // 6 - CGA NTSC - wikipedia\n '#000000', '#69001A', '#117800', '#769100', '#1A00A6', '#8019AB', '#289E76', '#A4A4A4',\n '#484848', '#C54E76', '#6DD441', '#D2ED46', '#765BFF', '#DC75FF', '#84FAD2', '#FFFFFF'\n ],\n [ // 7 - ZX Spectrum - wikipedia\n '#000000', '#aa0000', '#00aa00', '#aaaa00', '#0000aa', '#aa00aa', '#00aaaa', '#aaaaaa',\n '#000000', '#ff0000', '#00FF00', '#ffff00', '#0000ff', '#ff00ff', '#00ffff', '#ffffff'\n ],\n [ // 8 - Apple II - wikipedia\n '#000000', '#722640', '#0E5940', '#808080', '#40337F', '#E434FE', '#1B9AFE', '#BFB3FF',\n '#404C00', '#E46501', '#1BCB01', '#BFCC80', '#808080', '#F1A6BF', '#8DD9BF', '#ffffff'\n ],\n [ // 9 - Commodore - wikipedia\n '#000000', '#8D3E37', '#55A049', '#AAB95D', '#40318D', '#80348B', '#72C1C8', '#D59F74',\n '#8B5429', '#B86962', '#94E089', '#FFFFB2', '#8071CC', '#AA5FB6', '#87D6DD', '#ffffff'\n ],\n [ // 10 - Solarized Light - https://github.com/sgerrand/xfce4-terminal-colors-solarized\n '#eee8d5', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#073642',\n '#fdf6e3', '#cb4b16', '#93a1a1', '#839496', '#657b83', '#6c71c4', '#586e75', '#002b36'\n ],\n [ // 11 - Solarized Dark High contrast - https://github.com/sgerrand/xfce4-terminal-colors-solarized\n '#073642', '#dc322f', '#859900', '#b58900', '#268bd2', '#d33682', '#2aa198', '#fdf6e3',\n '#002b36', '#cb4b16', '#657b83', '#839496', '#93a1a1', '#6c71c4', '#eee8d5', '#fdf6e3'\n ]\n]\n\nexports.fgbgThemes = [\n ['#AAAAAA', '#000000', 'Lnx', 'Linux'],\n ['#FFFFFF', '#000000', 'W+K', 'White on Black'],\n ['#00FF00', '#000000', 'Lim', 'Lime'],\n ['#E53C00', '#000000', 'Nix', 'Nixie'],\n ['#EFF0F1', '#31363B', 'Brz', 'Breeze'],\n ['#FFFFFF', '#300A24', 'Amb', 'Ambiance'],\n ['#839496', '#002B36', 'SoD', 'Solarized Dark'],\n ['#93a1a1', '#002b36', 'SoH', 'Solarized Dark (High Contrast)'],\n ['#657B83', '#FDF6E3', 'SoL', 'Solarized Light'],\n ['#000000', '#FFD75F', 'Wsp', 'Wasp'],\n ['#000000', '#FFFFDD', 'K+Y', 'Black on Yellow'],\n ['#000000', '#FFFFFF', 'K+W', 'Black on White']\n]\n\nlet colorTable256 = null\n\nexports.buildColorTable = function () {\n if (colorTable256 !== null) return colorTable256\n\n // 256color lookup table\n // should not be used to look up 0-15 (will return transparent)\n colorTable256 = new Array(16).fill('#000000')\n\n // fill color table\n // colors 16-231 are a 6x6x6 color cube\n for (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(rgb255ToHex(redValue, greenValue, blueValue))\n }\n }\n }\n // colors 232-255 are a grayscale ramp, sans black and white\n for (let gray = 0; gray < 24; gray++) {\n let value = gray * 10 + 8\n colorTable256.push(rgb255ToHex(value, value, value))\n }\n\n return colorTable256\n}\n\nexports.SELECTION_FG = '#333'\nexports.SELECTION_BG = '#b2d7fe'\n\nexports.themePreview = function (themeN) {\n $('[data-fg]').forEach((elem) => {\n let shade = elem.dataset.fg\n if (/^\\d+$/.test(shade)) shade = exports.toHex(shade, themeN)\n elem.style.color = shade\n })\n $('[data-bg]').forEach((elem) => {\n let shade = elem.dataset.bg\n if (/^\\d+$/.test(shade)) shade = exports.toHex(shade, themeN)\n elem.style.backgroundColor = shade\n })\n}\n\nexports.toHex = function (shade, themeN) {\n if (/^\\d+$/.test(shade)) {\n shade = +shade\n if (shade < 16) shade = themes[themeN][shade]\n else {\n shade = exports.buildColorTable()[shade]\n }\n }\n return shade\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/themes.js","const EventEmitter = require('events')\nconst { parse2B } = require('../utils')\nconst { themes } = require('./themes')\n\nconst encodeAsCodePoint = i => String.fromCodePoint(i + (i >= 0xD800 ? 0x801 : 1))\n\nclass ANSIParser {\n constructor (handler) {\n this.reset()\n this.handler = handler\n this.joinChunks = true\n }\n reset () {\n this.currentSequence = 0\n this.sequence = ''\n }\n parseSequence (sequence) {\n if (sequence[0] === '[') {\n let type = sequence[sequence.length - 1]\n let content = sequence.substring(1, sequence.length - 1)\n\n let numbers = content ? content.split(';').map(i => +i.replace(/\\D/g, '')) : []\n let numOr1 = numbers.length ? numbers[0] : 1\n if (type === 'H') {\n this.handler('set-cursor', (numbers[0] | 0) - 1, (numbers[1] | 0) - 1)\n } else if (type >= 'A' && type <= 'D') {\n this.handler(`move-cursor-${type <= 'B' ? 'y' : 'x'}`, ((type === 'B' || type === 'C') ? 1 : -1) * numOr1)\n } else if (type === 'E' || type === 'F') {\n this.handler('move-cursor-line', (type === 'E' ? 1 : -1) * numOr1)\n } else if (type === 'G') {\n this.handler('set-cursor-x', numOr1 - 1)\n } else if (type === 'J') {\n let number = numbers.length ? numbers[0] : 2\n if (number === 2) this.handler('clear')\n } else if (type === 'P') {\n this.handler('delete', numOr1)\n } else if (type === '@') {\n this.handler('insert-blanks', numOr1)\n } else if (type === 'q') this.handler('set-cursor-style', numOr1)\n else if (type === 'm') {\n if (!numbers.length) {\n this.handler('reset-style')\n return\n }\n let type\n while ((type = numbers.shift())) {\n if (type === 0) this.handler('reset-style')\n else if (type === 1) this.handler('add-attrs', 1 << 2) // bold\n else if (type === 2) this.handler('add-attrs', 1 << 9) // faint\n else if (type === 3) this.handler('add-attrs', 1 << 6) // italic\n else if (type === 4) this.handler('add-attrs', 1 << 3) // underline\n else if (type === 5 || type === 6) this.handler('add-attrs', 1 << 5) // blink\n else if (type === 7) this.handler('add-attrs', 1 << 4) // invert\n else if (type === 9) this.handler('add-attrs', 1 << 7) // strike\n else if (type === 20) this.handler('add-attrs', 1 << 10) // fraktur\n else if (type >= 30 && type <= 37) this.handler('set-color-fg', type % 10)\n else if (type >= 40 && type <= 47) this.handler('set-color-bg', type % 10)\n else if (type === 39) this.handler('reset-color-fg')\n else if (type === 49) this.handler('reset-color-bg')\n else if (type >= 90 && type <= 98) this.handler('set-color-fg', (type % 10) + 8)\n else if (type >= 100 && type <= 108) this.handler('set-color-bg', (type % 10) + 8)\n else if (type === 38 || type === 48) {\n let mode = numbers.shift()\n if (mode === 2) {\n let r = numbers.shift()\n let g = numbers.shift()\n let b = numbers.shift()\n let color = (r << 16 | g << 8 | b) + 256\n if (type === 38) this.handler('set-color-fg', color)\n if (type === 48) this.handler('set-color-bg', color)\n } else if (mode === 5) {\n let color = (numbers.shift() | 0) & 0xFF\n if (type === 38) this.handler('set-color-fg', color)\n if (type === 48) this.handler('set-color-bg', color)\n }\n }\n }\n } else if (type === 'h' || type === 'l') {\n if (content === '?25') {\n if (type === 'h') this.handler('show-cursor')\n else if (type === 'l') this.handler('hide-cursor')\n }\n }\n }\n }\n write (text) {\n for (let character of text.toString()) {\n let code = character.codePointAt(0)\n if (code === 0x1b) this.currentSequence = 1\n else if (this.currentSequence === 1 && character === '[') {\n this.currentSequence = 2\n this.sequence += '['\n } else if (this.currentSequence && character.match(/[\\x40-\\x7e]/)) {\n this.parseSequence(this.sequence + character)\n this.currentSequence = 0\n this.sequence = ''\n } else if (this.currentSequence > 1) this.sequence += character\n else if (this.currentSequence === 1) {\n // something something nothing\n this.currentSequence = 0\n this.handler('write', character)\n } else if (code < 0x03) this.handler('_null')\n else if (code === 0x03) this.handler('sigint')\n else if (code <= 0x06) this.handler('_null')\n else if (code === 0x07) this.handler('bell')\n else if (code === 0x08) this.handler('back')\n else if (code === 0x09) this.handler('tab')\n else if (code === 0x0a) this.handler('new-line')\n else if (code === 0x0d) this.handler('return')\n else if (code === 0x15) this.handler('delete-line')\n else if (code === 0x17) this.handler('delete-word')\n else this.handler('write', character)\n }\n if (!this.joinChunks) this.reset()\n }\n}\nconst TERM_DEFAULT_STYLE = [0, 0, 0]\n\nlet getRainbowColor = t => {\n let r = Math.floor(Math.sin(t) * 2.5 + 2.5)\n let g = Math.floor(Math.sin(t + 2 / 3 * Math.PI) * 2.5 + 2.5)\n let b = Math.floor(Math.sin(t + 4 / 3 * Math.PI) * 2.5 + 2.5)\n return 16 + 36 * r + 6 * g + b\n}\n\nclass ScrollingTerminal {\n constructor (screen) {\n this.width = 80\n this.height = 25\n this.termScreen = screen\n this.parser = new ANSIParser((...args) => this.handleParsed(...args))\n this.buttonLabels = []\n\n this.reset()\n\n this._lastLoad = Date.now()\n this.loadTimer()\n\n window.showPage()\n }\n reset () {\n this.style = TERM_DEFAULT_STYLE.slice()\n this.cursor = { x: 0, y: 0, style: 1, visible: true }\n this.trackMouse = false\n this.theme = 0\n this.rainbow = this.superRainbow = false\n this.parser.reset()\n this.clear()\n }\n clear () {\n this.screen = []\n for (let i = 0; i < this.width * this.height; i++) {\n this.screen.push([' ', this.style.slice()])\n }\n }\n scroll () {\n this.screen.splice(0, this.width)\n for (let i = 0; i < this.width; i++) {\n this.screen.push([' ', TERM_DEFAULT_STYLE.slice()])\n }\n this.cursor.y--\n }\n newLine () {\n this.cursor.y++\n if (this.cursor.y >= this.height) this.scroll()\n }\n writeChar (character) {\n this.screen[this.cursor.y * this.width + this.cursor.x] = [character, this.style.slice()]\n this.cursor.x++\n if (this.cursor.x >= this.width) {\n this.cursor.x = 0\n this.newLine()\n }\n }\n moveBack (n = 1) {\n for (let i = 0; i < n; i++) {\n this.cursor.x--\n if (this.cursor.x < 0) {\n if (this.cursor.y > 0) this.cursor.x = this.width - 1\n else this.cursor.x = 0\n this.cursor.y = Math.max(0, this.cursor.y - 1)\n }\n }\n }\n moveForward (n = 1) {\n for (let i = 0; i < n; i++) {\n this.cursor.x++\n if (this.cursor.x >= this.width) {\n this.cursor.x = 0\n this.cursor.y++\n if (this.cursor.y >= this.height) this.scroll()\n }\n }\n }\n deleteChar () { // FIXME unused?\n this.moveBack()\n this.screen.splice((this.cursor.y + 1) * this.width, 0, [' ', TERM_DEFAULT_STYLE.slice()])\n this.screen.splice(this.cursor.y * this.width + this.cursor.x, 1)\n }\n deleteForward (n) {\n n = Math.min(this.width, n)\n for (let i = 0; i < n; i++) this.screen.splice((this.cursor.y + 1) * this.width, 0, [' ', TERM_DEFAULT_STYLE.slice()])\n this.screen.splice(this.cursor.y * this.width + this.cursor.x, n)\n }\n clampCursor () {\n if (this.cursor.x < 0) this.cursor.x = 0\n if (this.cursor.y < 0) this.cursor.y = 0\n if (this.cursor.x > this.width - 1) this.cursor.x = this.width - 1\n if (this.cursor.y > this.height - 1) this.cursor.y = this.height - 1\n }\n handleParsed (action, ...args) {\n if (action === 'write') {\n this.writeChar(args[0])\n } else if (action === 'delete') {\n this.deleteForward(args[0])\n } else if (action === 'insert-blanks') {\n this.insertBlanks(args[0]) // FIXME undefined?\n } else if (action === 'clear') {\n this.clear()\n } else if (action === 'bell') {\n this.termScreen.load('U\\x01B')\n } else if (action === 'back') {\n this.moveBack()\n } else if (action === 'new-line') {\n this.newLine()\n this.cursor.x = 0\n } else if (action === 'return') {\n this.cursor.x = 0\n } else if (action === 'set-cursor') {\n this.cursor.x = args[1]\n this.cursor.y = args[0]\n this.clampCursor()\n } else if (action === 'move-cursor-y') {\n this.cursor.y += args[0]\n this.clampCursor()\n } else if (action === 'move-cursor-x') {\n this.cursor.x += args[0]\n this.clampCursor()\n } else if (action === 'move-cursor-line') {\n this.cursor.x = 0\n this.cursor.y += args[0]\n this.clampCursor()\n } else if (action === 'set-cursor-x') {\n this.cursor.x = args[0]\n } else if (action === 'set-cursor-style') {\n this.cursor.style = Math.max(0, Math.min(6, args[0]))\n } else if (action === 'reset-style') {\n this.style = TERM_DEFAULT_STYLE.slice()\n } else if (action === 'add-attrs') {\n this.style[2] |= args[0]\n } else if (action === 'set-color-fg') {\n this.style[0] = args[0]\n this.style[2] |= 1\n } else if (action === 'set-color-bg') {\n this.style[1] = args[0]\n this.style[2] |= 1 << 1\n } else if (action === 'reset-color-fg') {\n this.style[0] = 0\n if (this.style[2] & 1) this.style[2] ^= 1\n } else if (action === 'reset-color-bg') {\n this.style[1] = 0\n if (this.style[2] & (1 << 1)) this.style[2] ^= (1 << 1)\n } else if (action === 'hide-cursor') {\n this.cursor.visible = false\n } else if (action === 'show-cursor') {\n this.cursor.visible = true\n }\n }\n write (text) {\n this.parser.write(text)\n }\n getScreenOpts () {\n let data = 'O'\n data += encodeAsCodePoint(25)\n data += encodeAsCodePoint(80)\n data += encodeAsCodePoint(this.theme)\n data += encodeAsCodePoint(7)\n data += encodeAsCodePoint(0)\n data += encodeAsCodePoint(0)\n data += encodeAsCodePoint(0)\n let attributes = +this.cursor.visible\n attributes |= (3 << 5) * +this.trackMouse // track mouse controls both\n attributes |= 3 << 7 // buttons/links always visible\n attributes |= (this.cursor.style << 9)\n data += encodeAsCodePoint(attributes)\n return data\n }\n getButtons () {\n let data = 'B'\n data += encodeAsCodePoint(this.buttonLabels.length)\n data += this.buttonLabels.map(x => x + '\\x01').join('')\n return data\n }\n getTitle () {\n return 'TESPTerm Web UI Demo\\x01'\n }\n getCursor () {\n let data = 'C'\n data += encodeAsCodePoint(this.cursor.y)\n data += encodeAsCodePoint(this.cursor.x)\n data += encodeAsCodePoint(0)\n return data\n }\n encodeColor (color) {\n if (color < 256) {\n return encodeAsCodePoint(color)\n } else {\n color -= 256\n return encodeAsCodePoint((color & 0xFFF) | 0x10000) + encodeAsCodePoint(color >> 12)\n }\n }\n serializeScreen () {\n let serialized = 'S'\n serialized += encodeAsCodePoint(0) + encodeAsCodePoint(0)\n serialized += encodeAsCodePoint(this.height) + encodeAsCodePoint(this.width)\n\n let lastStyle = [null, null, null]\n let index = 0\n for (let cell of this.screen) {\n let style = cell[1].slice()\n if (this.rainbow) {\n let x = index % this.width\n let y = Math.floor(index / this.width)\n // C instead of F in mask and 1 << 8 in attrs to change attr bits 1 and 2\n let t = (x + y) / 10 + Date.now() / 1000\n if (this.superRainbow) {\n t = (x * y + Date.now()) / 100 + Date.now() / 1000\n }\n style[0] = getRainbowColor(t)\n style[1] = 0\n if (this.superRainbow) style[1] = getRainbowColor(t / 10)\n style[2] = style[2] | 1\n if (!this.superRainbow && style[2] & (1 << 1)) style[2] ^= (1 << 1)\n index++\n }\n\n let foreground = style[0]\n let background = style[1]\n let attributes = style[2]\n let setForeground = foreground !== lastStyle[0]\n let setBackground = background !== lastStyle[1]\n let setAttributes = attributes !== lastStyle[2]\n\n if (setForeground && setBackground) {\n if (foreground < 256 && background < 256) {\n serialized += '\\x03' + encodeAsCodePoint((background << 8) | foreground)\n } else {\n serialized += '\\x05' + this.encodeColor(foreground)\n serialized += '\\x06' + this.encodeColor(background)\n }\n } else if (setForeground) serialized += '\\x05' + this.encodeColor(foreground)\n else if (setBackground) serialized += '\\x06' + this.encodeColor(background)\n if (setAttributes) serialized += '\\x04' + encodeAsCodePoint(attributes)\n lastStyle = style\n\n serialized += cell[0]\n }\n return serialized\n }\n getUpdate () {\n let topics = 0\n let topicData = []\n let screenOpts = this.getScreenOpts()\n let title = this.getTitle()\n let buttons = this.getButtons()\n let cursor = this.getCursor()\n let screen = this.serializeScreen()\n if (this._screenOpts !== screenOpts) {\n this._screenOpts = screenOpts\n topicData.push(screenOpts)\n }\n if (this._title !== title) {\n this._title = title\n topicData.push(title)\n }\n if (this._buttons !== buttons) {\n this._buttons = buttons\n topicData.push(buttons)\n }\n if (this._cursor !== cursor) {\n this._cursor = cursor\n topicData.push(cursor)\n }\n if (this._screen !== screen) {\n this._screen = screen\n topicData.push(screen)\n }\n if (!topicData.length) return ''\n return 'U' + encodeAsCodePoint(topics) + topicData.join('')\n }\n loadTimer () {\n clearInterval(this._loadTimer)\n this._loadTimer = setInterval(() => {\n let update = this.getUpdate()\n if (update) this.termScreen.load(update)\n }, 30)\n }\n}\n\nclass Process extends EventEmitter {\n write (data) {\n this.emit('in', data)\n }\n destroy () {\n // death.\n this.emit('exit', 0)\n }\n run () {\n // noop\n }\n}\n\nlet demoData = {\n buttons: [],\n mouseReceiver: null\n}\n\nlet demoshIndex = {\n clear: class Clear extends Process {\n run () {\n this.emit('write', '\\x1b[2J\\x1b[1;1H')\n this.destroy()\n }\n },\n screenfetch: class Screenfetch extends Process {\n run () {\n let image = `\n ###. ESPTerm Demo\n '###. Hostname: ${window.location.hostname}\n '###. Shell: ESPTerm Demo Shell\n '###. Resolution: 80x25@${window.devicePixelRatio}x\n :###-\n .###'\n .###'\n .###' ###############\n ###' ###############\n `.split('\\n').filter(line => line.trim())\n\n let chars = ''\n for (let y = 0; y < image.length; y++) {\n for (let x = 0; x < 80; x++) {\n if (image[y][x]) {\n chars += `\\x1b[38;5;${getRainbowColor((x + y) / 10)}m${image[y][x]}`\n } else chars += ' '\n }\n }\n\n this.emit('write', '\\r\\n\\x1b[?25l')\n let loop = () => {\n this.emit('write', chars.substr(0, 80))\n chars = chars.substr(80)\n if (chars.length) setTimeout(loop, 50)\n else {\n this.emit('write', '\\r\\n\\x1b[?25h')\n this.destroy()\n }\n }\n loop()\n }\n },\n 'local-echo': class LocalEcho extends Process {\n run (...args) {\n if (!args.includes('--suppress-note')) {\n this.emit('write', '\\x1b[38;5;239mNote: not all terminal features are supported or and may not work as expected in this demo\\x1b[0m\\r\\n')\n }\n }\n write (data) {\n this.emit('write', data)\n }\n },\n 'info': class Info extends Process {\n run (...args) {\n let fast = args.includes('--fast')\n this.showSplash().then(() => {\n this.printText(fast)\n })\n }\n showSplash () {\n let splash = `\n -#####- -###*..#####- ######-\n -#* -#- .## .##. *#-\n -##### .-###*..#####- *#- -*##*- #*-#--#**#-*##-\n -#* -#-.##. *#- *##@#* ##. -#* *# .#*\n -#####--####- .##. *#- -*#@@- ##. -#* *# .#*\n `.split('\\n').filter(line => line.trim())\n let levels = {\n ' ': -231,\n '.': 4,\n '-': 8,\n '*': 17,\n '#': 24\n }\n let characters = {\n ' ': ' ',\n '.': '░',\n '-': '▒',\n '*': '▓',\n '#': '█'\n }\n for (let i in splash) {\n if (splash[i].length < 79) splash[i] += ' '.repeat(79 - splash[i].length)\n }\n this.emit('write', '\\r\\n'.repeat(splash.length + 1))\n this.emit('write', '\\x1b[A'.repeat(splash.length))\n this.emit('write', '\\x1b[?25l')\n\n let cursorX = 0\n let cursorY = 0\n let moveTo = (x, y) => {\n let moveX = x - cursorX\n let moveY = y - cursorY\n this.emit('write', `\\x1b[${Math.abs(moveX)}${moveX > 0 ? 'C' : 'D'}`)\n this.emit('write', `\\x1b[${Math.abs(moveY)}${moveY > 0 ? 'B' : 'A'}`)\n cursorX = x\n cursorY = y\n }\n let drawCell = (x, y) => {\n moveTo(x, y)\n if (splash[y][x] === '@') {\n this.emit('write', '\\x1b[48;5;238m\\x1b[38;5;255m▄\\b')\n } else {\n let level = 231 + levels[splash[y][x]]\n let character = characters[splash[y][x]]\n this.emit('write', `\\x1b[48;5;${level}m\\x1b[38;5;${level}m${character}\\b`)\n }\n }\n return new Promise((resolve, reject) => {\n const self = this\n let x = 13\n let cycles = 0\n let loop = function () {\n for (let y = 0; y < splash.length; y++) {\n let dx = x - y\n if (dx > 0) drawCell(dx, y)\n }\n\n if (++x < 70) {\n if (++cycles >= 3) {\n setTimeout(loop, 50)\n cycles = 0\n } else loop()\n } else {\n moveTo(0, splash.length)\n self.emit('write', '\\x1b[m\\x1b[?25h')\n resolve()\n }\n }\n loop()\n })\n }\n printText (fast = false) {\n // lots of printing\n let parts = [\n '',\n ' ESPTerm is a VT100-like terminal emulator running on the ESP8266 WiFi chip.',\n '',\n ' \\x1b[93mThis is an online demo of the web user interface, simulating a simple ',\n ' terminal in your browser.\\x1b[m',\n '',\n ' Type \\x1b[92mls\\x1b[m to list available commands.',\n ' Use the \\x1b[94mlinks\\x1b[m below this screen for a demo of the options and more info.',\n ''\n ]\n\n if (fast) {\n this.emit('write', parts.join('\\r\\n') + '\\r\\n')\n this.destroy()\n } else {\n const self = this\n let loop = function () {\n self.emit('write', parts.shift() + '\\r\\n')\n if (parts.length) setTimeout(loop, 17)\n else self.destroy()\n }\n loop()\n }\n }\n },\n colors: class PrintColors extends Process {\n run () {\n this.emit('write', '\\r\\n')\n let fgtext = 'foreground-color'\n this.emit('write', ' ')\n for (let i = 0; i < 16; i++) {\n this.emit('write', '\\x1b[' + (i < 8 ? `3${i}` : `9${i - 8}`) + 'm')\n this.emit('write', fgtext[i] + ' ')\n }\n this.emit('write', '\\r\\n ')\n for (let i = 0; i < 16; i++) {\n this.emit('write', '\\x1b[' + (i < 8 ? `4${i}` : `10${i - 8}`) + 'm ')\n }\n this.emit('write', '\\x1b[m\\r\\n')\n for (let r = 0; r < 6; r++) {\n this.emit('write', ' ')\n for (let g = 0; g < 6; g++) {\n for (let b = 0; b < 6; b++) {\n this.emit('write', `\\x1b[48;5;${16 + r * 36 + g * 6 + b}m `)\n }\n this.emit('write', '\\x1b[m')\n }\n this.emit('write', '\\r\\n')\n }\n this.emit('write', ' ')\n for (let g = 0; g < 24; g++) {\n this.emit('write', `\\x1b[48;5;${232 + g}m `)\n }\n this.emit('write', '\\x1b[m\\r\\n\\n')\n this.destroy()\n }\n },\n ls: class ListCommands extends Process {\n run () {\n this.emit('write', '\\x1b[92mList of demo commands\\x1b[m\\r\\n')\n for (let i in demoshIndex) {\n if (typeof demoshIndex[i] === 'string') continue\n this.emit('write', i + '\\r\\n')\n }\n this.destroy()\n }\n },\n theme: class SetTheme extends Process {\n constructor (shell) {\n super()\n this.shell = shell\n }\n run (...args) {\n let theme = +args[0] | 0\n const maxnum = themes.length\n if (!args.length || !Number.isFinite(theme) || theme < 0 || theme >= maxnum) {\n this.emit('write', `\\x1b[31mUsage: theme [0–${maxnum - 1}]\\n`)\n this.destroy()\n return\n }\n this.shell.terminal.theme = theme\n // HACK: reset drawn screen to prevent only partly redrawn screen\n this.shell.terminal.termScreen.drawnScreenFG = []\n this.emit('write', '')\n this.destroy()\n }\n },\n themes: class ShowThemes extends Process {\n color (hex) {\n hex = parseInt(hex.substr(1), 16)\n let r = hex >> 16\n let g = (hex >> 8) & 0xFF\n let b = hex & 0xFF\n this.emit('write', `\\x1b[48;2;${r};${g};${b}m`)\n if (((r + g + b) / 3) > 127) {\n this.emit('write', '\\x1b[38;5;16m')\n } else {\n this.emit('write', '\\x1b[38;5;255m')\n }\n }\n run (...args) {\n for (let i in themes) {\n let theme = themes[i]\n\n let name = ` ${i}`.substr(-2)\n\n this.emit('write', `Theme ${name}: `)\n\n for (let col = 0; col < 16; col++) {\n let text = ` ${col}`.substr(-2)\n this.color(theme[col])\n this.emit('write', text)\n this.emit('write', '\\x1b[m ')\n }\n\n this.emit('write', '\\n')\n }\n\n this.destroy()\n }\n },\n cursor: class SetCursor extends Process {\n run (...args) {\n let steady = args.includes('--steady')\n if (args.includes('block')) {\n this.emit('write', `\\x1b[${2 * steady} q`)\n } else if (args.includes('line')) {\n this.emit('write', `\\x1b[${3 + steady} q`)\n } else if (args.includes('bar') || args.includes('beam')) {\n this.emit('write', `\\x1b[${5 + steady} q`)\n } else {\n this.emit('write', '\\x1b[31mUsage: cursor [block|line|bar] [--steady]\\r\\n')\n }\n this.destroy()\n }\n },\n rainbow: class ToggleRainbow extends Process {\n constructor (shell, options = {}) {\n super()\n this.shell = shell\n this.su = options.su\n this.abort = false\n }\n write (data, newLine = true) {\n if (data === 'y') {\n this.shell.terminal.rainbow = !this.shell.terminal.rainbow\n this.shell.terminal.superRainbow = true\n demoData._didWarnRainbow = true\n } else {\n this.emit('write', data)\n }\n if (newLine) this.emit('write', '\\x1b[0;32m\\x1b[G\\x1b[79PRainbow!\\n')\n this.destroy()\n }\n run () {\n if (this.su && !this.shell.terminal.rainbow) {\n if (!demoData._didWarnRainbow) {\n this.emit('write', '\\x1b[31;1mWarning: flashy colors. Continue? [y/N] ')\n } else {\n this.write('y', false)\n }\n } else {\n this.shell.terminal.rainbow = !this.shell.terminal.rainbow\n this.shell.terminal.superRainbow = false\n this.destroy()\n }\n }\n destroy () {\n this.abort = true\n super.destroy()\n }\n },\n mouse: class ShowMouse extends Process {\n constructor (shell) {\n super()\n this.shell = shell\n }\n run () {\n this.emit('buttons', [\n {\n label: 'Exit',\n action (shell) {\n shell.write('\\x03')\n }\n }\n ])\n\n this.shell.terminal.trackMouse = true\n demoData.mouseReceiver = this\n this.randomData = []\n this.highlighted = {}\n let characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'\n for (let i = 0; i < 23; i++) {\n let line = ''\n for (let j = 0; j < 79; j++) {\n line += characters[Math.floor(characters.length * Math.random())]\n }\n this.randomData.push(line)\n }\n this.scrollOffset = 0\n this.render()\n }\n render () {\n this.emit('write', '\\x1b[m\\x1b[2J\\x1b[1;1H')\n this.emit('write', '\\x1b[97m\\x1b[1mMouse Demo\\r\\n\\x1b[mMouse movement, clicking, and scrolling!')\n\n // render random data for scrolling\n for (let y = 0; y < 23; y++) {\n let index = y + this.scrollOffset\n // proper modulo:\n index = ((index % this.randomData.length) + this.randomData.length) % this.randomData.length\n let line = this.randomData[index]\n let lineData = `\\x1b[${3 + y};1H\\x1b[38;5;239m`\n for (let x in line) {\n if (this.highlighted[(y + 2) * 80 + (+x)]) lineData += '\\x1b[97m'\n lineData += line[x]\n if (this.highlighted[(y + 2) * 80 + (+x)]) lineData += '\\x1b[38;5;239m'\n }\n this.emit('write', lineData)\n }\n\n // move cursor to mouse\n if (this.mouse) {\n this.emit('write', `\\x1b[${this.mouse.y + 1};${this.mouse.x + 1}H`)\n }\n }\n mouseMove (x, y) {\n this.mouse = { x, y }\n this.render()\n }\n mouseDown (x, y, button) {\n if (button === 4) this.scrollOffset--\n else if (button === 5) this.scrollOffset++\n else this.highlighted[y * 80 + x] = !this.highlighted[y * 80 + x]\n this.render()\n }\n mouseUp (x, y, button) {}\n destroy () {\n this.shell.terminal.write('\\x1b[2J\\x1b[1;1H')\n this.shell.terminal.trackMouse = false\n if (demoData.mouseReceiver === this) demoData.mouseReceiver = null\n super.destroy()\n }\n },\n sudo: class Sudo extends Process {\n constructor (shell) {\n super()\n this.shell = shell\n this.didDestroy = false\n }\n run (...args) {\n if (args.length === 0) {\n this.emit('write', '\\x1b[31mUsage: sudo [command]\\x1b[m\\r\\n')\n this.destroy()\n } else {\n let name = args.shift()\n if (this.shell.index[name]) {\n let Process = this.shell.index[name]\n if (Process instanceof Function) {\n let child = this.child = new Process(this.shell, { su: true })\n this.on('in', data => child.write(data))\n let write = data => this.emit('write', data)\n let setButtons = buttons => this.emit('buttons', buttons)\n child.on('write', write)\n child.on('buttons', setButtons)\n child.on('exit', code => {\n child.removeListener('write', write)\n child.removeListener('buttons', setButtons)\n this.destroy()\n })\n child.run(...args)\n } else {\n this.emit('write', Process)\n this.destroy()\n }\n } else {\n this.emit('write', `sudo: ${name}: command not found\\r\\n`)\n this.destroy()\n }\n }\n }\n destroy () {\n if (this.didDestroy) return\n this.didDestroy = true\n if (this.child) this.child.destroy()\n super.destroy()\n }\n },\n make: class Make extends Process {\n constructor (shell, options = {}) {\n super()\n this.su = options.su\n }\n run (...args) {\n if (args.length === 0) this.emit('write', '\\x1b[31mmake: *** No targets specified. Stop.\\x1b[0m\\r\\n')\n else if (args.length === 3 && args.join(' ').toLowerCase() === 'me a sandwich') {\n if (this.su) {\n const b = '\\x1b[33m'\n const r = '\\x1b[0m'\n const l = '\\x1b[32m'\n const c = '\\x1b[38;5;229m'\n const h = '\\x1b[38;5;225m'\n this.emit('write',\n ` ${b}_.---._\\r\\n` +\n ` _.-~ ~-._\\r\\n` +\n ` _.-~ ~-._\\r\\n` +\n ` _.-~ ~---._\\r\\n` +\n ` _.-~ ~\\\\\\r\\n` +\n ` .-~ _.;\\r\\n` +\n ` :-._ _.-~ ./\\r\\n` +\n ` \\`-._~-._ _..__.-~ _.-~\\r\\n` +\n ` ${c}/ ${b}~-._~-._ / .__..--${c}~-${l}---._\\r\\n` +\n `${c} \\\\_____(_${b};-._\\\\. _.-~_/${c} ~)${l}.. . \\\\\\r\\n` +\n `${l} /(_____ ${b}\\\\\\`--...--~_.-~${c}______..-+${l}_______)\\r\\n` +\n `${l} .(_________/${b}\\`--...--~/${l} _/ ${h} ${b}/\\\\\\r\\n` +\n `${b} /-._${h} \\\\_ ${l}(___./_..-~${h}__.....${b}__..-~./\\r\\n` +\n `${b} \\`-._~-._${h} ~\\\\--------~ .-~${b}_..__.-~ _.-~\\r\\n` +\n `${b} ~-._~-._ ${h}~---------\\` ${b}/ .__..--~\\r\\n` +\n `${b} ~-._\\\\. _.-~_/\\r\\n` +\n `${b} \\\\\\`--...--~_.-~\\r\\n` +\n `${b} \\`--...--~${r}\\r\\n`)\n } else {\n this.emit('write', '\\x1b[31mmake: me a sandwich : Permission denied\\x1b[0m\\r\\n')\n }\n } else {\n this.emit('write', `\\x1b[31mmake: *** No rule to make target '${args.join(' ').toLowerCase()}'. Stop.\\x1b[0m\\r\\n`)\n }\n this.destroy()\n }\n },\n pwd: '/this/is/a/demo\\r\\n',\n cd: '\\x1b[38;5;239mNo directories to change to\\r\\n',\n whoami: `${window.navigator.userAgent}\\r\\n`,\n hostname: `${window.location.hostname}`,\n uname: 'ESPTerm Demo\\r\\n',\n mkdir: '\\x1b[38;5;239mDid not create a directory because this is a demo.\\r\\n',\n rm: '\\x1b[38;5;239mDid not delete anything because this is a demo.\\r\\n',\n cp: '\\x1b[38;5;239mNothing to copy because this is a demo.\\r\\n',\n mv: '\\x1b[38;5;239mNothing to move because this is a demo.\\r\\n',\n ln: '\\x1b[38;5;239mNothing to link because this is a demo.\\r\\n',\n touch: '\\x1b[38;5;239mNothing to touch\\r\\n',\n exit: '\\x1b[38;5;239mNowhere to go\\r\\n',\n github: class GoToGithub extends Process {\n run () {\n window.open('https://github.com/espterm/espterm-firmware')\n this.destroy()\n }\n }\n}\nlet autocompleteIndex = {\n 'local-echo': 'local-echo [--suppress-note]',\n theme: 'theme [n]',\n cursor: 'cursor [block|line|bar] [--steady]',\n sudo: 'sudo [command]'\n}\n\nclass DemoShell {\n constructor (terminal, printInfo) {\n this.terminal = terminal\n this.terminal.reset()\n this.parser = new ANSIParser((...args) => this.handleParsed(...args))\n this.history = []\n this.historyIndex = 0\n this.cursorPos = 0\n this.lastInputLength = 0\n this.child = null\n this.index = demoshIndex\n\n if (printInfo) this.run('info')\n else this.prompt()\n }\n write (text) {\n if (this.child) {\n if (text.codePointAt(0) === 3) this.child.destroy()\n else this.child.write(text)\n } else this.parser.write(text)\n }\n prompt (success = true) {\n if (this.terminal.cursor.x !== 0) this.terminal.write('\\x1b[m\\x1b[38;5;238m⏎\\r\\n')\n this.terminal.write('\\x1b[34;1mdemosh \\x1b[m')\n if (!success) this.terminal.write('\\x1b[31m')\n this.terminal.write('$ \\x1b[m')\n this.history.unshift('')\n this.cursorPos = 0\n\n this.setButtons()\n }\n copyFromHistoryIndex () {\n if (!this.historyIndex) return\n let current = this.history[this.historyIndex]\n this.history[0] = current\n this.historyIndex = 0\n }\n getCompleted (visual = false) {\n if (this.history[0]) {\n let input = this.history[0]\n let prefix = ''\n if (input.startsWith('sudo ')) {\n let newInput = input.replace(/^(sudo\\s+)+/, '')\n prefix = input.substr(0, input.length - newInput.length)\n input = newInput\n }\n for (let name in this.index) {\n if (name.startsWith(input) && name !== input) {\n if (visual && name in autocompleteIndex) return prefix + autocompleteIndex[name]\n return prefix + name\n }\n }\n return null\n }\n return null\n }\n handleParsed (action, ...args) {\n this.terminal.write(`\\x1b[${this.lastInputLength - this.cursorPos}P`)\n this.terminal.write('\\b\\x1b[P'.repeat(this.cursorPos))\n\n if (action === 'write') {\n this.copyFromHistoryIndex()\n this.history[0] = this.history[0].substr(0, this.cursorPos) + args[0] + this.history[0].substr(this.cursorPos)\n this.cursorPos++\n } else if (action === 'back') {\n this.copyFromHistoryIndex()\n this.history[0] = this.history[0].substr(0, this.cursorPos - 1) + this.history[0].substr(this.cursorPos)\n this.cursorPos--\n if (this.cursorPos < 0) this.cursorPos = 0\n } else if (action === 'tab') {\n let completed = this.getCompleted()\n if (completed) {\n this.history[0] = completed\n this.cursorPos = this.history[0].length\n }\n } else if (action === 'move-cursor-x') {\n this.cursorPos = Math.max(0, Math.min(this.history[this.historyIndex].length, this.cursorPos + args[0]))\n } else if (action === 'delete-line') {\n this.copyFromHistoryIndex()\n this.history[0] = ''\n this.cursorPos = 0\n } else if (action === 'delete-word') {\n this.copyFromHistoryIndex()\n let words = this.history[0].substr(0, this.cursorPos).split(' ')\n words.pop()\n this.history[0] = words.join(' ') + this.history[0].substr(this.cursorPos)\n this.cursorPos = words.join(' ').length\n } else if (action === 'move-cursor-y') {\n this.historyIndex -= args[0]\n if (this.historyIndex < 0) this.historyIndex = 0\n if (this.historyIndex >= this.history.length) this.historyIndex = this.history.length - 1\n this.cursorPos = this.history[this.historyIndex].length\n }\n\n this.terminal.write(this.history[this.historyIndex])\n this.terminal.write('\\b'.repeat(this.history[this.historyIndex].length))\n this.terminal.moveForward(this.cursorPos)\n\n this.lastInputLength = this.cursorPos\n\n let completed = this.getCompleted(true)\n if (this.historyIndex === 0 && completed && action !== 'return') {\n // show closest match faintly\n let rest = completed.substr(this.history[0].length)\n this.terminal.write(`\\x1b[2m${rest}\\x1b[m${'\\b'.repeat(rest.length)}`)\n this.lastInputLength += rest.length\n }\n\n if (action === 'return') {\n this.terminal.write('\\n')\n this.parse(this.history[this.historyIndex])\n }\n }\n parse (input) {\n if (input === 'help') input = 'info'\n // TODO: basic chaining (i.e. semicolon)\n if (input) this.run(input)\n else this.prompt()\n }\n run (command) {\n let parts = ['']\n\n let inQuote = false\n for (let character of command.trim()) {\n if (inQuote && character !== inQuote) {\n parts[parts.length - 1] += character\n } else if (inQuote) {\n inQuote = false\n } else if (character === '\"' || character === \"'\") {\n inQuote = character\n } else if (character.match(/\\s/)) {\n if (parts[parts.length - 1]) parts.push('')\n } else parts[parts.length - 1] += character\n }\n\n let name = parts.shift()\n\n if (name in this.index) {\n this.spawn(name, parts)\n } else {\n this.terminal.write(`demosh: Unknown command: ${name}\\r\\n`)\n this.prompt(false)\n }\n }\n spawn (name, args = []) {\n let Process = this.index[name]\n if (Process instanceof Function) {\n this.setButtons([])\n this.child = new Process(this)\n let write = data => this.terminal.write(data)\n let setButtons = buttons => this.setButtons(buttons)\n this.child.on('write', write)\n this.child.on('buttons', setButtons)\n this.child.on('exit', code => {\n if (this.child) {\n this.child.removeListener('write', write)\n this.child.removeListener('buttons', setButtons)\n }\n this.child = null\n this.prompt(!code)\n })\n this.child.run(...args)\n } else {\n this.terminal.write(Process)\n this.prompt()\n }\n }\n\n setButtons (buttons) {\n if (!buttons) {\n const shell = this\n let writeChars = chars => {\n let loop = () => {\n shell.write(chars[0])\n chars = chars.substr(1)\n if (chars) setTimeout(loop, 100)\n }\n setTimeout(loop, 200)\n }\n\n buttons = [\n {\n label: 'Open GitHub',\n action (shell) {\n if (shell.child) shell.child.destroy()\n writeChars('github\\r')\n }\n },\n {\n label: 'Help',\n action (shell) {\n if (shell.child) shell.child.destroy()\n writeChars('info\\r')\n }\n }\n ]\n }\n if (!buttons.length) buttons.push({ label: '', action () {} })\n this.buttons = buttons\n this.terminal.buttonLabels = buttons.map(x => x.label)\n }\n\n onButtonPress (index) {\n let button = this.buttons[index]\n if (!button) return\n button.action(this, this.terminal)\n }\n}\n\nwindow.demoInterface = module.exports = {\n input (data) {\n let type = data[0]\n let content = data.substr(1)\n\n if (type === 's') {\n this.shell.write(content)\n } else if (type === 'b') {\n let button = content.charCodeAt(0)\n this.shell.onButtonPress(button - 1)\n } else if (type === 'm' || type === 'p' || type === 'r') {\n let row = parse2B(content, 0)\n let column = parse2B(content, 2)\n let button = parse2B(content, 4)\n let modifiers = parse2B(content, 6)\n\n if (demoData.mouseReceiver) {\n if (type === 'm') demoData.mouseReceiver.mouseMove(column, row, button, modifiers)\n else if (type === 'p') demoData.mouseReceiver.mouseDown(column, row, button, modifiers)\n else if (type === 'r') demoData.mouseReceiver.mouseUp(column, row, button, modifiers)\n }\n }\n },\n didInit: false,\n init (screen) {\n if (this.didInit) return\n this.didInit = true\n this.terminal = new ScrollingTerminal(screen)\n this.shell = new DemoShell(this.terminal, true)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/demo.js","/*\n * Copyright (c) 2010 Tim Baumann\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// NOTE:\n// Extracted from ColorTriangle and\n// Converted to ES6 by MightyPork (2017)\n\n/*******************\n * Color conversion *\n *******************/\n\nconst M = Math\nconst TAU = 2 * M.PI\n\nexports.hue2rgb = function (v1, v2, h) {\n if (h < 0) h += 1\n if (h > 1) h -= 1\n\n if ((6 * h) < 1) return v1 + (v2 - v1) * 6 * h\n if ((2 * h) < 1) return v2\n if ((3 * h) < 2) return v1 + (v2 - v1) * ((2 / 3) - h) * 6\n return v1\n}\n\nexports.hsl2rgb = function (h, s, l) {\n h /= TAU\n let r, g, b\n\n if (s === 0) {\n r = g = b = l\n } else {\n let var_1, var_2\n\n if (l < 0.5) var_2 = l * (1 + s)\n else var_2 = (l + s) - (s * l)\n\n var_1 = 2 * l - var_2\n\n r = exports.hue2rgb(var_1, var_2, h + (1 / 3))\n g = exports.hue2rgb(var_1, var_2, h)\n b = exports.hue2rgb(var_1, var_2, h - (1 / 3))\n }\n return [r, g, b]\n}\n\nexports.rgb2hsl = function (r, g, b) {\n const min = M.min(r, g, b)\n const max = M.max(r, g, b)\n const d = max - min // delta\n\n let h, s, l\n\n l = (max + min) / 2\n\n if (d === 0) {\n // gray\n h = s = 0 // HSL results from 0 to 1\n } else {\n // chroma\n if (l < 0.5) s = d / (max + min)\n else s = d / (2 - max - min)\n\n const d_r = (((max - r) / 6) + (d / 2)) / d\n const d_g = (((max - g) / 6) + (d / 2)) / d\n const d_b = (((max - b) / 6) + (d / 2)) / d // deltas\n\n if (r === max) h = d_b - d_g\n else if (g === max) h = (1 / 3) + d_r - d_b\n else if (b === max) h = (2 / 3) + d_g - d_r\n\n if (h < 0) h += 1\n else if (h > 1) h -= 1\n }\n h *= TAU\n return [h, s, l]\n}\n\nexports.hex2rgb = function (hex) {\n const groups = hex.match(/^#([\\da-f]{3,6})$/i)\n if (groups) {\n hex = groups[1]\n const bytes = hex.length / 3\n const max = (16 ** bytes) - 1\n return [0, 1, 2].map(x => parseInt(hex.slice(x * bytes, (x + 1) * bytes), 16) / max)\n }\n return [0, 0, 0]\n}\n\nfunction pad (n) {\n return `00${n}`.substr(-2)\n}\n\nexports.rgb255ToHex = function (r, g, b) {\n return '#' + [r, g, b].map(x => pad(x.toString(16))).join('')\n}\n\nexports.rgb2hex = function (r, g, b) {\n return '#' + [r, g, b].map(x => pad(Math.round(x * 255).toString(16))).join('')\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/lib/color_utils.js","let data = require('locale-data')\n\nmodule.exports = function localize (key) {\n return data[key] || `?${key}?`\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/lang.js","require('./lib/polyfills')\nrequire('./modal')\nrequire('./notif')\nrequire('./appcommon')\ntry { require('./term/demo') } catch (err) {}\nrequire('./wifi')\n\nconst $ = require('./lib/chibi')\nconst { qs } = require('./utils')\n\n/* Export stuff to the global scope for inline scripts */\nwindow.termInit = require('./term')\nwindow.$ = $\nwindow.qs = qs\n\nwindow.themes = require('./term/themes')\n\nwindow.TermConf = require('./term_conf')\n\n\n\n// WEBPACK FOOTER //\n// ./js/index.js","/*! 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\n\n\n// WEBPACK FOOTER //\n// ./js/lib/polyfills.js","const $ = require('./lib/chibi')\nconst { mk, qs, qsa, cr } = require('./utils')\nconst modal = require('./modal')\nconst notify = require('./notif')\n\n/** Global generic init */\n$.ready(function () {\n // Opening menu on mobile / narrow screen\n function menuOpen () {\n $('#menu').toggleClass('expanded')\n }\n $('#brand')\n .on('click', menuOpen)\n .on('keypress', cr(menuOpen))\n\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 if ($(x).hasClass('d-expanded')) {\n $(x).removeClass('d-expanded')\n } else {\n $(x).toggleClass('expanded')\n }\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('wheel', 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.deltaY > 0) {\n val += step\n } else {\n val -= step\n }\n\n if (Number.isFinite(min)) val = Math.max(val, +min)\n if (Number.isFinite(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 = window.location.search.indexOf('err=')\n if (errAt !== -1 && qs('.Box.errors')) {\n let errs = decodeURIComponent(window.location.search.substr(errAt + 4)).split(',')\n let humanReadableErrors = []\n errs.forEach(function (er) {\n let lbls = qsa('label[for=\"' + er + '\"]')\n if (lbls) {\n for (let i = 0; i < lbls.length; i++) {\n let lbl = lbls[i]\n lbl.classList.add('error')\n if (i === 0) humanReadableErrors.push(lbl.childNodes[0].textContent.trim().replace(/: ?$/, ''))\n }\n } else {\n humanReadableErrors.push(er)\n }\n })\n\n qs('.Box.errors .list').innerHTML = humanReadableErrors.join(', ')\n qs('.Box.errors').classList.remove('hidden')\n }\n\n let msgAt = window.location.search.indexOf('msg=')\n if (msgAt !== -1 && qs('.Box.message')) {\n let msg = decodeURIComponent(window.location.search.substr(msgAt + 4))\n let box = qs('.Box.message')\n box.innerHTML = msg\n box.classList.remove('hidden')\n setTimeout(() => {\n box.classList.add('hiding')\n setTimeout(() => {\n box.classList.add('hidden')\n }, 1000)\n }, 2000)\n }\n\n modal.init()\n notify.init()\n\n // remove tabindices 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 window.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\nlet pageShown = false\n// reveal content on load\nfunction showPage () {\n pageShown = true\n $('#content').addClass('load')\n}\n// HACKITY HACK: fix this later\nwindow.showPage = showPage\n\n// Auto reveal pages other than the terminal (sets window.noAutoShow)\n$.ready(function () {\n if (window.noAutoShow === true) {\n setTimeout(function () {\n if (!pageShown) {\n let bnr = mk('P')\n bnr.id = 'load-failed'\n bnr.innerHTML =\n 'Server connection failed! Trying again' +\n '.'\n qs('#screen').appendChild(bnr)\n showPage()\n }\n }, 2000)\n } else {\n setTimeout(function () {\n showPage()\n }, 1)\n }\n})\n\n\n\n// WEBPACK FOOTER //\n// ./js/appcommon.js","const $ = require('./lib/chibi')\nconst { mk } = require('./utils')\nconst tr = require('./lang')\n\n{\n const w = window.WiFi = {}\n\n const authTypes = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2']\n let curSSID\n\n // Get XX % for a slider input\n function calc_dBm (inp) {\n return `+${(inp.value * 0.25).toFixed(2)} dBm`\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($.htmlEscape(name))\n const hasPassword = !!password\n\n // (the following is kind of confusing with the double-double negations,\n // but it works)\n $('#sta-nw .passwd').toggleClass('hidden', !hasPassword)\n $('#sta-nw .nopasswd').toggleClass('hidden', hasPassword)\n\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 5s 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 = !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((a, b) => b.rssi - a.rssi).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(`
${ap.rssi_perc}
`)\n .htmlAppend(`
${escapedSSID}
`)\n .htmlAppend(`
${authTypes[ap.enc]}
`)\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 = window.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 (window._demo) {\n onScan(window._demo_aps, 200)\n } else {\n $.get('http://' + window._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 = calc_dBm(inp)\n $(disp1).html(t)\n $(disp2).html(t)\n $(inp).on('input', function () {\n t = calc_dBm(inp)\n $(disp1).html(t)\n $(disp2).html(t)\n })\n })\n\n // Forget STA credentials\n $('#forget-sta').on('click', () => {\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}\n\n\n\n// WEBPACK FOOTER //\n// ./js/wifi.js"," 'WiFi Settings',\n\t'menu.cfg_network' => 'Network Settings',\n\t'menu.cfg_term' => 'Terminal Settings',\n\t'menu.about' => 'About ESPTerm',\n\t'menu.help' => 'Quick Reference',\n\t'menu.term' => 'Back to Terminal',\n\t'menu.cfg_system' => 'System Settings',\n\t'menu.cfg_wifi_conn' => 'Connecting to Network',\n\t'menu.settings' => 'Settings',\n\n\t// Terminal page\n\n\t'title.term' => 'Terminal', // page title of the terminal page\n\n\t'term_nav.fullscreen' => 'Fullscreen',\n\t'term_nav.config' => 'Config',\n\t'term_nav.wifi' => 'WiFi',\n\t'term_nav.help' => 'Help',\n\t'term_nav.about' => 'About',\n\t'term_nav.paste' => 'Paste',\n\t'term_nav.upload' => 'Upload',\n\t'term_nav.keybd' => 'Keyboard',\n\t'term_nav.paste_prompt' => 'Paste text to send:',\n\n\t'term_conn.connecting' => 'Connecting',\n\t'term_conn.waiting_content' => 'Waiting for content',\n\t'term_conn.disconnected' => 'Disconnected',\n\t'term_conn.waiting_server' => 'Waiting for server',\n\t'term_conn.reconnecting' => 'Reconnecting',\n\n\t// Terminal settings page\n\n\t'term.defaults' => 'Initial Settings',\n\t'term.expert' => 'Expert Options',\n\t'term.explain_initials' => '\n\t\tThose are the initial settings used after ESPTerm powers on, \n\t\tor when the screen reset command is received (\\ec).\n\t\tThey can be changed by the terminal application using escape sequences.\n\t\t',\n\t'term.explain_expert' => '\n\t\tThose are advanced config options that usually don\\'t need to be changed.\n\t\tEdit them only if you know what you\\'re doing.',\n\n\t'term.example' => 'Default colors preview',\n\n\t'term.explain_scheme' => '\n\t\tTo select default text and background color, click on the\n\t\tpreview palette. Alternatively, use numbers 0-15 for theme colors,\n\t\t16-255 for standard colors and hex (#FFFFFF) for True Color (24-bit).\n\t\t',\n\n\t'term.fgbg_presets' => 'Defaults Presets',\n\t'term.color_scheme' => 'Color Scheme',\n\t'term.reset_screen' => 'Reset screen & parser',\n\t'term.term_title' => 'Header Text',\n\t'term.term_width' => 'Width',\n\t'term.term_height' => 'Height',\n\t'term.buttons' => 'Button Labels',\n\t'term.theme' => 'Color Palette',\n\t'term.cursor_shape' => 'Cursor Style',\n\t'term.parser_tout_ms' => 'Parser Timeout',\n\t'term.display_tout_ms' => 'Redraw Delay',\n\t'term.display_cooldown_ms' => 'Redraw Cooldown',\n\t'term.allow_decopt_12' => 'Allow \\e?12h/l',\n\t'term.fn_alt_mode' => 'SS3 Fn keys',\n\t'term.show_config_links' => 'Show nav links',\n\t'term.show_buttons' => 'Show buttons',\n\t'term.loopback' => 'Local Echo (SRM)',\n\t'term.crlf_mode' => 'Enter = CR+LF (LNM)',\n\t'term.want_all_fn' => 'Capture F5, F11, F12',\n\t'term.button_msgs' => 'Button codes
(ASCII, dec, CSV)',\n\t'term.color_fg' => 'Default Fg.',\n\t'term.color_bg' => 'Default Bg.',\n\t'term.color_fg_prev' => 'Foreground',\n\t'term.color_bg_prev' => 'Background',\n\t'term.colors_preview' => '',\n\t'term.debugbar' => 'Debug internal state',\n\t'term.ascii_debug' => 'Display control codes',\n\n\t'cursor.block_blink' => 'Block, blinking',\n 'cursor.block_steady' => 'Block, steady',\n 'cursor.underline_blink' => 'Underline, blinking',\n 'cursor.underline_steady' => 'Underline, steady',\n 'cursor.bar_blink' => 'I-bar, blinking',\n 'cursor.bar_steady' => 'I-bar, steady',\n\n\t// Text upload dialog\n\n\t'upload.title' => 'Text Upload',\n\t'upload.prompt' => 'Load a text file:',\n\t'upload.endings' => 'Line endings:',\n\t'upload.endings.cr' => 'CR (Enter key)',\n\t'upload.endings.crlf' => 'CR LF (Windows)',\n\t'upload.endings.lf' => 'LF (Linux)',\n\t'upload.chunk_delay' => 'Chunk delay (ms):',\n\t'upload.chunk_size' => 'Chunk size (0=line):',\n\t'upload.progress' => 'Upload:',\n\n\t// Network config page\n\n\t'net.explain_sta' => '\n\t\tSwitch off Dynamic IP to configure the static IP address.',\n\n\t'net.explain_ap' => '\n\t\tThose settings affect the built-in DHCP server in AP mode.',\n\n\t'net.ap_dhcp_time' => 'Lease time',\n\t'net.ap_dhcp_start' => 'Pool start IP',\n\t'net.ap_dhcp_end' => 'Pool end IP',\n\t'net.ap_addr_ip' => 'Own IP address',\n\t'net.ap_addr_mask' => 'Subnet mask',\n\n\t'net.sta_dhcp_enable' => 'Use dynamic IP',\n\t'net.sta_addr_ip' => 'ESPTerm static IP',\n\t'net.sta_addr_mask' => 'Subnet mask',\n\t'net.sta_addr_gw' => 'Gateway IP',\n\n\t'net.ap' => 'DHCP Server (AP)',\n\t'net.sta' => 'DHCP Client (Station)',\n\t'net.sta_mac' => 'Station MAC',\n\t'net.ap_mac' => 'AP MAC',\n\t'net.details' => 'MAC addresses',\n\n\t// Wifi config page\n\n\t'wifi.ap' => 'Built-in Access Point',\n\t'wifi.sta' => 'Join Existing Network',\n\n\t'wifi.enable' => 'Enabled',\n\t'wifi.tpw' => 'Transmit power',\n\t'wifi.ap_channel' => 'Channel',\n\t'wifi.ap_ssid' => 'AP SSID',\n\t'wifi.ap_password' => 'Password',\n\t'wifi.ap_hidden' => 'Hide SSID',\n\t'wifi.sta_info' => 'Selected',\n\n\t'wifi.not_conn' => 'Not connected.',\n\t'wifi.sta_none' => 'None',\n\t'wifi.sta_active_pw' => '🔒 Password saved',\n\t'wifi.sta_active_nopw' => '🔓 Open access',\n\t'wifi.connected_ip_is' => 'Connected, IP is ',\n\t'wifi.sta_password' => 'Password:',\n\n\t'wifi.scanning' => 'Scanning',\n\t'wifi.scan_now' => 'Click here to start scanning!',\n\t'wifi.cant_scan_no_sta' => 'Click here to enable client mode and start scanning!',\n\t'wifi.select_ssid' => 'Available networks:',\n\t'wifi.enter_passwd' => 'Enter password for \":ssid:\"',\n\t'wifi.sta_explain' => 'After selecting a network, press Apply to connect.',\n\n\t// Wifi connecting status page\n\n\t'wificonn.status' => 'Status:',\n\t'wificonn.back_to_config' => 'Back to WiFi config',\n\t'wificonn.telemetry_lost' => 'Telemetry lost; something went wrong, or your device disconnected.',\n\t'wificonn.explain_android_sucks' => '\n\t\tIf you\\'re configuring ESPTerm via a smartphone, or were connected \n\t\tfrom another external network, your device may lose connection and \n\t\tthis progress indicator won\\'t work. Please wait a while (~ 15 seconds), \n\t\tthen check if the connection succeeded.',\n\n\t'wificonn.explain_reset' => '\n\t\tTo force enable the built-in AP, hold the BOOT button until the blue LED \n\t\tstarts flashing. Hold the button longer (until the LED flashes rapidly) \n\t\tfor a \"factory reset\".',\n\n\t'wificonn.disabled' =>\"Station mode is disabled.\",\n\t'wificonn.idle' =>\"Idle, not connected and has no IP.\",\n\t'wificonn.success' => \"Connected! Received IP \",\n\t'wificonn.working' => \"Connecting to selected AP\",\n\t'wificonn.fail' => \"Connection failed, check settings & try again. Cause: \",\n\n\t// Access restrictions form\n\n\t'pwlock.title' => 'Access Restrictions',\n\t'pwlock.explain' => '\n\t\tSome parts, or all of the web interface can be protected by a password prompt.\n\t\tLeave the new password fields empty if you do not wish to change it.
\n\t\tThe default password is \"%def_access_pw%\".\n\t',\n\t'pwlock.region' => 'Protected pages',\n\t'pwlock.region.none' => 'None, all open',\n\t'pwlock.region.settings_noterm' => 'WiFi, Net & System settings',\n\t'pwlock.region.settings' => 'All settings pages',\n\t'pwlock.region.menus' => 'This entire menu section',\n\t'pwlock.region.all' => 'Everything, even terminal',\n\t'pwlock.new_access_pw' => 'New password',\n\t'pwlock.new_access_pw2' => 'Repeat',\n\t'pwlock.admin_pw' => 'Admin password',\n\t'pwlock.access_name' => 'Username',\n\n\t// Setting admin password\n\n\t'adminpw.title' => 'Change Admin Password',\n\t'adminpw.explain' =>\n\t\t'\n\t\tThe \"admin password\" is used to manipulate the stored default settings \n\t\tand to change access restrictions. This password is not saved as part \n\t\tof the main config, i.e. using save / restore does not affect this \n\t\tpassword. When the admin password is forgotten, the easiest way to \n\t\tre-gain access is to wipe and re-flash the chip.
\n\t\tThe default admin password is \"%def_admin_pw%\".\n\t\t',\n\t'adminpw.new_admin_pw' => 'New admin password',\n\t'adminpw.new_admin_pw2' => 'Repeat',\n\t'adminpw.old_admin_pw' => 'Old admin password',\n\n\t// Persist form\n\n\t'persist.title' => 'Save & Restore',\n\t'persist.explain' => '\n\t\tESPTerm saves all settings in Flash. The active settings can be copied to\n\t\tthe \"defaults area\" and restored later using the blue button below.\n\t\t',\n\t'persist.confirm_restore' => 'Restore all settings to their default values?',\n\t'persist.confirm_restore_hard' =>\n\t\t'Restore to firmware default settings? This will reset ' .\n\t\t'all active settings and switch to AP mode with the default SSID.',\n\t'persist.confirm_store_defaults' =>\n\t\t'Enter admin password to confirm you want to overwrite the default settings.',\n\t'persist.password' => 'Admin password:',\n\t'persist.restore_defaults' => 'Reset to saved defaults',\n\t'persist.write_defaults' => 'Save active settings as defaults',\n\t'persist.restore_hard' => 'Reset active settings to factory defaults',\n\t'persist.restore_hard_explain' =>\n\t\t'(This clears the WiFi config! Does not affect saved defaults or admin password.)',\n\n\t// UART settings form\n\n\t'uart.title' => 'Serial Port Parameters',\n\t'uart.explain' => '\n\t\tThis form controls the communication UART. The debug UART is fixed\n\t\tat 115.200 baud, one stop-bit and no parity.\n\t\t',\n\t'uart.baud' => 'Baud rate',\n\t'uart.parity' => 'Parity',\n\t'uart.parity.none' => 'None',\n\t'uart.parity.odd' => 'Odd',\n\t'uart.parity.even' => 'Even',\n\t'uart.stop_bits' => 'Stop-bits',\n\t'uart.stop_bits.one' => 'One',\n\t'uart.stop_bits.one_and_half' => 'One and half',\n\t'uart.stop_bits.two' => 'Two',\n\n\t// HW tuning form\n\n\t'hwtuning.title' => 'Hardware Tuning',\n\t'hwtuning.explain' => '\n\t\tESP8266 can be overclocked from 80 MHz to 160 MHz. This will make \n\t\tit more responsive and allow faster screen updates at the expense of slightly \n\t\thigher power consumption. This can also make it more susceptible to interference.\n\t\tUse with care.\n\t\t',\n\t'hwtuning.overclock' => 'Overclock to 160MHz',\n\n\t// Generic button / dialog labels\n\n\t'apply' => 'Apply!',\n\t'start' => 'Start',\n\t'cancel' => 'Cancel',\n\t'enabled' => 'Enabled',\n\t'disabled' => 'Disabled',\n\t'yes' => 'Yes',\n\t'no' => 'No',\n\t'confirm' => 'OK',\n\t'copy' => 'Copy',\n\t'form_errors' => 'Validation errors for:',\n];\n\n\n\n// WEBPACK FOOTER //\n// ./lang/en.php","const { qs, mk } = require('../utils')\nconst localize = require('../lang')\nconst Notify = require('../notif')\nconst TermScreen = require('./screen')\nconst TermConnection = require('./connection')\nconst TermInput = require('./input')\nconst TermUpload = require('./upload')\nconst initSoftKeyboard = require('./soft_keyboard')\nconst attachDebugScreen = require('./debug_screen')\nconst initButtons = require('./buttons')\n\n/** Init the terminal sub-module - called from HTML */\nmodule.exports = function (opts) {\n const screen = new TermScreen()\n const conn = new TermConnection(screen)\n const input = TermInput(conn, screen)\n const termUpload = TermUpload(conn, input, screen)\n screen.input = input\n screen.conn = conn\n input.termUpload = termUpload\n\n const buttons = initButtons(input)\n screen.on('button-labels', labels => {\n // TODO: don't use pointers for this\n buttons.labels.splice(0, buttons.labels.length, ...labels)\n buttons.update()\n })\n\n let showSplashTimeout = null\n let showSplash = (obj, delay = 250) => {\n clearTimeout(showSplashTimeout)\n showSplashTimeout = setTimeout(() => {\n screen.window.statusScreen = obj\n }, delay)\n }\n\n conn.on('open', () => {\n // console.log('*open')\n showSplash({ title: localize('term_conn.connecting'), loading: true })\n })\n conn.on('connect', () => {\n // console.log('*connect')\n showSplash({ title: localize('term_conn.waiting_content'), loading: true })\n })\n conn.on('load', () => {\n // console.log('*load')\n clearTimeout(showSplashTimeout)\n if (screen.window.statusScreen) screen.window.statusScreen = null\n })\n conn.on('disconnect', () => {\n // console.log('*disconnect')\n showSplash({ title: localize('term_conn.disconnected') }, 500)\n screen.screen = []\n screen.screenFG = []\n screen.screenBG = []\n screen.screenAttrs = []\n })\n conn.on('silence', () => {\n // console.log('*silence')\n showSplash({ title: localize('term_conn.waiting_server'), loading: true }, 0)\n })\n // conn.on('ping-fail', () => { screen.window.statusScreen = { title: 'Disconnected' } })\n conn.on('ping-success', () => {\n // console.log('*ping-success')\n showSplash({ title: localize('term_conn.reconnecting'), loading: true }, 0)\n })\n\n conn.init()\n input.init(opts)\n termUpload.init()\n Notify.init()\n\n window.onerror = function (errorMsg, file, line, col) {\n Notify.show(`JS ERROR!
${errorMsg}
at ${file}:${line}:${col}`, 10000, true)\n return false\n }\n\n qs('#screen').appendChild(screen.canvas)\n\n initSoftKeyboard(screen, input)\n if (attachDebugScreen) attachDebugScreen(screen)\n\n let fullscreenIcon = {} // dummy\n let isFullscreen = false\n let properFullscreen = false\n let fitScreen = false\n let screenPadding = screen.window.padding\n let fitScreenIfNeeded = function fitScreenIfNeeded () {\n if (isFullscreen) {\n fullscreenIcon.className = 'icn-resize-small'\n if (properFullscreen) {\n screen.window.fitIntoWidth = window.screen.width\n screen.window.fitIntoHeight = window.screen.height\n screen.window.padding = 0\n } else {\n screen.window.fitIntoWidth = window.innerWidth\n if (qs('#term-nav').classList.contains('hidden')) {\n screen.window.fitIntoHeight = window.innerHeight\n } else {\n screen.window.fitIntoHeight = window.innerHeight - 24\n }\n screen.window.padding = 0\n }\n } else {\n fullscreenIcon.className = 'icn-resize-full'\n screen.window.fitIntoWidth = fitScreen ? window.innerWidth - 4 : 0\n screen.window.fitIntoHeight = fitScreen ? window.innerHeight : 0\n screen.window.padding = screenPadding\n }\n }\n fitScreenIfNeeded()\n window.addEventListener('resize', fitScreenIfNeeded)\n\n let 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\n qs('#term-fit-screen').addEventListener('click', function () {\n toggleFitScreen()\n return false\n })\n\n // add fullscreen mode & button\n if (window.Element.prototype.requestFullscreen || window.Element.prototype.webkitRequestFullscreen) {\n properFullscreen = true\n\n let checkForFullscreen = function () {\n // document.fullscreenElement is not really supported yet, so here's a hack\n if (isFullscreen && (window.innerWidth !== window.screen.width || window.innerHeight !== window.screen.height)) {\n isFullscreen = false\n fitScreenIfNeeded()\n }\n }\n setInterval(checkForFullscreen, 500)\n }\n\n // (why are the buttons anchors?)\n let button = mk('a')\n button.id = 'fullscreen-button'\n button.href = '#'\n button.addEventListener('click', e => {\n e.preventDefault()\n\n if (document.body.classList.contains('pseudo-fullscreen')) {\n document.body.classList.remove('pseudo-fullscreen')\n isFullscreen = false\n fitScreenIfNeeded()\n return\n }\n\n isFullscreen = true\n fitScreenIfNeeded()\n screen.updateSize()\n\n if (properFullscreen) {\n if (screen.canvas.requestFullscreen) screen.canvas.requestFullscreen()\n else screen.canvas.webkitRequestFullscreen()\n } else {\n document.body.classList.add('pseudo-fullscreen')\n }\n })\n fullscreenIcon = mk('i')\n fullscreenIcon.className = 'icn-resize-full'\n button.appendChild(fullscreenIcon)\n let span = mk('span')\n span.textContent = localize('term_nav.fullscreen')\n button.appendChild(span)\n qs('#term-nav').insertBefore(button, qs('#term-nav').firstChild)\n\n // for debugging\n window.termScreen = screen\n window.conn = conn\n window.input = input\n window.termUpl = termUpload\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/index.js","const EventEmitter = require('events')\nconst $ = require('../lib/chibi')\nconst { mk, qs } = require('../utils')\nconst notify = require('../notif')\nconst ScreenParser = require('./screen_parser')\nconst ScreenRenderer = require('./screen_renderer')\n\nmodule.exports = class TermScreen extends EventEmitter {\n constructor () {\n super()\n\n this.canvas = mk('canvas')\n this.ctx = this.canvas.getContext('2d')\n\n this.parser = new ScreenParser(this)\n this.renderer = new ScreenRenderer(this)\n\n // debug screen handle\n this._debug = null\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 // dummy. Handle for Input\n this.input = new Proxy({}, {\n get () {\n return () => console.warn('TermScreen#input not set!')\n }\n })\n // dummy. Handle for Conn\n this.conn = new Proxy({}, {\n get () {\n return () => console.warn('TermScreen#conn not set!')\n },\n set (a, b) {\n return () => console.warn('TermScreen#conn not set!')\n }\n })\n\n this.cursor = {\n x: 0,\n y: 0,\n blinking: true,\n visible: true,\n hanging: false,\n style: 'block'\n }\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 padding: 6,\n gridScaleX: 1.0,\n gridScaleY: 1.2,\n fitIntoWidth: 0,\n fitIntoHeight: 0,\n debug: false,\n graphics: 0,\n statusScreen: null\n }\n\n // scaling caused by fitIntoWidth/fitIntoHeight\n this._windowScale = 1\n\n // actual padding, as it may be disabled by fullscreen mode etc.\n this._padding = 0\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 padding: 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 // selection start and end (x, y) tuples\n start: [0, 0],\n end: [0, 0]\n }\n\n // mouse features\n this.mouseMode = { clicks: false, movement: false }\n\n // make writing to window update size and draw\n const self = this\n this.window = new Proxy(this._window, {\n set (target, key, value, receiver) {\n if (target[key] !== value) {\n target[key] = value\n self.scheduleSizeUpdate()\n self.renderer.scheduleDraw(`window:${key}=${value}`)\n self.emit(`update-window:${key}`, value)\n }\n return true\n }\n })\n\n this.bracketedPaste = false\n this.blinkingCellCount = 0\n this.reverseVideo = false\n\n this.screen = []\n this.screenFG = []\n this.screenBG = []\n this.screenAttrs = []\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, true)\n this.renderer.scheduleDraw('select-start')\n }\n\n let selectMove = (x, y) => {\n if (!selecting) return\n this.selection.end = this.screenToGrid(x, y, true)\n this.renderer.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, true)\n this.renderer.scheduleDraw('select-end')\n Object.assign(this.selection, this.getNormalizedSelection())\n }\n\n // bind event listeners\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 this.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 // touch event listeners\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 }, { passive: true })\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 // selection ended; show touch select menu\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 && !this.mouseMode.clicks) {\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.renderer.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 this.input.onMouseMove(...this.screenToGrid(e.offsetX, e.offsetY))\n }\n })\n\n this.canvas.addEventListener('mouseup', e => {\n if (!selecting) {\n this.input.onMouseUp(...this.screenToGrid(e.offsetX, e.offsetY),\n e.button + 1)\n }\n })\n\n let aggregateWheelDelta = 0\n this.canvas.addEventListener('wheel', e => {\n if (this.mouseMode.clicks) {\n if (Math.abs(e.wheelDeltaY) === 120) {\n // mouse wheel scrolling\n this.input.onMouseWheel(...this.screenToGrid(e.offsetX, e.offsetY), e.deltaY > 0 ? 1 : -1)\n } else {\n // smooth scrolling\n aggregateWheelDelta -= e.wheelDeltaY\n if (Math.abs(aggregateWheelDelta) >= 40) {\n this.input.onMouseWheel(...this.screenToGrid(e.offsetX, e.offsetY), aggregateWheelDelta > 0 ? 1 : -1)\n aggregateWheelDelta = 0\n }\n }\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\n /**\n * Schedule a size update in the next millisecond\n */\n scheduleSizeUpdate () {\n clearTimeout(this._scheduledSizeUpdate)\n this._scheduledSizeUpdate = setTimeout(() => this.updateSize(), 1)\n }\n\n /**\n * Returns a CSS font string with this TermScreen's font settings and the\n * font modifiers.\n * @param {Object} modifiers\n * @param {string} [modifiers.style] - the font style\n * @param {string} [modifiers.weight] - the font weight\n * @returns {string} a CSS font string\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 /**\n * Converts screen coordinates to grid coordinates.\n * @param {number} x - x in pixels\n * @param {number} y - y in pixels\n * @param {boolean} rounded - whether to round the coord, used for select highlighting\n * @returns {number[]} a tuple of (x, y) in cells\n */\n screenToGrid (x, y, rounded = false) {\n let cellSize = this.getCellSize()\n\n x = x / this._windowScale - this._padding\n y = y / this._windowScale - this._padding\n x = Math.floor((x + (rounded ? cellSize.width / 2 : 0)) / cellSize.width)\n y = Math.floor(y / cellSize.height)\n x = Math.max(0, Math.min(this.window.width - 1, x))\n y = Math.max(0, Math.min(this.window.height - 1, y))\n\n return [x, y]\n }\n\n /**\n * Converts grid coordinates to screen coordinates.\n * @param {number} x - x in cells\n * @param {number} y - y in cells\n * @param {boolean} [withScale] - when true, will apply window scale\n * @returns {number[]} a tuple of (x, y) in pixels\n */\n gridToScreen (x, y, withScale = false) {\n let cellSize = this.getCellSize()\n\n return [x * cellSize.width, y * cellSize.height].map(v => this._padding + (withScale ? v * this._windowScale : v))\n }\n\n /**\n * The character size, used for calculating the cell size. The space character\n * is used for measuring.\n * @returns {Object} the character size with `width` and `height` in pixels\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 /**\n * The cell size, which is the character size multiplied by the grid scale.\n * @returns {Object} the cell size with `width` and `height` in pixels\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 /**\n * Updates the canvas size if it changed\n */\n updateSize () {\n // see below (this is just updating it)\n this._window.devicePixelRatio = Math.ceil(this._windowScale * (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 fitIntoWidth,\n fitIntoHeight,\n padding\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 let originalWidth = realWidth\n\n if (fitIntoWidth && fitIntoHeight) {\n let terminalAspect = realWidth / realHeight\n let fitAspect = fitIntoWidth / fitIntoHeight\n\n if (terminalAspect < fitAspect) {\n // align heights\n realHeight = fitIntoHeight - 2 * padding\n realWidth = realHeight * terminalAspect\n } else {\n // align widths\n realWidth = fitIntoWidth - 2 * padding\n realHeight = realWidth / terminalAspect\n }\n }\n\n // store new window scale\n this._windowScale = realWidth / originalWidth\n\n realWidth += 2 * padding\n realHeight += 2 * padding\n\n // store padding\n this._padding = padding * (originalWidth / realWidth)\n\n // the DPR must be rounded to a very nice value to prevent gaps between cells\n let devicePixelRatio = this._window.devicePixelRatio = Math.ceil(this._windowScale * (window.devicePixelRatio || 1))\n\n this.canvas.width = (width * cellSize.width + 2 * Math.round(this._padding)) * devicePixelRatio\n this.canvas.style.width = `${realWidth}px`\n this.canvas.height = (height * cellSize.height + 2 * Math.round(this._padding)) * devicePixelRatio\n this.canvas.style.height = `${realHeight}px`\n\n // the screen has been cleared (by changing canvas width)\n this.renderer.resetDrawn()\n\n // draw immediately; the canvas shouldn't flash\n this.renderer.draw('update-size')\n }\n }\n\n /**\n * Returns a normalized version of the current selection, such that `start`\n * is always before `end`.\n * @returns {Object} the normalized selection, with `start` and `end`\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 /**\n * Returns whether or not a given cell is in the current selection.\n * @param {number} col - the column (x)\n * @param {number} line - the line (y)\n * @returns {boolean}\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 /**\n * Sweeps for selected cells and joins them in a multiline string.\n * @returns {string} the selection\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 /**\n * Copies the selection to clipboard and creates a notification balloon.\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 /**\n * Shows an actual notification (if possible) or a notification balloon.\n * @param {string} text - the notification content\n */\n showNotification (text) {\n console.info(`Notification: ${text}`)\n if (window.Notification && window.Notification.permission === 'granted') {\n let notification = new window.Notification('ESPTerm', {\n body: text\n })\n notification.addEventListener('click', () => window.focus())\n } else {\n if (window.Notification && window.Notification.permission !== 'denied') {\n window.Notification.requestPermission()\n } else {\n // Fallback using the built-in notification balloon\n notify.show(text)\n }\n }\n }\n\n /**\n * Creates a beep sound.\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 if (!this._convolver) {\n this._convolver = audioCtx.createConvolver()\n let impulseLength = audioCtx.sampleRate * 0.8\n let impulse = audioCtx.createBuffer(2, impulseLength, audioCtx.sampleRate)\n for (let i = 0; i < impulseLength; i++) {\n impulse.getChannelData(0)[i] = (1 - i / impulseLength) ** (7 + Math.random())\n impulse.getChannelData(1)[i] = (1 - i / impulseLength) ** (7 + Math.random())\n }\n this._convolver.buffer = impulse\n this._convolver.connect(audioCtx.destination)\n }\n\n // main beep\n const mainOsc = audioCtx.createOscillator()\n const mainGain = audioCtx.createGain()\n mainOsc.connect(mainGain)\n mainGain.gain.value = 4\n mainOsc.frequency.value = 750\n mainOsc.type = 'sine'\n\n // surrogate beep (making it sound like 'oops')\n const surrOsc = audioCtx.createOscillator()\n const surrGain = audioCtx.createGain()\n surrOsc.connect(surrGain)\n surrGain.gain.value = 2\n surrOsc.frequency.value = 400\n surrOsc.type = 'sine'\n\n mainGain.connect(this._convolver)\n surrGain.connect(this._convolver)\n\n let startTime = audioCtx.currentTime\n mainOsc.start()\n mainOsc.stop(startTime + 0.5)\n surrOsc.start(startTime + 0.05)\n surrOsc.stop(startTime + 0.8)\n\n let loop = function () {\n if (audioCtx.currentTime < startTime + 0.8) window.requestAnimationFrame(loop)\n mainGain.gain.value *= 0.8\n surrGain.gain.value *= 0.8\n }\n loop()\n }\n\n load (...args) {\n this.parser.load(...args)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/screen.js","const $ = require('../lib/chibi')\nconst { qs } = require('../utils')\n\n// constants for decoding the update blob\nconst SEQ_SKIP = 1\nconst SEQ_REPEAT = 2\nconst SEQ_SET_COLORS = 3\nconst SEQ_SET_ATTRS = 4\nconst SEQ_SET_FG = 5\nconst SEQ_SET_BG = 6\nconst SEQ_SET_ATTR_0 = 7\n\nfunction du (str) {\n let num = str.codePointAt(0)\n if (num > 0xDFFF) num -= 0x800\n return num - 1\n}\n\n/* eslint-disable no-multi-spaces */\nconst TOPIC_SCREEN_OPTS = 'O'\nconst TOPIC_CONTENT = 'S'\nconst TOPIC_TITLE = 'T'\nconst TOPIC_BUTTONS = 'B'\nconst TOPIC_CURSOR = 'C'\nconst TOPIC_INTERNAL = 'D'\nconst TOPIC_BELL = '!'\n\nconst OPT_CURSOR_VISIBLE = (1 << 0)\nconst OPT_DEBUGBAR = (1 << 1)\nconst OPT_CURSORS_ALT_MODE = (1 << 2)\nconst OPT_NUMPAD_ALT_MODE = (1 << 3)\nconst OPT_FN_ALT_MODE = (1 << 4)\nconst OPT_CLICK_TRACKING = (1 << 5)\nconst OPT_MOVE_TRACKING = (1 << 6)\nconst OPT_SHOW_BUTTONS = (1 << 7)\nconst OPT_SHOW_CONFIG_LINKS = (1 << 8)\n// const OPT_CURSOR_SHAPE = (7 << 9)\nconst OPT_CRLF_MODE = (1 << 12)\nconst OPT_BRACKETED_PASTE = (1 << 13)\nconst OPT_REVERSE_VIDEO = (1 << 14)\n\nconst ATTR_FG = (1 << 0) // 1 if not using default background color (ignore cell bg) - color extension bit\nconst ATTR_BG = (1 << 1) // 1 if not using default foreground color (ignore cell fg) - color extension bit\nconst ATTR_BOLD = (1 << 2) // Bold font\nconst ATTR_UNDERLINE = (1 << 3) // Underline decoration\nconst ATTR_INVERSE = (1 << 4) // Invert colors - this is useful so we can clear then with SGR manipulation commands\nconst ATTR_BLINK = (1 << 5) // Blinking\nconst ATTR_ITALIC = (1 << 6) // Italic font\nconst ATTR_STRIKE = (1 << 7) // Strike-through decoration\nconst ATTR_OVERLINE = (1 << 8) // Over-line decoration\nconst ATTR_FAINT = (1 << 9) // Faint foreground color (reduced alpha)\nconst ATTR_FRAKTUR = (1 << 10) // Fraktur font (unicode substitution)\n/* eslint-enable no-multi-spaces */\n\nmodule.exports = class ScreenParser {\n constructor (screen) {\n this.screen = screen\n\n // true if TermScreen#load was called at least once\n this.contentLoaded = false\n }\n\n /**\n * Hide the warning message about failed data load\n */\n hideLoadFailedMsg () {\n if (!this.contentLoaded) {\n let errmsg = qs('#load-failed')\n if (errmsg) errmsg.parentNode.removeChild(errmsg)\n this.contentLoaded = true\n }\n }\n\n loadUpdate (str) {\n // console.log(`update ${str}`)\n // current index\n let ci = 0\n let strArray = Array.from ? Array.from(str) : str.split('')\n\n let text\n let resized = false\n const topics = du(strArray[ci++])\n // this.screen.cursor.hanging = !!(attributes & (1 << 1))\n\n while (ci < strArray.length) {\n const topic = strArray[ci++]\n\n if (topic === TOPIC_SCREEN_OPTS) {\n const newHeight = du(strArray[ci++])\n const newWidth = du(strArray[ci++])\n const theme = du(strArray[ci++])\n const defFg = (du(strArray[ci++]) & 0xFFFF) | ((du(strArray[ci++]) & 0xFFFF) << 16)\n const defBg = (du(strArray[ci++]) & 0xFFFF) | ((du(strArray[ci++]) & 0xFFFF) << 16)\n const attributes = du(strArray[ci++])\n\n // theming\n this.screen.renderer.loadTheme(theme)\n this.screen.renderer.setDefaultColors(defFg, defBg)\n\n // apply size\n resized = (this.screen.window.height !== newHeight) || (this.screen.window.width !== newWidth)\n this.screen.window.height = newHeight\n this.screen.window.width = newWidth\n\n // process attributes\n this.screen.cursor.visible = !!(attributes & OPT_CURSOR_VISIBLE)\n\n this.screen.input.setAlts(\n !!(attributes & OPT_CURSORS_ALT_MODE),\n !!(attributes & OPT_NUMPAD_ALT_MODE),\n !!(attributes & OPT_FN_ALT_MODE),\n !!(attributes & OPT_CRLF_MODE)\n )\n\n const trackMouseClicks = !!(attributes & OPT_CLICK_TRACKING)\n const trackMouseMovement = !!(attributes & OPT_MOVE_TRACKING)\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 // 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 const cursorStyle = cursorShape >> 1\n const cursorBlinking = !(cursorShape & 1)\n if (cursorStyle === 0) this.screen.cursor.style = 'block'\n else if (cursorStyle === 1) this.screen.cursor.style = 'line'\n else if (cursorStyle === 2) this.screen.cursor.style = 'bar'\n if (this.screen.cursor.blinking !== cursorBlinking) {\n this.screen.cursor.blinking = cursorBlinking\n this.screen.renderer.resetCursorBlink()\n }\n\n this.screen.input.setMouseMode(trackMouseClicks, trackMouseMovement)\n this.screen.selection.selectable = !trackMouseClicks && !trackMouseMovement\n $(this.screen.canvas).toggleClass('selectable', this.screen.selection.selectable)\n this.screen.mouseMode = {\n clicks: trackMouseClicks,\n movement: trackMouseMovement\n }\n\n const showButtons = !!(attributes & OPT_SHOW_BUTTONS)\n const showConfigLinks = !!(attributes & OPT_SHOW_CONFIG_LINKS)\n\n $('.x-term-conf-btn').toggleClass('hidden', !showConfigLinks)\n $('#action-buttons').toggleClass('hidden', !showButtons)\n\n this.screen.bracketedPaste = !!(attributes & OPT_BRACKETED_PASTE)\n this.screen.reverseVideo = !!(attributes & OPT_REVERSE_VIDEO)\n\n const debugbar = !!(attributes & OPT_DEBUGBAR)\n // TODO do something with debugbar\n\n } else if (topic === TOPIC_CURSOR) {\n\n // cursor position\n const cursorY = du(strArray[ci++])\n const cursorX = du(strArray[ci++])\n const hanging = du(strArray[ci++])\n\n const cursorMoved = (\n hanging !== this.screen.cursor.hanging ||\n cursorX !== this.screen.cursor.x ||\n cursorY !== this.screen.cursor.y)\n\n this.screen.cursor.x = cursorX\n this.screen.cursor.y = cursorY\n\n this.screen.cursor.hanging = !!hanging\n\n if (cursorMoved) {\n this.screen.renderer.resetCursorBlink()\n this.screen.emit('cursor-moved')\n }\n\n this.screen.renderer.scheduleDraw('cursor-moved')\n } else if (topic === TOPIC_TITLE) {\n\n // TODO optimize this\n text = ''\n while (ci < strArray.length) {\n let c = strArray[ci++]\n if (c !== '\\x01') {\n text += c\n } else {\n break\n }\n }\n\n qs('#screen-title').textContent = text\n if (text.length === 0) text = 'Terminal'\n qs('title').textContent = `${text} :: ESPTerm`\n\n } else if (topic === TOPIC_BUTTONS) {\n const count = du(strArray[ci++])\n\n let labels = []\n for (let j = 0; j < count; j++) {\n text = ''\n while (ci < strArray.length) {\n let c = strArray[ci++]\n if (c === '\\x01') break\n text += c\n }\n labels.push(text)\n }\n\n this.screen.emit('button-labels', labels)\n } else if (topic === TOPIC_BELL) {\n\n this.screen.beep()\n\n } else if (topic === TOPIC_INTERNAL) {\n // debug info\n\n const flags = du(strArray[ci++])\n const cursorAttrs = du(strArray[ci++])\n const regionStart = du(strArray[ci++])\n const regionEnd = du(strArray[ci++])\n const charsetGx = du(strArray[ci++])\n const charsetG0 = strArray[ci++]\n const charsetG1 = strArray[ci++]\n const freeHeap = du(strArray[ci++])\n const clientCount = du(strArray[ci++])\n\n this.screen.emit('internal', {\n flags,\n cursorAttrs,\n regionStart,\n regionEnd,\n charsetGx,\n charsetG0,\n charsetG1,\n freeHeap,\n clientCount\n })\n } else if (topic === TOPIC_CONTENT) {\n // set screen content\n\n const frameY = du(strArray[ci++])\n const frameX = du(strArray[ci++])\n const frameHeight = du(strArray[ci++])\n const frameWidth = du(strArray[ci++])\n\n if (this.screen._debug && this.screen.window.debug) {\n this.screen._debug.pushFrame([frameX, frameY, frameWidth, frameHeight])\n }\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 frameLength = frameWidth * frameHeight\n let screenLength = this.screen.window.width * this.screen.window.height\n\n if (resized) {\n this.screen.updateSize()\n this.screen.blinkingCellCount = 0\n this.screen.screen = new Array(screenLength).fill(' ')\n this.screen.screenFG = new Array(screenLength).fill(' ')\n this.screen.screenBG = new Array(screenLength).fill(' ')\n this.screen.screenAttrs = new Array(screenLength).fill(0)\n }\n\n const MASK_LINE_ATTR = ATTR_UNDERLINE | ATTR_OVERLINE | ATTR_STRIKE\n const MASK_BLINK = ATTR_BLINK\n\n let pushCell = () => {\n // Remove blink attribute if it wouldn't have any effect\n let myAttrs = attrs\n let hasFG = attrs & ATTR_FG\n let hasBG = attrs & ATTR_BG\n let cellFG = fg\n let cellBG = bg\n\n // use 0,0 if no fg/bg. this is to match back-end implementation\n // and allow leaving out fg/bg setting for cells with none\n if (!hasFG) cellFG = 0\n if (!hasBG) cellBG = 0\n\n if ((myAttrs & MASK_BLINK) !== 0 &&\n ((lastChar === ' ' && ((myAttrs & MASK_LINE_ATTR) === 0)) || // no line styles\n (fg === bg && hasFG && hasBG) // invisible text\n )\n ) {\n myAttrs ^= MASK_BLINK\n }\n // update blinking cells counter if blink state changed\n if ((this.screen.screenAttrs[cell] & MASK_BLINK) !== (myAttrs & MASK_BLINK)) {\n if (myAttrs & MASK_BLINK) this.screen.blinkingCellCount++\n else this.screen.blinkingCellCount--\n }\n\n let cellXInFrame = cell % frameWidth\n let cellYInFrame = Math.floor(cell / frameWidth)\n let index = (frameY + cellYInFrame) * this.screen.window.width + frameX + cellXInFrame\n\n // 8 dark system colors turn bright when bold\n if ((myAttrs & ATTR_BOLD) && !(myAttrs & ATTR_FAINT) && hasFG && cellFG < 8) {\n cellFG += 8\n }\n\n this.screen.screen[index] = lastChar\n this.screen.screenFG[index] = cellFG\n this.screen.screenBG[index] = cellBG\n this.screen.screenAttrs[index] = myAttrs\n }\n\n while (ci < strArray.length && cell < frameLength) {\n let character = strArray[ci++]\n let charCode = character.codePointAt(0)\n\n let data, count\n switch (charCode) {\n case SEQ_REPEAT:\n count = du(strArray[ci++])\n for (let j = 0; j < count; j++) {\n pushCell()\n if (++cell > frameLength) break\n }\n break\n\n case SEQ_SKIP:\n cell += du(strArray[ci++])\n break\n\n case SEQ_SET_COLORS:\n data = du(strArray[ci++])\n fg = data & 0xFF\n bg = (data >> 8) & 0xFF\n break\n\n case SEQ_SET_ATTRS:\n data = du(strArray[ci++])\n attrs = data & 0xFFFF\n break\n\n case SEQ_SET_ATTR_0:\n attrs = 0\n break\n\n case SEQ_SET_FG:\n data = du(strArray[ci++])\n if (data & 0x10000) {\n data &= 0xFFF\n data |= (du(strArray[ci++]) & 0xFFF) << 12\n data += 256\n }\n fg = data\n break\n\n case SEQ_SET_BG:\n data = du(strArray[ci++])\n if (data & 0x10000) {\n data &= 0xFFF\n data |= (du(strArray[ci++]) & 0xFFF) << 12\n data += 256\n }\n bg = data\n break\n\n default:\n if (charCode < 32) character = '\\ufffd'\n lastChar = character\n pushCell()\n cell++\n }\n }\n\n if (this.screen.window.debug) console.log(`Blinky cells: ${this.screen.blinkingCellCount}`)\n\n this.screen.renderer.scheduleDraw('load', 16)\n this.screen.conn.emit('load')\n\n }\n\n if ((topics & 0x3B) !== 0) this.hideLoadFailedMsg()\n }\n }\n\n /**\n * Loads a message from the server, and optionally a theme.\n * @param {string} str - the message\n */\n load (str) {\n const content = str.substr(1)\n\n // This is a good place for debugging the message\n // console.log(str)\n\n switch (str[0]) {\n case 'U':\n this.loadUpdate(content)\n break\n\n case 'G':\n this.screen.showNotification(content)\n break\n\n default:\n console.warn(`Bad data message type; ignoring.\\n${JSON.stringify(str)}`)\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/screen_parser.js","const { themes, buildColorTable, SELECTION_FG, SELECTION_BG } = require('./themes')\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// TODO do not repeat - this is also defined in screen_parser ...\n/* eslint-disable no-multi-spaces */\nconst ATTR_FG = (1 << 0) // 1 if not using default background color (ignore cell bg) - color extension bit\nconst ATTR_BG = (1 << 1) // 1 if not using default foreground color (ignore cell fg) - color extension bit\nconst ATTR_BOLD = (1 << 2) // Bold font\nconst ATTR_UNDERLINE = (1 << 3) // Underline decoration\nconst ATTR_INVERSE = (1 << 4) // Invert colors - this is useful so we can clear then with SGR manipulation commands\nconst ATTR_BLINK = (1 << 5) // Blinking\nconst ATTR_ITALIC = (1 << 6) // Italic font\nconst ATTR_STRIKE = (1 << 7) // Strike-through decoration\nconst ATTR_OVERLINE = (1 << 8) // Over-line decoration\nconst ATTR_FAINT = (1 << 9) // Faint foreground color (reduced alpha)\nconst ATTR_FRAKTUR = (1 << 10) // Fraktur font (unicode substitution)\n/* eslint-enable no-multi-spaces */\n\nmodule.exports = class ScreenRenderer {\n constructor (screen) {\n this.screen = screen\n this.ctx = screen.ctx\n\n this._palette = null // colors 0-15\n this.defaultBgNum = 0\n this.defaultFgNum = 7\n\n // 256color lookup table\n // should not be used to look up 0-15 (will return transparent)\n this.colorTable256 = buildColorTable()\n\n this.resetDrawn()\n\n this.blinkStyleOn = false\n this.blinkInterval = null\n this.cursorBlinkOn = false\n this.cursorBlinkInterval = null\n\n // start blink timers\n this.resetBlink()\n this.resetCursorBlink()\n }\n\n resetDrawn () {\n // used to determine if a cell should be redrawn; storing the current state\n // as it is on screen\n if (this.screen.window && this.screen.window.debug) {\n console.log('Resetting drawn screen')\n }\n this.drawnScreen = []\n this.drawnScreenFG = []\n this.drawnScreenBG = []\n this.drawnScreenAttrs = []\n this.drawnCursor = [-1, -1, '']\n }\n\n /**\n * The color palette. Should define 16 colors in an array.\n * @type {string[]}\n */\n get palette () {\n return this._palette || themes[0]\n }\n\n /** @type {string[]} */\n set palette (palette) {\n if (this._palette !== palette) {\n this._palette = palette\n this.resetDrawn()\n this.scheduleDraw('palette')\n }\n }\n\n loadTheme (i) {\n if (i in themes) this.palette = themes[i]\n }\n\n setDefaultColors (fg, bg) {\n if (fg !== this.defaultFgNum || bg !== this.defaultBgNum) {\n this.resetDrawn()\n this.defaultFgNum = fg\n this.defaultBgNum = bg\n this.scheduleDraw('default-colors')\n }\n }\n\n /**\n * Schedule a draw in the next millisecond\n * @param {string} why - the reason why the draw occured (for debugging)\n * @param {number} [aggregateTime] - time to wait for more scheduleDraw calls\n * to occur. 1 ms by default.\n */\n scheduleDraw (why, aggregateTime = 1) {\n clearTimeout(this._scheduledDraw)\n this._scheduledDraw = setTimeout(() => this.draw(why), aggregateTime)\n }\n\n /**\n * Returns the specified color. If `i` is in the palette, it will return the\n * palette color. If `i` is between 16 and 255, it will return the 256color\n * value. If `i` is larger than 255, it will return an RGB color value. If `i`\n * is -1 (foreground) or -2 (background), it will return the selection colors.\n * @param {number} i - the color\n * @returns {string} the CSS color\n */\n getColor (i) {\n // return palette color if it exists\n if (i < 16 && i in this.palette) 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 this.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 // return error color\n return (Date.now() / 1000) % 2 === 0 ? '#f0f' : '#0f0'\n }\n\n /**\n * Resets the cursor blink to on and restarts the timer\n */\n resetCursorBlink () {\n this.cursorBlinkOn = true\n clearInterval(this.cursorBlinkInterval)\n this.cursorBlinkInterval = setInterval(() => {\n this.cursorBlinkOn = this.screen.cursor.blinking\n ? !this.cursorBlinkOn\n : true\n if (this.screen.cursor.blinking) this.scheduleDraw('cursor-blink')\n }, 500)\n }\n\n /**\n * Resets the blink style to on and restarts the timer\n */\n resetBlink () {\n this.blinkStyleOn = true\n clearInterval(this.blinkInterval)\n let intervals = 0\n this.blinkInterval = setInterval(() => {\n if (this.screen.blinkingCellCount <= 0) return\n\n intervals++\n if (intervals >= 4 && this.blinkStyleOn) {\n this.blinkStyleOn = false\n intervals = 0\n this.scheduleDraw('blink-style')\n } else if (intervals >= 1 && !this.blinkStyleOn) {\n this.blinkStyleOn = true\n intervals = 0\n this.scheduleDraw('blink-style')\n }\n }, 200)\n }\n\n /**\n * Draws a cell's background with the given parameters.\n * @param {Object} options\n * @param {number} options.x - x in cells\n * @param {number} options.y - y in cells\n * @param {number} options.cellWidth - cell width in pixels\n * @param {number} options.cellHeight - cell height in pixels\n * @param {number} options.bg - the background color\n */\n drawBackground ({ x, y, cellWidth, cellHeight, bg }) {\n const ctx = this.ctx\n const { width, height } = this.screen.window\n const padding = Math.round(this.screen._padding)\n ctx.fillStyle = this.getColor(bg)\n let screenX = x * cellWidth + padding\n let screenY = y * cellHeight + padding\n let isBorderCell = x === 0 || y === 0 || x === width - 1 || y === height - 1\n if (isBorderCell) {\n let left = screenX\n let top = screenY\n let right = screenX + cellWidth\n let bottom = screenY + cellHeight\n if (x === 0) left -= padding\n else if (x === width - 1) right += padding\n if (y === 0) top -= padding\n else if (y === height - 1) bottom += padding\n ctx.clearRect(left, top, right - left, bottom - top)\n ctx.fillRect(left, top, right - left, bottom - top)\n } else {\n ctx.clearRect(screenX, screenY, cellWidth, cellHeight)\n ctx.fillRect(screenX, screenY, cellWidth, cellHeight)\n }\n }\n\n /**\n * Draws a cell's character with the given parameters. Won't do anything if\n * text is an empty string.\n * @param {Object} options\n * @param {number} options.x - x in cells\n * @param {number} options.y - y in cells\n * @param {Object} options.charSize - the character size, an object with\n * `width` and `height` in pixels\n * @param {number} options.cellWidth - cell width in pixels\n * @param {number} options.cellHeight - cell height in pixels\n * @param {string} options.text - the cell content\n * @param {number} options.fg - the foreground color\n * @param {number} options.attrs - the cell's attributes\n */\n drawCharacter ({ x, y, charSize, cellWidth, cellHeight, text, fg, attrs }) {\n if (!text) return\n\n const ctx = this.ctx\n const padding = Math.round(this.screen._padding)\n\n let underline = false\n let strike = false\n let overline = false\n if (attrs & ATTR_FAINT) ctx.globalAlpha = 0.5\n if (attrs & ATTR_UNDERLINE) underline = true\n if (attrs & ATTR_FRAKTUR) text = ScreenRenderer.alphaToFraktur(text)\n if (attrs & ATTR_STRIKE) strike = true\n if (attrs & ATTR_OVERLINE) overline = true\n\n ctx.fillStyle = this.getColor(fg)\n\n let screenX = x * cellWidth + padding\n let screenY = y * cellHeight + padding\n\n let codePoint = text.codePointAt(0)\n if (codePoint >= 0x2580 && codePoint <= 0x259F) {\n // block elements\n ctx.beginPath()\n const left = screenX\n const top = screenY\n const cw = cellWidth\n const ch = cellHeight\n const c2w = cellWidth / 2\n const c2h = cellHeight / 2\n\n // http://www.fileformat.info/info/unicode/block/block_elements/utf8test.htm\n // 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F\n // 0x2580 ▀ ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▉ ▊ ▋ ▌ ▍ ▎ ▏\n // 0x2590 ▐ ░ ▒ ▓ ▔ ▕ ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▞ ▟\n\n if (codePoint === 0x2580) {\n // upper half block >▀<\n ctx.rect(left, top, cw, c2h)\n } else if (codePoint <= 0x2588) {\n // lower n eighth block (increasing) >▁< to >█<\n let offset = (1 - (codePoint - 0x2580) / 8) * ch\n ctx.rect(left, top + offset, cw, ch - offset)\n } else if (codePoint <= 0x258F) {\n // left n eighth block (decreasing) >▉< to >▏<\n let offset = (codePoint - 0x2588) / 8 * cw\n ctx.rect(left, top, cw - offset, ch)\n } else if (codePoint === 0x2590) {\n // right half block >▐<\n ctx.rect(left + c2w, top, c2w, ch)\n } else if (codePoint <= 0x2593) {\n // shading >░< >▒< >▓<\n\n // dot spacing by dividing cell size by a constant. This could be\n // reworked to always return a whole number, but that would require\n // prime factorization, and doing that without a loop would let you\n // take over the world, which is not within the scope of this project.\n let dotSpacingX, dotSpacingY, dotSize\n if (codePoint === 0x2591) {\n dotSpacingX = cw / 4\n dotSpacingY = ch / 10\n dotSize = 1\n } else if (codePoint === 0x2592) {\n dotSpacingX = cw / 6\n dotSpacingY = cw / 10\n dotSize = 1\n } else if (codePoint === 0x2593) {\n dotSpacingX = cw / 4\n dotSpacingY = cw / 7\n dotSize = 2\n }\n\n let alignRight = false\n for (let dy = 0; dy < ch; dy += dotSpacingY) {\n for (let dx = 0; dx < cw; dx += dotSpacingX) {\n // prevent overflow\n let dotSizeY = Math.min(dotSize, ch - dy)\n ctx.rect(left + (alignRight ? cw - dx - dotSize : dx), top + dy, dotSize, dotSizeY)\n }\n alignRight = !alignRight\n }\n } else if (codePoint === 0x2594) {\n // upper one eighth block >▔<\n ctx.rect(left, top, cw, ch / 8)\n } else if (codePoint === 0x2595) {\n // right one eighth block >▕<\n ctx.rect(left + (7 / 8) * cw, top, cw / 8, ch)\n } else if (codePoint === 0x2596) {\n // left bottom quadrant >▖<\n ctx.rect(left, top + c2h, c2w, c2h)\n } else if (codePoint === 0x2597) {\n // right bottom quadrant >▗<\n ctx.rect(left + c2w, top + c2h, c2w, c2h)\n } else if (codePoint === 0x2598) {\n // left top quadrant >▘<\n ctx.rect(left, top, c2w, c2h)\n } else if (codePoint === 0x2599) {\n // left chair >▙<\n ctx.rect(left, top, c2w, ch)\n ctx.rect(left + c2w, top + c2h, c2w, c2h)\n } else if (codePoint === 0x259A) {\n // quadrants lt rb >▚<\n ctx.rect(left, top, c2w, c2h)\n ctx.rect(left + c2w, top + c2h, c2w, c2h)\n } else if (codePoint === 0x259B) {\n // left chair upside down >▛<\n ctx.rect(left, top, c2w, ch)\n ctx.rect(left + c2w, top, c2w, c2h)\n } else if (codePoint === 0x259C) {\n // right chair upside down >▜<\n ctx.rect(left, top, cw, c2h)\n ctx.rect(left + c2w, top + c2h, c2w, c2h)\n } else if (codePoint === 0x259D) {\n // right top quadrant >▝<\n ctx.rect(left + c2w, top, c2w, c2h)\n } else if (codePoint === 0x259E) {\n // quadrants lb rt >▞<\n ctx.rect(left, top + c2h, c2w, c2h)\n ctx.rect(left + c2w, top, c2w, c2h)\n } else if (codePoint === 0x259F) {\n // right chair upside down >▟<\n ctx.rect(left, top + c2h, c2w, c2h)\n ctx.rect(left + c2w, top, c2w, ch)\n }\n\n ctx.fill()\n } else if (codePoint >= 0xE0B0 && codePoint <= 0xE0B3) {\n // powerline symbols, except branch, line, and lock. Basically, just the triangles\n ctx.beginPath()\n\n if (codePoint === 0xE0B0 || codePoint === 0xE0B1) {\n // right-pointing triangle\n ctx.moveTo(screenX, screenY)\n ctx.lineTo(screenX + cellWidth, screenY + cellHeight / 2)\n ctx.lineTo(screenX, screenY + cellHeight)\n } else if (codePoint === 0xE0B2 || codePoint === 0xE0B3) {\n // left-pointing triangle\n ctx.moveTo(screenX + cellWidth, screenY)\n ctx.lineTo(screenX, screenY + cellHeight / 2)\n ctx.lineTo(screenX + cellWidth, screenY + cellHeight)\n }\n\n if (codePoint % 2 === 0) {\n // triangle\n ctx.fill()\n } else {\n // chevron\n ctx.strokeStyle = ctx.fillStyle\n ctx.stroke()\n }\n } else {\n // Draw other characters using the text renderer\n ctx.fillText(text, screenX + 0.5 * cellWidth, screenY + 0.5 * cellHeight)\n }\n\n // -- line drawing - a reference for a possible future rect/line implementation ---\n // http://www.fileformat.info/info/unicode/block/box_drawing/utf8test.htm\n // 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F\n // 0x2500 ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏\n // 0x2510 ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟\n // 0x2520 ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯\n // 0x2530 ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿\n // 0x2540 ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏\n // 0x2550 ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟\n // 0x2560 ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯\n // 0x2570 ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿\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(screenY + charSize.height) + 0.5\n ctx.moveTo(screenX, lineY)\n ctx.lineTo(screenX + cellWidth, lineY)\n }\n\n if (strike) {\n let lineY = Math.round(screenY + 0.5 * cellHeight) + 0.5\n ctx.moveTo(screenX, lineY)\n ctx.lineTo(screenX + cellWidth, lineY)\n }\n\n if (overline) {\n let lineY = Math.round(screenY) + 0.5\n ctx.moveTo(screenX, lineY)\n ctx.lineTo(screenX + cellWidth, lineY)\n }\n\n ctx.stroke()\n }\n\n ctx.globalAlpha = 1\n }\n\n /**\n * Returns all adjacent cell indices given a radius.\n * @param {number} cell - the center cell index\n * @param {number} [radius] - the radius. 1 by default\n * @returns {number[]} an array of cell indices\n */\n getAdjacentCells (cell, radius = 1) {\n const { width, height } = this.screen.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 /**\n * Updates the screen.\n * @param {string} why - the draw reason (for debugging)\n */\n draw (why) {\n const ctx = this.ctx\n const {\n width,\n height,\n devicePixelRatio,\n statusScreen\n } = this.screen.window\n\n if (statusScreen) {\n // draw status screen instead\n this.drawStatus(statusScreen)\n this.startDrawLoop()\n return\n } else this.stopDrawLoop()\n\n const charSize = this.screen.getCharSize()\n const { width: cellWidth, height: cellHeight } = this.screen.getCellSize()\n const screenLength = width * height\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0)\n\n if (this.screen.window.debug && this.screen._debug) this.screen._debug.drawStart(why)\n\n ctx.font = this.screen.getFont()\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n\n // bits in the attr value that affect the font\n const FONT_MASK = ATTR_BOLD | ATTR_ITALIC\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.cursorBlinkOn &&\n this.screen.cursor.x === x &&\n this.screen.cursor.y === y &&\n this.screen.cursor.visible\n\n let wasCursor = x === this.drawnCursor[0] && y === this.drawnCursor[1]\n\n let inSelection = this.screen.isInSelection(x, y)\n\n let text = this.screen.screen[cell]\n let fg = this.screen.screenFG[cell] | 0\n let bg = this.screen.screenBG[cell] | 0\n let attrs = this.screen.screenAttrs[cell] | 0\n\n if (!(attrs & ATTR_FG)) fg = this.defaultFgNum\n if (!(attrs & ATTR_BG)) bg = this.defaultBgNum\n\n if (attrs & ATTR_INVERSE) [fg, bg] = [bg, fg] // swap - reversed character colors\n if (this.screen.reverseVideo) [fg, bg] = [bg, fg] // swap - reversed all screen\n\n if (attrs & ATTR_BLINK && !this.blinkStyleOn) {\n // blinking is enabled and blink style is off\n // set text to nothing so drawCharacter doesn't draw anything\n text = ''\n }\n\n if (inSelection) {\n fg = -1\n bg = -2\n }\n\n let didUpdate = text !== this.drawnScreen[cell] || // text updated\n fg !== this.drawnScreenFG[cell] || // foreground updated, and this cell has text\n bg !== this.drawnScreenBG[cell] || // background updated\n attrs !== this.drawnScreenAttrs[cell] || // attributes updated\n isCursor !== wasCursor || // cursor blink/position updated\n (isCursor && this.screen.cursor.style !== this.drawnCursor[2]) || // cursor style updated\n (isCursor && this.screen.cursor.hanging !== this.drawnCursor[3]) // cursor hanging updated\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, inSelection })\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) || false\n\n // TODO: fonts (necessary?)\n let text = this.screen.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 // update this cell if:\n // - the adjacent cell updated (For now, this'll always be true because characters can be slightly larger than they say they are)\n // - the adjacent cell updated and this cell or the adjacent cell is wide\n if (updateMap.get(adjacentCell) && (this.screen.window.graphics < 2 || isWideCell || isTextWide(this.screen.screen[adjacentCell]))) {\n adjacentDidUpdate = true\n break\n }\n }\n\n if (adjacentDidUpdate) shouldUpdate = true\n }\n\n redrawMap.set(cell, shouldUpdate)\n }\n\n for (let cell of updateMap.keys()) updateRedrawMapAt(cell)\n\n // mask to redrawing regions only\n if (this.screen.window.graphics >= 1) {\n let debug = this.screen.window.debug && this.screen._debug\n let padding = Math.round(this.screen._padding)\n ctx.save()\n ctx.beginPath()\n for (let y = 0; y < height; y++) {\n let regionStart = null\n for (let x = 0; x < width; x++) {\n let cell = y * width + x\n let redrawing = redrawMap.get(cell)\n if (redrawing && regionStart === null) regionStart = x\n if (!redrawing && regionStart !== null) {\n ctx.rect(padding + regionStart * cellWidth, padding + y * cellHeight, (x - regionStart) * cellWidth, cellHeight)\n if (debug) this.screen._debug.clipRect(regionStart * cellWidth, y * cellHeight, (x - regionStart) * cellWidth, cellHeight)\n regionStart = null\n }\n }\n if (regionStart !== null) {\n ctx.rect(padding + regionStart * cellWidth, padding + y * cellHeight, (width - regionStart) * cellWidth, cellHeight)\n if (debug) this.screen._debug.clipRect(regionStart * cellWidth, y * cellHeight, (width - regionStart) * cellWidth, cellHeight)\n }\n }\n ctx.clip()\n }\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, bg } = data\n\n if (redrawMap.get(cell)) {\n this.drawBackground({ x, y, cellWidth, cellHeight, bg })\n\n if (this.screen.window.debug && this.screen._debug) {\n // set cell flags\n let flags = (+redrawMap.get(cell))\n flags |= (+updateMap.get(cell)) << 1\n flags |= (+isTextWide(text)) << 2\n this.screen._debug.setCell(cell, flags)\n }\n }\n }\n }\n\n // reset drawn cursor\n this.drawnCursor = [-1, -1, -1]\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 & ATTR_BOLD) modifiers.weight = 'bold'\n if (font & ATTR_ITALIC) modifiers.style = 'italic'\n ctx.font = this.screen.getFont(modifiers)\n\n for (let data of fontGroups.get(font)) {\n let { cell, x, y, text, fg, bg, attrs, isCursor, inSelection } = data\n\n if (redrawMap.get(cell)) {\n this.drawCharacter({\n x, y, charSize, cellWidth, cellHeight, text, fg, 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 (isCursor) this.drawnCursor = [x, y, this.screen.cursor.style, this.screen.cursor.hanging]\n\n // draw cursor\n if (isCursor && !inSelection) {\n ctx.save()\n ctx.beginPath()\n\n let cursorX = x\n let cursorY = y\n\n if (this.screen.cursor.hanging) {\n // draw hanging cursor in the margin\n cursorX += 1\n }\n\n let screenX = cursorX * cellWidth + this.screen._padding\n let screenY = cursorY * cellHeight + this.screen._padding\n if (this.screen.cursor.style === 'block') {\n // block\n ctx.rect(screenX, screenY, cellWidth, cellHeight)\n } else if (this.screen.cursor.style === 'bar') {\n // vertical bar\n let barWidth = 2\n ctx.rect(screenX, screenY, barWidth, cellHeight)\n } else if (this.screen.cursor.style === 'line') {\n // underline\n let lineHeight = 2\n ctx.rect(screenX, screenY + charSize.height, cellWidth, lineHeight)\n }\n ctx.clip()\n\n // swap foreground/background\n ;[fg, bg] = [bg, fg]\n\n // HACK: ensure cursor is visible\n if (fg === bg) bg = fg === 0 ? 7 : 0\n\n this.drawBackground({ x: cursorX, y: cursorY, cellWidth, cellHeight, bg })\n this.drawCharacter({\n x: cursorX, y: cursorY, charSize, cellWidth, cellHeight, text, fg, attrs\n })\n ctx.restore()\n }\n }\n }\n }\n\n if (this.screen.window.graphics >= 1) ctx.restore()\n\n if (this.screen.window.debug && this.screen._debug) this.screen._debug.drawEnd()\n\n this.screen.emit('draw', why)\n }\n\n drawStatus (statusScreen) {\n const ctx = this.ctx\n const {\n fontFamily,\n width,\n height,\n devicePixelRatio\n } = this.screen.window\n\n // reset drawnScreen to force redraw when statusScreen is disabled\n this.drawnScreen = []\n\n const cellSize = this.screen.getCellSize()\n const screenWidth = width * cellSize.width + 2 * this.screen._padding\n const screenHeight = height * cellSize.height + 2 * this.screen._padding\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0)\n ctx.fillStyle = this.getColor(this.defaultBgNum)\n ctx.fillRect(0, 0, screenWidth, screenHeight)\n\n ctx.font = `24px ${fontFamily}`\n ctx.fillStyle = this.getColor(this.defaultFgNum)\n ctx.textAlign = 'center'\n ctx.textBaseline = 'middle'\n ctx.fillText(statusScreen.title || '', screenWidth / 2, screenHeight / 2 - 50)\n\n if (statusScreen.loading) {\n // show loading spinner\n ctx.save()\n ctx.translate(screenWidth / 2, screenHeight / 2 + 20)\n\n ctx.strokeStyle = this.getColor(this.defaultFgNum)\n ctx.lineWidth = 5\n ctx.lineCap = 'round'\n\n let t = Date.now() / 1000\n\n for (let i = 0; i < 12; i++) {\n ctx.rotate(Math.PI / 6)\n let offset = ((t * 12) - i) % 12\n ctx.globalAlpha = Math.max(0.2, 1 - offset / 3)\n ctx.beginPath()\n ctx.moveTo(0, 15)\n ctx.lineTo(0, 30)\n ctx.stroke()\n }\n\n ctx.restore()\n }\n }\n\n startDrawLoop () {\n if (this._drawTimerThread) return\n let threadID = Math.random().toString(36)\n this._drawTimerThread = threadID\n this.drawTimerLoop(threadID)\n }\n\n stopDrawLoop () {\n this._drawTimerThread = null\n }\n\n drawTimerLoop (threadID) {\n if (!threadID || threadID !== this._drawTimerThread) return\n window.requestAnimationFrame(() => this.drawTimerLoop(threadID))\n this.draw('draw-loop')\n }\n\n /**\n * Converts an alphabetic character to its fraktur variant.\n * @param {string} character - the character\n * @returns {string} the converted character\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(0x1d504 - 0x41 + character.charCodeAt(0))\n }\n return character\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/screen_renderer.js","const EventEmitter = require('events')\nconst $ = require('../lib/chibi')\nlet demo\ntry { demo = require('./demo') } catch (err) {}\n\nconst RECONN_DELAY = 2000\nconst HEARTBEAT_TIME = 3000\n\n/** Handle connections */\nmodule.exports = class TermConnection extends EventEmitter {\n constructor (screen) {\n super()\n\n this.screen = screen\n this.ws = null\n this.heartbeatTimeout = null\n this.pingInterval = null\n this.xoff = false\n this.autoXoffTimeout = null\n this.reconnTimeout = null\n this.forceClosing = false\n\n try {\n this.blobReader = new FileReader()\n this.blobReader.onload = (evt) => {\n this.onDecodedWSMessage(this.blobReader.result)\n }\n this.blobReader.onerror = (evt) => {\n console.error(evt)\n }\n } catch (e) {\n this.blobReader = null\n }\n\n this.pageShown = false\n\n this.disconnectTimeout = null\n\n document.addEventListener('visibilitychange', () => {\n if (document.hidden === true) {\n console.info('Window lost focus, freeing socket')\n // Delayed, avoid disconnecting if the background time is short\n this.disconnectTimeout = setTimeout(() => {\n this.closeSocket()\n clearTimeout(this.heartbeatTimeout)\n }, 1000)\n } else {\n clearTimeout(this.disconnectTimeout)\n console.info('Window got focus, re-connecting')\n this.init()\n }\n }, false)\n }\n\n onWSOpen (evt) {\n console.log('CONNECTED')\n this.heartbeat()\n this.send('i')\n this.forceClosing = false\n\n this.emit('connect')\n }\n\n onWSClose (evt) {\n if (this.forceClosing) {\n this.forceClosing = false\n return\n }\n console.warn('SOCKET CLOSED, code ' + evt.code + '. Reconnecting...')\n if (evt.code < 1000) {\n console.error('Bad code from socket!')\n // this sometimes happens for unknown reasons, code < 1000 is invalid\n // location.reload()\n }\n\n clearTimeout(this.reconnTimeout)\n this.reconnTimeout = setTimeout(() => this.init(), RECONN_DELAY)\n\n this.emit('disconnect', evt.code)\n }\n\n onDecodedWSMessage (str) {\n switch (str.charAt(0)) {\n case '.':\n console.log(str)\n // heartbeat, no-op message\n break\n\n case '-':\n // console.log('xoff');\n this.xoff = true\n this.autoXoffTimeout = setTimeout(() => {\n this.xoff = false\n }, 250)\n break\n\n case '+':\n // console.log('xon');\n this.xoff = false\n clearTimeout(this.autoXoffTimeout)\n break\n\n default:\n this.screen.load(str)\n if (!this.pageShown) {\n window.showPage()\n this.pageShown = true\n }\n break\n }\n this.heartbeat()\n }\n\n onWSMessage (evt) {\n if (typeof evt.data === 'string') this.onDecodedWSMessage(evt.data)\n else {\n if (!this.blobReader) {\n console.error('No FileReader!')\n return\n }\n\n if (this.blobReader.readyState !== 1) {\n this.blobReader.readAsText(evt.data)\n } else {\n setTimeout(() => {\n this.onWSMessage(evt)\n }, 1)\n }\n }\n }\n\n canSend () {\n return !this.xoff\n }\n\n send (message) {\n if (window._demo) {\n if (typeof window.demoInterface !== 'undefined') {\n demo.input(message)\n } else {\n console.log(`TX: ${JSON.stringify(message)}`)\n }\n return true // Simulate success\n }\n if (this.xoff) {\n // TODO queue\n console.log(\"Can't send, flood control.\")\n return false\n }\n\n if (!this.ws) return false // for dry testing\n if (this.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 this.ws.send(message)\n return true\n }\n\n /** Safely close the socket */\n closeSocket () {\n if (this.ws) {\n this.forceClosing = true\n if (this.ws.readyState === 1) this.ws.close()\n this.ws = null\n }\n }\n\n init () {\n if (window._demo) {\n if (typeof window.demoInterface === 'undefined') {\n window.alert('Demoing non-demo build!') // this will catch mistakes when deploying to the website\n } else {\n demo.init(this.screen)\n }\n return\n }\n\n clearTimeout(this.reconnTimeout)\n clearTimeout(this.heartbeatTimeout)\n\n this.closeSocket()\n\n this.ws = new window.WebSocket('ws://' + window._root + '/term/update.ws')\n this.ws.addEventListener('open', (...args) => this.onWSOpen(...args))\n this.ws.addEventListener('close', (...args) => this.onWSClose(...args))\n this.ws.addEventListener('message', (...args) => this.onWSMessage(...args))\n console.log('Opening socket.')\n this.heartbeat()\n\n this.emit('open')\n }\n\n heartbeat () {\n clearTimeout(this.heartbeatTimeout)\n this.heartbeatTimeout = setTimeout(() => this.onHeartbeatFail(), HEARTBEAT_TIME)\n }\n\n sendPing () {\n console.log('> ping')\n this.emit('ping')\n $.get('http://' + window._root + '/api/v1/ping', (resp, status) => {\n if (status === 200) {\n clearInterval(this.pingInterval)\n console.info('Server ready, opening socket…')\n this.emit('ping-success')\n this.init()\n // location.reload()\n } else this.emit('ping-fail', status)\n }, {\n timeout: 100,\n loader: false // we have loader on-screen\n })\n }\n\n onHeartbeatFail () {\n this.closeSocket()\n this.emit('silence')\n console.error('Heartbeat lost, probing server...')\n clearInterval(this.pingInterval)\n this.pingInterval = setInterval(() => { this.sendPing() }, 1000)\n\n // first ping, if this gets through, it'll will reduce delay\n setTimeout(() => { this.sendPing() }, 200)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/connection.js","const $ = require('../lib/chibi')\nconst { encode2B } = require('../utils')\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 */\nmodule.exports = function (conn, screen) {\n // handle for input object\n let input\n\n const KEY_NAMES = {\n 0x03: 'Cancel',\n 0x06: 'Help',\n 0x08: 'Backspace',\n 0x09: 'Tab',\n 0x0C: 'Clear',\n 0x0D: 'Enter',\n 0x10: 'Shift',\n 0x11: 'Control',\n 0x12: 'Alt',\n 0x13: 'Pause',\n 0x14: 'CapsLock',\n 0x1B: 'Escape',\n 0x20: ' ',\n 0x21: 'PageUp',\n 0x22: 'PageDown',\n 0x23: 'End',\n 0x24: 'Home',\n 0x25: 'ArrowLeft',\n 0x26: 'ArrowUp',\n 0x27: 'ArrowRight',\n 0x28: 'ArrowDown',\n 0x29: 'Select',\n 0x2A: 'Print',\n 0x2B: 'Execute',\n 0x2C: 'PrintScreen',\n 0x2D: 'Insert',\n 0x2E: 'Delete',\n 0x3A: ':',\n 0x3B: ';',\n 0x3C: '<',\n 0x3D: '=',\n 0x3E: '>',\n 0x3F: '?',\n 0x40: '@',\n 0x5B: 'Meta',\n 0x5C: 'Meta',\n 0x5D: 'ContextMenu',\n 0x6A: 'Numpad*',\n 0x6B: 'Numpad+',\n 0x6D: 'Numpad-',\n 0x6E: 'Numpad.',\n 0x6F: 'Numpad/',\n 0x90: 'NumLock',\n 0x91: 'ScrollLock',\n 0xA0: '^',\n 0xA1: '!',\n 0xA2: '\"',\n 0xA3: '#',\n 0xA4: '$',\n 0xA5: '%',\n 0xA6: '&',\n 0xA7: '_',\n 0xA8: '(',\n 0xA9: ')',\n 0xAA: '*',\n 0xAB: '+',\n 0xAC: '|',\n 0xAD: '-',\n 0xAE: '{',\n 0xAF: '}',\n 0xB0: '~',\n 0xBA: ';',\n 0xBB: '=',\n 0xBC: 'Numpad,',\n 0xBD: '-',\n 0xBE: 'Numpad,',\n 0xC0: '`',\n 0xC2: 'Numpad,',\n 0xDB: '[',\n 0xDC: '\\\\',\n 0xDD: ']',\n 0xDE: \"'\",\n 0xE0: 'Meta'\n }\n // numbers 0-9\n for (let i = 0x30; i <= 0x39; i++) KEY_NAMES[i] = String.fromCharCode(i)\n // characters A-Z\n for (let i = 0x41; i <= 0x5A; i++) KEY_NAMES[i] = String.fromCharCode(i)\n // function F1-F20\n for (let i = 0x70; i <= 0x83; i++) KEY_NAMES[i] = `F${i - 0x70 + 1}`\n // numpad 0-9\n for (let i = 0x60; i <= 0x69; i++) KEY_NAMES[i] = `Numpad${i - 0x60}`\n\n let cfg = {\n np_alt: false, // Application Numpad Mode\n cu_alt: false, // Application Cursors Mode\n fn_alt: false, // SS3 function keys mode\n mt_click: false, // Mouse click tracking\n mt_move: false, // Mouse move tracking\n no_keys: false, // Suppress any key / clipboard event intercepting\n crlf_mode: false, // Enter sends CR LF\n all_fn: false // Capture also F5, F11 and F12\n }\n\n /** Fn alt choice for key message */\n const fa = (alt, normal) => cfg.fn_alt ? alt : normal\n\n /** Cursor alt choice for key message */\n const ca = (alt, normal) => cfg.cu_alt ? alt : normal\n\n /** Numpad alt choice for key message */\n const na = (alt, normal) => cfg.np_alt ? alt : normal\n\n const keymap = {\n /* eslint-disable key-spacing */\n 'Backspace': '\\x08',\n 'Tab': '\\x09',\n 'Enter': () => cfg.crlf_mode ? '\\x0d\\x0a' : '\\x0d',\n 'Control+Enter': '\\x0a',\n 'Escape': '\\x1b',\n 'ArrowUp': () => ca('\\x1bOA', '\\x1b[A'),\n 'ArrowDown': () => ca('\\x1bOB', '\\x1b[B'),\n 'ArrowRight': () => ca('\\x1bOC', '\\x1b[C'),\n 'ArrowLeft': () => 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 'Numpad0': () => na('\\x1bOp', '0'),\n 'Numpad1': () => na('\\x1bOq', '1'),\n 'Numpad2': () => na('\\x1bOr', '2'),\n 'Numpad3': () => na('\\x1bOs', '3'),\n 'Numpad4': () => na('\\x1bOt', '4'),\n 'Numpad5': () => na('\\x1bOu', '5'),\n 'Numpad6': () => na('\\x1bOv', '6'),\n 'Numpad7': () => na('\\x1bOw', '7'),\n 'Numpad8': () => na('\\x1bOx', '8'),\n 'Numpad9': () => na('\\x1bOy', '9'),\n 'Numpad*': () => na('\\x1bOR', '*'),\n 'Numpad+': () => na('\\x1bOl', '+'),\n 'Numpad-': () => na('\\x1bOS', '-'),\n 'Numpad.': () => na('\\x1bOn', '.'),\n 'Numpad/': () => na('\\x1bOQ', '/'),\n // we don't implement numlock key (should change in numpad_alt mode,\n // but it's even more useless than the rest and also has the side\n // effect of changing the user's numlock state)\n\n // shortcuts\n 'Control+]': '\\x1b', // alternate way to enter ESC\n 'Control+\\\\': '\\x1c',\n 'Control+[': '\\x1d',\n 'Control+^': '\\x1e',\n 'Control+_': '\\x1f',\n\n // extra controls\n 'Control+ArrowLeft': '\\x1f[1;5D',\n 'Control+ArrowRight': '\\x1f[1;5C',\n 'Control+ArrowUp': '\\x1f[1;5A',\n 'Control+ArrowDown': '\\x1f[1;5B',\n 'Control+Home': '\\x1f[1;5H',\n 'Control+End': '\\x1f[1;5F',\n\n // extra shift controls\n 'Shift+ArrowLeft': '\\x1f[1;2D',\n 'Shift+ArrowRight': '\\x1f[1;2C',\n 'Shift+ArrowUp': '\\x1f[1;2A',\n 'Shift+ArrowDown': '\\x1f[1;2B',\n 'Shift+Home': '\\x1f[1;2H',\n 'Shift+End': '\\x1f[1;2F',\n\n // macOS text editing commands\n 'Alt+ArrowLeft': '\\x1bb', // ⌥← to go back a word (^[b)\n 'Alt+ArrowRight': '\\x1bf', // ⌥→ to go forward one word (^[f)\n 'Meta+ArrowLeft': '\\x01', // ⌘← to go to the beginning of a line (^A)\n 'Meta+ArrowRight': '\\x05', // ⌘→ to go to the end of a line (^E)\n 'Alt+Backspace': '\\x17', // ⌥⌫ to delete a word (^W)\n 'Meta+Backspace': '\\x15', // ⌘⌫ to delete to the beginning of a line (^U)\n\n // copy to clipboard\n 'Control+Shift+C' () {\n screen.copySelectionToClipboard()\n },\n 'Control+Insert' () {\n screen.copySelectionToClipboard()\n },\n\n // toggle debug mode\n 'Control+F12' () {\n screen.window.debug ^= 1\n }\n /* eslint-enable key-spacing */\n }\n\n // ctrl+[A-Z] sent as simple low ASCII codes\n for (let i = 1; i <= 26; i++) {\n keymap[`Control+${String.fromCharCode(0x40 + i)}`] = String.fromCharCode(i)\n }\n\n /** Send a literal message */\n function sendString (str) {\n return conn.send('s' + str)\n }\n\n /** Send a button event */\n function sendButton (index) {\n conn.send('b' + String.fromCharCode(index + 1))\n }\n\n const shouldAcceptEvent = function () {\n if (cfg.no_keys) return false\n if (document.activeElement instanceof window.HTMLTextAreaElement) return false\n return true\n }\n\n const keyBlacklist = [\n 'F5', 'F11', 'F12', 'Shift+F5'\n ]\n\n let softModifiers = {\n alt: false,\n ctrl: false,\n meta: false,\n shift: false\n }\n\n const handleKeyDown = function (e) {\n if (!shouldAcceptEvent()) return\n\n let modifiers = []\n // sorted alphabetically\n if (e.altKey || softModifiers.alt) modifiers.push('Alt')\n if (e.ctrlKey || softModifiers.ctrl) modifiers.push('Control')\n if (e.metaKey || softModifiers.meta) modifiers.push('Meta')\n if (e.shiftKey || softModifiers.shift) modifiers.push('Shift')\n\n let key = KEY_NAMES[e.which] || e.key\n\n // ignore clipboard events\n if ((e.ctrlKey || e.metaKey) && key === 'V') return\n\n let binding = null\n\n for (let name in keymap) {\n let itemModifiers = name.split('+')\n let itemKey = itemModifiers.pop()\n\n if (itemKey === key && itemModifiers.sort().join() === modifiers.join()) {\n if (keyBlacklist.includes(name) && !cfg.all_fn) continue\n binding = keymap[name]\n break\n }\n }\n\n if (binding) {\n if (binding instanceof Function) binding = binding()\n e.preventDefault()\n if (typeof binding === 'string') {\n sendString(binding)\n }\n }\n }\n\n /** Bind/rebind key messages */\n function initKeys ({ allFn }) {\n // This takes care of text characters typed\n window.addEventListener('keypress', function (evt) {\n if (!shouldAcceptEvent()) return\n if (evt.ctrlKey || evt.metaKey) return\n\n let str = ''\n if (evt.key && evt.key.length === 1) str = evt.key\n else if (evt.which && evt.which !== 229) str = String.fromCodePoint(evt.which)\n\n if (str.length > 0 && str.charCodeAt(0) >= 32) {\n // prevent space from scrolling\n if (evt.which === 32) evt.preventDefault()\n sendString(str)\n }\n })\n\n window.addEventListener('keydown', handleKeyDown)\n window.addEventListener('copy', e => {\n if (!shouldAcceptEvent()) return\n let selectedText = screen.getSelectedText()\n if (selectedText) {\n e.preventDefault()\n e.clipboardData.setData('text/plain', selectedText)\n }\n })\n window.addEventListener('paste', e => {\n if (!shouldAcceptEvent()) return\n e.preventDefault()\n let string = e.clipboardData.getData('text/plain')\n if (string.includes('\\n') || string.length > 90) {\n if (!input.termUpload) console.error('input.termUpload is undefined')\n input.termUpload.setContent(string)\n input.termUpload.open()\n } else {\n // simple string, just paste it\n if (screen.bracketedPaste) string = `\\x1b[200~${string}\\x1b[201~`\n sendString(string)\n }\n })\n\n cfg.all_fn = allFn\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 (opts) {\n initKeys(opts)\n\n // global mouse state tracking - for motion reporting\n window.addEventListener('mousedown', 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', 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 // record modifier keys\n // bits: Meta, Alt, Shift, Ctrl\n let modifiers = 0b0000\n\n window.addEventListener('keydown', e => {\n if (e.ctrlKey) modifiers |= 1\n if (e.shiftKey) modifiers |= 2\n if (e.altKey) modifiers |= 4\n if (e.metaKey) modifiers |= 8\n })\n window.addEventListener('keyup', e => {\n modifiers = 0\n if (e.ctrlKey) modifiers |= 1\n if (e.shiftKey) modifiers |= 2\n if (e.altKey) modifiers |= 4\n if (e.metaKey) modifiers |= 8\n })\n\n /** Prepare modifiers byte for mouse message */\n function packModifiersForMouse () {\n return modifiers\n }\n\n input = {\n /** Init the Input module */\n init,\n\n /** Send a literal string message */\n sendString,\n sendButton,\n\n /** Enable alternate key modes (cursors, numpad, fn) */\n setAlts: function (cu, np, fn, crlf) {\n if (cfg.cu_alt !== cu || cfg.np_alt !== np || cfg.fn_alt !== fn || cfg.crlf_mode !== crlf) {\n cfg.cu_alt = cu\n cfg.np_alt = np\n cfg.fn_alt = fn\n cfg.crlf_mode = crlf\n }\n },\n\n setMouseMode (click, move) {\n cfg.mt_click = click\n cfg.mt_move = move\n },\n\n // Mouse events\n onMouseMove (x, y) {\n if (!cfg.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 (x, y, b) {\n if (!cfg.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 },\n\n onMouseUp (x, y, b) {\n if (!cfg.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 (x, y, dir) {\n if (!cfg.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 /**\n * Prevent capturing keys. This is used for text input\n * modals on the terminal screen\n */\n blockKeys (yes) {\n cfg.no_keys = yes\n },\n\n handleKeyDown,\n softModifiers\n }\n return input\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/input.js","const $ = require('../lib/chibi')\nconst { qs } = require('../utils')\nconst modal = require('../modal')\n\n/** File upload utility */\nmodule.exports = function (conn, input, screen) {\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 openUploadDialog () {\n updateStatus('Ready...')\n modal.show('#fu_modal', onDialogClose)\n $('#fu_form').toggleClass('busy', false)\n input.blockKeys(true)\n }\n\n function onDialogClose () {\n console.log('Upload modal closed.')\n clearTimeout(fuTout)\n line_i = 0\n input.blockKeys(false)\n }\n\n function updateStatus (msg) {\n qs('#fu_prog').textContent = msg\n }\n\n function startUpload () {\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 updateStatus('Starting...')\n uploadLine()\n }\n\n function uploadLine () {\n if (!$('#fu_modal').hasClass('visible')) {\n // Modal is closed, cancel\n return\n }\n\n if (!conn.canSend()) {\n // postpone\n fuTout = setTimeout(uploadLine, 1)\n return\n }\n\n if (inline_pos === 0) {\n curLine = ''\n if (line_i === 0) {\n if (screen.bracketedPaste) {\n curLine = '\\x1b[200~'\n }\n }\n\n curLine += lines[line_i++] + nl_str\n\n if (line_i === lines.length) {\n if (screen.bracketedPaste) {\n curLine += '\\x1b[201~'\n }\n }\n }\n\n let maxChunk = +qs('#fu_chunk').value\n if (maxChunk === 0 || maxChunk > MAX_LINE_LEN) {\n maxChunk = MAX_LINE_LEN\n }\n\n let chunk\n if ((curLine.length - inline_pos) <= maxChunk) {\n chunk = curLine.substr(inline_pos, maxChunk)\n inline_pos = 0\n } else {\n chunk = curLine.substr(inline_pos, maxChunk)\n inline_pos += maxChunk\n }\n\n if (!input.sendString(chunk)) {\n updateStatus('FAILED!')\n return\n }\n\n let pt = Math.round((line_i / lines.length) * 1000) / 10\n updateStatus(`${line_i} / ${lines.length} (${pt}%)`)\n\n if (lines.length > line_i || inline_pos > 0) {\n fuTout = setTimeout(uploadLine, 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 updateStatus('Waiting for Tx buffer...')\n setTimeout(closeWhenReady, 100)\n } else {\n updateStatus('Done.')\n // delay to show it\n fuClose()\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 window.FileReader()\n let file = evt.target.files[0]\n let ftype = file.type || 'application/octet-stream'\n console.log('Selected file type: ' + ftype)\n if (!ftype.match(/text\\/.*|application\\/(json|csv|.*xml.*|.*script.*|x-php)/)) {\n // Deny load of blobs like img - can crash browser and will get corrupted anyway\n if (!window.confirm(`This does not look like a text file: ${ftype}\\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 qs('#term-fu-open').addEventListener('click', e => {\n e.preventDefault()\n openUploadDialog()\n })\n\n qs('#term-fu-start').addEventListener('click', e => {\n e.preventDefault()\n startUpload()\n })\n\n qs('#term-fu-close').addEventListener('click', e => {\n e.preventDefault()\n fuClose()\n })\n },\n open: openUploadDialog,\n setContent (content) {\n qs('#fu_text').value = content\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/upload.js","const { qs } = require('../utils')\n\nmodule.exports = function (screen, input) {\n const keyInput = qs('#softkb-input')\n if (!keyInput) return // abort, we're not on the terminal page\n\n const shortcutBar = document.createElement('div')\n shortcutBar.id = 'keyboard-shortcut-bar'\n if (navigator.userAgent.match(/iPad|iPhone|iPod/)) {\n qs('#screen').appendChild(shortcutBar)\n }\n\n let keyboardOpen = false\n\n // moves the input to where the cursor is on the canvas.\n // this is because most browsers will always scroll to wherever the focused\n // input is\n let updateInputPosition = function () {\n if (!keyboardOpen) return\n\n let [x, y] = screen.gridToScreen(screen.cursor.x, screen.cursor.y, true)\n keyInput.style.transform = `translate(${x}px, ${y}px)`\n }\n\n keyInput.addEventListener('focus', () => {\n keyboardOpen = true\n updateInputPosition()\n shortcutBar.classList.add('open')\n })\n\n keyInput.addEventListener('blur', () => {\n keyboardOpen = false\n shortcutBar.classList.remove('open')\n })\n\n screen.on('cursor-moved', updateInputPosition)\n\n qs('#term-kb-open').addEventListener('click', e => {\n e.preventDefault()\n keyInput.focus()\n })\n\n // Chrome for Android doesn't send proper keydown/keypress events with\n // real key values instead of 229 “Unidentified,” so here's a workaround\n // that deals with the input composition events.\n\n let lastCompositionString = ''\n\n // sends the difference between the last and the new composition string\n let sendInputDelta = function (newValue) {\n if (newValue === null) newValue = '' // this sometimes happens, why?\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 keyInput.addEventListener('keydown', e => {\n if (e.key === 'Unidentified') return\n\n keyInput.value = ''\n\n e.stopPropagation()\n input.handleKeyDown(e)\n })\n\n keyInput.addEventListener('keypress', e => {\n // prevent key duplication on iOS (because Safari *does* send proper events)\n e.stopPropagation()\n })\n\n keyInput.addEventListener('input', e => {\n e.stopPropagation()\n\n if (e.isComposing && 'data' in e) {\n sendInputDelta(e.data)\n } else if (e.isComposing) {\n // Firefox Mobile doesn't support InputEvent#data, so here's a hack\n // that just takes the input value and uses that\n sendInputDelta(keyInput.value)\n } else {\n if (e.inputType === 'insertCompositionText') input.sendString(e.data)\n else if (e.inputType === 'deleteContentBackward') {\n lastCompositionString = ''\n sendInputDelta('')\n } else if (e.inputType === 'insertText') {\n input.sendString(e.data)\n }\n }\n })\n\n keyInput.addEventListener('compositionstart', e => {\n lastCompositionString = ''\n })\n\n keyInput.addEventListener('compositionend', e => {\n lastCompositionString = ''\n keyInput.value = ''\n })\n\n screen.on('open-soft-keyboard', () => keyInput.focus())\n\n // shortcut bar\n const shortcuts = {\n Control: 'ctrl',\n Esc: 0x1b,\n Tab: 0x09,\n '←': 0x25,\n '↓': 0x28,\n '↑': 0x26,\n '→': 0x27\n }\n\n let touchMoved = false\n\n for (const shortcut in shortcuts) {\n const button = document.createElement('button')\n button.classList.add('shortcut-button')\n button.textContent = shortcut\n shortcutBar.appendChild(button)\n\n const key = shortcuts[shortcut]\n if (typeof key === 'string') button.classList.add('modifier')\n button.addEventListener('touchstart', e => {\n touchMoved = false\n if (typeof key === 'string') {\n // modifier button\n input.softModifiers[key] = true\n button.classList.add('enabled')\n\n // prevent default. This prevents scrolling, but also prevents the\n // selection popup\n e.preventDefault()\n }\n })\n window.addEventListener('touchmove', e => {\n touchMoved = true\n })\n button.addEventListener('touchend', e => {\n e.preventDefault()\n if (typeof key === 'number') {\n if (touchMoved) return\n let fakeEvent = { which: key, preventDefault: () => {} }\n input.handleKeyDown(fakeEvent)\n } else if (typeof key === 'string') {\n button.classList.remove('enabled')\n input.softModifiers[key] = false\n }\n })\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/soft_keyboard.js","const { mk } = require('../utils')\n\nmodule.exports = function attachDebugScreen (screen) {\n const debugCanvas = mk('canvas')\n const ctx = debugCanvas.getContext('2d')\n\n debugCanvas.classList.add('debug-canvas')\n\n let mouseHoverCell = null\n let updateToolbar\n\n let onMouseMove = e => {\n mouseHoverCell = screen.screenToGrid(e.offsetX, e.offsetY)\n startDrawing()\n updateToolbar()\n }\n let onMouseOut = () => (mouseHoverCell = null)\n\n let addCanvas = function () {\n if (!debugCanvas.parentNode) {\n screen.canvas.parentNode.appendChild(debugCanvas)\n screen.canvas.addEventListener('mousemove', onMouseMove)\n screen.canvas.addEventListener('mouseout', onMouseOut)\n }\n }\n let removeCanvas = function () {\n if (debugCanvas.parentNode) {\n debugCanvas.parentNode.removeChild(debugCanvas)\n screen.canvas.removeEventListener('mousemove', onMouseMove)\n screen.canvas.removeEventListener('mouseout', onMouseOut)\n onMouseOut()\n }\n }\n let updateCanvasSize = function () {\n let { width, height, devicePixelRatio } = screen.window\n let cellSize = screen.getCellSize()\n debugCanvas.width = width * cellSize.width * devicePixelRatio\n debugCanvas.height = height * cellSize.height * devicePixelRatio\n debugCanvas.style.width = `${width * cellSize.width}px`\n debugCanvas.style.height = `${height * cellSize.height}px`\n }\n\n let drawInfo = mk('div')\n drawInfo.classList.add('draw-info')\n\n let startTime, endTime, lastReason\n let cells = new Map()\n let clippedRects = []\n let updateFrames = []\n\n let startDrawing\n\n screen._debug = {\n drawStart (reason) {\n lastReason = reason\n startTime = Date.now()\n clippedRects = []\n },\n drawEnd () {\n endTime = Date.now()\n console.log(drawInfo.textContent = `Draw: ${lastReason} (${(endTime - startTime)} ms) with graphics=${screen.window.graphics}`)\n startDrawing()\n },\n setCell (cell, flags) {\n cells.set(cell, [flags, Date.now()])\n },\n clipRect (...args) {\n clippedRects.push(args)\n },\n pushFrame (frame) {\n frame.push(Date.now())\n updateFrames.push(frame)\n startDrawing()\n }\n }\n\n let clipPattern\n {\n let patternCanvas = document.createElement('canvas')\n patternCanvas.width = patternCanvas.height = 12\n let pctx = patternCanvas.getContext('2d')\n pctx.lineWidth = 1\n pctx.strokeStyle = '#00f'\n pctx.beginPath()\n pctx.moveTo(0, 0)\n pctx.lineTo(0 - 4, 12)\n pctx.moveTo(4, 0)\n pctx.lineTo(4 - 4, 12)\n pctx.moveTo(8, 0)\n pctx.lineTo(8 - 4, 12)\n pctx.moveTo(12, 0)\n pctx.lineTo(12 - 4, 12)\n pctx.moveTo(16, 0)\n pctx.lineTo(16 - 4, 12)\n pctx.stroke()\n clipPattern = ctx.createPattern(patternCanvas, 'repeat')\n }\n\n let isDrawing = false\n let lastDrawTime = 0\n let t = 0\n\n let drawLoop = function () {\n if (isDrawing) window.requestAnimationFrame(drawLoop)\n\n let dt = (Date.now() - lastDrawTime) / 1000\n lastDrawTime = Date.now()\n t += dt\n\n let { devicePixelRatio, width, height } = screen.window\n let { width: cellWidth, height: cellHeight } = screen.getCellSize()\n let screenLength = width * height\n let now = Date.now()\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0)\n ctx.clearRect(0, 0, width * cellWidth, height * cellHeight)\n\n let activeCells = 0\n for (let cell = 0; cell < screenLength; cell++) {\n if (!cells.has(cell) || cells.get(cell)[0] === 0) continue\n\n let [flags, timestamp] = cells.get(cell)\n let elapsedTime = (now - timestamp) / 1000\n\n if (elapsedTime > 1) continue\n\n activeCells++\n ctx.globalAlpha = 0.5 * Math.max(0, 1 - elapsedTime)\n\n let x = cell % width\n let y = Math.floor(cell / width)\n\n if (flags & 1) {\n // redrawn\n ctx.fillStyle = '#f0f'\n }\n if (flags & 2) {\n // updated\n ctx.fillStyle = '#0f0'\n }\n\n ctx.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight)\n\n if (flags & 4) {\n // wide cell\n ctx.lineWidth = 2\n ctx.strokeStyle = '#f00'\n ctx.strokeRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight)\n }\n }\n\n if (clippedRects.length) {\n ctx.globalAlpha = 0.5\n ctx.beginPath()\n\n for (let rect of clippedRects) {\n ctx.rect(...rect)\n }\n\n ctx.fillStyle = clipPattern\n ctx.fill()\n }\n\n let didDrawUpdateFrames = false\n if (updateFrames.length) {\n let framesToDelete = []\n for (let frame of updateFrames) {\n let time = frame[4]\n let elapsed = Date.now() - time\n if (elapsed > 1000) framesToDelete.push(frame)\n else {\n didDrawUpdateFrames = true\n ctx.globalAlpha = 1 - elapsed / 1000\n ctx.strokeStyle = '#ff0'\n ctx.lineWidth = 2\n ctx.strokeRect(frame[0] * cellWidth, frame[1] * cellHeight, frame[2] * cellWidth, frame[3] * cellHeight)\n }\n }\n for (let frame of framesToDelete) {\n updateFrames.splice(updateFrames.indexOf(frame), 1)\n }\n }\n\n if (mouseHoverCell) {\n ctx.save()\n ctx.globalAlpha = 1\n ctx.lineWidth = 1 + 0.5 * Math.sin(t * 10)\n ctx.strokeStyle = '#fff'\n ctx.lineJoin = 'round'\n ctx.setLineDash([2, 2])\n ctx.lineDashOffset = t * 10\n ctx.strokeRect(mouseHoverCell[0] * cellWidth, mouseHoverCell[1] * cellHeight, cellWidth, cellHeight)\n ctx.lineDashOffset += 2\n ctx.strokeStyle = '#000'\n ctx.strokeRect(mouseHoverCell[0] * cellWidth, mouseHoverCell[1] * cellHeight, cellWidth, cellHeight)\n ctx.restore()\n }\n\n if (activeCells === 0 && !mouseHoverCell && !didDrawUpdateFrames) {\n isDrawing = false\n removeCanvas()\n }\n }\n\n startDrawing = function () {\n if (isDrawing) return\n addCanvas()\n updateCanvasSize()\n isDrawing = true\n lastDrawTime = Date.now()\n drawLoop()\n }\n\n // debug toolbar\n const toolbar = mk('div')\n toolbar.classList.add('debug-toolbar')\n let toolbarAttached = false\n const dataDisplay = mk('div')\n dataDisplay.classList.add('data-display')\n toolbar.appendChild(dataDisplay)\n const internalDisplay = mk('div')\n internalDisplay.classList.add('internal-display')\n toolbar.appendChild(internalDisplay)\n toolbar.appendChild(drawInfo)\n const buttons = mk('div')\n buttons.classList.add('toolbar-buttons')\n toolbar.appendChild(buttons)\n\n {\n const redraw = mk('button')\n redraw.textContent = 'Redraw'\n redraw.addEventListener('click', e => {\n screen.renderer.resetDrawn()\n screen.renderer.draw('debug-redraw')\n })\n buttons.appendChild(redraw)\n\n const fancyGraphics = mk('button')\n fancyGraphics.textContent = 'Toggle Graphics'\n fancyGraphics.addEventListener('click', e => {\n screen.window.graphics = +!screen.window.graphics\n })\n buttons.appendChild(fancyGraphics)\n }\n\n const attachToolbar = function () {\n screen.canvas.parentNode.appendChild(toolbar)\n }\n const detachToolbar = function () {\n toolbar.parentNode.removeChild(toolbar)\n }\n\n screen.on('update-window:debug', debug => {\n if (debug !== toolbarAttached) {\n toolbarAttached = debug\n if (debug) attachToolbar()\n else {\n detachToolbar()\n removeCanvas()\n }\n }\n })\n\n const displayCellAttrs = attrs => {\n let result = attrs.toString(16)\n if (attrs & 1 || attrs & 2) {\n result += ':has('\n if (attrs & 1) result += 'fg'\n if (attrs & 2) result += (attrs & 1 ? ',' : '') + 'bg'\n result += ')'\n }\n let attributes = []\n if (attrs & (1 << 2)) attributes.push('\\\\[bold]bold\\\\()')\n if (attrs & (1 << 3)) attributes.push('\\\\[underline]underln\\\\()')\n if (attrs & (1 << 4)) attributes.push('\\\\[invert]invert\\\\()')\n if (attrs & (1 << 5)) attributes.push('blink')\n if (attrs & (1 << 6)) attributes.push('\\\\[italic]italic\\\\()')\n if (attrs & (1 << 7)) attributes.push('\\\\[strike]strike\\\\()')\n if (attrs & (1 << 8)) attributes.push('\\\\[overline]overln\\\\()')\n if (attrs & (1 << 9)) attributes.push('\\\\[faint]faint\\\\()')\n if (attrs & (1 << 10)) attributes.push('fraktur')\n if (attributes.length) result += ':' + attributes.join()\n return result.trim()\n }\n\n const formatColor = color => color < 256 ? color : `#${`000000${(color - 256).toString(16)}`.substr(-6)}`\n const getCellData = cell => {\n if (cell < 0 || cell > screen.screen.length) return '(-)'\n let cellAttrs = screen.renderer.drawnScreenAttrs[cell] | 0\n let cellFG = screen.renderer.drawnScreenFG[cell] | 0\n let cellBG = screen.renderer.drawnScreenBG[cell] | 0\n let fgText = formatColor(cellFG)\n let bgText = formatColor(cellBG)\n fgText += `\\\\[color=${screen.renderer.getColor(cellFG).replace(/ /g, '')}]●\\\\[]`\n bgText += `\\\\[color=${screen.renderer.getColor(cellBG).replace(/ /g, '')}]●\\\\[]`\n let cellCode = (screen.renderer.drawnScreen[cell] || '').codePointAt(0) | 0\n let hexcode = cellCode.toString(16).toUpperCase()\n if (hexcode.length < 4) hexcode = `0000${hexcode}`.substr(-4)\n hexcode = `U+${hexcode}`\n let x = cell % screen.window.width\n let y = Math.floor(cell / screen.window.width)\n return `((${y},${x})=${cell}:\\\\[bold]${hexcode}\\\\[]:F${fgText}:B${bgText}:A(${displayCellAttrs(cellAttrs)}))`\n }\n\n const setFormattedText = (node, text) => {\n node.innerHTML = ''\n\n let match\n let attrs = {}\n\n let pushSpan = content => {\n let span = mk('span')\n node.appendChild(span)\n span.textContent = content\n for (let key in attrs) span[key] = attrs[key]\n }\n\n while ((match = text.match(/\\\\\\[(.*?)\\]/))) {\n if (match.index > 0) pushSpan(text.substr(0, match.index))\n\n attrs = { style: '' }\n let data = match[1].split(' ')\n for (let attr of data) {\n if (!attr) continue\n let key, value\n if (attr.indexOf('=') > -1) {\n key = attr.substr(0, attr.indexOf('='))\n value = attr.substr(attr.indexOf('=') + 1)\n } else {\n key = attr\n value = true\n }\n\n if (key === 'color') console.log(value)\n\n if (key === 'bold') attrs.style += 'font-weight:bold;'\n if (key === 'italic') attrs.style += 'font-style:italic;'\n if (key === 'underline') attrs.style += 'text-decoration:underline;'\n if (key === 'invert') attrs.style += 'background:#000;filter:invert(1);'\n if (key === 'strike') attrs.style += 'text-decoration:line-through;'\n if (key === 'overline') attrs.style += 'text-decoration:overline;'\n if (key === 'faint') attrs.style += 'opacity:0.5;'\n else if (key === 'color') attrs.style += `color:${value};`\n else attrs[key] = value\n }\n\n text = text.substr(match.index + match[0].length)\n }\n\n if (text) pushSpan(text)\n }\n\n let internalInfo = {}\n\n updateToolbar = () => {\n if (!toolbarAttached) return\n let text = `C((${screen.cursor.y},${screen.cursor.x}),hang:${screen.cursor.hanging},vis:${screen.cursor.visible})`\n if (mouseHoverCell) {\n text += ' m' + getCellData(mouseHoverCell[1] * screen.window.width + mouseHoverCell[0])\n }\n setFormattedText(dataDisplay, text)\n\n if ('flags' in internalInfo) {\n // we got ourselves some internal data\n let text = ' '\n text += ` flags:${internalInfo.flags.toString(2)}`\n text += ` curAttrs:${internalInfo.cursorAttrs.toString(2)}`\n text += ` Region:${internalInfo.regionStart}->${internalInfo.regionEnd}`\n text += ` Charset:${internalInfo.charsetGx} (0:${internalInfo.charsetG0},1:${internalInfo.charsetG1})`\n text += ` Heap:${internalInfo.freeHeap}`\n text += ` Clients:${internalInfo.clientCount}`\n setFormattedText(internalDisplay, text)\n }\n }\n\n screen.on('draw', updateToolbar)\n screen.on('internal', data => {\n internalInfo = data\n updateToolbar()\n })\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/debug_screen.js","const { qs } = require('../utils')\n\nmodule.exports = function initButtons (input) {\n let container = qs('#action-buttons')\n\n // button labels\n let labels = []\n\n // button elements\n let buttons = []\n\n // add a button element\n let pushButton = function pushButton () {\n let button = document.createElement('button')\n button.classList.add('action-button')\n button.setAttribute('data-n', buttons.length)\n buttons.push(button)\n container.appendChild(button)\n\n button.addEventListener('click', e => {\n // might as well use the attribute ¯\\_(ツ)_/¯\n let index = +button.getAttribute('data-n')\n input.sendButton(index)\n })\n\n return button\n }\n\n // remove a button element\n let popButton = function popButton () {\n let button = buttons.pop()\n button.parentNode.removeChild(button)\n }\n\n // sync with DOM\n let update = function updateButtons () {\n if (labels.length > buttons.length) {\n for (let i = buttons.length; i < labels.length; i++) {\n pushButton()\n }\n } else if (buttons.length > labels.length) {\n for (let i = labels.length; i <= buttons.length; i++) {\n popButton()\n }\n }\n\n for (let i = 0; i < labels.length; i++) {\n let label = labels[i].trim()\n let button = buttons[i]\n button.textContent = label || '\\u00a0' // label or nbsp\n if (!label) button.classList.add('inactive')\n else button.classList.remove('inactive')\n }\n }\n\n return { update, labels }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/buttons.js","const ColorTriangle = require('./lib/colortriangle')\nconst $ = require('./lib/chibi')\nconst themes = require('./term/themes')\nconst { qs } = require('./utils')\n\nfunction selectedTheme () {\n return +$('#theme').val()\n}\n\nexports.init = function () {\n $('#theme').on('change', showColor)\n\n $('#default_fg').on('input', showColor)\n $('#default_bg').on('input', showColor)\n\n let opts = {\n padding: 10,\n event: 'drag',\n uppercase: true,\n trianglePointerSize: 20,\n // wheelPointerSize: 12,\n size: 200,\n parseColor: (color) => {\n return themes.toHex(color, selectedTheme())\n }\n }\n\n ColorTriangle.initInput(qs('#default_fg'), opts)\n ColorTriangle.initInput(qs('#default_bg'), opts)\n\n $('.colorprev.bg span').on('click', function () {\n const bg = this.dataset.bg\n if (typeof bg != 'undefined') $('#default_bg').val(bg)\n showColor()\n })\n\n $('.colorprev.fg span').on('click', function () {\n const fg = this.dataset.fg\n if (typeof fg != 'undefined') $('#default_fg').val(fg)\n showColor()\n })\n\n let $presets = $('#fgbg_presets')\n for (let i = 0; i < themes.fgbgThemes.length; i++) {\n const thm = themes.fgbgThemes[i]\n const fg = thm[0]\n const bg = thm[1]\n const lbl = thm[2]\n const tit = thm[3]\n $presets.htmlAppend(\n ' ' + lbl + ' ')\n\n if ((i + 1) % 5 === 0) $presets.htmlAppend('
')\n }\n\n $('.preset').on('click', function () {\n $('#default_fg').val(this.dataset.xfg)\n $('#default_bg').val(this.dataset.xbg)\n showColor()\n })\n\n showColor()\n}\n\nfunction showColor () {\n let ex = qs('.color-example')\n let fg = $('#default_fg').val()\n let bg = $('#default_bg').val()\n\n if (/^\\d+$/.test(fg)) {\n fg = +fg\n } else if (!/^#[\\da-f]{6}$/i.test(fg)) {\n fg = 'black'\n }\n\n if (/^\\d+$/.test(bg)) {\n bg = +bg\n } else if (!/^#[\\da-f]{6}$/i.test(bg)) {\n bg = 'black'\n }\n\n const themeN = selectedTheme()\n ex.dataset.fg = fg\n ex.dataset.bg = bg\n\n themes.themePreview(themeN)\n\n $('.colorprev.fg span').css('background', themes.toHex(bg, themeN))\n}\n\nexports.nextTheme = () => {\n let sel = qs('#theme')\n let i = sel.selectedIndex\n sel.options[++i % sel.options.length].selected = true\n showColor()\n}\n\nexports.prevTheme = () => {\n let sel = qs('#theme')\n let i = sel.selectedIndex\n sel.options[(sel.options.length + (--i)) % sel.options.length].selected = true\n showColor()\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term_conf.js","/*\n * Copyright (c) 2010 Tim Baumann\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// NOTE: Converted to ES6 by MightyPork (2017)\n// Modified for ESPTerm\n\nconst EventEmitter = require('events')\nconst {\n rgb2hex,\n hex2rgb,\n hsl2rgb,\n rgb2hsl\n} = require('./color_utils')\n\nconst win = window\nconst doc = document\nconst M = Math\nconst TAU = 2 * M.PI\n\nfunction times (i, fn) {\n for (let j = 0; j < i; j++) {\n fn(j)\n }\n}\n\nfunction each (obj, fn) {\n if (obj.length) {\n times(obj.length, function (i) {\n fn(obj[i], i)\n })\n } else {\n for (let key in obj) {\n if (obj.hasOwnProperty(key)) {\n fn(obj[key], key)\n }\n }\n }\n}\n\nmodule.exports = class ColorTriangle extends EventEmitter {\n /****************\n * ColorTriangle *\n ****************/\n\n // Constructor function:\n constructor (color, options) {\n super()\n\n this.options = {\n size: 150,\n padding: 8,\n triangleSize: 0.8,\n wheelPointerColor1: '#444',\n wheelPointerColor2: '#eee',\n trianglePointerSize: 16,\n // wheelPointerSize: 16,\n trianglePointerColor1: '#eee',\n trianglePointerColor2: '#444',\n background: 'transparent'\n }\n\n this.pixelRatio = window.devicePixelRatio\n\n this.setOptions(options)\n this.calculateProperties()\n\n this.createContainer()\n this.createTriangle()\n this.createWheel()\n this.createWheelPointer()\n this.createTrianglePointer()\n this.attachEvents()\n\n color = color || '#f00'\n if (typeof color == 'string') {\n this.setHEX(color)\n }\n }\n\n calculateProperties () {\n let opts = this.options\n\n this.padding = opts.padding\n this.innerSize = opts.size - opts.padding * 2\n this.triangleSize = opts.triangleSize * this.innerSize\n this.wheelThickness = (this.innerSize - this.triangleSize) / 2\n this.wheelPointerSize = opts.wheelPointerSize || this.wheelThickness\n\n this.wheelRadius = (this.innerSize) / 2\n this.triangleRadius = (this.triangleSize) / 2\n this.triangleSideLength = M.sqrt(3) * this.triangleRadius\n }\n\n calculatePositions () {\n const r = this.triangleRadius\n const hue = this.hue\n const third = TAU / 3\n const s = this.saturation\n const l = this.lightness\n\n // Colored point\n const hx = this.hx = M.cos(hue) * r\n const hy = this.hy = -M.sin(hue) * r\n // Black point\n const sx = this.sx = M.cos(hue - third) * r\n const sy = this.sy = -M.sin(hue - third) * r\n // White point\n const vx = this.vx = M.cos(hue + third) * r\n const vy = this.vy = -M.sin(hue + third) * r\n // Current point\n const mx = (sx + vx) / 2\n const my = (sy + vy) / 2\n const a = (1 - 2 * M.abs(l - 0.5)) * s\n this.x = sx + (vx - sx) * l + (hx - mx) * a\n this.y = sy + (vy - sy) * l + (hy - my) * a\n }\n\n createContainer () {\n let c = this.container = doc.createElement('div')\n c.className = 'color-triangle'\n\n c.style.display = 'block'\n c.style.padding = `${this.padding}px`\n c.style.position = 'relative'\n c.style.boxShadow = '0 1px 10px black'\n c.style.borderRadius = '5px'\n c.style.width = c.style.height = `${this.innerSize + 2 * this.padding}px`\n c.style.background = this.options.background\n }\n\n createWheel () {\n let c = this.wheel = doc.createElement('canvas')\n c.width = c.height = this.innerSize * this.pixelRatio\n c.style.width = c.style.height = `${this.innerSize}px`\n c.style.position = 'absolute'\n c.style.margin = c.style.padding = '0'\n c.style.left = c.style.top = `${this.padding}px`\n\n this.drawWheel(c.getContext('2d'))\n this.container.appendChild(c)\n }\n\n drawWheel (ctx) {\n let s, i\n\n ctx.save()\n ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0)\n ctx.translate(this.wheelRadius, this.wheelRadius)\n s = this.wheelRadius - this.triangleRadius\n // Draw a circle for every color\n for (i = 0; i < 360; i++) {\n ctx.rotate(TAU / -360) // rotate one degree\n ctx.beginPath()\n ctx.fillStyle = 'hsl(' + i + ', 100%, 50%)'\n ctx.arc(this.wheelRadius - (s / 2), 0, s / 2, 0, TAU, true)\n ctx.fill()\n }\n ctx.restore()\n }\n\n createTriangle () {\n let c = this.triangle = doc.createElement('canvas')\n\n c.width = c.height = this.innerSize * this.pixelRatio\n c.style.width = c.style.height = `${this.innerSize}px`\n c.style.position = 'absolute'\n c.style.margin = c.style.padding = '0'\n c.style.left = c.style.top = this.padding + 'px'\n\n this.triangleCtx = c.getContext('2d')\n\n this.container.appendChild(c)\n }\n\n drawTriangle () {\n const hx = this.hx\n const hy = this.hy\n const sx = this.sx\n const sy = this.sy\n const vx = this.vx\n const vy = this.vy\n const size = this.innerSize\n\n let ctx = this.triangleCtx\n\n // clear\n ctx.clearRect(0, 0, size * this.pixelRatio, size * this.pixelRatio)\n\n ctx.save()\n ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0)\n ctx.translate(this.wheelRadius, this.wheelRadius)\n\n // make a triangle\n ctx.beginPath()\n ctx.moveTo(hx, hy)\n ctx.lineTo(sx, sy)\n ctx.lineTo(vx, vy)\n ctx.closePath()\n ctx.clip()\n\n ctx.fillStyle = '#000'\n ctx.fillRect(-this.wheelRadius, -this.wheelRadius, size, size)\n // => black triangle\n\n // create gradient from hsl(hue, 1, 1) to transparent\n let grad0 = ctx.createLinearGradient(hx, hy, (sx + vx) / 2, (sy + vy) / 2)\n const hsla = 'hsla(' + M.round(this.hue * (360 / TAU)) + ', 100%, 50%, '\n grad0.addColorStop(0, hsla + '1)')\n grad0.addColorStop(1, hsla + '0)')\n ctx.fillStyle = grad0\n ctx.fillRect(-this.wheelRadius, -this.wheelRadius, size, size)\n // => gradient: one side of the triangle is black, the opponent angle is $color\n\n // create color gradient from white to transparent\n let grad1 = ctx.createLinearGradient(vx, vy, (hx + sx) / 2, (hy + sy) / 2)\n grad1.addColorStop(0, '#fff')\n grad1.addColorStop(1, 'rgba(255, 255, 255, 0)')\n ctx.globalCompositeOperation = 'lighter'\n ctx.fillStyle = grad1\n ctx.fillRect(-this.wheelRadius, -this.wheelRadius, size, size)\n // => white angle\n\n ctx.restore()\n }\n\n // The two pointers\n createWheelPointer () {\n let c = this.wheelPointer = doc.createElement('canvas')\n const size = this.wheelPointerSize\n c.width = c.height = size * this.pixelRatio\n c.style.width = c.style.height = `${size}px`\n c.style.position = 'absolute'\n c.style.margin = c.style.padding = '0'\n this.drawPointer(c.getContext('2d'), size / 2, this.options.wheelPointerColor1, this.options.wheelPointerColor2)\n this.container.appendChild(c)\n }\n\n moveWheelPointer () {\n const r = this.wheelPointerSize / 2\n const s = this.wheelPointer.style\n s.top = this.padding + this.wheelRadius - M.sin(this.hue) * (this.triangleRadius + this.wheelThickness / 2) - r + 'px'\n s.left = this.padding + this.wheelRadius + M.cos(this.hue) * (this.triangleRadius + this.wheelThickness / 2) - r + 'px'\n }\n\n createTrianglePointer () { // create pointer in the triangle\n let c = this.trianglePointer = doc.createElement('canvas')\n const size = this.options.trianglePointerSize\n\n c.width = c.height = size * this.pixelRatio\n c.style.width = c.style.height = `${size}px`\n c.style.position = 'absolute'\n c.style.margin = c.style.padding = '0'\n this.drawPointer(c.getContext('2d'), size / 2, this.options.trianglePointerColor1, this.options.trianglePointerColor2)\n this.container.appendChild(c)\n }\n\n moveTrianglePointer (x, y) {\n const s = this.trianglePointer.style\n const r = this.options.trianglePointerSize / 2\n s.top = (this.y + this.wheelRadius + this.padding - r) + 'px'\n s.left = (this.x + this.wheelRadius + this.padding - r) + 'px'\n }\n\n drawPointer (ctx, r, color1, color2) {\n ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0)\n ctx.fillStyle = color2\n ctx.beginPath()\n ctx.arc(r, r, r, 0, TAU, true)\n ctx.fill() // => black circle\n ctx.fillStyle = color1\n ctx.beginPath()\n ctx.arc(r, r, r - 2, 0, TAU, true)\n ctx.fill() // => white circle with 1px black border\n ctx.fillStyle = color2\n ctx.beginPath()\n ctx.arc(r, r, r / 4 + 2, 0, TAU, true)\n ctx.fill() // => black circle with big white border and a small black border\n ctx.globalCompositeOperation = 'destination-out'\n ctx.beginPath()\n ctx.arc(r, r, r / 4, 0, TAU, true)\n ctx.fill() // => transparent center\n }\n\n // The Element and the DOM\n inject (parent) {\n parent.appendChild(this.container)\n }\n\n getRelativeCoordinates (evt) {\n let elem = this.triangle\n let rect = elem.getBoundingClientRect()\n\n return {\n x: evt.clientX - rect.x,\n y: evt.clientY - rect.y\n }\n }\n\n dispose () {\n let parent = this.container.parentNode\n if (parent) {\n parent.removeChild(this.container)\n }\n }\n\n getElement () {\n return this.container\n }\n\n // Color accessors\n getCSS () {\n const h = Math.round(this.hue * (360 / TAU))\n const s = Math.round(this.saturation * 100)\n const l = Math.round(this.lightness * 100)\n\n return `hsl(${h}, ${s}%, ${l}%)`\n }\n\n getHEX () {\n return rgb2hex(...this.getRGB())\n }\n\n setHEX (hex) {\n this.setRGB(...hex2rgb(hex))\n }\n\n getRGB () {\n return hsl2rgb(...this.getHSL())\n }\n\n setRGB (r, g, b) {\n this.setHSL(...rgb2hsl(r, g, b))\n }\n\n getHSL () {\n return [this.hue, this.saturation, this.lightness]\n }\n\n setHSL (h, s, l) {\n this.hue = h\n this.saturation = s\n this.lightness = l\n\n this.initColor()\n }\n\n initColor () {\n this.calculatePositions()\n this.moveWheelPointer()\n this.drawTriangle()\n this.moveTrianglePointer()\n }\n\n // Mouse event handling\n attachEvents () {\n this.down = null\n\n let mousedown = (evt) => {\n evt.stopPropagation()\n evt.preventDefault()\n\n doc.body.addEventListener('mousemove', mousemove, false)\n doc.body.addEventListener('mouseup', mouseup, false)\n\n let xy = this.getRelativeCoordinates(evt)\n this.map(xy.x, xy.y)\n }\n\n let mousemove = (evt) => {\n let xy = this.getRelativeCoordinates(evt)\n this.move(xy.x, xy.y)\n }\n\n let mouseup = (evt) => {\n if (this.down) {\n this.down = null\n this.emit('dragend')\n }\n doc.body.removeEventListener('mousemove', mousemove, false)\n doc.body.removeEventListener('mouseup', mouseup, false)\n }\n\n this.container.addEventListener('mousedown', mousedown, false)\n this.container.addEventListener('mousemove', mousemove, false)\n }\n\n map (x, y) {\n let x0 = x\n let y0 = y\n x -= this.wheelRadius\n y -= this.wheelRadius\n\n const r = M.sqrt(x * x + y * y) // Pythagoras\n if (r > this.triangleRadius && r < this.wheelRadius) {\n // Wheel\n this.down = 'wheel'\n this.emit('dragstart')\n this.move(x0, y0)\n } else if (r < this.triangleRadius) {\n // Inner circle\n this.down = 'triangle'\n this.emit('dragstart')\n this.move(x0, y0)\n }\n }\n\n move (x, y) {\n if (!this.down) {\n return\n }\n\n x -= this.wheelRadius\n y -= this.wheelRadius\n\n let rad = M.atan2(-y, x)\n if (rad < 0) {\n rad += TAU\n }\n\n if (this.down === 'wheel') {\n this.hue = rad\n this.initColor()\n this.emit('drag')\n } else if (this.down === 'triangle') {\n // get radius and max radius\n let rad0 = (rad + TAU - this.hue) % TAU\n let rad1 = rad0 % (TAU / 3) - (TAU / 6)\n let a = 0.5 * this.triangleRadius\n let b = M.tan(rad1) * a\n let r = M.sqrt(x * x + y * y) // Pythagoras\n let maxR = M.sqrt(a * a + b * b) // Pythagoras\n\n if (r > maxR) {\n const dx = M.tan(rad1) * r\n let rad2 = M.atan(dx / maxR)\n if (rad2 > TAU / 6) {\n rad2 = TAU / 6\n } else if (rad2 < -TAU / 6) {\n rad2 = -TAU / 6\n }\n rad += rad2 - rad1\n\n rad0 = (rad + TAU - this.hue) % TAU\n rad1 = rad0 % (TAU / 3) - (TAU / 6)\n b = M.tan(rad1) * a\n r = maxR = M.sqrt(a * a + b * b) // Pythagoras\n }\n\n x = M.round(M.cos(rad) * r)\n y = M.round(-M.sin(rad) * r)\n\n const l = this.lightness = ((M.sin(rad0) * r) / this.triangleSideLength) + 0.5\n\n const widthShare = 1 - (M.abs(l - 0.5) * 2)\n let s = this.saturation = (((M.cos(rad0) * r) + (this.triangleRadius / 2)) / (1.5 * this.triangleRadius)) / widthShare\n s = M.max(0, s) // cannot be lower than 0\n s = M.min(1, s) // cannot be greater than 1\n\n this.lightness = l\n this.saturation = s\n\n this.x = x\n this.y = y\n this.moveTrianglePointer()\n\n this.emit('drag')\n }\n }\n\n /***************\n * Init helpers *\n ***************/\n\n static initInput (input, options) {\n options = options || {}\n\n let ct\n let openColorTriangle = function () {\n let hex = input.value\n if (options.parseColor) hex = options.parseColor(hex)\n if (!ct) {\n options.size = options.size || input.offsetWidth\n options.background = win.getComputedStyle(input, null).backgroundColor\n options.margin = options.margin || 10\n options.event = options.event || 'dragend'\n\n ct = new ColorTriangle(hex, options)\n ct.on(options.event, () => {\n const hex = ct.getHEX()\n input.value = options.uppercase ? hex.toUpperCase() : hex\n fireChangeEvent()\n })\n } else {\n ct.setHEX(hex)\n }\n\n let top = input.offsetTop\n if (win.innerHeight - input.getBoundingClientRect().top > input.offsetHeight + options.margin + options.size) {\n top += input.offsetHeight + options.margin // below\n } else {\n top -= options.margin + options.size // above\n }\n\n let el = ct.getElement()\n el.style.position = 'absolute'\n el.style.left = input.offsetLeft + 'px'\n el.style.top = top + 'px'\n el.style.zIndex = '1338' // above everything\n\n ct.inject(input.parentNode)\n }\n\n let closeColorTriangle = () => {\n if (ct) {\n ct.dispose()\n }\n }\n\n let fireChangeEvent = () => {\n let evt = doc.createEvent('HTMLEvents')\n evt.initEvent('input', true, false) // bubbles = true, cancable = false\n input.dispatchEvent(evt) // fire event\n }\n\n input.addEventListener('focus', openColorTriangle, false)\n input.addEventListener('blur', closeColorTriangle, false)\n input.addEventListener('keyup', () => {\n const val = input.value\n if (val.match(/^#((?:[0-9A-Fa-f]{3})|(?:[0-9A-Fa-f]{6}))$/)) {\n openColorTriangle()\n fireChangeEvent()\n } else {\n closeColorTriangle()\n }\n }, false)\n }\n\n /*******************\n * Helper functions *\n *******************/\n\n setOptions (opts) {\n opts = opts || {}\n let dflt = this.options\n let options = this.options = {}\n\n each(dflt, function (val, key) {\n options[key] = (opts.hasOwnProperty(key))\n ? opts[key]\n : val\n })\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/lib/colortriangle.js"],"sourceRoot":""}