See espterm.github.io
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
espterm-demo-website/js/app.69e5b77.js.map

1 lines
646 KiB

{"version":3,"sources":["webpack:///app.69e5b77.js","webpack:///webpack/bootstrap a7b91f69eb799b1cbf4b","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:///./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","1","2","3","terminal","shell","4","5","child","destroy","chars","loop","substr","mouseReceiver","demoshIndex","Clear","_Process","screenfetch","Screenfetch","_Process2","_this6","image","location","hostname","devicePixelRatio","filter","line","trim","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","_this13","_Process7","maxnum","Number","isFinite","drawnScreenFG","ShowThemes","_Process8","hex","parseInt","col","SetCursor","_Process9","_len3","_key3","steady","ToggleRainbow","_this16","su","_Process10","_didWarnRainbow","mouse","ShowMouse","_this17","_Process11","randomData","highlighted","random","scrollOffset","render","lineData","button","sudo","Sudo","_this18","didDestroy","_Process12","_this19","_len4","_key4","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","demoInterface","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","_tr","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","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","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","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","cellCode","hexcode","setFormattedText","node","pushSpan","internalInfo","container","pushButton","popButton","label","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.69e5b77.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'&': '&amp;',\n\t\t'<': '&lt;',\n\t\t'>': '&gt;',\n\t\t'\"': '&quot;',\n\t\t\"'\": '&#39;',\n\t\t'/': '&#x2F;',\n\t\t'`': '&#x60;',\n\t\t'=': '&#x3D;'\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 = ['', '', '^C', '', 'Help'];\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(5);\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 1: '',\n 2: '',\n 3: function _(terminal, shell) {\n return shell.write('\\x03');\n },\n 4: '',\n 5: function _(terminal, shell) {\n if (shell.child) shell.child.destroy();\n var chars = 'info\\r';\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 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.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 child.on('write', write);\n child.on('exit', function (code) {\n child.removeListener('write', write);\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 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 }, {\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) {\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.child = new Process(this);\n var write = function write(data) {\n return _this23.terminal.write(data);\n };\n this.child.on('write', write);\n this.child.on('exit', function (code) {\n if (_this23.child) _this23.child.removeListener('write', write);\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\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 var action = demoData.buttons[button];\n if (action) {\n if (typeof action === 'string') this.shell.write(action);else if (action instanceof Function) action(this.terminal, this.shell);\n }\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\n// Generated from PHP locale file\nvar _tr = {\n \"wifi.connected_ip_is\": \"Connected, IP is \",\n \"wifi.not_conn\": \"Not connected.\",\n \"wifi.enter_passwd\": \"Enter password for \\\":ssid:\\\"\",\n \"term_nav.fullscreen\": \"Fullscreen\",\n \"term_conn.connecting\": \"Connecting\",\n \"term_conn.waiting_content\": \"Waiting for content\",\n \"term_conn.disconnected\": \"Disconnected\",\n \"term_conn.waiting_server\": \"Waiting for server\",\n \"term_conn.reconnecting\": \"Reconnecting\"\n};\n\nmodule.exports = function tr(key) {\n return _tr[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__(13);\nwindow.$ = $;\nwindow.qs = qs;\n\nwindow.themes = __webpack_require__(5);\n\nwindow.TermConf = __webpack_require__(23);\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' + '<span class=\"anim-dots\" style=\"width:1.5em;text-align:left;display:inline-block\">.</span>';\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('<div class=\"rssi\">' + ap.rssi_perc + '</div>').htmlAppend('<div class=\"essid\" title=\"' + escapedSSID + '\">' + escapedSSID + '</div>').htmlAppend('<div class=\"auth\">' + authTypes[ap.enc] + '</div>');\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, __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__(14);\nvar TermConnection = __webpack_require__(17);\nvar TermInput = __webpack_require__(18);\nvar TermUpload = __webpack_require__(19);\nvar initSoftKeyboard = __webpack_require__(20);\nvar attachDebugScreen = __webpack_require__(21);\nvar initButtons = __webpack_require__(22);\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('<b>JS ERROR!</b><br>' + errorMsg + '<br>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/* 14 */\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__(15);\nvar ScreenRenderer = __webpack_require__(16);\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/* 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 _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/* 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 _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/* 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\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/* 18 */\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/* 19 */\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 () {\n openUploadDialog();\n return false;\n });\n\n qs('#term-fu-start').addEventListener('click', function () {\n startUpload();\n return false;\n });\n\n qs('#term-fu-close').addEventListener('click', function () {\n fuClose();\n return false;\n });\n },\n open: openUploadDialog,\n setContent: function setContent(content) {\n qs('#fu_text').value = content;\n }\n };\n};\n\n/***/ }),\n/* 20 */\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 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/* 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\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 = formatColor(screen.renderer.drawnScreenFG[cell]) | 0;\n var cellBG = formatColor(screen.renderer.drawnScreenBG[cell]) | 0;\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' + cellFG + ':B' + cellBG + ':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 === '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/* 22 */\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) {\n button.classList.add('inactive');\n }\n }\n };\n\n return { update: update, labels: labels };\n};\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar ColorTriangle = __webpack_require__(24);\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('<span class=\"preset\" ' + 'data-xfg=\"' + fg + '\" data-xbg=\"' + bg + '\" ' + 'style=\"color:' + fg + ';background:' + bg + '\" title=\"' + tit + '\">&nbsp;' + lbl + '&nbsp;</span>');\n\n if ((i + 1) % 5 === 0) $presets.htmlAppend('<br>');\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/* 24 */\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.69e5b77.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 a7b91f69eb799b1cbf4b","/** 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'&': '&amp;',\n\t\t'<': '&lt;',\n\t\t'>': '&gt;',\n\t\t'\"': '&quot;',\n\t\t\"'\": '&#39;',\n\t\t'/': '&#x2F;',\n\t\t'`': '&#x60;',\n\t\t'=': '&#x3D;'\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 = ['', '', '^C', '', 'Help']\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(5)\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 1: '',\n 2: '',\n 3: (terminal, shell) => shell.write('\\x03'),\n 4: '',\n 5: function (terminal, shell) {\n if (shell.child) shell.child.destroy()\n let chars = 'info\\r'\n let loop = function () {\n shell.write(chars[0])\n chars = chars.substr(1)\n if (chars) setTimeout(loop, 100)\n }\n setTimeout(loop, 200)\n }\n },\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.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 child.on('write', write)\n child.on('exit', code => {\n child.removeListener('write', write)\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 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 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) {\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.child = new Process(this)\n let write = data => this.terminal.write(data)\n this.child.on('write', write)\n this.child.on('exit', code => {\n if (this.child) this.child.removeListener('write', write)\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\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 let action = demoData.buttons[button]\n if (action) {\n if (typeof action === 'string') this.shell.write(action)\n else if (action instanceof Function) action(this.terminal, this.shell)\n }\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","// Generated from PHP locale file\nlet _tr = {\n \"wifi.connected_ip_is\": \"Connected, IP is \",\n \"wifi.not_conn\": \"Not connected.\",\n \"wifi.enter_passwd\": \"Enter password for \\\":ssid:\\\"\",\n \"term_nav.fullscreen\": \"Fullscreen\",\n \"term_conn.connecting\": \"Connecting\",\n \"term_conn.waiting_content\": \"Waiting for content\",\n \"term_conn.disconnected\": \"Disconnected\",\n \"term_conn.waiting_server\": \"Waiting for server\",\n \"term_conn.reconnecting\": \"Reconnecting\"\n};\n\nmodule.exports = function tr (key) { return _tr[key] || '?' + key + '?' }\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 '<span class=\"anim-dots\" style=\"width:1.5em;text-align:left;display:inline-block\">.</span>'\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(`<div class=\"rssi\">${ap.rssi_perc}</div>`)\n .htmlAppend(`<div class=\"essid\" title=\"${escapedSSID}\">${escapedSSID}</div>`)\n .htmlAppend(`<div class=\"auth\">${authTypes[ap.enc]}</div>`)\n\n $item.on('click', function () {\n let $th = $(this)\n\n const conn_ssid = $th.data('ssid')\n let conn_pass = ''\n\n if (+$th.data('pwd')) {\n // this AP needs a password\n conn_pass = 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","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(`<b>JS ERROR!</b><br>${errorMsg}<br>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', function () {\n openUploadDialog()\n return false\n })\n\n qs('#term-fu-start').addEventListener('click', function () {\n startUpload()\n return false\n })\n\n qs('#term-fu-close').addEventListener('click', function () {\n fuClose()\n return false\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 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 = formatColor(screen.renderer.drawnScreenFG[cell]) | 0\n let cellBG = formatColor(screen.renderer.drawnScreenBG[cell]) | 0\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${cellFG}:B${cellBG}: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 === '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) {\n button.classList.add('inactive')\n }\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 '<span class=\"preset\" ' +\n 'data-xfg=\"' + fg + '\" data-xbg=\"' + bg + '\" ' +\n 'style=\"color:' + fg + ';background:' + bg + '\" title=\"' + tit + '\">&nbsp;' + lbl + '&nbsp;</span>')\n\n if ((i + 1) % 5 === 0) $presets.htmlAppend('<br>')\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":""}