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.8b43b1d-en.js.map

1 lines
759 KiB

{"version":3,"sources":["webpack:///app.8b43b1d-en.js","webpack:///webpack/bootstrap ed37efe935ee7fa8c127","webpack:///./js/utils.js","webpack:///./js/lib/chibi.js","webpack:///./node_modules/events/events.js","webpack:///./js/term/themes.js","webpack:///./js/modal.js","webpack:///./js/notif.js","webpack:///./js/term/screen_attr_bits.js","webpack:///./js/lib/color_utils.js","webpack:///./js/term/demo.js","webpack:///./js/lang.js","webpack:///./js/index.js","webpack:///./js/lib/polyfills.js","webpack:///./js/appcommon.js","webpack:///./js/wifi.js","webpack:///./lang/en.php","webpack:///./js/term/index.js","webpack:///./js/term/screen.js","webpack:///./js/term/screen_parser.js","webpack:///./js/term/screen_layout.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.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","EventEmitter","this","_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","ensureColorTable256","getColor","palette","substr","Math","floor","now","modal","curCloseCb","sel","closeCb","$m","init","stopImmediatePropagation","nt","$balloon","timerHideBegin","timerHideEnd","canCancel","stopTimeouts","message","isError","ATTR_FG","ATTR_BG","ATTR_BOLD","ATTR_UNDERLINE","ATTR_INVERSE","ATTR_BLINK","ATTR_ITALIC","ATTR_STRIKE","ATTR_OVERLINE","ATTR_FAINT","ATTR_FRAKTUR","pad","M","TAU","PI","hue2rgb","v1","v2","h","hsl2rgb","r","b","var_1","var_2","rgb2hsl","min","max","d_r","d_g","d_b","hex2rgb","hex","groups","match","bytes","pow","map","x","parseInt","join","rgb2hex","round","_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","numOr1","number","mode","text","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_step","_iterator","next","done","character","code","codePointAt","parseSequence","return","TERM_DEFAULT_STYLE","getRainbowColor","t","sin","ScrollingTerminal","screen","_this","width","height","termScreen","parser","handleParsed","buttonLabels","_lastLoad","loadTimer","showPage","cursor","y","visible","trackMouse","theme","defaultFG","defaultBG","rainbow","superRainbow","clear","scroll","newLine","moveBack","writeChar","deleteForward","insertBlanks","load","clampCursor","write","encodeColor","attributes","serialized","lastStyle","index","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_iterator2","cell","foreground","background","setForeground","setBackground","setAttributes","topicData","screenOpts","getScreenOpts","title","getTitle","buttons","getButtons","getCursor","serializeScreen","_screenOpts","_title","_buttons","_cursor","_screen","_this2","clearInterval","_loadTimer","setInterval","update","getUpdate","Process","_EventEmitter","demoData","mouseReceiver","demoshIndex","Clear","_Process","destroy","screenfetch","Screenfetch","_Process2","_this6","image","location","hostname","devicePixelRatio","filter","line","trim","chars","loop","local-echo","_Process3","LocalEcho","_len","_key","includes","label","shell","info","Info","_Process4","_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","terminal","drawnScreenFG","ShowThemes","_this14","_Process8","savedCursorStyle","_this15","fgType","bgType","get24FG","set24FG","v","get24BG","set24BG","make24Control","getValue","setValue","getDisplay","shouldShow","parseValue","input","moveAfterInput","controls","count","selection","render","selectedX","_iteratorNormalCompletion3","_didIteratorError3","_iteratorError3","_step3","_iterator3","control","_iteratorNormalCompletion4","_didIteratorError4","_iteratorError4","_step4","_iterator4","_iteratorNormalCompletion5","_didIteratorError5","_iteratorError5","_step5","_iterator5","_console","_len3","_key3","log","concat","getControlCount","getSelectedControl","parsed","SetCursor","_Process9","_len4","_key4","steady","ToggleRainbow","_this17","su","_Process10","_didWarnRainbow","mouse","MouseDemo","_this18","_Process11","_this19","boxes","generateRandomBox","grabbedBox","grabOffset","_iteratorNormalCompletion6","_didIteratorError6","_iteratorError6","_step6","_iterator6","box","drawnX","random","reverse","_iteratorNormalCompletion7","_didIteratorError7","_iteratorError7","_step7","_iterator7","button","scrollInsideBox","getBoxAt","_boxes","amount","sudo","Sudo","_this20","didDestroy","_Process12","_this21","_len5","_key5","child","setButtons","run","make","Make","_this22","_Process14","_len6","_key6","pwd","cd","whoami","navigator","userAgent","uname","mkdir","rm","cp","mv","ln","touch","exit","github","GoToGithub","_Process15","autocompleteIndex","DemoShell","printInfo","_this24","history","historyIndex","cursorPos","lastInputLength","prompt","success","unshift","current","visual","prefix","startsWith","newInput","copyFromHistoryIndex","completed","getCompleted","words","moveForward","rest","parse","command","inQuote","_iteratorNormalCompletion8","_didIteratorError8","_iteratorError8","_step8","_iterator8","spawn","_this25","_child","writeChars","demoInterface","onButtonPress","row","column","modifiers","mouseMove","mouseDown","mouseUp","didInit","termInit","TermConf","$defineProperty","stringFromCharCode","highSurrogate","lowSurrogate","codeUnits","codePoint","RangeError","pageShown","notify","menuOpen","inp","keyCode","ctrlKey","submit","$x","dots","$this","step","deltaY","evt","createEvent","initEvent","dispatchEvent","fireEvent","preventDefault","msgAt","search","errs","decodeURIComponent","humanReadableErrors","lbls","lbl","childNodes","textContent","JSON","stringify","fademsgbox","time","msg","innerWidth","removeAttribute","br","href","vis","noAutoShow","bnr","id","tr","HTTPS","protocol","calc_dBm","toFixed","selectSta","password","ip","hasPassword","onScan","resp","rescan","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","wifiInit","cfg","disp1","disp2","sta_ssid","sta_password","sta_active_ip","sta_active_ssid","WiFi","wifi.connected_ip_is","wifi.not_conn","wifi.enter_passwd","term_nav.fullscreen","term_conn.connecting","term_conn.waiting_content","term_conn.disconnected","term_conn.waiting_server","term_conn.reconnecting","localize","Notify","TermScreen","TermConnection","TermInput","TermUpload","initSoftKeyboard","attachDebugger","initButtons","conn","termUpload","onMouseDown","onMouseMove","onMouseUp","onMouseWheel","setAlts","setMouseMode","touchSelectMenu","rect","getBoundingClientRect","transform","copyButton","copySelectionToClipboard","labels","layout","renderer","scr","errmsg","setLinkVisibility","setButtonVisibility","showLinks","showButtons","showSplashTimeout","delay","statusScreen","loading","screenFG","screenBG","screenAttrs","onerror","errorMsg","file","col","canvas","fullscreenIcon","isFullscreen","properFullscreen","fitScreen","screenPadding","padding","fitScreenIfNeeded","fitIntoWidth","fitIntoHeight","innerHeight","toggleFitScreen","resizeButtonIcon","Element","requestFullscreen","webkitRequestFullscreen","checkForFullscreen","body","updateSize","span","termUpl","ScreenParser","ScreenLayout","_debug","audioCtx","AudioContext","webkitAudioContext","warn","_window","debug","Proxy","updateLayout","renderScreen","blinking","hanging","selectable","start","end","setSelectable","mouseMode","clicks","movement","bracketedPaste","blinkingCellCount","reverseVideo","screenLines","selecting","selectStart","screenToGrid","selectMove","selectEnd","getNormalizedSelection","altKey","offsetX","offsetY","touchPosition","touchDownTime","touchDidMove","getTouchPositionOffset","clientX","left","clientY","top","touches","_this$layout","_this$layout2","selectionPos","gridToScreen","_this$layout3","resetSelection","aggregateWheelDelta","wheelDeltaY","reason","isInSelection","screenSelection","hasBlinkingCells","_selection","_ref","_getNormalizedSelecti","colAfterStart","colBeforeEnd","onStartLine","onEndLine","screenLength","lines","previousLineIndex","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","updates","topic","resetScreen","loadTheme","setDefaultColors","defFG","defBG","cursorVisible","inputAlts","trackMouseClicks","trackMouseMovement","cursorBlinking","resetCursorBlink","cursorStyle","debugEnabled","showConfigLinks","fontFamily","fontStack","fontSize","backgroundImage","beep","frameX","frameY","frameWidth","frameHeight","cells","pushFrame","cellXInFrame","cellYInFrame","showNotification","du","str","NaN","num","contentLoaded","ci","strArray","topics","collectOneTerminatedString","collectColor","cursorShape","flags","cursorAttrs","regionStart","regionEnd","charsetGx","charsetG0","charsetG1","cursorFg","cursorBg","freeHeap","clientCount","attrs","lastChar","frameLength","MASK_LINE_ATTR","MASK_BLINK","pushCell","hasFG","hasBG","cellFG","cellBG","cellAttrs","charCode","parseUpdate","CanvasRenderer","DEFAULT_FONT","gridScaleX","gridScaleY","_windowScale","_padding","windowState","charSize","scheduleSizeUpdate","scheduleDraw","_scheduledSizeUpdate","fontStyle","fontWeight","weight","rounded","cellSize","getCellSize","drawnScreenLines","_this3","withScale","getCharWidthFor","getFont","updateCharSize","ceil","didChange","realWidth","realHeight","originalWidth","terminalAspect","resetDrawn","serializeRenderData","fonts","_slicedToArray","sliceIterator","_arr","_n","_d","_e","_s","_i","frakturExceptions","C","H","I","R","Z","ctx","getContext","_palette","graphics","statusFont","blinkStyleOn","blinkInterval","cursorBlinkOn","cursorBlinkInterval","resetBlink","drawnScreen","drawnScreenBG","drawnScreenAttrs","drawnCursor","font","measureText","why","aggregateTime","_scheduledDraw","draw","_this4","intervals","cellWidth","cellHeight","isDefaultBG","fillStyle","screenX","screenY","isBorderCell","fillX","fillY","fillWidth","fillHeight","right","bottom","clearRect","fillRect","_ref2","underline","strike","overline","globalAlpha","alphaToFraktur","dblWidth","dblHeightTop","dblHeightBot","save","translate","scale","beginPath","clip","cw","ch","c2w","c2h","offset","dotSpacingX","dotSpacingY","dotSize","alignRight","dy","dotSizeY","lineTo","strokeStyle","stroke","fillText","lineWidth","lineCap","lineY","restore","radius","drawStatus","startDrawLoop","stopDrawLoop","_cellSize","setTransform","drawStart","textAlign","textBaseline","FONT_MASK","fontGroups","Map","updateMap","isCursor","wasCursor","inSelection","_ref3","_ref4","didUpdate","debugFilledUpdates","keys","previous","redrawMap","maskedCells","isTextWide","shouldUpdate","isWideCell","checkRadius","adjacentDidUpdate","getAdjacentCells","adjacentCell","regions","masked","region","other","_region2","endX","endY","rectX","rectY","rectWidth","rectHeight","drawBackground","setCell","fontIndex","drawCharacter","cursorWidth","_ref5","drawEnd","screenWidth","screenHeight","rotate","_drawTimerThread","threadID","drawTimerLoop","_this5","demo","ws","heartbeatTimeout","pingInterval","xoff","autoXoffTimeout","reconnTimeout","forceClosing","queue","blobReader","FileReader","onDecodedWSMessage","disconnectTimeout","hidden","closeSocket","heartbeat","flushQueue","readAsText","onWSMessage","close","alert","WebSocket","onWSOpen","onWSClose","onHeartbeatFail","_this7","_this8","sendPing","sendString","sendButton","initKeys","allFn","shouldAcceptEvent","metaKey","handleKeyDown","clipboardData","setData","getData","setContent","all_fn","mb1","mb2","mb3","packModifiersForMouse","KEY_NAMES","3","6","8","9","12","13","16","17","18","19","20","27","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","58","59","60","61","62","63","64","91","92","93","106","107","109","110","111","144","145","160","161","162","163","164","165","166","167","168","169","170","171","172","173","174","175","176","186","187","188","189","190","192","194","219","220","221","222","224","np_alt","cu_alt","fn_alt","mt_click","mt_move","no_keys","crlf_mode","fa","alt","normal","ca","na","keymap","Backspace","Tab","Enter","Control+Enter","Escape","ArrowUp","ArrowDown","ArrowRight","ArrowLeft","Home","Insert","Delete","End","PageUp","PageDown","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12","Shift+F1","Shift+F2","Shift+F3","Shift+F4","Shift+F5","Shift+F6","Shift+F7","Shift+F8","Shift+F9","Shift+F10","Shift+F11","Shift+F12","Numpad0","Numpad1","Numpad2","Numpad3","Numpad4","Numpad5","Numpad6","Numpad7","Numpad8","Numpad9","Numpad*","Numpad+","Numpad-","Numpad.","Numpad/","Control+]","Control+\\","Control+[","Control+^","Control+_","Control+ArrowLeft","Control+ArrowRight","Control+ArrowUp","Control+ArrowDown","Control+Home","Control+End","Shift+ArrowLeft","Shift+ArrowRight","Shift+ArrowUp","Shift+ArrowDown","Shift+Home","Shift+End","Alt+ArrowLeft","Alt+ArrowRight","Meta+ArrowLeft","Meta+ArrowRight","Alt+Backspace","Meta+Backspace","Control+Shift+C","Control+Insert","Control+F12","activeElement","HTMLTextAreaElement","keyBlacklist","softModifiers","ctrl","meta","shiftKey","binding","itemModifiers","cu","np","crlf","click","move","dir","blockKeys","yes","openUploadDialog","updateStatus","onDialogClose","fuTout","line_i","startUpload","fuClose","inline_pos","send_delay_ms","nl_str","CR","LF","CRLF","uploadLine","canSend","curLine","maxChunk","MAX_LINE_LEN","chunk","pt","closeWhenReady","reader","files","ftype","confirm","txt","keyInput","shortcutBar","keyboardOpen","updateInputPosition","_screen$layout$gridTo","_screen$layout$gridTo2","lastCompositionString","sendInputDelta","newValue","resend","stopPropagation","isComposing","inputType","shortcuts","Control","Esc","←","↓","↑","→","touchMoved","shortcut","fakeEvent","connection","debugCanvas","toolbar","tooltip","updateTooltip","updateToolbar","selectedCell","onMouseOut","updateCanvasSize","_screen$layout$window","screenAttached","eventNode","setScreenAttached","attached","setToolbarAttached","enabled","drawData","showUpdates","endTime","frames","scrollRegion","performance","frame","isDrawing","drawLoop","_screen$layout$window2","lineJoin","_cells$get","_cells$get2","timestamp","elapsedTime","delete","framesToDelete","strokeRect","_selectedCell","_selectedCell2","setLineDash","lineDashOffset","_drawData$scrollRegio","pad2","formatColor","makeSpan","styles","formatAttributes","textDecoration","opacity","preview","bgPreview","formattedCodePoint","Cell","Foreground","Background","Character","Attributes","table","Text","posX","posY","toolbarData","toolbarNodes","initToolbar","fancyGraphics","Position","Style","Visible","Hanging","internal","Flags","Cursor Attributes","Code Page","Heap","Clients","drawing","Last Update","Show Updates","Fancy Graphics","Redraw Screen","group","Node","drawTime","_require3","container","pushButton","blur","popButton","clr","hsl","boxShadow","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","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.8b43b1d-en.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 10);\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) {\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/* 3 */\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\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.colorTable256 = null;\nexports.ensureColorTable256 = function () {\n if (!exports.colorTable256) exports.colorTable256 = exports.buildColorTable();\n};\n\nexports.getColor = function (i) {\n var palette = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n // return palette color if it exists\n if (i < 16 && i in palette) return palette[i];\n\n // -1 for selection foreground, -2 for selection background\n if (i === -1) return exports.SELECTION_FG;\n if (i === -2) return exports.SELECTION_BG;\n\n // 256 color\n if (i > 15 && i < 256) {\n exports.ensureColorTable256();\n return exports.colorTable256[i];\n }\n\n // 24-bit color, encoded as (hex) + 256 (such that #000000 == 256)\n if (i > 255) {\n i -= 256;\n return '#' + ('000000' + i.toString(16)).substr(-6);\n }\n\n // return error color\n return Math.floor(Date.now() / 1000) % 2 === 0 ? '#ff0ff' : '#00ff00';\n};\n\nexports.toHex = function (shade, themeN) {\n if (/^\\d+$/.test(shade)) {\n shade = +shade;\n return exports.getColor(shade, themes[themeN]);\n }\n return shade;\n};\n\n/***/ }),\n/* 4 */\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/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar $ = __webpack_require__(1);\nvar modal = __webpack_require__(4);\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/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n// Bits in the cell attribs word\n\n/* eslint-disable no-multi-spaces */\nexports.ATTR_FG = 1 << 0; // 1 if not using default background color (ignore cell bg) - color extension bit\nexports.ATTR_BG = 1 << 1; // 1 if not using default foreground color (ignore cell fg) - color extension bit\nexports.ATTR_BOLD = 1 << 2; // Bold font\nexports.ATTR_UNDERLINE = 1 << 3; // Underline decoration\nexports.ATTR_INVERSE = 1 << 4; // Invert colors - this is useful so we can clear then with SGR manipulation commands\nexports.ATTR_BLINK = 1 << 5; // Blinking\nexports.ATTR_ITALIC = 1 << 6; // Italic font\nexports.ATTR_STRIKE = 1 << 7; // Strike-through decoration\nexports.ATTR_OVERLINE = 1 << 8; // Over-line decoration\nexports.ATTR_FAINT = 1 << 9; // Faint foreground color (reduced alpha)\nexports.ATTR_FRAKTUR = 1 << 10; // Fraktur font (unicode substitution)\n/* eslint-enable no-multi-spaces */\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/*\n * Copyright (c) 2010 Tim Baumann\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// NOTE:\n// Extracted from ColorTriangle and\n// Converted to ES6 by MightyPork (2017)\n\n/*******************\n * Color conversion *\n *******************/\n\nvar M = Math;\nvar TAU = 2 * M.PI;\n\nexports.hue2rgb = function (v1, v2, h) {\n if (h < 0) h += 1;\n if (h > 1) h -= 1;\n\n if (6 * h < 1) return v1 + (v2 - v1) * 6 * h;\n if (2 * h < 1) return v2;\n if (3 * h < 2) return v1 + (v2 - v1) * (2 / 3 - h) * 6;\n return v1;\n};\n\nexports.hsl2rgb = function (h, s, l) {\n h /= TAU;\n var r = void 0,\n g = void 0,\n b = void 0;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n var var_1 = void 0,\n var_2 = void 0;\n\n if (l < 0.5) var_2 = l * (1 + s);else var_2 = l + s - s * l;\n\n var_1 = 2 * l - var_2;\n\n r = exports.hue2rgb(var_1, var_2, h + 1 / 3);\n g = exports.hue2rgb(var_1, var_2, h);\n b = exports.hue2rgb(var_1, var_2, h - 1 / 3);\n }\n return [r, g, b];\n};\n\nexports.rgb2hsl = function (r, g, b) {\n var min = M.min(r, g, b);\n var max = M.max(r, g, b);\n var d = max - min; // delta\n\n var h = void 0,\n s = void 0,\n l = void 0;\n\n l = (max + min) / 2;\n\n if (d === 0) {\n // gray\n h = s = 0; // HSL results from 0 to 1\n } else {\n // chroma\n if (l < 0.5) s = d / (max + min);else s = d / (2 - max - min);\n\n var d_r = ((max - r) / 6 + d / 2) / d;\n var d_g = ((max - g) / 6 + d / 2) / d;\n var d_b = ((max - b) / 6 + d / 2) / d; // deltas\n\n if (r === max) h = d_b - d_g;else if (g === max) h = 1 / 3 + d_r - d_b;else if (b === max) h = 2 / 3 + d_g - d_r;\n\n if (h < 0) h += 1;else if (h > 1) h -= 1;\n }\n h *= TAU;\n return [h, s, l];\n};\n\nexports.hex2rgb = function (hex) {\n var groups = hex.match(/^#([\\da-f]{3,6})$/i);\n if (groups) {\n hex = groups[1];\n var bytes = hex.length / 3;\n var max = Math.pow(16, bytes) - 1;\n return [0, 1, 2].map(function (x) {\n return parseInt(hex.slice(x * bytes, (x + 1) * bytes), 16) / max;\n });\n }\n return [0, 0, 0];\n};\n\nfunction pad(n) {\n return ('00' + n).substr(-2);\n}\n\nexports.rgb255ToHex = function (r, g, b) {\n return '#' + [r, g, b].map(function (x) {\n return pad(x.toString(16));\n }).join('');\n};\n\nexports.rgb2hex = function (r, g, b) {\n return '#' + [r, g, b].map(function (x) {\n return pad(Math.round(x * 255).toString(16));\n }).join('');\n};\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _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__(2);\n\nvar _require = __webpack_require__(0),\n parse2B = _require.parse2B;\n\nvar _require2 = __webpack_require__(3),\n themes = _require2.themes;\n\nvar encodeAsCodePoint = function encodeAsCodePoint(i) {\n return String.fromCodePoint(i + (i >= 0xD800 ? 0x801 : 1));\n};\n\nvar ANSIParser = function () {\n function ANSIParser(handler) {\n _classCallCheck(this, ANSIParser);\n\n this.reset();\n this.handler = handler;\n this.joinChunks = true;\n }\n\n _createClass(ANSIParser, [{\n key: 'reset',\n value: function reset() {\n this.currentSequence = 0;\n this.sequence = '';\n }\n }, {\n key: 'parseSequence',\n value: function parseSequence(sequence) {\n if (sequence[0] === '[') {\n var type = sequence[sequence.length - 1];\n var content = sequence.substring(1, sequence.length - 1);\n\n var numbers = content ? content.split(';').map(function (i) {\n return +i.replace(/\\D/g, '');\n }) : [];\n var numOr1 = numbers.length ? numbers[0] : 1;\n if (type === 'H') {\n this.handler('set-cursor', (numbers[0] | 0) - 1, (numbers[1] | 0) - 1);\n } else if (type >= 'A' && type <= 'D') {\n this.handler('move-cursor-' + (type <= 'B' ? 'y' : 'x'), (type === 'B' || type === 'C' ? 1 : -1) * numOr1);\n } else if (type === 'E' || type === 'F') {\n this.handler('move-cursor-line', (type === 'E' ? 1 : -1) * numOr1);\n } else if (type === 'G') {\n this.handler('set-cursor-x', numOr1 - 1);\n } else if (type === 'J') {\n var number = numbers.length ? numbers[0] : 2;\n if (number === 2) this.handler('clear');\n } else if (type === 'P') {\n this.handler('delete', numOr1);\n } else if (type === '@') {\n this.handler('insert-blanks', numOr1);\n } else if (type === 'q') this.handler('set-cursor-style', numOr1);else if (type === 'm') {\n if (!numbers.length) {\n this.handler('reset-style');\n return;\n }\n var _type = void 0;\n while (_type = numbers.shift()) {\n if (_type === 0) this.handler('reset-style');else if (_type === 1) this.handler('add-attrs', 1 << 2); // bold\n else if (_type === 2) this.handler('add-attrs', 1 << 9); // faint\n else if (_type === 3) this.handler('add-attrs', 1 << 6); // italic\n else if (_type === 4) this.handler('add-attrs', 1 << 3); // underline\n else if (_type === 5 || _type === 6) this.handler('add-attrs', 1 << 5); // blink\n else if (_type === 7) this.handler('add-attrs', 1 << 4); // invert\n else if (_type === 9) this.handler('add-attrs', 1 << 7); // strike\n else if (_type === 20) this.handler('add-attrs', 1 << 10); // fraktur\n else if (_type >= 30 && _type <= 37) this.handler('set-color-fg', _type % 10);else if (_type >= 40 && _type <= 47) this.handler('set-color-bg', _type % 10);else if (_type === 39) this.handler('reset-color-fg');else if (_type === 49) this.handler('reset-color-bg');else if (_type >= 90 && _type <= 98) this.handler('set-color-fg', _type % 10 + 8);else if (_type >= 100 && _type <= 108) this.handler('set-color-bg', _type % 10 + 8);else if (_type === 38 || _type === 48) {\n var mode = numbers.shift();\n if (mode === 2) {\n var r = numbers.shift();\n var g = numbers.shift();\n var b = numbers.shift();\n var color = (r << 16 | g << 8 | b) + 256;\n if (_type === 38) this.handler('set-color-fg', color);\n if (_type === 48) this.handler('set-color-bg', color);\n } else if (mode === 5) {\n var _color = (numbers.shift() | 0) & 0xFF;\n if (_type === 38) this.handler('set-color-fg', _color);\n if (_type === 48) this.handler('set-color-bg', _color);\n }\n }\n }\n } else if (type === 'h' || type === 'l') {\n if (content === '?25') {\n if (type === 'h') this.handler('show-cursor');else if (type === 'l') this.handler('hide-cursor');\n }\n }\n }\n }\n }, {\n key: 'write',\n value: function write(text) {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = text.toString()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var character = _step.value;\n\n var code = character.codePointAt(0);\n if (code === 0x1b) this.currentSequence = 1;else if (this.currentSequence === 1 && character === '[') {\n this.currentSequence = 2;\n this.sequence += '[';\n } else if (this.currentSequence && character.match(/[\\x40-\\x7e]/)) {\n this.parseSequence(this.sequence + character);\n this.currentSequence = 0;\n this.sequence = '';\n } else if (this.currentSequence > 1) this.sequence += character;else if (this.currentSequence === 1) {\n // something something nothing\n this.currentSequence = 0;\n this.handler('write', character);\n } else if (code < 0x03) this.handler('_null');else if (code === 0x03) this.handler('sigint');else if (code <= 0x06) this.handler('_null');else if (code === 0x07) this.handler('bell');else if (code === 0x08) this.handler('back');else if (code === 0x09) this.handler('tab');else if (code === 0x0a) this.handler('new-line');else if (code === 0x0d) this.handler('return');else if (code === 0x15) this.handler('delete-line');else if (code === 0x17) this.handler('delete-word');else this.handler('write', character);\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n if (!this.joinChunks) this.reset();\n }\n }]);\n\n return ANSIParser;\n}();\n\nvar TERM_DEFAULT_STYLE = [0, 0, 0];\n\nvar getRainbowColor = function getRainbowColor(t) {\n var r = Math.floor(Math.sin(t) * 2.5 + 2.5);\n var g = Math.floor(Math.sin(t + 2 / 3 * Math.PI) * 2.5 + 2.5);\n var b = Math.floor(Math.sin(t + 4 / 3 * Math.PI) * 2.5 + 2.5);\n return 16 + 36 * r + 6 * g + b;\n};\n\nvar ScrollingTerminal = function () {\n function ScrollingTerminal(screen) {\n var _this = this;\n\n _classCallCheck(this, ScrollingTerminal);\n\n this.width = 80;\n this.height = 25;\n this.termScreen = screen;\n this.parser = new ANSIParser(function () {\n return _this.handleParsed.apply(_this, arguments);\n });\n this.buttonLabels = [];\n\n this.reset();\n\n this._lastLoad = Date.now();\n this.loadTimer();\n\n window.showPage();\n }\n\n _createClass(ScrollingTerminal, [{\n key: 'reset',\n value: function reset() {\n this.style = TERM_DEFAULT_STYLE.slice();\n this.cursor = { x: 0, y: 0, style: 1, visible: true };\n this.trackMouse = false;\n this.theme = 0;\n this.defaultFG = 7;\n this.defaultBG = 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 += this.encodeColor(this.defaultFG);\n data += this.encodeColor(this.defaultBG);\n var attributes = +this.cursor.visible;\n attributes |= (3 << 5) * +this.trackMouse; // track mouse controls both\n attributes |= 3 << 7; // buttons/links always visible\n attributes |= this.cursor.style << 9;\n data += encodeAsCodePoint(attributes);\n return data;\n }\n }, {\n key: 'getButtons',\n value: function getButtons() {\n var data = 'B';\n data += encodeAsCodePoint(this.buttonLabels.length);\n data += this.buttonLabels.map(function (x) {\n return '\\x01' + x + '\\x01';\n }).join('');\n return data;\n }\n }, {\n key: 'getTitle',\n value: function getTitle() {\n return 'TESPTerm Web UI Demo\\x01';\n }\n }, {\n key: 'getCursor',\n value: function getCursor() {\n var data = 'C';\n data += encodeAsCodePoint(this.cursor.y);\n data += encodeAsCodePoint(this.cursor.x);\n data += encodeAsCodePoint(0);\n return data;\n }\n }, {\n key: 'encodeColor',\n value: function encodeColor(color) {\n if (color < 256) {\n return encodeAsCodePoint(color);\n } else {\n color -= 256;\n return encodeAsCodePoint(color & 0xFFF | 0x10000) + encodeAsCodePoint(color >> 12);\n }\n }\n }, {\n key: 'serializeScreen',\n value: function serializeScreen() {\n var serialized = 'S';\n serialized += encodeAsCodePoint(0) + encodeAsCodePoint(0);\n serialized += encodeAsCodePoint(this.height) + encodeAsCodePoint(this.width);\n\n var lastStyle = [null, null, null];\n var index = 0;\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = this.screen[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var cell = _step2.value;\n\n var style = cell[1].slice();\n if (this.rainbow) {\n var x = index % this.width;\n var y = Math.floor(index / this.width);\n // C instead of F in mask and 1 << 8 in attrs to change attr bits 1 and 2\n var t = (x + y) / 10 + Date.now() / 1000;\n if (this.superRainbow) {\n t = (x * y + Date.now()) / 100 + Date.now() / 1000;\n }\n style[0] = getRainbowColor(t);\n style[1] = 0;\n if (this.superRainbow) style[1] = getRainbowColor(t / 10);\n style[2] = style[2] | 1;\n if (!this.superRainbow && style[2] & 1 << 1) style[2] ^= 1 << 1;\n index++;\n }\n\n var foreground = style[0];\n var background = style[1];\n var attributes = style[2];\n var setForeground = foreground !== lastStyle[0];\n var setBackground = background !== lastStyle[1];\n var setAttributes = attributes !== lastStyle[2];\n\n if (setForeground && setBackground) {\n if (foreground < 256 && background < 256) {\n serialized += '\\x03' + encodeAsCodePoint(background << 8 | foreground);\n } else {\n serialized += '\\x05' + this.encodeColor(foreground);\n serialized += '\\x06' + this.encodeColor(background);\n }\n } else if (setForeground) serialized += '\\x05' + this.encodeColor(foreground);else if (setBackground) serialized += '\\x06' + this.encodeColor(background);\n if (setAttributes) serialized += '\\x04' + encodeAsCodePoint(attributes);\n lastStyle = style;\n\n serialized += cell[0];\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n return serialized;\n }\n }, {\n key: 'getUpdate',\n value: function getUpdate() {\n var topics = 0;\n var topicData = [];\n var screenOpts = this.getScreenOpts();\n var title = this.getTitle();\n var buttons = this.getButtons();\n var cursor = this.getCursor();\n var screen = this.serializeScreen();\n if (this._screenOpts !== screenOpts) {\n this._screenOpts = screenOpts;\n topicData.push(screenOpts);\n }\n if (this._title !== title) {\n this._title = title;\n topicData.push(title);\n }\n if (this._buttons !== buttons) {\n this._buttons = buttons;\n topicData.push(buttons);\n }\n if (this._cursor !== cursor) {\n this._cursor = cursor;\n topicData.push(cursor);\n }\n if (this._screen !== screen) {\n this._screen = screen;\n topicData.push(screen);\n }\n if (!topicData.length) return '';\n return 'U' + encodeAsCodePoint(topics) + topicData.join('');\n }\n }, {\n key: 'loadTimer',\n value: function loadTimer() {\n var _this2 = this;\n\n clearInterval(this._loadTimer);\n this._loadTimer = setInterval(function () {\n var update = _this2.getUpdate();\n if (update) _this2.termScreen.load(update);\n }, 30);\n }\n }]);\n\n return ScrollingTerminal;\n}();\n\nvar Process = function (_EventEmitter) {\n _inherits(Process, _EventEmitter);\n\n function Process() {\n _classCallCheck(this, Process);\n\n return _possibleConstructorReturn(this, (Process.__proto__ || Object.getPrototypeOf(Process)).apply(this, arguments));\n }\n\n _createClass(Process, [{\n key: 'write',\n value: function write(data) {\n this.emit('in', data);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n // death.\n this.emit('exit', 0);\n }\n }, {\n key: 'run',\n value: function run() {\n // noop\n }\n }]);\n\n return Process;\n}(EventEmitter);\n\nvar demoData = {\n buttons: [],\n mouseReceiver: null\n};\n\nvar demoshIndex = {\n clear: function (_Process) {\n _inherits(Clear, _Process);\n\n function Clear() {\n _classCallCheck(this, Clear);\n\n return _possibleConstructorReturn(this, (Clear.__proto__ || Object.getPrototypeOf(Clear)).apply(this, arguments));\n }\n\n _createClass(Clear, [{\n key: 'run',\n value: function run() {\n this.emit('write', '\\x1b[2J\\x1b[1;1H');\n this.destroy();\n }\n }]);\n\n return Clear;\n }(Process),\n screenfetch: function (_Process2) {\n _inherits(Screenfetch, _Process2);\n\n function Screenfetch() {\n _classCallCheck(this, Screenfetch);\n\n return _possibleConstructorReturn(this, (Screenfetch.__proto__ || Object.getPrototypeOf(Screenfetch)).apply(this, arguments));\n }\n\n _createClass(Screenfetch, [{\n key: 'run',\n value: function run() {\n var _this6 = this;\n\n var image = ('\\n ###. ESPTerm Demo\\n \\'###. Hostname: ' + window.location.hostname + '\\n \\'###. Shell: ESPTerm Demo Shell\\n \\'###. Resolution: 80x25@' + window.devicePixelRatio + 'x\\n :###-\\n .###\\'\\n .###\\'\\n .###\\' ###############\\n ###\\' ###############\\n ').split('\\n').filter(function (line) {\n return line.trim();\n });\n\n var chars = '';\n for (var y = 0; y < image.length; y++) {\n for (var x = 0; x < 80; x++) {\n if (image[y][x]) {\n chars += '\\x1B[38;5;' + getRainbowColor((x + y) / 10) + 'm' + image[y][x];\n } else chars += ' ';\n }\n }\n\n this.emit('write', '\\r\\n\\x1b[?25l');\n var loop = function loop() {\n _this6.emit('write', chars.substr(0, 80));\n chars = chars.substr(80);\n if (chars.length) setTimeout(loop, 50);else {\n _this6.emit('write', '\\r\\n\\x1b[?25h');\n _this6.destroy();\n }\n };\n loop();\n }\n }]);\n\n return Screenfetch;\n }(Process),\n 'local-echo': function (_Process3) {\n _inherits(LocalEcho, _Process3);\n\n function LocalEcho() {\n _classCallCheck(this, LocalEcho);\n\n return _possibleConstructorReturn(this, (LocalEcho.__proto__ || Object.getPrototypeOf(LocalEcho)).apply(this, arguments));\n }\n\n _createClass(LocalEcho, [{\n key: 'run',\n value: function run() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n if (!args.includes('--suppress-note')) {\n this.emit('write', '\\x1b[38;5;239mNote: not all terminal features are supported and may not work as expected in this demo\\x1b[m\\n');\n }\n this.emit('buttons', [{\n label: 'Exit',\n action: function action(shell) {\n shell.write('\\x03');\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(shell) {\n _classCallCheck(this, ShowThemes);\n\n var _this14 = _possibleConstructorReturn(this, (ShowThemes.__proto__ || Object.getPrototypeOf(ShowThemes)).call(this));\n\n _this14.shell = shell;\n _this14.parser = new ANSIParser(function () {\n return _this14.handler.apply(_this14, arguments);\n });\n return _this14;\n }\n\n _createClass(ShowThemes, [{\n key: 'destroy',\n value: function destroy() {\n this.shell.terminal.cursor.style = this.savedCursorStyle;\n this.emit('write', '\\n\\n');\n _get(ShowThemes.prototype.__proto__ || Object.getPrototypeOf(ShowThemes.prototype), 'destroy', this).call(this);\n }\n }, {\n key: 'run',\n value: function run() {\n var _this15 = this;\n\n this.savedCursorStyle = this.shell.terminal.cursor.style;\n this.shell.terminal.cursor.style = 3;\n\n this.fgType = 0;\n this.bgType = 0;\n\n var get24FG = function get24FG() {\n return _this15.shell.terminal.defaultFG - 256;\n };\n var set24FG = function set24FG(v) {\n _this15.shell.terminal.defaultFG = v + 256;\n };\n var get24BG = function get24BG() {\n return _this15.shell.terminal.defaultBG - 256;\n };\n var set24BG = function set24BG(v) {\n _this15.shell.terminal.defaultBG = v + 256;\n };\n\n var make24Control = function make24Control(label, index, _getValue, _setValue, type) {\n index *= 4;\n\n return {\n label: label,\n length: 1,\n getValue: function getValue() {\n return _getValue() >> index & 0xF;\n },\n getDisplay: function getDisplay() {\n return (_getValue() >> index & 0xF).toString(16);\n },\n setValue: function setValue(value) {\n _setValue(_getValue() & (0xFFFFFF ^ 0xF << index) | (value & 0xF) << index);\n },\n shouldShow: function shouldShow() {\n return _this15[type + 'Type'] === 1;\n },\n parseValue: function parseValue(input) {\n return parseInt(input, 16) & 0xF;\n },\n moveAfterInput: index !== 0\n };\n };\n\n this.controls = [{\n label: 'Theme: ',\n length: themes.length.toString().length,\n getValue: function getValue() {\n return _this15.shell.terminal.theme;\n },\n setValue: function setValue(value) {\n var count = themes.length;\n _this15.shell.terminal.theme = (value % count + count) % count;\n }\n }, {\n label: ' Default Foreground: ',\n length: 6,\n getValue: function getValue() {\n return _this15.fgType;\n },\n getDisplay: function getDisplay() {\n return _this15.fgType === 0 ? '256' : '24-bit';\n },\n setValue: function setValue(value) {\n _this15.fgType = (value % 2 + 2) % 2;\n }\n }, {\n label: ' ',\n length: 3,\n getValue: function getValue() {\n return _this15.shell.terminal.defaultFG & 0xFF;\n },\n setValue: function setValue(value) {\n _this15.shell.terminal.defaultFG = value & 0xFF;\n },\n shouldShow: function shouldShow() {\n return _this15.fgType === 0;\n },\n parseValue: function parseValue(input) {\n return parseInt(input, 16);\n }\n }, make24Control(' #', 5, get24FG, set24FG, 'fg'), make24Control('', 4, get24FG, set24FG, 'fg'), make24Control('', 3, get24FG, set24FG, 'fg'), make24Control('', 2, get24FG, set24FG, 'fg'), make24Control('', 1, get24FG, set24FG, 'fg'), make24Control('', 0, get24FG, set24FG, 'fg'), {\n label: ' Default Background: ',\n length: 6,\n getValue: function getValue() {\n return _this15.bgType;\n },\n getDisplay: function getDisplay() {\n return _this15.bgType === 0 ? '256' : '24-bit';\n },\n setValue: function setValue(value) {\n _this15.bgType = (value % 2 + 2) % 2;\n }\n }, {\n label: ' ',\n length: 3,\n getValue: function getValue() {\n return _this15.shell.terminal.defaultBG & 0xFF;\n },\n setValue: function setValue(value) {\n _this15.shell.terminal.defaultBG = value & 0xFF;\n },\n shouldShow: function shouldShow() {\n return _this15.bgType === 0;\n },\n parseValue: function parseValue(input) {\n return parseInt(input, 16);\n }\n }, make24Control(' #', 5, get24BG, set24BG, 'bg'), make24Control('', 4, get24BG, set24BG, 'bg'), make24Control('', 3, get24BG, set24BG, 'bg'), make24Control('', 2, get24BG, set24BG, 'bg'), make24Control('', 1, get24BG, set24BG, 'bg'), make24Control('', 0, get24BG, set24BG, 'bg')];\n this.selection = 0;\n\n this.emit('write', '\\x1b[1mThemes\\x1b[m\\n\\n\\n\\n\\x1b[2A');\n\n this.render();\n }\n }, {\n key: 'render',\n value: function render() {\n this.emit('write', '\\x1b[m\\r');\n // no ^[2K implementation, here's a hack\n this.emit('write', ' '.repeat(this.shell.terminal.width - 1) + '\\r');\n\n var index = 0;\n var selectedX = 0;\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = this.controls[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var control = _step3.value;\n\n if (control.shouldShow && !control.shouldShow()) continue;\n if (control.label) {\n this.emit('write', '\\x1B[1m' + control.label + '\\x1B[m');\n }\n // TODO: colors\n this.emit('write', '\\x1b[38;5;255m\\x1b[48;5;16m');\n var value = control.getDisplay ? control.getDisplay() : control.getValue().toString();\n this.emit('write', (control.fill || ' ').repeat(Math.max(0, control.length - value.length)));\n this.emit('write', value.substr(0, control.length));\n this.emit('write', '\\x1b[m');\n\n if (index === this.selection) {\n selectedX = this.shell.terminal.cursor.x - 1;\n\n // draw arrows\n this.emit('write', '\\x1b[m\\x1b[D\\x1b[A▲\\x1b[D\\x1b[2B▼\\x1b[A');\n } else {\n // clear arrows if they were there\n this.emit('write', '\\x1b[m\\x1b[D\\x1b[A \\x1b[D\\x1b[2B \\x1b[A');\n }\n\n index++;\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 this.shell.terminal.cursor.x = selectedX;\n }\n }, {\n key: 'write',\n value: function write(data) {\n this.parser.write(data);\n }\n }, {\n key: 'getControlCount',\n value: function getControlCount() {\n var count = 0;\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = this.controls[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n var control = _step4.value;\n\n if (control.shouldShow && !control.shouldShow()) continue;\n count++;\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 return count;\n }\n }, {\n key: 'getSelectedControl',\n value: function getSelectedControl() {\n var selected = null;\n var index = 0;\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = this.controls[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var control = _step5.value;\n\n if (control.shouldShow && !control.shouldShow()) continue;\n if (index === this.selection) {\n selected = control;\n break;\n }\n index++;\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 return selected;\n }\n }, {\n key: 'handler',\n value: function handler(action) {\n var _console;\n\n for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n\n (_console = console).log.apply(_console, [action].concat(args));\n\n if (action === 'move-cursor-x') {\n this.selection += args[0];\n var count = this.getControlCount();\n this.selection = (this.selection % count + count) % count;\n } else if (action === 'move-cursor-y') {\n var control = this.getSelectedControl();\n if (control) control.setValue(control.getValue() - args[0]);\n } else if (action === 'write') {\n var _control = this.getSelectedControl();\n if (_control && _control.parseValue) {\n var parsed = _control.parseValue(args[0]);\n if (Number.isFinite(parsed)) {\n _control.setValue(parsed);\n if (_control.moveAfterInput) {\n if (this.selection < this.getControlCount() - 1) this.selection++;\n }\n }\n }\n }\n\n this.render();\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 _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\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 _this17 = _possibleConstructorReturn(this, (ToggleRainbow.__proto__ || Object.getPrototypeOf(ToggleRainbow)).call(this));\n\n _this17.shell = shell;\n _this17.su = options.su;\n _this17.abort = false;\n return _this17;\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(MouseDemo, _Process11);\n\n function MouseDemo(shell) {\n _classCallCheck(this, MouseDemo);\n\n var _this18 = _possibleConstructorReturn(this, (MouseDemo.__proto__ || Object.getPrototypeOf(MouseDemo)).call(this));\n\n _this18.shell = shell;\n return _this18;\n }\n\n _createClass(MouseDemo, [{\n key: 'run',\n value: function run() {\n var _this19 = this;\n\n var self = this;\n this.emit('buttons', [{\n label: 'Exit',\n action: function action(shell) {\n shell.write('\\x03');\n }\n }, {\n label: 'Add Box',\n action: function action() {\n self.boxes.push(self.generateRandomBox());\n self.render();\n }\n }]);\n\n this.shell.terminal.trackMouse = true;\n demoData.mouseReceiver = this;\n\n this.boxes = Array(3).fill(0).map(function (x) {\n return _this19.generateRandomBox();\n });\n this.grabbedBox = null;\n this.grabOffset = [0, 0];\n\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[mMove boxes around or scroll their contents!');\n\n // draw boxes\n var _iteratorNormalCompletion6 = true;\n var _didIteratorError6 = false;\n var _iteratorError6 = undefined;\n\n try {\n for (var _iterator6 = this.boxes[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {\n var box = _step6.value;\n\n this.emit('write', '\\x1B[' + (box.y + 1) + ';' + (box.x + 1) + 'H');\n this.emit('write', '\\x1B[m\\x1B[48;2;' + box.color.join(';') + 'm');\n for (var y = box.y; y < box.y + box.height; y++) {\n var drawnX = 0;\n for (var x = box.x; x < box.x + box.width; x++) {\n if (x < 0 || x >= this.shell.terminal.width - 1) continue;\n if (y < 0 || y >= this.shell.terminal.height) continue;\n drawnX++;\n this.emit('write', box.content[y - box.y][x - box.x]);\n }\n this.emit('write', '\\x1b[D'.repeat(drawnX) + '\\x1b[B');\n }\n }\n\n // move cursor to mouse\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 if (this.mouse) {\n this.emit('write', '\\x1B[' + (this.mouse.y + 1) + ';' + (this.mouse.x + 1) + 'H');\n }\n }\n }, {\n key: 'generateRandomBox',\n value: function generateRandomBox() {\n var chars = 'abcdefghijklmnopqrstuvwxyz-*()!@#$%';\n var content = [];\n var width = [5, 10, 15][Math.floor(Math.random() * 3)];\n var height = [4, 5, 6][Math.floor(Math.random() * 3)];\n\n for (var y = 0; y < height; y++) {\n content.push('');\n for (var x = 0; x < width; x++) {\n if (Math.random() > 0.6) {\n content[y] += chars[Math.floor(Math.random() * chars.length)];\n } else content[y] += ' ';\n }\n }\n\n return {\n x: Math.floor(Math.random() * (this.shell.terminal.width - 1)) + 1,\n y: Math.floor(Math.random() * (this.shell.terminal.height - 1)) + 1,\n width: width,\n height: height,\n color: [Math.random(), Math.random(), Math.random()].map(function (x) {\n return Math.floor(x * 255);\n }),\n content: content\n };\n }\n }, {\n key: 'getBoxAt',\n value: function getBoxAt(x, y) {\n var boxes = this.boxes.slice().reverse(); // top to bottom, like drawing order\n var _iteratorNormalCompletion7 = true;\n var _didIteratorError7 = false;\n var _iteratorError7 = undefined;\n\n try {\n for (var _iterator7 = boxes[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {\n var box = _step7.value;\n\n if (box.x <= x && box.x + box.width > x && box.y <= y && box.y + box.height > y) {\n return box;\n }\n }\n } catch (err) {\n _didIteratorError7 = true;\n _iteratorError7 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion7 && _iterator7.return) {\n _iterator7.return();\n }\n } finally {\n if (_didIteratorError7) {\n throw _iteratorError7;\n }\n }\n }\n }\n }, {\n key: 'mouseMove',\n value: function mouseMove(x, y) {\n this.mouse = { x: x, y: y };\n if (this.grabbedBox) {\n this.grabbedBox.x = x + this.grabOffset[0];\n this.grabbedBox.y = y + this.grabOffset[1];\n }\n this.render();\n }\n }, {\n key: 'mouseDown',\n value: function mouseDown(x, y, button) {\n if (button === 4) this.scrollInsideBox(this.getBoxAt(x, y), -1);else if (button === 5) this.scrollInsideBox(this.getBoxAt(x, y), 1);else {\n var box = this.getBoxAt(x, y);\n if (box) {\n var _boxes;\n\n this.grabbedBox = box;\n this.grabOffset = [box.x - x, box.y - y];\n // move grabbed box to top of stack\n (_boxes = this.boxes).push.apply(_boxes, _toConsumableArray(this.boxes.splice(this.boxes.indexOf(box), 1)));\n }\n }\n this.render();\n }\n }, {\n key: 'mouseUp',\n value: function mouseUp(x, y, button) {\n this.grabbedBox = null;\n }\n }, {\n key: 'scrollInsideBox',\n value: function scrollInsideBox(box, amount) {\n if (!box) return;\n var content = box.content.slice();\n box.content = [];\n for (var i = 0; i < content.length; i++) {\n box.content.push(content[(i + amount % content.length + content.length) % content.length]);\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.shell.terminal.write('\\x1b[m\\x1b[2J\\x1b[1;1H');\n this.shell.terminal.trackMouse = false;\n if (demoData.mouseReceiver === this) demoData.mouseReceiver = null;\n _get(MouseDemo.prototype.__proto__ || Object.getPrototypeOf(MouseDemo.prototype), 'destroy', this).call(this);\n }\n }]);\n\n return MouseDemo;\n }(Process),\n sudo: function (_Process12) {\n _inherits(Sudo, _Process12);\n\n function Sudo(shell) {\n _classCallCheck(this, Sudo);\n\n var _this20 = _possibleConstructorReturn(this, (Sudo.__proto__ || Object.getPrototypeOf(Sudo)).call(this));\n\n _this20.shell = shell;\n _this20.didDestroy = false;\n return _this20;\n }\n\n _createClass(Sudo, [{\n key: 'run',\n value: function run() {\n var _this21 = this;\n\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) {\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 _this21.emit('write', data);\n };\n var setButtons = function setButtons(buttons) {\n return _this21.emit('buttons', buttons);\n };\n child.on('write', write);\n child.on('buttons', setButtons);\n child.on('exit', function (code) {\n child.removeListener('write', write);\n child.removeListener('buttons', setButtons);\n _this21.destroy();\n });\n child.run.apply(child, args);\n } else {\n this.emit('write', _Process13);\n this.destroy();\n }\n } else {\n this.emit('write', 'sudo: ' + name + ': command not found\\r\\n');\n this.destroy();\n }\n }\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n if (this.didDestroy) return;\n this.didDestroy = true;\n if (this.child) this.child.destroy();\n _get(Sudo.prototype.__proto__ || Object.getPrototypeOf(Sudo.prototype), 'destroy', this).call(this);\n }\n }]);\n\n return Sudo;\n }(Process),\n make: function (_Process14) {\n _inherits(Make, _Process14);\n\n function Make(shell) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n _classCallCheck(this, Make);\n\n var _this22 = _possibleConstructorReturn(this, (Make.__proto__ || Object.getPrototypeOf(Make)).call(this));\n\n _this22.su = options.su;\n return _this22;\n }\n\n _createClass(Make, [{\n key: 'run',\n value: function run() {\n for (var _len6 = arguments.length, args = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {\n args[_key6] = arguments[_key6];\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 _this24 = this;\n\n _classCallCheck(this, DemoShell);\n\n this.terminal = terminal;\n this.terminal.reset();\n this.parser = new ANSIParser(function () {\n return _this24.handleParsed.apply(_this24, arguments);\n });\n this.history = [];\n this.historyIndex = 0;\n this.cursorPos = 0;\n this.lastInputLength = 0;\n this.child = null;\n this.index = demoshIndex;\n\n if (printInfo) this.run('info');else this.prompt();\n }\n\n _createClass(DemoShell, [{\n key: 'write',\n value: function write(text) {\n if (this.child) {\n if (text.codePointAt(0) === 3) this.child.destroy();else this.child.write(text);\n } else this.parser.write(text);\n }\n }, {\n key: 'prompt',\n value: function prompt() {\n var success = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n if (this.terminal.cursor.x !== 0) this.terminal.write('\\x1b[m\\x1b[38;5;238m⏎\\r\\n');\n this.terminal.write('\\x1b[34;1mdemosh \\x1b[m');\n if (!success) this.terminal.write('\\x1b[31m');\n this.terminal.write('$ \\x1b[m');\n this.history.unshift('');\n this.cursorPos = 0;\n\n this.setButtons();\n }\n }, {\n key: 'copyFromHistoryIndex',\n value: function copyFromHistoryIndex() {\n if (!this.historyIndex) return;\n var current = this.history[this.historyIndex];\n this.history[0] = current;\n this.historyIndex = 0;\n }\n }, {\n key: 'getCompleted',\n value: function getCompleted() {\n var visual = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n\n if (this.history[0]) {\n var input = this.history[0];\n var prefix = '';\n if (input.startsWith('sudo ')) {\n var newInput = input.replace(/^(sudo\\s+)+/, '');\n prefix = input.substr(0, input.length - newInput.length);\n input = newInput;\n }\n if (!input) return null;\n for (var name in this.index) {\n if (name.startsWith(input) && name !== input) {\n if (visual && name in autocompleteIndex) return prefix + autocompleteIndex[name];\n return prefix + name;\n }\n }\n return null;\n }\n return null;\n }\n }, {\n key: 'handleParsed',\n value: function handleParsed(action) {\n this.terminal.write('\\x1B[' + (this.lastInputLength - this.cursorPos) + 'P');\n this.terminal.write('\\b\\x1b[P'.repeat(this.cursorPos));\n\n if (action === 'write') {\n this.copyFromHistoryIndex();\n this.history[0] = this.history[0].substr(0, this.cursorPos) + (arguments.length <= 1 ? undefined : arguments[1]) + this.history[0].substr(this.cursorPos);\n this.cursorPos++;\n } else if (action === 'back') {\n this.copyFromHistoryIndex();\n this.history[0] = this.history[0].substr(0, this.cursorPos - 1) + this.history[0].substr(this.cursorPos);\n this.cursorPos--;\n if (this.cursorPos < 0) this.cursorPos = 0;\n } else if (action === 'tab') {\n var _completed = this.getCompleted();\n if (_completed) {\n this.history[0] = _completed;\n this.cursorPos = this.history[0].length;\n }\n } else if (action === 'move-cursor-x') {\n this.cursorPos = Math.max(0, Math.min(this.history[this.historyIndex].length, this.cursorPos + (arguments.length <= 1 ? undefined : arguments[1])));\n } else if (action === 'delete-line') {\n this.copyFromHistoryIndex();\n this.history[0] = '';\n this.cursorPos = 0;\n } else if (action === 'delete-word') {\n this.copyFromHistoryIndex();\n var words = this.history[0].substr(0, this.cursorPos).split(' ');\n words.pop();\n this.history[0] = words.join(' ') + this.history[0].substr(this.cursorPos);\n this.cursorPos = words.join(' ').length;\n } else if (action === 'move-cursor-y') {\n this.historyIndex -= arguments.length <= 1 ? undefined : arguments[1];\n if (this.historyIndex < 0) this.historyIndex = 0;\n if (this.historyIndex >= this.history.length) this.historyIndex = this.history.length - 1;\n this.cursorPos = this.history[this.historyIndex].length;\n }\n\n this.terminal.write(this.history[this.historyIndex]);\n this.terminal.write('\\b'.repeat(this.history[this.historyIndex].length));\n this.terminal.moveForward(this.cursorPos);\n\n this.lastInputLength = this.cursorPos;\n\n var completed = this.getCompleted(true);\n if (this.historyIndex === 0 && completed && action !== 'return') {\n // show closest match faintly\n var rest = completed.substr(this.history[0].length);\n this.terminal.write('\\x1B[2m' + rest + '\\x1B[m' + '\\b'.repeat(rest.length));\n this.lastInputLength += rest.length;\n }\n\n if (action === 'return') {\n this.terminal.write('\\n');\n this.parse(this.history[this.historyIndex]);\n }\n }\n }, {\n key: 'parse',\n value: function parse(input) {\n if (input === 'help') input = 'info';\n // TODO: basic chaining (i.e. semicolon)\n if (input) this.run(input);else this.prompt();\n }\n }, {\n key: 'run',\n value: function run(command) {\n var parts = [''];\n\n var inQuote = false;\n var _iteratorNormalCompletion8 = true;\n var _didIteratorError8 = false;\n var _iteratorError8 = undefined;\n\n try {\n for (var _iterator8 = command.trim()[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {\n var character = _step8.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 _didIteratorError8 = true;\n _iteratorError8 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion8 && _iterator8.return) {\n _iterator8.return();\n }\n } finally {\n if (_didIteratorError8) {\n throw _iteratorError8;\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 _this25 = this;\n\n var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n var Process = this.index[name];\n if (Process instanceof Function) {\n var _child;\n\n this.setButtons([]);\n this.child = new Process(this);\n var write = function write(data) {\n return _this25.terminal.write(data);\n };\n var setButtons = function setButtons(buttons) {\n return _this25.setButtons(buttons);\n };\n this.child.on('write', write);\n this.child.on('buttons', setButtons);\n this.child.on('exit', function (code) {\n if (_this25.child) {\n _this25.child.removeListener('write', write);\n _this25.child.removeListener('buttons', setButtons);\n }\n _this25.child = null;\n _this25.prompt(!code);\n });\n (_child = this.child).run.apply(_child, _toConsumableArray(args));\n } else {\n this.terminal.write(Process);\n this.prompt();\n }\n }\n }, {\n key: 'setButtons',\n value: function setButtons(buttons) {\n if (!buttons) {\n var shell = this;\n var writeChars = function writeChars(chars) {\n var loop = function loop() {\n shell.write(chars[0]);\n chars = chars.substr(1);\n if (chars) setTimeout(loop, 100);\n };\n setTimeout(loop, 200);\n };\n\n buttons = [{\n label: 'Open GitHub',\n action: function action(shell) {\n if (shell.child) shell.child.destroy();\n writeChars('github\\r');\n }\n }, {\n label: 'Help',\n action: function action(shell) {\n if (shell.child) shell.child.destroy();\n writeChars('info\\r');\n }\n }];\n }\n if (!buttons.length) buttons.push({ label: '', action: function action() {}\n });\n this.buttons = buttons;\n this.terminal.buttonLabels = buttons.map(function (x) {\n return x.label;\n });\n }\n }, {\n key: 'onButtonPress',\n value: function onButtonPress(index) {\n var button = this.buttons[index];\n if (!button) return;\n button.action(this, this.terminal);\n }\n }]);\n\n return DemoShell;\n}();\n\nwindow.demoInterface = module.exports = {\n input: function input(data) {\n var type = data[0];\n var content = data.substr(1);\n\n if (type === 's') {\n this.shell.write(content);\n } else if (type === 'b') {\n var button = content.charCodeAt(0);\n this.shell.onButtonPress(button - 1);\n } else if (type === 'm' || type === 'p' || type === 'r') {\n var row = parse2B(content, 0);\n var column = parse2B(content, 2);\n var _button = parse2B(content, 4);\n var modifiers = parse2B(content, 6);\n\n if (demoData.mouseReceiver) {\n if (type === 'm') demoData.mouseReceiver.mouseMove(column, row, _button, modifiers);else if (type === 'p') demoData.mouseReceiver.mouseDown(column, row, _button, modifiers);else if (type === 'r') demoData.mouseReceiver.mouseUp(column, row, _button, modifiers);\n }\n }\n },\n\n didInit: false,\n init: function init(screen) {\n if (this.didInit) return;\n this.didInit = true;\n this.terminal = new ScrollingTerminal(screen);\n this.shell = new DemoShell(this.terminal, true);\n }\n};\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar data = __webpack_require__(14);\n\nmodule.exports = function localize(key) {\n return data[key] || '?' + key + '?';\n};\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n__webpack_require__(11);\n__webpack_require__(4);\n__webpack_require__(5);\n__webpack_require__(12);\ntry {\n __webpack_require__(8);\n} catch (err) {}\n__webpack_require__(13);\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__(15);\nwindow.$ = $;\nwindow.qs = qs;\n\nwindow.themes = __webpack_require__(3);\n\nwindow.TermConf = __webpack_require__(26);\n\n/***/ }),\n/* 11 */\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/* 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 qs = _require.qs,\n qsa = _require.qsa,\n cr = _require.cr;\n\nvar modal = __webpack_require__(4);\nvar notify = __webpack_require__(5);\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 try {\n do {\n var msgAt = void 0,\n box = void 0;\n // populate the form errors box from GET arg ?err=...\n // (a way to pass errors back from server via redirect)\n msgAt = window.location.search.indexOf('err=');\n if (msgAt !== -1 && qs('.Box.errors')) {\n var _ret = function () {\n var errs = decodeURIComponent(window.location.search.substr(msgAt + 4)).split(',');\n var humanReadableErrors = [];\n errs.forEach(function (er) {\n if (er.length === 0) return;\n var lbls = qsa('label[for=\"' + er + '\"]');\n if (lbls && lbls.length > 0) {\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 console.log(JSON.stringify(er));\n humanReadableErrors.push(er);\n }\n });\n\n qs('.Box.errors .list').innerHTML = humanReadableErrors.join(', ');\n qs('.Box.errors').classList.remove('hidden');\n return 'break';\n }();\n\n if (_ret === 'break') break;\n }\n\n var fademsgbox = function fademsgbox(box, time) {\n box.classList.remove('hidden');\n setTimeout(function () {\n box.classList.add('hiding');\n setTimeout(function () {\n box.classList.add('hidden');\n }, 1000);\n }, time);\n };\n\n msgAt = window.location.search.indexOf('errmsg=');\n box = qs('.Box.errmessage');\n if (msgAt !== -1 && box) {\n var msg = decodeURIComponent(window.location.search.substr(msgAt + 7));\n box.innerHTML = msg;\n fademsgbox(box, 3000);\n break;\n }\n\n msgAt = window.location.search.indexOf('msg=');\n box = qs('.Box.message');\n if (msgAt !== -1 && box) {\n var _msg = decodeURIComponent(window.location.search.substr(msgAt + 4));\n box.innerHTML = _msg;\n fademsgbox(box, 2000);\n break;\n }\n } while (0);\n } catch (e) {\n console.error(e);\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 qs('#screen').classList.add('failed');\n showPage();\n }\n }, 2000);\n } else {\n setTimeout(function () {\n showPage();\n }, 1);\n }\n});\n\n/***/ }),\n/* 13 */\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__(9);\n\nvar HTTPS = window.location.protocol.match(/s:/);\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((HTTPS ? 'https' : '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/* 14 */\n/***/ (function(module, exports) {\n\n/* Generated language file */\nmodule.exports={\"wifi.connected_ip_is\":\"Connected, IP is \",\"wifi.not_conn\":\"Not connected.\",\"wifi.enter_passwd\":\"Enter password for \\\":ssid:\\\"\",\"term_nav.fullscreen\":\"Fullscreen\",\"term_conn.connecting\":\"Connecting\",\"term_conn.waiting_content\":\"Waiting for content\",\"term_conn.disconnected\":\"Disconnected\",\"term_conn.waiting_server\":\"Waiting for server\",\"term_conn.reconnecting\":\"Reconnecting\"}\n\n\n/***/ }),\n/* 15 */\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 $ = __webpack_require__(1);\n\nvar _require = __webpack_require__(0),\n qs = _require.qs,\n mk = _require.mk;\n\nvar localize = __webpack_require__(9);\nvar Notify = __webpack_require__(5);\nvar TermScreen = __webpack_require__(16);\nvar TermConnection = __webpack_require__(20);\nvar TermInput = __webpack_require__(21);\nvar TermUpload = __webpack_require__(22);\nvar initSoftKeyboard = __webpack_require__(23);\nvar attachDebugger = __webpack_require__(24);\nvar initButtons = __webpack_require__(25);\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 input.termUpload = termUpload;\n\n // forward screen input events\n screen.on('mousedown', function () {\n return input.onMouseDown.apply(input, arguments);\n });\n screen.on('mousemove', function () {\n return input.onMouseMove.apply(input, arguments);\n });\n screen.on('mouseup', function () {\n return input.onMouseUp.apply(input, arguments);\n });\n screen.on('mousewheel', function () {\n return input.onMouseWheel.apply(input, arguments);\n });\n screen.on('input-alts', function () {\n return input.setAlts.apply(input, arguments);\n });\n screen.on('mouse-mode', function () {\n return input.setMouseMode.apply(input, arguments);\n });\n\n // touch selection menu (the Copy button)\n $.ready(function () {\n var touchSelectMenu = qs('#touch-select-menu');\n screen.on('show-touch-select-menu', function (x, y) {\n var rect = touchSelectMenu.getBoundingClientRect();\n x -= rect.width / 2;\n y -= rect.height / 2;\n\n touchSelectMenu.classList.add('open');\n touchSelectMenu.style.transform = 'translate(' + x + 'px,' + y + 'px)';\n });\n screen.on('hide-touch-select-menu', function () {\n return touchSelectMenu.classList.remove('open');\n });\n\n var copyButton = qs('#touch-select-copy-btn');\n if (copyButton) {\n copyButton.addEventListener('click', function () {\n screen.copySelectionToClipboard();\n });\n }\n });\n\n // buttons\n var buttons = initButtons(input);\n screen.on('buttons-update', function (update) {\n buttons.labels = update.labels;\n buttons.colors = update.colors;\n });\n // TODO: don't access the renderer here\n buttons.palette = screen.layout.renderer.palette;\n screen.layout.renderer.on('palette-update', function (palette) {\n buttons.palette = palette;\n });\n\n screen.on('full-load', function () {\n var scr = qs('#screen');\n var errmsg = qs('#load-failed');\n if (scr) scr.classList.remove('failed');\n if (errmsg) errmsg.parentNode.removeChild(errmsg);\n });\n\n var setLinkVisibility = function setLinkVisibility(visible) {\n var buttons = [].concat(_toConsumableArray(document.querySelectorAll('.x-term-conf-btn')));\n if (visible) buttons.forEach(function (x) {\n return x.classList.remove('hidden');\n });else buttons.forEach(function (x) {\n return x.classList.add('hidden');\n });\n };\n var setButtonVisibility = function setButtonVisibility(visible) {\n if (visible) qs('#action-buttons').classList.remove('hidden');else qs('#action-buttons').classList.add('hidden');\n };\n\n screen.on('opts-update', function () {\n setLinkVisibility(screen.showLinks);\n setButtonVisibility(screen.showButtons);\n });\n\n screen.on('title-update', function (text) {\n qs('#screen-title').textContent = text;\n if (!text) text = 'Terminal';\n qs('title').textContent = text + ' :: ESPTerm';\n });\n\n // connection status\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 screen.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.layout.canvas);\n\n initSoftKeyboard(screen, input);\n if (attachDebugger) attachDebugger(screen, conn);\n\n // fullscreen mode\n\n var fullscreenIcon = {}; // dummy\n var isFullscreen = false;\n var properFullscreen = false;\n var fitScreen = false;\n var screenPadding = screen.layout.window.padding;\n var fitScreenIfNeeded = function fitScreenIfNeeded() {\n if (isFullscreen) {\n fullscreenIcon.className = 'icn-resize-small';\n if (properFullscreen) {\n screen.layout.window.fitIntoWidth = window.screen.width;\n screen.layout.window.fitIntoHeight = window.screen.height;\n screen.layout.window.padding = 0;\n } else {\n screen.layout.window.fitIntoWidth = window.innerWidth;\n if (qs('#term-nav').classList.contains('hidden')) {\n screen.layout.window.fitIntoHeight = window.innerHeight;\n } else {\n screen.layout.window.fitIntoHeight = window.innerHeight - 24;\n }\n screen.layout.window.padding = 0;\n }\n } else {\n fullscreenIcon.className = 'icn-resize-full';\n screen.layout.window.fitIntoWidth = fitScreen ? window.innerWidth - 4 : 0;\n screen.layout.window.fitIntoHeight = fitScreen ? window.innerHeight : 0;\n screen.layout.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.layout.updateSize();\n\n if (properFullscreen) {\n if (screen.layout.canvas.requestFullscreen) screen.layout.canvas.requestFullscreen();else screen.layout.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.buttons = buttons;\n window.conn = conn;\n window.input = input;\n window.termUpl = termUpload;\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 _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__(2);\n\nvar _require = __webpack_require__(0),\n mk = _require.mk;\n\nvar notify = __webpack_require__(5);\nvar ScreenParser = __webpack_require__(17);\nvar ScreenLayout = __webpack_require__(18);\n\nvar _require2 = __webpack_require__(6),\n ATTR_BLINK = _require2.ATTR_BLINK;\n\n/**\n * A terminal screen.\n */\n\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.parser = new ScreenParser();\n _this.layout = new ScreenLayout();\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 _this._window = {\n width: 0,\n height: 0,\n // two bits. LSB: debug enabled by user, MSB: debug enabled by server\n debug: 0,\n statusScreen: null\n\n // make writing to window update size and draw\n };_this.window = new Proxy(_this._window, {\n set: function set(target, key, value) {\n if (target[key] !== value) {\n target[key] = value;\n self.updateLayout();\n self.renderScreen('window:' + key + '=' + value);\n self.emit('update-window:' + key, value);\n }\n return true;\n }\n });\n\n _this.on('update-window:debug', function (debug) {\n _this.layout.window.debug = !!debug;\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 var self = _this;\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: null,\n\n // selection start and end (x, y) tuples\n start: [0, 0],\n end: [0, 0],\n\n setSelectable: function setSelectable(value) {\n if (value !== this.selectable) {\n this.selectable = self.layout.selectable = value;\n }\n }\n };\n\n // mouse features\n _this.mouseMode = { clicks: false, movement: false };\n\n _this.showLinks = false;\n _this.showButtons = false;\n _this.title = '';\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 _this.screenLines = [];\n\n // For testing TODO remove\n // this.screenLines[0] = 0b001\n // this.screenLines[1] = 0b010\n // this.screenLines[2] = 0b100\n // this.screenLines[3] = 0b011\n // this.screenLines[4] = 0b101\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.layout.screenToGrid(x, y, true);\n _this.renderScreen('select-start');\n };\n\n var selectMove = function selectMove(x, y) {\n if (!selecting) return;\n _this.selection.end = _this.layout.screenToGrid(x, y, true);\n _this.renderScreen('select-move');\n };\n\n var selectEnd = function selectEnd(x, y) {\n if (!selecting) return;\n selecting = false;\n _this.selection.end = _this.layout.screenToGrid(x, y, true);\n _this.renderScreen('select-end');\n Object.assign(_this.selection, _this.getNormalizedSelection());\n };\n\n // bind event listeners\n\n _this.layout.on('mousedown', function (e) {\n _this.emit('hide-touch-select-menu');\n if ((_this.selection.selectable || e.altKey) && e.button === 0) {\n selectStart(e.offsetX, e.offsetY);\n } else {\n _this.emit.apply(_this, ['mousedown'].concat(_toConsumableArray(_this.layout.screenToGrid(e.offsetX, e.offsetY)), [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.layout.canvas.getBoundingClientRect();\n return [touch.clientX - rect.left, touch.clientY - rect.top];\n };\n\n _this.layout.on('touchstart', function (e) {\n touchPosition = getTouchPositionOffset(e.touches[0]);\n touchDidMove = false;\n touchDownTime = Date.now();\n\n if (_this.mouseMode.clicks) {\n var _this$layout;\n\n _this.emit.apply(_this, ['mousedown'].concat(_toConsumableArray((_this$layout = _this.layout).screenToGrid.apply(_this$layout, _toConsumableArray(touchPosition))), [1]));\n e.preventDefault();\n }\n });\n\n _this.layout.on('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 } else if (_this.mouseMode.movement && !selecting) {\n var _this$layout2;\n\n _this.emit.apply(_this, ['mousemove'].concat(_toConsumableArray((_this$layout2 = _this.layout).screenToGrid.apply(_this$layout2, _toConsumableArray(touchPosition)))));\n e.preventDefault();\n }\n\n touchDidMove = true;\n });\n\n _this.layout.on('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 // use middle position for x and one line above for y\n var selectionPos = _this.layout.gridToScreen((_this.selection.start[0] + _this.selection.end[0]) / 2, _this.selection.start[1] - 1);\n\n _this.emit('show-touch-select-menu', selectionPos[0], selectionPos[1]);\n } else if (_this.mouseMode.clicks) {\n var _this$layout3;\n\n _this.emit.apply(_this, ['mouseup'].concat(_toConsumableArray((_this$layout3 = _this.layout).screenToGrid.apply(_this$layout3, _toConsumableArray(touchPosition))), [1]));\n e.preventDefault();\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 } else if (!touchDidMove) _this.resetSelection();\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 _this.resetSelection();\n } else {\n e.preventDefault();\n _this.emit('open-soft-keyboard');\n }\n });\n\n _this.layout.on('mousemove', function (e) {\n if (!selecting) {\n _this.emit.apply(_this, ['mousemove'].concat(_toConsumableArray(_this.layout.screenToGrid(e.offsetX, e.offsetY))));\n }\n });\n\n _this.layout.on('mouseup', function (e) {\n if (!selecting) {\n _this.emit.apply(_this, ['mouseup'].concat(_toConsumableArray(_this.layout.screenToGrid(e.offsetX, e.offsetY)), [e.button + 1]));\n }\n });\n\n var aggregateWheelDelta = 0;\n _this.layout.on('wheel', function (e) {\n if (_this.mouseMode.clicks) {\n if (Math.abs(e.wheelDeltaY) === 120) {\n // mouse wheel scrolling\n _this.emit.apply(_this, ['mousewheel'].concat(_toConsumableArray(_this.layout.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.emit.apply(_this, ['mousewheel'].concat(_toConsumableArray(_this.layout.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.layout.on('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 _createClass(TermScreen, [{\n key: 'resetScreen',\n value: function resetScreen() {\n var _window = this.window,\n width = _window.width,\n height = _window.height;\n\n this.blinkingCellCount = 0;\n this.screen.screen = new Array(width * height).fill(' ');\n this.screen.screenFG = new Array(width * height).fill(0);\n this.screen.screenBG = new Array(width * height).fill(0);\n this.screen.screenAttrs = new Array(width * height).fill(0);\n this.screen.screenLines = new Array(height).fill(0);\n }\n }, {\n key: 'updateLayout',\n value: function updateLayout() {\n this.layout.window.width = this.window.width;\n this.layout.window.height = this.window.height;\n }\n }, {\n key: 'renderScreen',\n value: function renderScreen(reason) {\n var selection = [];\n\n for (var cell = 0; cell < this.screen.length; cell++) {\n selection.push(this.isInSelection(cell % this.window.width, Math.floor(cell / this.window.width)));\n }\n\n this.layout.render(reason, {\n width: this.window.width,\n height: this.window.height,\n screen: this.screen,\n screenFG: this.screenFG,\n screenBG: this.screenBG,\n screenSelection: selection,\n screenAttrs: this.screenAttrs,\n screenLines: this.screenLines,\n cursor: this.cursor,\n statusScreen: this.window.statusScreen,\n reverseVideo: this.reverseVideo,\n hasBlinkingCells: !!this.blinkingCellCount\n });\n }\n }, {\n key: 'resetSelection',\n value: function resetSelection() {\n this.selection.start = this.selection.end = [0, 0];\n this.emit('hide-touch-select-menu');\n this.renderScreen('select-reset');\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 var updates = (_parser = this.parser).parse.apply(_parser, arguments);\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = updates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var update = _step.value;\n\n switch (update.topic) {\n case 'screen-opts':\n if (update.width !== this.window.width || update.height !== this.window.height) {\n this.window.width = update.width;\n this.window.height = update.height;\n this.resetScreen();\n }\n this.layout.renderer.loadTheme(update.theme);\n this.layout.renderer.setDefaultColors(update.defFG, update.defBG);\n this.cursor.visible = update.cursorVisible;\n this.emit.apply(this, ['input-alts'].concat(_toConsumableArray(update.inputAlts)));\n this.mouseMode.clicks = update.trackMouseClicks;\n this.mouseMode.movement = update.trackMouseMovement;\n this.emit('mouse-mode', update.trackMouseClicks, update.trackMouseMovement);\n this.selection.setSelectable(!update.trackMouseClicks && !update.trackMouseMovement);\n if (this.cursor.blinking !== update.cursorBlinking) {\n this.cursor.blinking = update.cursorBlinking;\n this.layout.renderer.resetCursorBlink();\n }\n this.cursor.style = update.cursorStyle;\n this.bracketedPaste = update.bracketedPaste;\n this.reverseVideo = update.reverseVideo;\n this.window.debug &= 1;\n this.window.debug |= +update.debugEnabled << 1;\n\n this.showLinks = update.showConfigLinks;\n this.showButtons = update.showButtons;\n this.emit('opts-update');\n break;\n\n case 'double-lines':\n this.screenLines = update.lines;\n this.renderScreen('double-lines');\n break;\n\n case 'static-opts':\n this.layout.window.fontFamily = update.fontStack || null;\n this.layout.window.fontSize = update.fontSize;\n break;\n\n case 'cursor':\n if (this.cursor.x !== update.x || this.cursor.y !== update.y || this.cursor.hanging !== update.hanging) {\n this.cursor.x = update.x;\n this.cursor.y = update.y;\n this.cursor.hanging = update.hanging;\n this.layout.renderer.resetCursorBlink();\n this.emit('cursor-moved');\n this.renderScreen('cursor-moved');\n }\n break;\n\n case 'title':\n this.emit('title-update', this.title = update.title);\n break;\n\n case 'buttons-update':\n this.emit('buttons-update', update);\n break;\n\n case 'backdrop':\n this.backgroundImage = update.image;\n break;\n\n case 'bell':\n this.beep();\n break;\n\n case 'internal':\n this.emit('internal', update);\n break;\n\n case 'content':\n var frameX = update.frameX,\n frameY = update.frameY,\n frameWidth = update.frameWidth,\n frameHeight = update.frameHeight,\n cells = update.cells;\n\n\n if (this._debug && this.window.debug) {\n this._debug.pushFrame([frameX, frameY, frameWidth, frameHeight]);\n }\n\n for (var cell = 0; cell < cells.length; cell++) {\n var data = cells[cell];\n\n var cellXInFrame = cell % frameWidth;\n var cellYInFrame = Math.floor(cell / frameWidth);\n var index = (frameY + cellYInFrame) * this.window.width + frameX + cellXInFrame;\n\n if ((this.screenAttrs[index] & ATTR_BLINK) !== (data[3] & ATTR_BLINK)) {\n if (data[3] & ATTR_BLINK) this.blinkingCellCount++;else this.blinkingCellCount--;\n }\n\n this.screen[index] = data[0];\n this.screenFG[index] = data[1];\n this.screenBG[index] = data[2];\n this.screenAttrs[index] = data[3];\n }\n\n if (this.window.debug) console.log('Blinking cells: ' + this.blinkingCellCount);\n\n this.renderScreen('load');\n this.emit('load');\n break;\n\n case 'full-load-complete':\n this.emit('full-load');\n break;\n\n case 'notification':\n this.showNotification(update.content);\n break;\n\n default:\n console.warn('Unhandled update', update);\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 this.emit('update');\n }\n }]);\n\n return TermScreen;\n}(EventEmitter);\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 _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\nvar _require = __webpack_require__(6),\n ATTR_FG = _require.ATTR_FG,\n ATTR_BG = _require.ATTR_BG,\n ATTR_BOLD = _require.ATTR_BOLD,\n ATTR_UNDERLINE = _require.ATTR_UNDERLINE,\n ATTR_BLINK = _require.ATTR_BLINK,\n ATTR_STRIKE = _require.ATTR_STRIKE,\n ATTR_OVERLINE = _require.ATTR_OVERLINE,\n ATTR_FAINT = _require.ATTR_FAINT;\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\n// decode a number encoded as a unicode code point\nfunction du(str) {\n if (!str) return NaN;\n var num = str.codePointAt(0);\n if (num > 0xDFFF) num -= 0x800;\n return num - 1;\n}\n\n/* eslint-disable no-multi-spaces */\n// mnemonic\nvar TOPIC_SCREEN_OPTS = 'O'; // O-ptions\nvar TOPIC_STATIC_OPTS = 'P'; // P-arams\nvar TOPIC_CONTENT = 'S'; // S-creen\nvar TOPIC_TITLE = 'T'; // T-itle\nvar TOPIC_BUTTONS = 'B'; // B-uttons\nvar TOPIC_CURSOR = 'C'; // C-ursor\nvar TOPIC_INTERNAL = 'D'; // D-ebug\nvar TOPIC_BELL = '!'; // !!!\nvar TOPIC_BACKDROP = 'W'; // W-allpaper\nvar TOPIC_DOUBLE_LINES = 'H'; // H-uge\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\n/* eslint-enable no-multi-spaces */\n\n/**\n * A parser for screen update messages\n */\nmodule.exports = function () {\n function ScreenParser() {\n _classCallCheck(this, ScreenParser);\n\n // true if full content was loaded\n this.contentLoaded = false;\n }\n\n _createClass(ScreenParser, [{\n key: 'parseUpdate',\n value: function parseUpdate(str) {\n // console.log(`update ${str}`)\n\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 topics = du(strArray[ci++]);\n\n var collectOneTerminatedString = function collectOneTerminatedString() {\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 return text;\n };\n\n var collectColor = function collectColor() {\n var c = du(strArray[ci++]);\n if (c & 0x10000) {\n // support for trueColor\n c &= 0xFFF;\n c |= (du(strArray[ci++]) & 0xFFF) << 12;\n c += 256;\n }\n return c;\n };\n\n var updates = [];\n\n while (ci < strArray.length) {\n var topic = strArray[ci++];\n\n if (topic === TOPIC_SCREEN_OPTS) {\n var height = du(strArray[ci++]);\n var width = du(strArray[ci++]);\n var theme = du(strArray[ci++]);\n var defFG = collectColor();\n var defBG = collectColor();\n\n // process attributes\n var attributes = du(strArray[ci++]);\n\n var cursorVisible = !!(attributes & OPT_CURSOR_VISIBLE);\n\n // HACK: input alts are formatted as arguments for Input#setAlts\n var inputAlts = [!!(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) cursorStyle = 'block';else if (cursorStyle === 1) cursorStyle = 'line';else cursorStyle = 'bar';\n\n var showButtons = !!(attributes & OPT_SHOW_BUTTONS);\n var showConfigLinks = !!(attributes & OPT_SHOW_CONFIG_LINKS);\n\n var bracketedPaste = !!(attributes & OPT_BRACKETED_PASTE);\n var reverseVideo = !!(attributes & OPT_REVERSE_VIDEO);\n\n var debugEnabled = !!(attributes & OPT_DEBUGBAR);\n\n updates.push({\n topic: 'screen-opts',\n width: width,\n height: height,\n theme: theme,\n defFG: defFG,\n defBG: defBG,\n cursorVisible: cursorVisible,\n cursorBlinking: cursorBlinking,\n cursorStyle: cursorStyle,\n inputAlts: inputAlts,\n trackMouseClicks: trackMouseClicks,\n trackMouseMovement: trackMouseMovement,\n showButtons: showButtons,\n showConfigLinks: showConfigLinks,\n bracketedPaste: bracketedPaste,\n reverseVideo: reverseVideo,\n debugEnabled: debugEnabled\n });\n } else if (topic === TOPIC_CURSOR) {\n // cursor position\n var y = du(strArray[ci++]);\n var x = du(strArray[ci++]);\n var hanging = !!du(strArray[ci++]);\n\n updates.push({\n topic: 'cursor',\n x: x,\n y: y,\n hanging: hanging\n });\n } else if (topic === TOPIC_STATIC_OPTS) {\n var fontStack = collectOneTerminatedString();\n var fontSize = du(strArray[ci++]);\n\n updates.push({\n topic: 'static-opts',\n fontStack: fontStack,\n fontSize: fontSize\n });\n } else if (topic === TOPIC_DOUBLE_LINES) {\n var lines = [];\n var count = du(strArray[ci++]);\n for (var i = 0; i < count; i++) {\n // format: INDEX<<3 | (dbl-h-bot : dbl-h-top : dbl-w)\n var n = du(strArray[ci++]);\n lines[n >> 3] = n & 7;\n }\n updates.push({ topic: 'double-lines', lines: lines });\n } else if (topic === TOPIC_TITLE) {\n updates.push({ topic: 'title', title: collectOneTerminatedString() });\n } else if (topic === TOPIC_BUTTONS) {\n var _count = du(strArray[ci++]);\n\n var labels = [];\n var colors = [];\n for (var j = 0; j < _count; j++) {\n colors.push(collectColor());\n labels.push(collectOneTerminatedString());\n }\n\n updates.push({\n topic: 'buttons-update',\n labels: labels,\n colors: colors\n });\n } else if (topic === TOPIC_BACKDROP) {\n updates.push({ topic: 'backdrop', image: collectOneTerminatedString() });\n } else if (topic === TOPIC_BELL) {\n updates.push({ topic: 'bell' });\n } else if (topic === TOPIC_INTERNAL) {\n // debug info\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\n var cursorFg = collectColor();\n var cursorBg = collectColor();\n\n var freeHeap = du(strArray[ci++]);\n var clientCount = du(strArray[ci++]);\n\n updates.push({\n topic: 'internal',\n flags: flags,\n cursorAttrs: cursorAttrs,\n regionStart: regionStart,\n regionEnd: regionEnd,\n charsetGx: charsetGx,\n charsetG0: charsetG0,\n charsetG1: charsetG1,\n cursorFg: cursorFg,\n cursorBg: cursorBg,\n freeHeap: freeHeap,\n clientCount: clientCount\n });\n } else if (topic === TOPIC_CONTENT) {\n (function () {\n // set screen content\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 // 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\n var MASK_LINE_ATTR = ATTR_UNDERLINE | ATTR_OVERLINE | ATTR_STRIKE;\n var MASK_BLINK = ATTR_BLINK;\n\n var cells = [];\n\n var pushCell = function pushCell() {\n var hasFG = attrs & ATTR_FG;\n var hasBG = attrs & ATTR_BG;\n var cellFG = fg;\n var cellBG = bg;\n var cellAttrs = attrs;\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 // Remove blink attribute if it wouldn't have any effect\n if (cellAttrs & MASK_BLINK && (lastChar === ' ' && (cellAttrs & MASK_LINE_ATTR) === 0 || // no line styles\n fg === bg && hasFG && hasBG // invisible text\n )) {\n cellAttrs ^= MASK_BLINK;\n }\n\n // 8 dark system colors turn bright when bold\n if (cellAttrs & ATTR_BOLD && !(cellAttrs & ATTR_FAINT) && hasFG && cellFG < 8) {\n cellFG += 8;\n }\n\n cells.push([lastChar, cellFG, cellBG, cellAttrs]);\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 _count2 = void 0;\n switch (charCode) {\n case SEQ_REPEAT:\n _count2 = du(strArray[ci++]);\n for (var _j = 0; _j < _count2; _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 updates.push({\n topic: 'content',\n frameX: frameX,\n frameY: frameY,\n frameWidth: frameWidth,\n frameHeight: frameHeight,\n cells: cells\n });\n })();\n }\n\n if (topics & 0x3B && !this.contentLoaded) {\n updates.push({ topic: 'full-load-complete' });\n this.contentLoaded = true;\n }\n }\n\n return updates;\n }\n\n /**\n * Parses a message from the server\n * @param {string} message - the message\n */\n\n }, {\n key: 'parse',\n value: function parse(message) {\n var content = message.substr(1);\n var updates = [];\n\n // This is a good place for debugging the message\n // console.log(message)\n\n switch (message[0]) {\n case 'U':\n updates.push.apply(updates, _toConsumableArray(this.parseUpdate(content)));\n break;\n\n case 'G':\n return [{\n topic: 'notification',\n content: content\n }];\n\n default:\n console.warn('Bad data message type; ignoring.\\n' + JSON.stringify(message));\n }\n\n return updates;\n }\n }]);\n\n return ScreenParser;\n}();\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar EventEmitter = __webpack_require__(2);\nvar CanvasRenderer = __webpack_require__(19);\n\nvar DEFAULT_FONT = '\"DejaVu Sans Mono\", \"Liberation Mono\", \"Inconsolata\", \"Menlo\", monospace';\n\n/**\n * Manages terminal screen layout and sizing\n */\nmodule.exports = function (_EventEmitter) {\n _inherits(ScreenLayout, _EventEmitter);\n\n function ScreenLayout() {\n _classCallCheck(this, ScreenLayout);\n\n var _this = _possibleConstructorReturn(this, (ScreenLayout.__proto__ || Object.getPrototypeOf(ScreenLayout)).call(this));\n\n _this.canvas = document.createElement('canvas');\n _this.renderer = new CanvasRenderer(_this.canvas);\n\n _this._window = {\n width: 0,\n height: 0,\n devicePixelRatio: 1,\n fontFamily: DEFAULT_FONT,\n fontSize: 20,\n padding: 6,\n gridScaleX: 1.0,\n gridScaleY: 1.2,\n fitIntoWidth: 0,\n fitIntoHeight: 0,\n debug: false\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 _this.charSize = { width: 0, height: 0 };\n\n var self = _this;\n\n // make writing to window update size and draw\n _this.window = new Proxy(_this._window, {\n set: function set(target, key, value) {\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.on('update-window:debug', function (debug) {\n _this.renderer.debug = debug;\n });\n\n _this.canvas.addEventListener('mousedown', function (e) {\n return _this.emit('mousedown', e);\n });\n _this.canvas.addEventListener('mousemove', function (e) {\n return _this.emit('mousemove', e);\n });\n _this.canvas.addEventListener('mouseup', function (e) {\n return _this.emit('mouseup', e);\n });\n _this.canvas.addEventListener('touchstart', function (e) {\n return _this.emit('touchstart', e);\n });\n _this.canvas.addEventListener('touchmove', function (e) {\n return _this.emit('touchmove', e);\n });\n _this.canvas.addEventListener('touchend', function (e) {\n return _this.emit('touchend', e);\n });\n _this.canvas.addEventListener('wheel', function (e) {\n return _this.emit('wheel', e);\n });\n _this.canvas.addEventListener('contextmenu', function (e) {\n return _this.emit('contextmenu', e);\n });\n return _this;\n }\n\n /**\n * Schedule a size update in the next millisecond\n */\n\n\n _createClass(ScreenLayout, [{\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 key: 'getFont',\n\n\n /**\n * Returns a CSS font string with the current font settings and the\n * specified 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 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 var fontFamily = this.window.fontFamily || '';\n if (fontFamily.length > 0) fontFamily += ',';\n fontFamily += DEFAULT_FONT;\n return fontStyle + ' normal ' + fontWeight + ' ' + this.window.fontSize + 'px ' + 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 y = Math.floor(y / cellSize.height);\n if (this.renderer.drawnScreenLines[y]) x /= 2; // double size\n x = Math.floor((x + (rounded ? cellSize.width / 2 : 0)) / cellSize.width);\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 if (this.renderer.drawnScreenLines[y]) x *= 2; // double size\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 * Update the character size, used for calculating the cell size.\n * The space character is used for measuring.\n * @returns {Object} the character size with `width` and `height` in pixels\n */\n\n }, {\n key: 'updateCharSize',\n value: function updateCharSize() {\n this.charSize = {\n width: this.renderer.getCharWidthFor(this.getFont()),\n height: this.window.fontSize\n };\n\n return this.charSize;\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 if (!this.charSize.height && this.window.fontSize) this.updateCharSize();\n\n return {\n width: Math.ceil(this.charSize.width * this.window.gridScaleX),\n height: Math.ceil(this.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\n this.updateCharSize();\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 this.renderer.render('update-size', this.serializeRenderData());\n\n this.emit('size-update');\n }\n }\n }, {\n key: 'serializeRenderData',\n value: function serializeRenderData() {\n return {\n padding: Math.round(this._padding),\n devicePixelRatio: this.window.devicePixelRatio,\n charSize: this.charSize,\n cellSize: this.getCellSize(),\n fonts: [this.getFont(), this.getFont({ weight: 'bold' }), this.getFont({ style: 'italic' }), this.getFont({ weight: 'bold', style: 'italic' })]\n };\n }\n }, {\n key: 'render',\n value: function render(reason, data) {\n this.window.width = data.width;\n this.window.height = data.height;\n\n Object.assign(data, this.serializeRenderData());\n\n this.renderer.render(reason, data);\n }\n }, {\n key: 'backgroundImage',\n get: function get() {\n return this.canvas.style.backgroundImage;\n },\n set: function set(value) {\n this.canvas.style.backgroundImage = value ? 'url(' + value + ')' : '';\n if (this.renderer.backgroundImage !== !!value) {\n this.renderer.backgroundImage = !!value;\n this.renderer.resetDrawn();\n this.renderer.scheduleDraw('background-image');\n }\n }\n }, {\n key: 'selectable',\n get: function get() {\n return this.canvas.classList.contains('selectable');\n },\n set: function set(selectable) {\n if (selectable) this.canvas.classList.add('selectable');else this.canvas.classList.remove('selectable');\n }\n }]);\n\n return ScreenLayout;\n}(EventEmitter);\n\n/***/ }),\n/* 19 */\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 _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__(2);\n\nvar _require = __webpack_require__(3),\n themes = _require.themes,\n _getColor = _require.getColor;\n\nvar _require2 = __webpack_require__(6),\n ATTR_FG = _require2.ATTR_FG,\n ATTR_BG = _require2.ATTR_BG,\n ATTR_BOLD = _require2.ATTR_BOLD,\n ATTR_UNDERLINE = _require2.ATTR_UNDERLINE,\n ATTR_INVERSE = _require2.ATTR_INVERSE,\n ATTR_BLINK = _require2.ATTR_BLINK,\n ATTR_ITALIC = _require2.ATTR_ITALIC,\n ATTR_STRIKE = _require2.ATTR_STRIKE,\n ATTR_OVERLINE = _require2.ATTR_OVERLINE,\n ATTR_FAINT = _require2.ATTR_FAINT,\n ATTR_FRAKTUR = _require2.ATTR_FRAKTUR;\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 /**\n * A terminal screen renderer, using canvas 2D\n */\n};module.exports = function (_EventEmitter) {\n _inherits(CanvasRenderer, _EventEmitter);\n\n function CanvasRenderer(canvas) {\n _classCallCheck(this, CanvasRenderer);\n\n var _this = _possibleConstructorReturn(this, (CanvasRenderer.__proto__ || Object.getPrototypeOf(CanvasRenderer)).call(this));\n\n _this.canvas = canvas;\n _this.ctx = _this.canvas.getContext('2d');\n\n _this._palette = null; // colors 0-15\n _this.defaultBG = 0;\n _this.defaultFG = 7;\n\n _this.debug = false;\n _this._debug = null;\n\n _this.graphics = 0;\n\n _this.statusFont = \"-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif\";\n\n // screen data, considered immutable\n _this.width = 0;\n _this.height = 0;\n _this.padding = 0;\n _this.charSize = { width: 0, height: 0 };\n _this.cellSize = { width: 0, height: 0 };\n _this.fonts = ['', '', '', '']; // normal, bold, italic, bold-italic\n _this.screen = [];\n _this.screenFG = [];\n _this.screenBG = [];\n _this.screenAttrs = [];\n _this.screenSelection = [];\n _this.screenLines = [];\n _this.cursor = {};\n _this.reverseVideo = false;\n _this.hasBlinkingCells = false;\n _this.statusScreen = null;\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 return _this;\n }\n\n _createClass(CanvasRenderer, [{\n key: 'render',\n value: function render(reason, data) {\n if ('hasBlinkingCells' in data && data.hasBlinkingCells !== this.hasBlinkingCells) {\n if (data.hasBlinkingCells) this.resetBlink();else clearInterval(this.blinkInterval);\n }\n\n Object.assign(this, data);\n this.scheduleDraw(reason);\n }\n }, {\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.debug) console.log('Resetting drawn screen');\n\n this.drawnScreen = [];\n this.drawnScreenFG = [];\n this.drawnScreenBG = [];\n this.drawnScreenAttrs = [];\n this.drawnScreenLines = [];\n this.drawnCursor = [-1, -1, '', false];\n }\n\n /**\n * The color palette. Should define 16 colors in an array.\n * @type {string[]}\n */\n\n }, {\n key: 'getCharWidthFor',\n value: function getCharWidthFor(font) {\n this.ctx.font = font;\n return Math.floor(this.ctx.measureText(' ').width);\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.defaultFG || bg !== this.defaultBG) {\n this.resetDrawn();\n this.defaultFG = fg;\n this.defaultBG = bg;\n this.scheduleDraw('default-colors');\n\n // full bg with default color (goes behind the image)\n this.canvas.style.backgroundColor = this.getColor(bg);\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 _this2 = 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 _this2.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 _getColor(i, this.palette);\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 _this3 = this;\n\n this.cursorBlinkOn = true;\n clearInterval(this.cursorBlinkInterval);\n this.cursorBlinkInterval = setInterval(function () {\n _this3.cursorBlinkOn = _this3.cursor.blinking ? !_this3.cursorBlinkOn : true;\n if (_this3.cursor.blinking) _this3.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 _this4 = this;\n\n this.blinkStyleOn = true;\n clearInterval(this.blinkInterval);\n var intervals = 0;\n this.blinkInterval = setInterval(function () {\n if (_this4.blinkingCellCount <= 0) return;\n\n intervals++;\n if (intervals >= 4 && _this4.blinkStyleOn) {\n _this4.blinkStyleOn = false;\n intervals = 0;\n _this4.scheduleDraw('blink-style');\n } else if (intervals >= 1 && !_this4.blinkStyleOn) {\n _this4.blinkStyleOn = true;\n intervals = 0;\n _this4.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 * @param {number} options.isDefaultBG - if true, will draw image background if available\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 isDefaultBG = _ref.isDefaultBG;\n var ctx = this.ctx,\n width = this.width,\n height = this.height,\n padding = this.padding;\n\n // is a double-width/double-height line\n\n if (this.screenLines[y] & 1) cellWidth *= 2;\n\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\n var fillX = void 0,\n fillY = void 0,\n fillWidth = void 0,\n fillHeight = void 0;\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\n fillX = left;\n fillY = top;\n fillWidth = right - left;\n fillHeight = bottom - top;\n } else {\n fillX = screenX;\n fillY = screenY;\n fillWidth = cellWidth;\n fillHeight = cellHeight;\n }\n\n ctx.clearRect(fillX, fillY, fillWidth, fillHeight);\n\n if (!isDefaultBG || bg < 0 || !this.backgroundImage) {\n ctx.fillRect(fillX, fillY, fillWidth, fillHeight);\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 padding = this.padding;\n\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 = CanvasRenderer.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 dblWidth = this.screenLines[y] & 1;\n var dblHeightTop = this.screenLines[y] & 2;\n var dblHeightBot = this.screenLines[y] & 4;\n\n if (this.screenLines[y]) {\n // is a double-width/double-height line\n if (dblWidth) cellWidth *= 2;\n\n ctx.save();\n ctx.translate(padding, screenY + 0.5 * cellHeight);\n if (dblWidth) ctx.scale(2, 1);\n if (dblHeightTop) {\n // top half\n ctx.scale(1, 2);\n ctx.translate(0, cellHeight / 4);\n } else if (dblHeightBot) {\n // bottom half\n ctx.scale(1, 2);\n ctx.translate(0, -cellHeight / 4);\n }\n ctx.translate(-padding, -screenY - 0.5 * cellHeight);\n if (dblWidth) ctx.translate(-cellWidth / 4, 0);\n\n if (dblHeightBot || dblHeightTop) {\n // characters overflow -- needs clipping\n // TODO: clipping is really expensive\n ctx.beginPath();\n if (dblHeightTop) ctx.rect(screenX, screenY, cellWidth, cellHeight / 2);else ctx.rect(screenX, screenY + cellHeight / 2, cellWidth, cellHeight / 2);\n ctx.clip();\n }\n }\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 if (this.screenLines[y]) ctx.restore();\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 width = this.width,\n height = this.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 ctx = this.ctx;\n var width = this.width,\n height = this.height,\n devicePixelRatio = this.devicePixelRatio,\n statusScreen = this.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.charSize;\n var _cellSize = this.cellSize,\n cellWidth = _cellSize.width,\n cellHeight = _cellSize.height;\n\n var screenLength = width * height;\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n\n if (this.debug && this._debug) this._debug.drawStart(why);\n\n ctx.font = this.fonts[0];\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.cursor.x === x && this.cursor.y === y && this.cursor.visible;\n\n var wasCursor = x === this.drawnCursor[0] && y === this.drawnCursor[1];\n\n var text = this.screen[cell];\n var fg = this.screenFG[cell] | 0;\n var bg = this.screenBG[cell] | 0;\n var attrs = this.screenAttrs[cell] | 0;\n var inSelection = this.screenSelection[cell];\n\n var isDefaultBG = false;\n\n if (!(attrs & ATTR_FG)) fg = this.defaultFG;\n if (!(attrs & ATTR_BG)) {\n bg = this.defaultBG;\n isDefaultBG = true;\n }\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.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 only draws decoration\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 this.screenLines[y] !== this.drawnScreenLines[y] || // line updated\n // TODO: fix artifacts or keep this hack:\n isCursor || wasCursor || // cursor blink/position updated\n isCursor && this.cursor.style !== this.drawnCursor[2] || // cursor style updated\n isCursor && this.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, isDefaultBG: isDefaultBG });\n updateMap.set(cell, didUpdate);\n }\n\n // set drawn screen lines\n this.drawnScreenLines = this.screenLines.slice();\n\n var debugFilledUpdates = [];\n\n if (this.graphics >= 1) {\n // fancy graphics gets really slow when there's a lot of masks\n // so here's an algorithm that fills in holes in the update map\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = updateMap.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var _cell = _step.value;\n\n if (updateMap.get(_cell)) continue;\n var previous = updateMap.get(_cell - 1) || false;\n var next = updateMap.get(_cell + 1) || false;\n\n if (previous && next) {\n // set cell to true of horizontally adjacent updated\n updateMap.set(_cell, true);\n if (this.debug && this._debug) debugFilledUpdates.push(_cell);\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\n // Map of (cell index) -> boolean, whether or not a cell should be redrawn\n var redrawMap = new Map();\n var maskedCells = 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 _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 _cell2 = _step2.value;\n\n var shouldUpdate = updateMap.get(_cell2) || redrawMap.get(_cell2) || false;\n\n // TODO: fonts (necessary?)\n var _text = this.screen[_cell2];\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 _iteratorNormalCompletion6 = true;\n var _didIteratorError6 = false;\n var _iteratorError6 = undefined;\n\n try {\n for (var _iterator6 = this.getAdjacentCells(_cell2, checkRadius)[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {\n var adjacentCell = _step6.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 // - this or the adjacent cell is not double-sized\n if (updateMap.get(adjacentCell) && (this.graphics < 2 || isWideCell || isTextWide(this.screen[adjacentCell])) && !this.screenLines[Math.floor(_cell2 / this.width)] && !this.screenLines[Math.floor(adjacentCell / this.width)]) {\n adjacentDidUpdate = true;\n\n if (this.getAdjacentCells(_cell2, 1).includes(adjacentCell)) {\n // this is within a radius of 1, therefore this cell should be included in the mask as well\n maskedCells.set(_cell2, true);\n }\n break;\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 if (adjacentDidUpdate) shouldUpdate = true;\n }\n\n if (updateMap.get(_cell2)) {\n // this was updated, it should definitely be included in the mask\n maskedCells.set(_cell2, true);\n }\n\n redrawMap.set(_cell2, shouldUpdate);\n }\n\n // mask to masked 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.graphics >= 1) {\n // TODO: include padding in border cells\n var padding = this.padding;\n\n var regions = [];\n\n for (var _y = 0; _y < height; _y++) {\n var regionStart = null;\n for (var _x3 = 0; _x3 < width; _x3++) {\n var _cell3 = _y * width + _x3;\n var masked = maskedCells.get(_cell3);\n if (masked && regionStart === null) regionStart = _x3;\n if (!masked && regionStart !== null) {\n regions.push([regionStart, _y, _x3, _y + 1]);\n regionStart = null;\n }\n }\n if (regionStart !== null) {\n regions.push([regionStart, _y, width, _y + 1]);\n }\n }\n\n // join regions if possible (O(n^2-1), sorry)\n var i = 0;\n while (i < regions.length) {\n var region = regions[i];\n var j = 0;\n while (j < regions.length) {\n var other = regions[j];\n if (other === region) {\n j++;\n continue;\n }\n if (other[0] === region[0] && other[2] === region[2] && other[3] === region[1]) {\n region[1] = other[1];\n regions.splice(j, 1);\n if (i > j) i--;\n j--;\n }\n j++;\n }\n i++;\n }\n\n ctx.save();\n ctx.beginPath();\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = regions[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var _region = _step3.value;\n\n var _region2 = _slicedToArray(_region, 4),\n _regionStart = _region2[0],\n _y2 = _region2[1],\n endX = _region2[2],\n endY = _region2[3];\n\n var rectX = padding + _regionStart * cellWidth;\n var rectY = padding + _y2 * cellHeight;\n var rectWidth = (endX - _regionStart) * cellWidth;\n var rectHeight = (endY - _y2) * cellHeight;\n\n // compensate for padding\n if (_regionStart === 0) {\n rectX -= padding;\n rectWidth += padding;\n }\n if (_y2 === 0) {\n rectY -= padding;\n rectHeight += padding;\n }\n if (endX === width - 1) rectWidth += padding;\n if (_y2 === height - 1) rectHeight += padding;\n\n ctx.rect(rectX, rectY, rectWidth, rectHeight);\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 ctx.clip();\n }\n\n // pass 1: backgrounds\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 _font = _step4.value;\n var _iteratorNormalCompletion7 = true;\n var _didIteratorError7 = false;\n var _iteratorError7 = undefined;\n\n try {\n for (var _iterator7 = fontGroups.get(_font)[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {\n var data = _step7.value;\n var _cell4 = data.cell,\n _x4 = data.x,\n _y3 = data.y,\n _text2 = data.text,\n _bg = data.bg,\n _isDefaultBG = data.isDefaultBG;\n\n\n if (redrawMap.get(_cell4)) {\n this.drawBackground({ x: _x4, y: _y3, cellWidth: cellWidth, cellHeight: cellHeight, bg: _bg, isDefaultBG: _isDefaultBG });\n\n if (this.debug) {\n // set cell flags\n var flags = +redrawMap.get(_cell4);\n flags |= +updateMap.get(_cell4) << 1;\n flags |= +maskedCells.get(_cell4) << 2;\n flags |= +isTextWide(_text2) << 3;\n flags |= +debugFilledUpdates.includes(_cell4) << 4;\n this._debug.setCell(_cell4, flags);\n }\n }\n }\n } catch (err) {\n _didIteratorError7 = true;\n _iteratorError7 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion7 && _iterator7.return) {\n _iterator7.return();\n }\n } finally {\n if (_didIteratorError7) {\n throw _iteratorError7;\n }\n }\n }\n }\n\n // reset drawn cursor\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 this.drawnCursor = [-1, -1, '', false];\n\n // pass 2: characters\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = fontGroups.keys()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var _font2 = _step5.value;\n\n // set font once because in Firefox, this is a really slow action for some\n // reason\n var fontIndex = 0;\n if (_font2 & ATTR_BOLD) fontIndex |= 1;\n if (_font2 & ATTR_ITALIC) fontIndex |= 2;\n ctx.font = this.fonts[fontIndex];\n\n var _iteratorNormalCompletion8 = true;\n var _didIteratorError8 = false;\n var _iteratorError8 = undefined;\n\n try {\n for (var _iterator8 = fontGroups.get(_font2)[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {\n var _data = _step8.value;\n var _cell5 = _data.cell,\n _x5 = _data.x,\n _y4 = _data.y,\n _text3 = _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(_cell5)) {\n this.drawCharacter({\n x: _x5, y: _y4, charSize: charSize, cellWidth: cellWidth, cellHeight: cellHeight, text: _text3, fg: _fg, attrs: _attrs\n });\n\n this.drawnScreen[_cell5] = _text3;\n this.drawnScreenFG[_cell5] = _fg;\n this.drawnScreenBG[_cell5] = _bg2;\n this.drawnScreenAttrs[_cell5] = _attrs;\n\n if (_isCursor) this.drawnCursor = [_x5, _y4, this.cursor.style, this.cursor.hanging];\n\n // draw cursor\n if (_isCursor && !_inSelection) {\n ctx.save();\n ctx.beginPath();\n\n var cursorX = _x5;\n var cursorY = _y4;\n var cursorWidth = cellWidth; // JS doesn't allow same-name assignment\n\n if (this.cursor.hanging) {\n // draw hanging cursor in the margin\n cursorX += 1;\n }\n\n // double-width lines\n if (this.screenLines[cursorY] & 1) cursorWidth *= 2;\n\n var screenX = cursorX * cursorWidth + this.padding;\n var screenY = cursorY * cellHeight + this.padding;\n\n if (this.cursor.style === 'block') {\n // block\n ctx.rect(screenX, screenY, cursorWidth, cellHeight);\n } else if (this.cursor.style === 'bar') {\n // vertical bar\n var barWidth = 2;\n ctx.rect(screenX, screenY, barWidth, cellHeight);\n } else if (this.cursor.style === 'line') {\n // underline\n var lineHeight = 2;\n ctx.rect(screenX, screenY + charSize.height, cursorWidth, 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: _text3, fg: _fg, attrs: _attrs\n });\n ctx.restore();\n }\n }\n }\n } catch (err) {\n _didIteratorError8 = true;\n _iteratorError8 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion8 && _iterator8.return) {\n _iterator8.return();\n }\n } finally {\n if (_didIteratorError8) {\n throw _iteratorError8;\n }\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 if (this.graphics >= 1) ctx.restore();\n\n if (this.debug && this._debug) this._debug.drawEnd();\n\n this.emit('draw', why);\n }\n }, {\n key: 'drawStatus',\n value: function drawStatus(statusScreen) {\n var ctx = this.ctx,\n width = this.width,\n height = this.height,\n devicePixelRatio = this.devicePixelRatio;\n\n // reset drawnScreen to force redraw when statusScreen is disabled\n\n this.drawnScreen = [];\n\n var cellSize = this.cellSize;\n var screenWidth = width * cellSize.width + 2 * this.padding;\n var screenHeight = height * cellSize.height + 2 * this.padding;\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n ctx.fillStyle = this.getColor(this.defaultBG);\n ctx.fillRect(0, 0, screenWidth, screenHeight);\n\n ctx.font = '24px ' + this.statusFont;\n ctx.fillStyle = this.getColor(this.defaultFG);\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.defaultFG);\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.emit('palette-update', palette);\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 CanvasRenderer;\n}(EventEmitter);\n\n/***/ }),\n/* 20 */\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__(2);\nvar $ = __webpack_require__(1);\nvar demo = void 0;\ntry {\n demo = __webpack_require__(8);\n} catch (err) {}\n\nvar RECONN_DELAY = 2000;\nvar HEARTBEAT_TIME = 3000;\nvar HTTPS = window.location.protocol.match(/s:/);\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 _this.queue = [];\n\n try {\n _this.blobReader = new window.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 // 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 _this3.flushQueue();\n }, 250);\n break;\n\n case '+':\n // console.log('xon');\n this.xoff = false;\n this.flushQueue();\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 console.log(\"Can't send, flood control. Queueing\");\n this.queue.push(message);\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 key: 'flushQueue',\n value: function flushQueue() {\n console.log('Flushing input queue');\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = this.queue[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var message = _step.value;\n this.send(message);\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 this.queue = [];\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((HTTPS ? 'wss' : '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 this.emit('heartbeat');\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((HTTPS ? 'https' : '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/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\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/* 22 */\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__(4);\n\n/** File upload utility */\nmodule.exports = function (conn, input, screen) {\n var lines = void 0,\n // array of lines without newlines\n line_i = void 0,\n // current line index\n fuTout = void 0,\n // timeout handle for line sending\n send_delay_ms = void 0,\n // delay between lines (ms)\n nl_str = void 0,\n // newline string to use\n curLine = void 0,\n // current line (when using fuOil)\n inline_pos = void 0; // Offset in line (for long lines)\n\n // lines longer than this are split to chunks\n // sending a super-ling string through the socket is not a good idea\n var MAX_LINE_LEN = 128;\n\n function openUploadDialog() {\n updateStatus('Ready...');\n modal.show('#fu_modal', onDialogClose);\n $('#fu_form').toggleClass('busy', false);\n input.blockKeys(true);\n }\n\n function onDialogClose() {\n console.log('Upload modal closed.');\n clearTimeout(fuTout);\n line_i = 0;\n input.blockKeys(false);\n }\n\n function updateStatus(msg) {\n qs('#fu_prog').textContent = msg;\n }\n\n function startUpload() {\n var v = qs('#fu_text').value;\n if (!v.length) {\n fuClose();\n return;\n }\n\n lines = v.split('\\n');\n line_i = 0;\n inline_pos = 0; // offset in line\n send_delay_ms = +qs('#fu_delay').value;\n\n // sanitize - 0 causes overflows\n if (send_delay_ms < 0) {\n send_delay_ms = 0;\n qs('#fu_delay').value = send_delay_ms;\n }\n\n nl_str = {\n 'CR': '\\r',\n 'LF': '\\n',\n 'CRLF': '\\r\\n'\n }[qs('#fu_crlf').value];\n\n $('#fu_form').toggleClass('busy', true);\n updateStatus('Starting...');\n uploadLine();\n }\n\n function uploadLine() {\n if (!$('#fu_modal').hasClass('visible')) {\n // Modal is closed, cancel\n return;\n }\n\n if (!conn.canSend()) {\n // postpone\n fuTout = setTimeout(uploadLine, 1);\n return;\n }\n\n if (inline_pos === 0) {\n curLine = '';\n if (line_i === 0) {\n if (screen.bracketedPaste) {\n curLine = '\\x1b[200~';\n }\n }\n\n curLine += lines[line_i++] + nl_str;\n\n if (line_i === lines.length) {\n if (screen.bracketedPaste) {\n curLine += '\\x1b[201~';\n }\n }\n }\n\n var maxChunk = +qs('#fu_chunk').value;\n if (maxChunk === 0 || maxChunk > MAX_LINE_LEN) {\n maxChunk = MAX_LINE_LEN;\n }\n\n var chunk = void 0;\n if (curLine.length - inline_pos <= maxChunk) {\n chunk = curLine.substr(inline_pos, maxChunk);\n inline_pos = 0;\n } else {\n chunk = curLine.substr(inline_pos, maxChunk);\n inline_pos += maxChunk;\n }\n\n if (!input.sendString(chunk)) {\n updateStatus('FAILED!');\n return;\n }\n\n var pt = Math.round(line_i / lines.length * 1000) / 10;\n updateStatus(line_i + ' / ' + lines.length + ' (' + pt + '%)');\n\n if (lines.length > line_i || inline_pos > 0) {\n fuTout = setTimeout(uploadLine, send_delay_ms);\n } else {\n closeWhenReady();\n }\n }\n\n function closeWhenReady() {\n if (!conn.canSend()) {\n // stuck in XOFF still, wait to process...\n updateStatus('Waiting for Tx buffer...');\n setTimeout(closeWhenReady, 100);\n } else {\n updateStatus('Done.');\n // delay to show it\n fuClose();\n }\n }\n\n function fuClose() {\n modal.hide('#fu_modal');\n }\n\n return {\n init: function init() {\n qs('#fu_file').addEventListener('change', function (evt) {\n var reader = new window.FileReader();\n var file = evt.target.files[0];\n var ftype = file.type || 'application/octet-stream';\n console.log('Selected file type: ' + ftype);\n if (!ftype.match(/text\\/.*|application\\/(json|csv|.*xml.*|.*script.*|x-php)/)) {\n // Deny load of blobs like img - can crash browser and will get corrupted anyway\n if (!window.confirm('This does not look like a text file: ' + ftype + '\\nReally load?')) {\n qs('#fu_file').value = '';\n return;\n }\n }\n reader.onload = function (e) {\n var txt = e.target.result.replace(/[\\r\\n]+/, '\\n');\n qs('#fu_text').value = txt;\n };\n console.log('Loading file...');\n reader.readAsText(file);\n }, false);\n\n qs('#term-fu-open').addEventListener('click', function (e) {\n e.preventDefault();\n openUploadDialog();\n });\n\n qs('#term-fu-start').addEventListener('click', function (e) {\n e.preventDefault();\n startUpload();\n });\n\n qs('#term-fu-close').addEventListener('click', function (e) {\n e.preventDefault();\n fuClose();\n });\n },\n open: openUploadDialog,\n setContent: function setContent(content) {\n qs('#fu_text').value = content;\n }\n };\n};\n\n/***/ }),\n/* 23 */\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$layout$gridTo = screen.layout.gridToScreen(screen.cursor.x, screen.cursor.y, true),\n _screen$layout$gridTo2 = _slicedToArray(_screen$layout$gridTo, 2),\n x = _screen$layout$gridTo2[0],\n y = _screen$layout$gridTo2[1];\n\n keyInput.style.transform = 'translate(' + x + 'px, ' + y + 'px)';\n };\n\n keyInput.addEventListener('focus', function () {\n keyboardOpen = true;\n updateInputPosition();\n shortcutBar.classList.add('open');\n });\n\n keyInput.addEventListener('blur', function () {\n keyboardOpen = false;\n shortcutBar.classList.remove('open');\n });\n\n screen.on('cursor-moved', updateInputPosition);\n\n qs('#term-kb-open').addEventListener('click', function (e) {\n e.preventDefault();\n keyInput.focus();\n });\n\n // Chrome for Android doesn't send proper keydown/keypress events with\n // real key values instead of 229 “Unidentified,” so here's a workaround\n // that deals with the input composition events.\n\n var lastCompositionString = '';\n\n // sends the difference between the last and the new composition string\n var sendInputDelta = function sendInputDelta(newValue) {\n if (newValue === null) newValue = ''; // this sometimes happens, why?\n var resend = false;\n if (newValue.length > lastCompositionString.length) {\n if (newValue.startsWith(lastCompositionString)) {\n // characters have been added at the end\n input.sendString(newValue.substr(lastCompositionString.length));\n } else resend = true;\n } else if (newValue.length < lastCompositionString.length) {\n if (lastCompositionString.startsWith(newValue)) {\n // characters have been removed at the end\n input.sendString('\\b'.repeat(lastCompositionString.length - newValue.length));\n } else resend = true;\n } else if (newValue !== lastCompositionString) resend = true;\n\n if (resend) {\n // the entire string changed; resend everything\n input.sendString('\\b'.repeat(lastCompositionString.length) + newValue);\n }\n lastCompositionString = newValue;\n };\n\n keyInput.addEventListener('keydown', function (e) {\n if (e.key === 'Unidentified') return;\n\n keyInput.value = '';\n\n e.stopPropagation();\n input.handleKeyDown(e);\n });\n\n keyInput.addEventListener('keypress', function (e) {\n // prevent key duplication on iOS (because Safari *does* send proper events)\n e.stopPropagation();\n });\n\n keyInput.addEventListener('input', function (e) {\n e.stopPropagation();\n\n if (e.isComposing && 'data' in e) {\n sendInputDelta(e.data);\n } else if (e.isComposing) {\n // Firefox Mobile doesn't support InputEvent#data, so here's a hack\n // that just takes the input value and uses that\n sendInputDelta(keyInput.value);\n } else {\n if (e.inputType === 'insertCompositionText') input.sendString(e.data);else if (e.inputType === 'deleteContentBackward') {\n lastCompositionString = '';\n sendInputDelta('');\n } else if (e.inputType === 'insertText') {\n input.sendString(e.data);\n }\n }\n });\n\n keyInput.addEventListener('compositionstart', function (e) {\n lastCompositionString = '';\n });\n\n keyInput.addEventListener('compositionend', function (e) {\n lastCompositionString = '';\n keyInput.value = '';\n });\n\n screen.on('open-soft-keyboard', function () {\n return keyInput.focus();\n });\n\n // shortcut bar\n var shortcuts = {\n Control: 'ctrl',\n Esc: 0x1b,\n Tab: 0x09,\n '←': 0x25,\n '↓': 0x28,\n '↑': 0x26,\n '→': 0x27\n };\n\n var touchMoved = false;\n\n var _loop = function _loop(shortcut) {\n var button = document.createElement('button');\n button.classList.add('shortcut-button');\n button.textContent = shortcut;\n shortcutBar.appendChild(button);\n\n var key = shortcuts[shortcut];\n if (typeof key === 'string') button.classList.add('modifier');\n button.addEventListener('touchstart', function (e) {\n touchMoved = false;\n if (typeof key === 'string') {\n // modifier button\n input.softModifiers[key] = true;\n button.classList.add('enabled');\n\n // prevent default. This prevents scrolling, but also prevents the\n // selection popup\n e.preventDefault();\n }\n });\n window.addEventListener('touchmove', function (e) {\n touchMoved = true;\n });\n button.addEventListener('touchend', function (e) {\n e.preventDefault();\n if (typeof key === 'number') {\n if (touchMoved) return;\n var fakeEvent = { which: key, preventDefault: function preventDefault() {} };\n input.handleKeyDown(fakeEvent);\n } else if (typeof key === 'string') {\n button.classList.remove('enabled');\n input.softModifiers[key] = false;\n }\n });\n };\n\n for (var shortcut in shortcuts) {\n _loop(shortcut);\n }\n};\n\n/***/ }),\n/* 24 */\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__(3),\n getColor = _require.getColor;\n\nvar _require2 = __webpack_require__(6),\n ATTR_FG = _require2.ATTR_FG,\n ATTR_BG = _require2.ATTR_BG,\n ATTR_BOLD = _require2.ATTR_BOLD,\n ATTR_UNDERLINE = _require2.ATTR_UNDERLINE,\n ATTR_BLINK = _require2.ATTR_BLINK,\n ATTR_ITALIC = _require2.ATTR_ITALIC,\n ATTR_STRIKE = _require2.ATTR_STRIKE,\n ATTR_OVERLINE = _require2.ATTR_OVERLINE,\n ATTR_FAINT = _require2.ATTR_FAINT,\n ATTR_FRAKTUR = _require2.ATTR_FRAKTUR;\n\n// debug toolbar, tooltip and screen\n\n\nmodule.exports = function attachDebugger(screen, connection) {\n // debug screen overlay\n var debugCanvas = document.createElement('canvas');\n debugCanvas.classList.add('debug-canvas');\n var ctx = debugCanvas.getContext('2d');\n\n // debug toolbar\n var toolbar = document.createElement('div');\n toolbar.classList.add('debug-toolbar');\n\n // debug tooltip\n var tooltip = document.createElement('div');\n tooltip.classList.add('debug-tooltip');\n tooltip.classList.add('hidden');\n\n // update functions, defined somewhere below\n var updateTooltip = void 0;\n var updateToolbar = void 0;\n\n // tooltip cell\n var selectedCell = null;\n\n // update tooltip cell when mouse moves\n var onMouseMove = function onMouseMove(e) {\n if (e.target !== screen.layout.canvas) {\n selectedCell = null;\n return;\n }\n selectedCell = screen.layout.screenToGrid(e.offsetX, e.offsetY);\n updateTooltip();\n };\n\n // hide tooltip when mouse leaves\n var onMouseOut = function onMouseOut(e) {\n selectedCell = null;\n tooltip.classList.add('hidden');\n };\n\n // updates debug canvas size\n var updateCanvasSize = function updateCanvasSize() {\n var _screen$layout$window = screen.layout.window,\n width = _screen$layout$window.width,\n height = _screen$layout$window.height,\n devicePixelRatio = _screen$layout$window.devicePixelRatio;\n\n var cellSize = screen.layout.getCellSize();\n var padding = Math.round(screen.layout._padding);\n debugCanvas.width = (width * cellSize.width + 2 * padding) * devicePixelRatio;\n debugCanvas.height = (height * cellSize.height + 2 * padding) * devicePixelRatio;\n debugCanvas.style.width = width * cellSize.width + 2 * screen.layout._padding + 'px';\n debugCanvas.style.height = height * cellSize.height + 2 * screen.layout._padding + 'px';\n };\n\n // defined somewhere below\n var startDrawLoop = void 0;\n\n var screenAttached = false;\n\n // node to which events were bound (kept here for when they need to be removed)\n var eventNode = void 0;\n\n // attaches/detaches debug screen overlay to/from DOM\n var setScreenAttached = function setScreenAttached(attached) {\n if (attached && !debugCanvas.parentNode) {\n screen.layout.canvas.parentNode.appendChild(debugCanvas);\n eventNode = debugCanvas.parentNode;\n eventNode.addEventListener('mousemove', onMouseMove);\n eventNode.addEventListener('mouseout', onMouseOut);\n screen.layout.on('size-update', updateCanvasSize);\n updateCanvasSize();\n screenAttached = true;\n startDrawLoop();\n } else if (!attached && debugCanvas.parentNode) {\n debugCanvas.parentNode.removeChild(debugCanvas);\n eventNode.removeEventListener('mousemove', onMouseMove);\n eventNode.removeEventListener('mouseout', onMouseOut);\n screen.layout.removeListener('size-update', updateCanvasSize);\n screenAttached = false;\n }\n };\n\n // attaches/detaches toolbar and tooltip to/from DOM\n var setToolbarAttached = function setToolbarAttached(attached) {\n if (attached && !toolbar.parentNode) {\n screen.layout.canvas.parentNode.appendChild(toolbar);\n screen.layout.canvas.parentNode.appendChild(tooltip);\n updateToolbar();\n } else if (!attached && toolbar.parentNode) {\n screen.layout.canvas.parentNode.removeChild(toolbar);\n screen.layout.canvas.parentNode.removeChild(tooltip);\n }\n };\n\n // attach/detach toolbar when debug mode is enabled/disabled\n screen.on('update-window:debug', function (enabled) {\n setToolbarAttached(enabled);\n });\n\n // ditto ^\n screen.layout.on('update-window:debug', function (enabled) {\n setScreenAttached(enabled);\n });\n\n var drawData = {\n // last draw reason\n reason: '',\n\n // when true, will show colored cell update overlays\n showUpdates: false,\n\n // draw start time in milliseconds\n startTime: 0,\n\n // end time\n endTime: 0,\n\n // partial update frames\n frames: [],\n\n // cell data\n cells: new Map(),\n\n // scroll region\n scrollRegion: null\n\n // debug interface\n };screen._debug = screen.layout.renderer._debug = {\n drawStart: function drawStart(reason) {\n drawData.reason = reason;\n drawData.startTime = window.performance.now();\n },\n drawEnd: function drawEnd() {\n drawData.endTime = window.performance.now();\n },\n setCell: function setCell(cell, flags) {\n drawData.cells.set(cell, [flags, window.performance.now()]);\n },\n pushFrame: function pushFrame(frame) {\n drawData.frames.push([].concat(_toConsumableArray(frame), [window.performance.now()]));\n }\n };\n\n var isDrawing = false;\n var drawLoop = function drawLoop() {\n // draw while the screen is attached\n if (screenAttached) window.requestAnimationFrame(drawLoop);else isDrawing = false;\n\n var now = window.performance.now();\n\n var _screen$layout$window2 = screen.layout.window,\n width = _screen$layout$window2.width,\n height = _screen$layout$window2.height,\n devicePixelRatio = _screen$layout$window2.devicePixelRatio;\n\n var padding = Math.round(screen.layout._padding);\n var cellSize = screen.layout.getCellSize();\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);\n ctx.clearRect(0, 0, width * cellSize.width + 2 * padding, height * cellSize.height + 2 * padding);\n ctx.translate(padding, padding);\n\n ctx.lineWidth = 2;\n ctx.lineJoin = 'round';\n\n if (drawData.showUpdates) {\n var cells = drawData.cells;\n for (var cell = 0; cell < width * height; cell++) {\n // cell does not exist or has no flags set\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) {\n cells.delete(cell);\n continue;\n }\n\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 & 2) {\n // updated\n ctx.fillStyle = '#0f0';\n } else if (flags & 1) {\n // redrawn\n ctx.fillStyle = '#f0f';\n }\n\n if (!(flags & 4)) {\n // outside a clipped region\n ctx.fillStyle = '#0ff';\n }\n\n if (flags & 16) {\n // was filled to speed up rendering\n ctx.globalAlpha /= 2;\n }\n\n ctx.fillRect(x * cellSize.width, y * cellSize.height, cellSize.width, cellSize.height);\n\n if (flags & 8) {\n // wide cell\n ctx.strokeStyle = '#f00';\n ctx.beginPath();\n ctx.moveTo(x * cellSize.width, (y + 1) * cellSize.height);\n ctx.lineTo((x + 1) * cellSize.width, (y + 1) * cellSize.height);\n ctx.stroke();\n }\n }\n\n var framesToDelete = [];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = drawData.frames[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var frame = _step.value;\n\n var _timestamp = frame[4];\n var _elapsedTime = (now - _timestamp) / 1000;\n if (_elapsedTime > 1) framesToDelete.push(frame);else {\n ctx.globalAlpha = 1 - _elapsedTime;\n ctx.strokeStyle = '#ff0';\n ctx.strokeRect(frame[0] * cellSize.width, frame[1] * cellSize.height, frame[2] * cellSize.width, frame[3] * cellSize.height);\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 var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = framesToDelete[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var _frame = _step2.value;\n\n drawData.frames.splice(drawData.frames.indexOf(_frame), 1);\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\n if (selectedCell !== null) {\n // draw a dashed outline around the selected cell\n var _selectedCell = selectedCell,\n _selectedCell2 = _slicedToArray(_selectedCell, 2),\n _x = _selectedCell2[0],\n _y = _selectedCell2[1];\n\n ctx.save();\n ctx.globalAlpha = 0.5;\n ctx.lineWidth = 1;\n\n // draw X line\n ctx.beginPath();\n ctx.moveTo(0, _y * cellSize.height);\n ctx.lineTo(_x * cellSize.width, _y * cellSize.height);\n ctx.strokeStyle = '#f00';\n ctx.setLineDash([cellSize.width]);\n ctx.stroke();\n\n // draw Y line\n ctx.beginPath();\n ctx.moveTo(_x * cellSize.width, 0);\n ctx.lineTo(_x * cellSize.width, _y * cellSize.height);\n ctx.strokeStyle = '#0f0';\n ctx.setLineDash([cellSize.height]);\n ctx.stroke();\n\n ctx.globalAlpha = 1;\n ctx.lineWidth = 1 + 0.5 * Math.sin(now / 1000 * 10);\n ctx.strokeStyle = '#fff';\n ctx.lineJoin = 'round';\n ctx.setLineDash([2, 2]);\n ctx.lineDashOffset = now / 1000 * 10;\n ctx.strokeRect(_x * cellSize.width, _y * cellSize.height, cellSize.width, cellSize.height);\n ctx.lineDashOffset += 2;\n ctx.strokeStyle = '#000';\n ctx.strokeRect(_x * cellSize.width, _y * cellSize.height, cellSize.width, cellSize.height);\n ctx.restore();\n }\n\n if (drawData.scrollRegion !== null) {\n // draw two lines marking the scroll region bounds\n var _drawData$scrollRegio = _slicedToArray(drawData.scrollRegion, 2),\n start = _drawData$scrollRegio[0],\n end = _drawData$scrollRegio[1];\n\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.strokeStyle = '#00f';\n ctx.lineWidth = 2;\n ctx.setLineDash([2, 2]);\n\n ctx.beginPath();\n ctx.moveTo(0, start * cellSize.height);\n ctx.lineTo(width * cellSize.width, start * cellSize.height);\n ctx.stroke();\n\n ctx.beginPath();\n ctx.moveTo(0, (end + 1) * cellSize.height);\n ctx.lineTo(width * cellSize.width, (end + 1) * cellSize.height);\n ctx.stroke();\n\n ctx.restore();\n }\n };\n\n startDrawLoop = function startDrawLoop() {\n if (isDrawing) return;\n isDrawing = true;\n drawLoop();\n };\n\n var pad2 = function pad2(i) {\n return ('00' + i.toString()).substr(-2);\n };\n var formatColor = function formatColor(color) {\n return color < 256 ? color.toString() : '#' + pad2(color >> 16) + pad2(color >> 8 & 0xFF) + pad2(color & 0xFF);\n };\n\n var makeSpan = function makeSpan(text, styles) {\n var span = document.createElement('span');\n span.textContent = text;\n Object.assign(span.style, styles || {});\n return span;\n };\n var formatAttributes = function formatAttributes(target, attrs) {\n if (attrs & ATTR_FG) target.appendChild(makeSpan('HasFG'));\n if (attrs & ATTR_BG) target.appendChild(makeSpan('HasBG'));\n if (attrs & ATTR_BOLD) target.appendChild(makeSpan('Bold', { fontWeight: 'bold' }));\n if (attrs & ATTR_UNDERLINE) target.appendChild(makeSpan('Uline', { textDecoration: 'underline' }));\n if (attrs & ATTR_BLINK) target.appendChild(makeSpan('Blink'));\n if (attrs & ATTR_ITALIC) target.appendChild(makeSpan('Italic', { fontStyle: 'italic' }));\n if (attrs & ATTR_STRIKE) target.appendChild(makeSpan('Strike', { textDecoration: 'line-through' }));\n if (attrs & ATTR_OVERLINE) target.appendChild(makeSpan('Oline', { textDecoration: 'overline' }));\n if (attrs & ATTR_FAINT) target.appendChild(makeSpan('Faint', { opacity: 0.5 }));\n if (attrs & ATTR_FRAKTUR) target.appendChild(makeSpan('Fraktur'));\n };\n\n updateTooltip = function updateTooltip() {\n // TODO: make this not destroy and recreate the same nodes every time\n tooltip.classList.remove('hidden');\n tooltip.innerHTML = '';\n var cell = selectedCell[1] * screen.window.width + selectedCell[0];\n if (!screen.screen[cell]) return;\n\n var foreground = document.createElement('span');\n foreground.textContent = formatColor(screen.screenFG[cell]);\n var preview = document.createElement('span');\n preview.textContent = ' ●';\n preview.style.color = getColor(screen.screenFG[cell], screen.layout.renderer.palette);\n foreground.appendChild(preview);\n\n var background = document.createElement('span');\n background.textContent = formatColor(screen.screenBG[cell]);\n var bgPreview = document.createElement('span');\n bgPreview.textContent = ' ●';\n bgPreview.style.color = getColor(screen.screenBG[cell], screen.layout.renderer.palette);\n background.appendChild(bgPreview);\n\n var character = screen.screen[cell];\n var codePoint = character.codePointAt(0);\n var formattedCodePoint = codePoint.toString(16).length <= 4 ? ('0000' + codePoint.toString(16)).substr(-4) : codePoint.toString(16);\n\n var attributes = document.createElement('span');\n attributes.classList.add('attributes');\n formatAttributes(attributes, screen.screenAttrs[cell]);\n\n var data = {\n Cell: 'col ' + (selectedCell[0] + 1) + ', ln ' + (selectedCell[1] + 1) + ' (' + cell + ')',\n Foreground: foreground,\n Background: background,\n Character: 'U+' + formattedCodePoint,\n Attributes: attributes\n };\n\n var table = document.createElement('table');\n\n for (var name in data) {\n var row = document.createElement('tr');\n var label = document.createElement('td');\n label.appendChild(new window.Text(name));\n label.classList.add('label');\n\n var value = document.createElement('td');\n value.appendChild(typeof data[name] === 'string' ? new window.Text(data[name]) : data[name]);\n value.classList.add('value');\n\n row.appendChild(label);\n row.appendChild(value);\n table.appendChild(row);\n }\n\n tooltip.appendChild(table);\n\n var cellSize = screen.layout.getCellSize();\n // add 3 to the position because for some reason the corner is off\n var posX = (selectedCell[0] + 1) * cellSize.width + 3;\n var posY = (selectedCell[1] + 1) * cellSize.height + 3;\n tooltip.style.transform = 'translate(' + posX + 'px, ' + posY + 'px)';\n };\n\n var toolbarData = null;\n var toolbarNodes = {};\n\n // construct the toolbar if it wasn't already\n var initToolbar = function initToolbar() {\n if (toolbarData) return;\n\n var showUpdates = document.createElement('input');\n showUpdates.type = 'checkbox';\n showUpdates.addEventListener('change', function (e) {\n drawData.showUpdates = showUpdates.checked;\n });\n\n var fancyGraphics = document.createElement('input');\n fancyGraphics.type = 'checkbox';\n fancyGraphics.value = !!screen.layout.renderer.graphics;\n fancyGraphics.addEventListener('change', function (e) {\n screen.layout.renderer.graphics = +fancyGraphics.checked;\n });\n\n toolbarData = {\n cursor: {\n title: 'Cursor',\n Position: '',\n Style: '',\n Visible: true,\n Hanging: false\n },\n internal: {\n Flags: '',\n 'Cursor Attributes': '',\n 'Code Page': '',\n Heap: 0,\n Clients: 0\n },\n drawing: {\n title: 'Drawing',\n 'Last Update': '',\n 'Show Updates': showUpdates,\n 'Fancy Graphics': fancyGraphics,\n 'Redraw Screen': function RedrawScreen() {\n screen.layout.renderer.resetDrawn();\n screen.layout.renderer.draw('debug-redraw');\n }\n }\n };\n\n var _loop = function _loop(i) {\n var group = toolbarData[i];\n var table = document.createElement('table');\n table.classList.add('toolbar-group');\n\n toolbarNodes[i] = {};\n\n var _loop2 = function _loop2(key) {\n var item = document.createElement('tr');\n var name = document.createElement('td');\n name.classList.add('name');\n var value = document.createElement('td');\n value.classList.add('value');\n\n toolbarNodes[i][key] = { name: name, value: value };\n\n if (key === 'title') {\n name.textContent = group[key];\n name.classList.add('title');\n } else {\n name.textContent = key;\n if (group[key] instanceof Function) {\n name.textContent = '';\n var button = document.createElement('button');\n name.classList.add('has-button');\n name.appendChild(button);\n button.textContent = key;\n button.addEventListener('click', function (e) {\n return group[key](e);\n });\n } else if (group[key] instanceof window.Node) value.appendChild(group[key]);else value.textContent = group[key];\n }\n\n item.appendChild(name);\n item.appendChild(value);\n table.appendChild(item);\n };\n\n for (var key in group) {\n _loop2(key);\n }\n\n toolbar.appendChild(table);\n };\n\n for (var i in toolbarData) {\n _loop(i);\n }\n\n var heartbeat = toolbarNodes.heartbeat = document.createElement('div');\n heartbeat.classList.add('heartbeat');\n heartbeat.textContent = '❤';\n toolbar.appendChild(heartbeat);\n };\n\n connection.on('heartbeat', function () {\n if (screenAttached && toolbarNodes.heartbeat) {\n toolbarNodes.heartbeat.classList.remove('beat');\n window.requestAnimationFrame(function () {\n toolbarNodes.heartbeat.classList.add('beat');\n });\n }\n });\n\n updateToolbar = function updateToolbar() {\n initToolbar();\n\n Object.assign(toolbarData.cursor, {\n Position: 'col ' + (screen.cursor.x + 1) + ', ln ' + (screen.cursor.y + 1),\n Style: screen.cursor.style + (screen.cursor.blinking ? ', blink' : ''),\n Visible: screen.cursor.visible,\n Hanging: screen.cursor.hanging\n });\n\n var drawTime = Math.round((drawData.endTime - drawData.startTime) * 100) / 100;\n toolbarData.drawing['Last Update'] = drawData.reason + ' (' + drawTime + 'ms)';\n toolbarData.drawing['Fancy Graphics'].checked = !!screen.layout.renderer.graphics;\n\n for (var i in toolbarData) {\n var _group = toolbarData[i];\n var nodes = toolbarNodes[i];\n for (var key in _group) {\n if (key === 'title') continue;\n var _value = nodes[key].value;\n if (!(_group[key] instanceof window.Node) && !(_group[key] instanceof Function)) {\n _value.textContent = _group[key];\n }\n }\n }\n };\n\n screen.on('update', updateToolbar);\n screen.on('internal', function (data) {\n if (screenAttached && toolbarData) {\n Object.assign(toolbarData.internal, {\n Flags: data.flags.toString(2),\n 'Cursor Attributes': data.cursorAttrs.toString(2),\n 'Code Page': data.charsetGx + ' (' + data.charsetG0 + ', ' + data.charsetG1 + ')',\n Heap: data.freeHeap,\n Clients: data.clientCount\n });\n drawData.scrollRegion = [data.regionStart, data.regionEnd];\n updateToolbar();\n }\n });\n};\n\n/***/ }),\n/* 25 */\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__(3),\n getColor = _require.getColor;\n\nvar _require2 = __webpack_require__(0),\n qs = _require2.qs;\n\nvar _require3 = __webpack_require__(7),\n rgb2hsl = _require3.rgb2hsl,\n hex2rgb = _require3.hex2rgb,\n rgb2hex = _require3.rgb2hex,\n hsl2rgb = _require3.hsl2rgb;\n\nmodule.exports = function initButtons(input) {\n var container = qs('#action-buttons');\n\n // current color palette\n var palette = [];\n\n // button labels\n var labels = [];\n\n // button colors\n var colors = {};\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 e.target.blur(); // if it keeps focus, spacebar will push it\n });\n\n // this prevents button retaining focus after half-click/drag-away\n button.addEventListener('mouseleave', function (e) {\n e.target.blur();\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 = buttons.length; _i > labels.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 var color = colors[_i2];\n\n button.textContent = label || '\\xA0'; // label or nbsp\n\n if (!label) button.classList.add('inactive');else button.classList.remove('inactive');\n\n // 0 or undefined can be used to disable custom color\n if (Number.isFinite(color) && color !== 0) {\n var clr = getColor(color, palette);\n button.style.background = clr;\n\n // darken the color a bit for the 3D side\n var hsl = rgb2hsl.apply(undefined, _toConsumableArray(hex2rgb(clr)));\n var hex = rgb2hex.apply(undefined, _toConsumableArray(hsl2rgb(hsl[0], hsl[1], hsl[2] * 0.7)));\n button.style.boxShadow = '0 3px 0 ' + hex;\n } else {\n button.style.background = null;\n button.style.boxShadow = null;\n }\n }\n };\n\n return {\n update: update,\n get labels() {\n return labels;\n },\n set labels(value) {\n labels = value;\n update();\n },\n get colors() {\n return colors;\n },\n set colors(value) {\n colors = value;\n update();\n },\n get palette() {\n return palette;\n },\n set palette(value) {\n palette = value;\n update();\n }\n };\n};\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar ColorTriangle = __webpack_require__(27);\nvar $ = __webpack_require__(1);\nvar themes = __webpack_require__(3);\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 $('#default_fg,#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 for (var i = 1; i <= 5; i++) {\n ColorTriangle.initInput(qs('#bc' + i), opts);\n }\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/* 27 */\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__(2);\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.8b43b1d-en.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 10);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap ed37efe935ee7fa8c127","/** 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","// 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 = 2\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\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.colorTable256 = null\nexports.ensureColorTable256 = function () {\n if (!exports.colorTable256) exports.colorTable256 = exports.buildColorTable()\n}\n\nexports.getColor = function (i, palette = []) {\n // return palette color if it exists\n if (i < 16 && i in palette) return palette[i]\n\n // -1 for selection foreground, -2 for selection background\n if (i === -1) return exports.SELECTION_FG\n if (i === -2) return exports.SELECTION_BG\n\n // 256 color\n if (i > 15 && i < 256) {\n exports.ensureColorTable256()\n return exports.colorTable256[i]\n }\n\n // 24-bit color, encoded as (hex) + 256 (such that #000000 == 256)\n if (i > 255) {\n i -= 256\n return '#' + `000000${i.toString(16)}`.substr(-6)\n }\n\n // return error color\n return Math.floor(Date.now() / 1000) % 2 === 0 ? '#ff0ff' : '#00ff00'\n}\n\nexports.toHex = function (shade, themeN) {\n if (/^\\d+$/.test(shade)) {\n shade = +shade\n return exports.getColor(shade, themes[themeN])\n }\n return shade\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/themes.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","// Bits in the cell attribs word\n\n/* eslint-disable no-multi-spaces */\nexports.ATTR_FG = (1 << 0) // 1 if not using default background color (ignore cell bg) - color extension bit\nexports.ATTR_BG = (1 << 1) // 1 if not using default foreground color (ignore cell fg) - color extension bit\nexports.ATTR_BOLD = (1 << 2) // Bold font\nexports.ATTR_UNDERLINE = (1 << 3) // Underline decoration\nexports.ATTR_INVERSE = (1 << 4) // Invert colors - this is useful so we can clear then with SGR manipulation commands\nexports.ATTR_BLINK = (1 << 5) // Blinking\nexports.ATTR_ITALIC = (1 << 6) // Italic font\nexports.ATTR_STRIKE = (1 << 7) // Strike-through decoration\nexports.ATTR_OVERLINE = (1 << 8) // Over-line decoration\nexports.ATTR_FAINT = (1 << 9) // Faint foreground color (reduced alpha)\nexports.ATTR_FRAKTUR = (1 << 10) // Fraktur font (unicode substitution)\n/* eslint-enable no-multi-spaces */\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/screen_attr_bits.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","const EventEmitter = require('events')\nconst { parse2B } = require('../utils')\nconst { themes } = require('./themes')\n\nconst encodeAsCodePoint = i => String.fromCodePoint(i + (i >= 0xD800 ? 0x801 : 1))\n\nclass ANSIParser {\n constructor (handler) {\n this.reset()\n this.handler = handler\n this.joinChunks = true\n }\n reset () {\n this.currentSequence = 0\n this.sequence = ''\n }\n parseSequence (sequence) {\n if (sequence[0] === '[') {\n let type = sequence[sequence.length - 1]\n let content = sequence.substring(1, sequence.length - 1)\n\n let numbers = content ? content.split(';').map(i => +i.replace(/\\D/g, '')) : []\n let numOr1 = numbers.length ? numbers[0] : 1\n if (type === 'H') {\n this.handler('set-cursor', (numbers[0] | 0) - 1, (numbers[1] | 0) - 1)\n } else if (type >= 'A' && type <= 'D') {\n this.handler(`move-cursor-${type <= 'B' ? 'y' : 'x'}`, ((type === 'B' || type === 'C') ? 1 : -1) * numOr1)\n } else if (type === 'E' || type === 'F') {\n this.handler('move-cursor-line', (type === 'E' ? 1 : -1) * numOr1)\n } else if (type === 'G') {\n this.handler('set-cursor-x', numOr1 - 1)\n } else if (type === 'J') {\n let number = numbers.length ? numbers[0] : 2\n if (number === 2) this.handler('clear')\n } else if (type === 'P') {\n this.handler('delete', numOr1)\n } else if (type === '@') {\n this.handler('insert-blanks', numOr1)\n } else if (type === 'q') this.handler('set-cursor-style', numOr1)\n else if (type === 'm') {\n if (!numbers.length) {\n this.handler('reset-style')\n return\n }\n let type\n while ((type = numbers.shift())) {\n if (type === 0) this.handler('reset-style')\n else if (type === 1) this.handler('add-attrs', 1 << 2) // bold\n else if (type === 2) this.handler('add-attrs', 1 << 9) // faint\n else if (type === 3) this.handler('add-attrs', 1 << 6) // italic\n else if (type === 4) this.handler('add-attrs', 1 << 3) // underline\n else if (type === 5 || type === 6) this.handler('add-attrs', 1 << 5) // blink\n else if (type === 7) this.handler('add-attrs', 1 << 4) // invert\n else if (type === 9) this.handler('add-attrs', 1 << 7) // strike\n else if (type === 20) this.handler('add-attrs', 1 << 10) // fraktur\n else if (type >= 30 && type <= 37) this.handler('set-color-fg', type % 10)\n else if (type >= 40 && type <= 47) this.handler('set-color-bg', type % 10)\n else if (type === 39) this.handler('reset-color-fg')\n else if (type === 49) this.handler('reset-color-bg')\n else if (type >= 90 && type <= 98) this.handler('set-color-fg', (type % 10) + 8)\n else if (type >= 100 && type <= 108) this.handler('set-color-bg', (type % 10) + 8)\n else if (type === 38 || type === 48) {\n let mode = numbers.shift()\n if (mode === 2) {\n let r = numbers.shift()\n let g = numbers.shift()\n let b = numbers.shift()\n let color = (r << 16 | g << 8 | b) + 256\n if (type === 38) this.handler('set-color-fg', color)\n if (type === 48) this.handler('set-color-bg', color)\n } else if (mode === 5) {\n let color = (numbers.shift() | 0) & 0xFF\n if (type === 38) this.handler('set-color-fg', color)\n if (type === 48) this.handler('set-color-bg', color)\n }\n }\n }\n } else if (type === 'h' || type === 'l') {\n if (content === '?25') {\n if (type === 'h') this.handler('show-cursor')\n else if (type === 'l') this.handler('hide-cursor')\n }\n }\n }\n }\n write (text) {\n for (let character of text.toString()) {\n let code = character.codePointAt(0)\n if (code === 0x1b) this.currentSequence = 1\n else if (this.currentSequence === 1 && character === '[') {\n this.currentSequence = 2\n this.sequence += '['\n } else if (this.currentSequence && character.match(/[\\x40-\\x7e]/)) {\n this.parseSequence(this.sequence + character)\n this.currentSequence = 0\n this.sequence = ''\n } else if (this.currentSequence > 1) this.sequence += character\n else if (this.currentSequence === 1) {\n // something something nothing\n this.currentSequence = 0\n this.handler('write', character)\n } else if (code < 0x03) this.handler('_null')\n else if (code === 0x03) this.handler('sigint')\n else if (code <= 0x06) this.handler('_null')\n else if (code === 0x07) this.handler('bell')\n else if (code === 0x08) this.handler('back')\n else if (code === 0x09) this.handler('tab')\n else if (code === 0x0a) this.handler('new-line')\n else if (code === 0x0d) this.handler('return')\n else if (code === 0x15) this.handler('delete-line')\n else if (code === 0x17) this.handler('delete-word')\n else this.handler('write', character)\n }\n if (!this.joinChunks) this.reset()\n }\n}\nconst TERM_DEFAULT_STYLE = [0, 0, 0]\n\nlet getRainbowColor = t => {\n let r = Math.floor(Math.sin(t) * 2.5 + 2.5)\n let g = Math.floor(Math.sin(t + 2 / 3 * Math.PI) * 2.5 + 2.5)\n let b = Math.floor(Math.sin(t + 4 / 3 * Math.PI) * 2.5 + 2.5)\n return 16 + 36 * r + 6 * g + b\n}\n\nclass ScrollingTerminal {\n constructor (screen) {\n this.width = 80\n this.height = 25\n this.termScreen = screen\n this.parser = new ANSIParser((...args) => this.handleParsed(...args))\n this.buttonLabels = []\n\n this.reset()\n\n this._lastLoad = Date.now()\n this.loadTimer()\n\n window.showPage()\n }\n reset () {\n this.style = TERM_DEFAULT_STYLE.slice()\n this.cursor = { x: 0, y: 0, style: 1, visible: true }\n this.trackMouse = false\n this.theme = 0\n this.defaultFG = 7\n this.defaultBG = 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 += this.encodeColor(this.defaultFG)\n data += this.encodeColor(this.defaultBG)\n let attributes = +this.cursor.visible\n attributes |= (3 << 5) * +this.trackMouse // track mouse controls both\n attributes |= 3 << 7 // buttons/links always visible\n attributes |= (this.cursor.style << 9)\n data += encodeAsCodePoint(attributes)\n return data\n }\n getButtons () {\n let data = 'B'\n data += encodeAsCodePoint(this.buttonLabels.length)\n data += this.buttonLabels.map(x => `\\x01${x}\\x01`).join('')\n return data\n }\n getTitle () {\n return 'TESPTerm Web UI Demo\\x01'\n }\n getCursor () {\n let data = 'C'\n data += encodeAsCodePoint(this.cursor.y)\n data += encodeAsCodePoint(this.cursor.x)\n data += encodeAsCodePoint(0)\n return data\n }\n encodeColor (color) {\n if (color < 256) {\n return encodeAsCodePoint(color)\n } else {\n color -= 256\n return encodeAsCodePoint((color & 0xFFF) | 0x10000) + encodeAsCodePoint(color >> 12)\n }\n }\n serializeScreen () {\n let serialized = 'S'\n serialized += encodeAsCodePoint(0) + encodeAsCodePoint(0)\n serialized += encodeAsCodePoint(this.height) + encodeAsCodePoint(this.width)\n\n let lastStyle = [null, null, null]\n let index = 0\n for (let cell of this.screen) {\n let style = cell[1].slice()\n if (this.rainbow) {\n let x = index % this.width\n let y = Math.floor(index / this.width)\n // C instead of F in mask and 1 << 8 in attrs to change attr bits 1 and 2\n let t = (x + y) / 10 + Date.now() / 1000\n if (this.superRainbow) {\n t = (x * y + Date.now()) / 100 + Date.now() / 1000\n }\n style[0] = getRainbowColor(t)\n style[1] = 0\n if (this.superRainbow) style[1] = getRainbowColor(t / 10)\n style[2] = style[2] | 1\n if (!this.superRainbow && style[2] & (1 << 1)) style[2] ^= (1 << 1)\n index++\n }\n\n let foreground = style[0]\n let background = style[1]\n let attributes = style[2]\n let setForeground = foreground !== lastStyle[0]\n let setBackground = background !== lastStyle[1]\n let setAttributes = attributes !== lastStyle[2]\n\n if (setForeground && setBackground) {\n if (foreground < 256 && background < 256) {\n serialized += '\\x03' + encodeAsCodePoint((background << 8) | foreground)\n } else {\n serialized += '\\x05' + this.encodeColor(foreground)\n serialized += '\\x06' + this.encodeColor(background)\n }\n } else if (setForeground) serialized += '\\x05' + this.encodeColor(foreground)\n else if (setBackground) serialized += '\\x06' + this.encodeColor(background)\n if (setAttributes) serialized += '\\x04' + encodeAsCodePoint(attributes)\n lastStyle = style\n\n serialized += cell[0]\n }\n return serialized\n }\n getUpdate () {\n let topics = 0\n let topicData = []\n let screenOpts = this.getScreenOpts()\n let title = this.getTitle()\n let buttons = this.getButtons()\n let cursor = this.getCursor()\n let screen = this.serializeScreen()\n if (this._screenOpts !== screenOpts) {\n this._screenOpts = screenOpts\n topicData.push(screenOpts)\n }\n if (this._title !== title) {\n this._title = title\n topicData.push(title)\n }\n if (this._buttons !== buttons) {\n this._buttons = buttons\n topicData.push(buttons)\n }\n if (this._cursor !== cursor) {\n this._cursor = cursor\n topicData.push(cursor)\n }\n if (this._screen !== screen) {\n this._screen = screen\n topicData.push(screen)\n }\n if (!topicData.length) return ''\n return 'U' + encodeAsCodePoint(topics) + topicData.join('')\n }\n loadTimer () {\n clearInterval(this._loadTimer)\n this._loadTimer = setInterval(() => {\n let update = this.getUpdate()\n if (update) this.termScreen.load(update)\n }, 30)\n }\n}\n\nclass Process extends EventEmitter {\n write (data) {\n this.emit('in', data)\n }\n destroy () {\n // death.\n this.emit('exit', 0)\n }\n run () {\n // noop\n }\n}\n\nlet demoData = {\n buttons: [],\n mouseReceiver: null\n}\n\nlet demoshIndex = {\n clear: class Clear extends Process {\n run () {\n this.emit('write', '\\x1b[2J\\x1b[1;1H')\n this.destroy()\n }\n },\n screenfetch: class Screenfetch extends Process {\n run () {\n let image = `\n ###. ESPTerm Demo\n '###. Hostname: ${window.location.hostname}\n '###. Shell: ESPTerm Demo Shell\n '###. Resolution: 80x25@${window.devicePixelRatio}x\n :###-\n .###'\n .###'\n .###' ###############\n ###' ###############\n `.split('\\n').filter(line => line.trim())\n\n let chars = ''\n for (let y = 0; y < image.length; y++) {\n for (let x = 0; x < 80; x++) {\n if (image[y][x]) {\n chars += `\\x1b[38;5;${getRainbowColor((x + y) / 10)}m${image[y][x]}`\n } else chars += ' '\n }\n }\n\n this.emit('write', '\\r\\n\\x1b[?25l')\n let loop = () => {\n this.emit('write', chars.substr(0, 80))\n chars = chars.substr(80)\n if (chars.length) setTimeout(loop, 50)\n else {\n this.emit('write', '\\r\\n\\x1b[?25h')\n this.destroy()\n }\n }\n loop()\n }\n },\n 'local-echo': class LocalEcho extends Process {\n run (...args) {\n if (!args.includes('--suppress-note')) {\n this.emit('write', '\\x1b[38;5;239mNote: not all terminal features are supported and may not work as expected in this demo\\x1b[m\\n')\n }\n this.emit('buttons', [\n {\n label: 'Exit',\n action (shell) {\n shell.write('\\x03')\n }\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 constructor (shell) {\n super()\n this.shell = shell\n this.parser = new ANSIParser((...args) => this.handler(...args))\n }\n\n destroy () {\n this.shell.terminal.cursor.style = this.savedCursorStyle\n this.emit('write', '\\n\\n')\n super.destroy()\n }\n\n run (...args) {\n this.savedCursorStyle = this.shell.terminal.cursor.style\n this.shell.terminal.cursor.style = 3\n\n this.fgType = 0\n this.bgType = 0\n\n let get24FG = () => this.shell.terminal.defaultFG - 256\n let set24FG = v => { this.shell.terminal.defaultFG = v + 256 }\n let get24BG = () => this.shell.terminal.defaultBG - 256\n let set24BG = v => { this.shell.terminal.defaultBG = v + 256 }\n\n let make24Control = (label, index, getValue, setValue, type) => {\n index *= 4\n\n return {\n label,\n length: 1,\n getValue: () => (getValue() >> index) & 0xF,\n getDisplay: () => ((getValue() >> index) & 0xF).toString(16),\n setValue: value => {\n setValue((getValue() & (0xFFFFFF ^ (0xF << index))) | ((value & 0xF) << index))\n },\n shouldShow: () => this[type + 'Type'] === 1,\n parseValue: input => {\n return parseInt(input, 16) & 0xF\n },\n moveAfterInput: index !== 0\n }\n }\n\n this.controls = [\n {\n label: 'Theme: ',\n length: themes.length.toString().length,\n getValue: () => this.shell.terminal.theme,\n setValue: value => {\n let count = themes.length\n this.shell.terminal.theme = ((value % count) + count) % count\n }\n },\n {\n label: ' Default Foreground: ',\n length: 6,\n getValue: () => this.fgType,\n getDisplay: () => this.fgType === 0 ? '256' : '24-bit',\n setValue: value => {\n this.fgType = ((value % 2) + 2) % 2\n }\n },\n {\n label: ' ',\n length: 3,\n getValue: () => this.shell.terminal.defaultFG & 0xFF,\n setValue: value => {\n this.shell.terminal.defaultFG = value & 0xFF\n },\n shouldShow: () => this.fgType === 0,\n parseValue: input => parseInt(input, 16)\n },\n make24Control(' #', 5, get24FG, set24FG, 'fg'),\n make24Control('', 4, get24FG, set24FG, 'fg'),\n make24Control('', 3, get24FG, set24FG, 'fg'),\n make24Control('', 2, get24FG, set24FG, 'fg'),\n make24Control('', 1, get24FG, set24FG, 'fg'),\n make24Control('', 0, get24FG, set24FG, 'fg'),\n {\n label: ' Default Background: ',\n length: 6,\n getValue: () => this.bgType,\n getDisplay: () => this.bgType === 0 ? '256' : '24-bit',\n setValue: value => {\n this.bgType = ((value % 2) + 2) % 2\n }\n },\n {\n label: ' ',\n length: 3,\n getValue: () => this.shell.terminal.defaultBG & 0xFF,\n setValue: value => {\n this.shell.terminal.defaultBG = value & 0xFF\n },\n shouldShow: () => this.bgType === 0,\n parseValue: input => parseInt(input, 16)\n },\n make24Control(' #', 5, get24BG, set24BG, 'bg'),\n make24Control('', 4, get24BG, set24BG, 'bg'),\n make24Control('', 3, get24BG, set24BG, 'bg'),\n make24Control('', 2, get24BG, set24BG, 'bg'),\n make24Control('', 1, get24BG, set24BG, 'bg'),\n make24Control('', 0, get24BG, set24BG, 'bg')\n ]\n this.selection = 0\n\n this.emit('write', '\\x1b[1mThemes\\x1b[m\\n\\n\\n\\n\\x1b[2A')\n\n this.render()\n }\n\n render () {\n this.emit('write', '\\x1b[m\\r')\n // no ^[2K implementation, here's a hack\n this.emit('write', ' '.repeat(this.shell.terminal.width - 1) + '\\r')\n\n let index = 0\n let selectedX = 0\n for (let control of this.controls) {\n if (control.shouldShow && !control.shouldShow()) continue\n if (control.label) {\n this.emit('write', `\\x1b[1m${control.label}\\x1b[m`)\n }\n // TODO: colors\n this.emit('write', '\\x1b[38;5;255m\\x1b[48;5;16m')\n let value = control.getDisplay ? control.getDisplay() : control.getValue().toString()\n this.emit('write', (control.fill || ' ').repeat(Math.max(0, control.length - value.length)))\n this.emit('write', value.substr(0, control.length))\n this.emit('write', '\\x1b[m')\n\n if (index === this.selection) {\n selectedX = this.shell.terminal.cursor.x - 1\n\n // draw arrows\n this.emit('write', '\\x1b[m\\x1b[D\\x1b[A▲\\x1b[D\\x1b[2B▼\\x1b[A')\n } else {\n // clear arrows if they were there\n this.emit('write', '\\x1b[m\\x1b[D\\x1b[A \\x1b[D\\x1b[2B \\x1b[A')\n }\n\n index++\n }\n\n this.shell.terminal.cursor.x = selectedX\n }\n\n write (data) {\n this.parser.write(data)\n }\n\n getControlCount () {\n let count = 0\n for (let control of this.controls) {\n if (control.shouldShow && !control.shouldShow()) continue\n count++\n }\n return count\n }\n\n getSelectedControl () {\n let selected = null\n let index = 0\n for (let control of this.controls) {\n if (control.shouldShow && !control.shouldShow()) continue\n if (index === this.selection) {\n selected = control\n break\n }\n index++\n }\n return selected\n }\n\n handler (action, ...args) {\n console.log(action, ...args)\n\n if (action === 'move-cursor-x') {\n this.selection += args[0]\n let count = this.getControlCount()\n this.selection = ((this.selection % count) + count) % count\n } else if (action === 'move-cursor-y') {\n let control = this.getSelectedControl()\n if (control) control.setValue(control.getValue() - args[0])\n } else if (action === 'write') {\n let control = this.getSelectedControl()\n if (control && control.parseValue) {\n let parsed = control.parseValue(args[0])\n if (Number.isFinite(parsed)) {\n control.setValue(parsed)\n if (control.moveAfterInput) {\n if (this.selection < this.getControlCount() - 1) this.selection++\n }\n }\n }\n }\n\n this.render()\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 MouseDemo extends Process {\n constructor (shell) {\n super()\n this.shell = shell\n }\n run () {\n const self = this\n this.emit('buttons', [\n {\n label: 'Exit',\n action (shell) {\n shell.write('\\x03')\n }\n },\n {\n label: 'Add Box',\n action () {\n self.boxes.push(self.generateRandomBox())\n self.render()\n }\n }\n ])\n\n this.shell.terminal.trackMouse = true\n demoData.mouseReceiver = this\n\n this.boxes = Array(3).fill(0).map(x => this.generateRandomBox())\n this.grabbedBox = null\n this.grabOffset = [0, 0]\n\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[mMove boxes around or scroll their contents!')\n\n // draw boxes\n for (let box of this.boxes) {\n this.emit('write', `\\x1b[${box.y + 1};${box.x + 1}H`)\n this.emit('write', `\\x1b[m\\x1b[48;2;${box.color.join(';')}m`)\n for (let y = box.y; y < box.y + box.height; y++) {\n let drawnX = 0\n for (let x = box.x; x < box.x + box.width; x++) {\n if (x < 0 || x >= this.shell.terminal.width - 1) continue\n if (y < 0 || y >= this.shell.terminal.height) continue\n drawnX++\n this.emit('write', box.content[y - box.y][x - box.x])\n }\n this.emit('write', '\\x1b[D'.repeat(drawnX) + '\\x1b[B')\n }\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 generateRandomBox () {\n let chars = 'abcdefghijklmnopqrstuvwxyz-*()!@#$%'\n let content = []\n let width = [5, 10, 15][Math.floor(Math.random() * 3)]\n let height = [4, 5, 6][Math.floor(Math.random() * 3)]\n\n for (let y = 0; y < height; y++) {\n content.push('')\n for (let x = 0; x < width; x++) {\n if (Math.random() > 0.6) {\n content[y] += chars[Math.floor(Math.random() * chars.length)]\n } else content[y] += ' '\n }\n }\n\n return {\n x: Math.floor(Math.random() * (this.shell.terminal.width - 1)) + 1,\n y: Math.floor(Math.random() * (this.shell.terminal.height - 1)) + 1,\n width,\n height,\n color: [Math.random(), Math.random(), Math.random()].map(x => Math.floor(x * 255)),\n content\n }\n }\n getBoxAt (x, y) {\n let boxes = this.boxes.slice().reverse() // top to bottom, like drawing order\n for (let box of boxes) {\n if (box.x <= x && box.x + box.width > x && box.y <= y && box.y + box.height > y) {\n return box\n }\n }\n }\n mouseMove (x, y) {\n this.mouse = { x, y }\n if (this.grabbedBox) {\n this.grabbedBox.x = x + this.grabOffset[0]\n this.grabbedBox.y = y + this.grabOffset[1]\n }\n this.render()\n }\n mouseDown (x, y, button) {\n if (button === 4) this.scrollInsideBox(this.getBoxAt(x, y), -1)\n else if (button === 5) this.scrollInsideBox(this.getBoxAt(x, y), 1)\n else {\n let box = this.getBoxAt(x, y)\n if (box) {\n this.grabbedBox = box\n this.grabOffset = [box.x - x, box.y - y]\n // move grabbed box to top of stack\n this.boxes.push(...this.boxes.splice(this.boxes.indexOf(box), 1))\n }\n }\n this.render()\n }\n mouseUp (x, y, button) {\n this.grabbedBox = null\n }\n scrollInsideBox (box, amount) {\n if (!box) return\n let content = box.content.slice()\n box.content = []\n for (let i = 0; i < content.length; i++) {\n box.content.push(content[((i + amount % content.length) + content.length) % content.length])\n }\n }\n destroy () {\n this.shell.terminal.write('\\x1b[m\\x1b[2J\\x1b[1;1H')\n this.shell.terminal.trackMouse = false\n if (demoData.mouseReceiver === this) demoData.mouseReceiver = null\n super.destroy()\n }\n },\n sudo: class Sudo extends Process {\n constructor (shell) {\n super()\n this.shell = shell\n this.didDestroy = false\n }\n run (...args) {\n if (args.length === 0) {\n this.emit('write', '\\x1b[31mUsage: sudo [command]\\x1b[m\\r\\n')\n this.destroy()\n } else {\n let name = args.shift()\n if (this.shell.index[name]) {\n let Process = this.shell.index[name]\n if (Process instanceof Function) {\n let child = this.child = new Process(this.shell, { su: true })\n this.on('in', data => child.write(data))\n let write = data => this.emit('write', data)\n let setButtons = buttons => this.emit('buttons', buttons)\n child.on('write', write)\n child.on('buttons', setButtons)\n child.on('exit', code => {\n child.removeListener('write', write)\n child.removeListener('buttons', setButtons)\n this.destroy()\n })\n child.run(...args)\n } else {\n this.emit('write', Process)\n this.destroy()\n }\n } else {\n this.emit('write', `sudo: ${name}: command not found\\r\\n`)\n this.destroy()\n }\n }\n }\n destroy () {\n if (this.didDestroy) return\n this.didDestroy = true\n if (this.child) this.child.destroy()\n super.destroy()\n }\n },\n make: class Make extends Process {\n constructor (shell, options = {}) {\n super()\n this.su = options.su\n }\n run (...args) {\n if (args.length === 0) this.emit('write', '\\x1b[31mmake: *** No targets specified. Stop.\\x1b[0m\\r\\n')\n else if (args.length === 3 && args.join(' ').toLowerCase() === 'me a sandwich') {\n if (this.su) {\n const b = '\\x1b[33m'\n const r = '\\x1b[0m'\n const l = '\\x1b[32m'\n const c = '\\x1b[38;5;229m'\n const h = '\\x1b[38;5;225m'\n this.emit('write',\n ` ${b}_.---._\\r\\n` +\n ` _.-~ ~-._\\r\\n` +\n ` _.-~ ~-._\\r\\n` +\n ` _.-~ ~---._\\r\\n` +\n ` _.-~ ~\\\\\\r\\n` +\n ` .-~ _.;\\r\\n` +\n ` :-._ _.-~ ./\\r\\n` +\n ` \\`-._~-._ _..__.-~ _.-~\\r\\n` +\n ` ${c}/ ${b}~-._~-._ / .__..--${c}~-${l}---._\\r\\n` +\n `${c} \\\\_____(_${b};-._\\\\. _.-~_/${c} ~)${l}.. . \\\\\\r\\n` +\n `${l} /(_____ ${b}\\\\\\`--...--~_.-~${c}______..-+${l}_______)\\r\\n` +\n `${l} .(_________/${b}\\`--...--~/${l} _/ ${h} ${b}/\\\\\\r\\n` +\n `${b} /-._${h} \\\\_ ${l}(___./_..-~${h}__.....${b}__..-~./\\r\\n` +\n `${b} \\`-._~-._${h} ~\\\\--------~ .-~${b}_..__.-~ _.-~\\r\\n` +\n `${b} ~-._~-._ ${h}~---------\\` ${b}/ .__..--~\\r\\n` +\n `${b} ~-._\\\\. _.-~_/\\r\\n` +\n `${b} \\\\\\`--...--~_.-~\\r\\n` +\n `${b} \\`--...--~${r}\\r\\n`)\n } else {\n this.emit('write', '\\x1b[31mmake: me a sandwich : Permission denied\\x1b[0m\\r\\n')\n }\n } else {\n this.emit('write', `\\x1b[31mmake: *** No rule to make target '${args.join(' ').toLowerCase()}'. Stop.\\x1b[0m\\r\\n`)\n }\n this.destroy()\n }\n },\n pwd: '/this/is/a/demo\\r\\n',\n cd: '\\x1b[38;5;239mNo directories to change to\\r\\n',\n whoami: `${window.navigator.userAgent}\\r\\n`,\n hostname: `${window.location.hostname}`,\n uname: 'ESPTerm Demo\\r\\n',\n mkdir: '\\x1b[38;5;239mDid not create a directory because this is a demo.\\r\\n',\n rm: '\\x1b[38;5;239mDid not delete anything because this is a demo.\\r\\n',\n cp: '\\x1b[38;5;239mNothing to copy because this is a demo.\\r\\n',\n mv: '\\x1b[38;5;239mNothing to move because this is a demo.\\r\\n',\n ln: '\\x1b[38;5;239mNothing to link because this is a demo.\\r\\n',\n touch: '\\x1b[38;5;239mNothing to touch\\r\\n',\n exit: '\\x1b[38;5;239mNowhere to go\\r\\n',\n github: class GoToGithub extends Process {\n run () {\n window.open('https://github.com/espterm/espterm-firmware')\n this.destroy()\n }\n }\n}\nlet autocompleteIndex = {\n 'local-echo': 'local-echo [--suppress-note]',\n theme: 'theme [n]',\n cursor: 'cursor [block|line|bar] [--steady]',\n sudo: 'sudo [command]'\n}\n\nclass DemoShell {\n constructor (terminal, printInfo) {\n this.terminal = terminal\n this.terminal.reset()\n this.parser = new ANSIParser((...args) => this.handleParsed(...args))\n this.history = []\n this.historyIndex = 0\n this.cursorPos = 0\n this.lastInputLength = 0\n this.child = null\n this.index = demoshIndex\n\n if (printInfo) this.run('info')\n else this.prompt()\n }\n write (text) {\n if (this.child) {\n if (text.codePointAt(0) === 3) this.child.destroy()\n else this.child.write(text)\n } else this.parser.write(text)\n }\n prompt (success = true) {\n if (this.terminal.cursor.x !== 0) this.terminal.write('\\x1b[m\\x1b[38;5;238m⏎\\r\\n')\n this.terminal.write('\\x1b[34;1mdemosh \\x1b[m')\n if (!success) this.terminal.write('\\x1b[31m')\n this.terminal.write('$ \\x1b[m')\n this.history.unshift('')\n this.cursorPos = 0\n\n this.setButtons()\n }\n copyFromHistoryIndex () {\n if (!this.historyIndex) return\n let current = this.history[this.historyIndex]\n this.history[0] = current\n this.historyIndex = 0\n }\n getCompleted (visual = false) {\n if (this.history[0]) {\n let input = this.history[0]\n let prefix = ''\n if (input.startsWith('sudo ')) {\n let newInput = input.replace(/^(sudo\\s+)+/, '')\n prefix = input.substr(0, input.length - newInput.length)\n input = newInput\n }\n if (!input) return null\n for (let name in this.index) {\n if (name.startsWith(input) && name !== input) {\n if (visual && name in autocompleteIndex) return prefix + autocompleteIndex[name]\n return prefix + name\n }\n }\n return null\n }\n return null\n }\n handleParsed (action, ...args) {\n this.terminal.write(`\\x1b[${this.lastInputLength - this.cursorPos}P`)\n this.terminal.write('\\b\\x1b[P'.repeat(this.cursorPos))\n\n if (action === 'write') {\n this.copyFromHistoryIndex()\n this.history[0] = this.history[0].substr(0, this.cursorPos) + args[0] + this.history[0].substr(this.cursorPos)\n this.cursorPos++\n } else if (action === 'back') {\n this.copyFromHistoryIndex()\n this.history[0] = this.history[0].substr(0, this.cursorPos - 1) + this.history[0].substr(this.cursorPos)\n this.cursorPos--\n if (this.cursorPos < 0) this.cursorPos = 0\n } else if (action === 'tab') {\n let completed = this.getCompleted()\n if (completed) {\n this.history[0] = completed\n this.cursorPos = this.history[0].length\n }\n } else if (action === 'move-cursor-x') {\n this.cursorPos = Math.max(0, Math.min(this.history[this.historyIndex].length, this.cursorPos + args[0]))\n } else if (action === 'delete-line') {\n this.copyFromHistoryIndex()\n this.history[0] = ''\n this.cursorPos = 0\n } else if (action === 'delete-word') {\n this.copyFromHistoryIndex()\n let words = this.history[0].substr(0, this.cursorPos).split(' ')\n words.pop()\n this.history[0] = words.join(' ') + this.history[0].substr(this.cursorPos)\n this.cursorPos = words.join(' ').length\n } else if (action === 'move-cursor-y') {\n this.historyIndex -= args[0]\n if (this.historyIndex < 0) this.historyIndex = 0\n if (this.historyIndex >= this.history.length) this.historyIndex = this.history.length - 1\n this.cursorPos = this.history[this.historyIndex].length\n }\n\n this.terminal.write(this.history[this.historyIndex])\n this.terminal.write('\\b'.repeat(this.history[this.historyIndex].length))\n this.terminal.moveForward(this.cursorPos)\n\n this.lastInputLength = this.cursorPos\n\n let completed = this.getCompleted(true)\n if (this.historyIndex === 0 && completed && action !== 'return') {\n // show closest match faintly\n let rest = completed.substr(this.history[0].length)\n this.terminal.write(`\\x1b[2m${rest}\\x1b[m${'\\b'.repeat(rest.length)}`)\n this.lastInputLength += rest.length\n }\n\n if (action === 'return') {\n this.terminal.write('\\n')\n this.parse(this.history[this.historyIndex])\n }\n }\n parse (input) {\n if (input === 'help') input = 'info'\n // TODO: basic chaining (i.e. semicolon)\n if (input) this.run(input)\n else this.prompt()\n }\n run (command) {\n let parts = ['']\n\n let inQuote = false\n for (let character of command.trim()) {\n if (inQuote && character !== inQuote) {\n parts[parts.length - 1] += character\n } else if (inQuote) {\n inQuote = false\n } else if (character === '\"' || character === \"'\") {\n inQuote = character\n } else if (character.match(/\\s/)) {\n if (parts[parts.length - 1]) parts.push('')\n } else parts[parts.length - 1] += character\n }\n\n let name = parts.shift()\n\n if (name in this.index) {\n this.spawn(name, parts)\n } else {\n this.terminal.write(`demosh: Unknown command: ${name}\\r\\n`)\n this.prompt(false)\n }\n }\n spawn (name, args = []) {\n let Process = this.index[name]\n if (Process instanceof Function) {\n this.setButtons([])\n this.child = new Process(this)\n let write = data => this.terminal.write(data)\n let setButtons = buttons => this.setButtons(buttons)\n this.child.on('write', write)\n this.child.on('buttons', setButtons)\n this.child.on('exit', code => {\n if (this.child) {\n this.child.removeListener('write', write)\n this.child.removeListener('buttons', setButtons)\n }\n this.child = null\n this.prompt(!code)\n })\n this.child.run(...args)\n } else {\n this.terminal.write(Process)\n this.prompt()\n }\n }\n\n setButtons (buttons) {\n if (!buttons) {\n const shell = this\n let writeChars = chars => {\n let loop = () => {\n shell.write(chars[0])\n chars = chars.substr(1)\n if (chars) setTimeout(loop, 100)\n }\n setTimeout(loop, 200)\n }\n\n buttons = [\n {\n label: 'Open GitHub',\n action (shell) {\n if (shell.child) shell.child.destroy()\n writeChars('github\\r')\n }\n },\n {\n label: 'Help',\n action (shell) {\n if (shell.child) shell.child.destroy()\n writeChars('info\\r')\n }\n }\n ]\n }\n if (!buttons.length) buttons.push({ label: '', action () {} })\n this.buttons = buttons\n this.terminal.buttonLabels = buttons.map(x => x.label)\n }\n\n onButtonPress (index) {\n let button = this.buttons[index]\n if (!button) return\n button.action(this, this.terminal)\n }\n}\n\nwindow.demoInterface = module.exports = {\n input (data) {\n let type = data[0]\n let content = data.substr(1)\n\n if (type === 's') {\n this.shell.write(content)\n } else if (type === 'b') {\n let button = content.charCodeAt(0)\n this.shell.onButtonPress(button - 1)\n } else if (type === 'm' || type === 'p' || type === 'r') {\n let row = parse2B(content, 0)\n let column = parse2B(content, 2)\n let button = parse2B(content, 4)\n let modifiers = parse2B(content, 6)\n\n if (demoData.mouseReceiver) {\n if (type === 'm') demoData.mouseReceiver.mouseMove(column, row, button, modifiers)\n else if (type === 'p') demoData.mouseReceiver.mouseDown(column, row, button, modifiers)\n else if (type === 'r') demoData.mouseReceiver.mouseUp(column, row, button, modifiers)\n }\n }\n },\n didInit: false,\n init (screen) {\n if (this.didInit) return\n this.didInit = true\n this.terminal = new ScrollingTerminal(screen)\n this.shell = new DemoShell(this.terminal, true)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/demo.js","let data = require('locale-data')\n\nmodule.exports = function localize (key) {\n return data[key] || `?${key}?`\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/lang.js","require('./lib/polyfills')\nrequire('./modal')\nrequire('./notif')\nrequire('./appcommon')\ntry { require('./term/demo') } catch (err) {}\nrequire('./wifi')\n\nconst $ = require('./lib/chibi')\nconst { qs } = require('./utils')\n\n/* Export stuff to the global scope for inline scripts */\nwindow.termInit = require('./term')\nwindow.$ = $\nwindow.qs = qs\n\nwindow.themes = require('./term/themes')\n\nwindow.TermConf = require('./term_conf')\n\n\n\n// WEBPACK FOOTER //\n// ./js/index.js","/*! http://mths.be/fromcodepoint v0.1.0 by @mathias */\nif (!String.fromCodePoint) {\n (function () {\n var defineProperty = (function () {\n // IE 8 only supports `Object.defineProperty` on DOM elements\n try {\n var object = {};\n var $defineProperty = Object.defineProperty;\n var result = $defineProperty(object, object, object) && $defineProperty;\n } catch (error) {\n }\n return result;\n }());\n var stringFromCharCode = String.fromCharCode;\n var floor = Math.floor;\n var fromCodePoint = function () {\n var MAX_SIZE = 0x4000;\n var codeUnits = [];\n var highSurrogate;\n var lowSurrogate;\n var index = -1;\n var length = arguments.length;\n if (!length) {\n return '';\n }\n var result = '';\n while (++index < length) {\n var codePoint = Number(arguments[index]);\n if (\n !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity`\n codePoint < 0 || // not a valid Unicode code point\n codePoint > 0x10FFFF || // not a valid Unicode code point\n floor(codePoint) != codePoint // not an integer\n ) {\n throw RangeError('Invalid code point: ' + codePoint);\n }\n if (codePoint <= 0xFFFF) { // BMP code point\n codeUnits.push(codePoint);\n } else { // Astral code point; split in surrogate halves\n // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n codePoint -= 0x10000;\n highSurrogate = (codePoint >> 10) + 0xD800;\n lowSurrogate = (codePoint % 0x400) + 0xDC00;\n codeUnits.push(highSurrogate, lowSurrogate);\n }\n if (index + 1 == length || codeUnits.length > MAX_SIZE) {\n result += stringFromCharCode.apply(null, codeUnits);\n codeUnits.length = 0;\n }\n }\n return result;\n };\n if (defineProperty) {\n defineProperty(String, 'fromCodePoint', {\n 'value': fromCodePoint,\n 'configurable': true,\n 'writable': true\n });\n } else {\n String.fromCodePoint = fromCodePoint;\n }\n }());\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/lib/polyfills.js","const $ = require('./lib/chibi')\nconst { mk, qs, qsa, cr } = require('./utils')\nconst modal = require('./modal')\nconst notify = require('./notif')\n\n/** Global generic init */\n$.ready(function () {\n // Opening menu on mobile / narrow screen\n function menuOpen () {\n $('#menu').toggleClass('expanded')\n }\n $('#brand')\n .on('click', menuOpen)\n .on('keypress', cr(menuOpen))\n\n // Checkbox UI (checkbox CSS and hidden input with int value)\n $('.Row.checkbox').forEach(function (x) {\n let inp = x.querySelector('input')\n let box = x.querySelector('.box')\n\n $(box).toggleClass('checked', inp.value)\n\n let hdl = function () {\n inp.value = 1 - inp.value\n $(box).toggleClass('checked', inp.value)\n }\n\n $(x).on('click', hdl).on('keypress', cr(hdl))\n })\n\n // Expanding boxes on mobile\n $('.Box.mobcol,.Box.fold').forEach(function (x) {\n let h = x.querySelector('h2')\n\n let hdl = function () {\n if ($(x).hasClass('d-expanded')) {\n $(x).removeClass('d-expanded')\n } else {\n $(x).toggleClass('expanded')\n }\n }\n $(h).on('click', hdl).on('keypress', cr(hdl))\n })\n\n $('form').forEach(function (x) {\n $(x).on('keypress', function (e) {\n if ((e.keyCode === 10 || e.keyCode === 13) && e.ctrlKey) {\n x.submit()\n }\n })\n })\n\n // loader dots...\n setInterval(function () {\n $('.anim-dots').each(function (x) {\n let $x = $(x)\n let dots = $x.html() + '.'\n if (dots.length === 5) dots = '.'\n $x.html(dots)\n })\n }, 1000)\n\n // flipping number boxes with the mouse wheel\n $('input[type=number]').on('wheel', function (e) {\n let $this = $(this)\n let val = +$this.val()\n if (isNaN(val)) val = 1\n\n const step = +($this.attr('step') || 1)\n const min = +$this.attr('min')\n const max = +$this.attr('max')\n if (e.deltaY > 0) {\n val += step\n } else {\n val -= step\n }\n\n if (Number.isFinite(min)) val = Math.max(val, +min)\n if (Number.isFinite(max)) val = Math.min(val, +max)\n $this.val(val)\n\n if ('createEvent' in document) {\n let evt = document.createEvent('HTMLEvents')\n evt.initEvent('change', false, true)\n $this[0].dispatchEvent(evt)\n } else {\n $this[0].fireEvent('onchange')\n }\n\n e.preventDefault()\n })\n\n try {\n do {\n let msgAt, box\n // populate the form errors box from GET arg ?err=...\n // (a way to pass errors back from server via redirect)\n msgAt = window.location.search.indexOf('err=')\n if (msgAt !== -1 && qs('.Box.errors')) {\n let errs = decodeURIComponent(window.location.search.substr(msgAt + 4)).split(',')\n let humanReadableErrors = []\n errs.forEach(function (er) {\n if (er.length === 0) return\n let lbls = qsa('label[for=\"' + er + '\"]')\n if (lbls && lbls.length > 0) {\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 console.log(JSON.stringify(er))\n humanReadableErrors.push(er)\n }\n })\n\n qs('.Box.errors .list').innerHTML = humanReadableErrors.join(', ')\n qs('.Box.errors').classList.remove('hidden')\n break\n }\n\n let fademsgbox = function (box, time) {\n box.classList.remove('hidden')\n setTimeout(() => {\n box.classList.add('hiding')\n setTimeout(() => {\n box.classList.add('hidden')\n }, 1000)\n }, time)\n }\n\n msgAt = window.location.search.indexOf('errmsg=')\n box = qs('.Box.errmessage')\n if (msgAt !== -1 && box) {\n let msg = decodeURIComponent(window.location.search.substr(msgAt + 7))\n box.innerHTML = msg\n fademsgbox(box, 3000)\n break\n }\n\n msgAt = window.location.search.indexOf('msg=')\n box = qs('.Box.message')\n if (msgAt !== -1 && box) {\n let msg = decodeURIComponent(window.location.search.substr(msgAt + 4))\n box.innerHTML = msg\n fademsgbox(box, 2000)\n break\n }\n } while (0)\n } catch (e) {\n console.error(e)\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 qs('#screen').classList.add('failed')\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\nconst HTTPS = window.location.protocol.match(/s:/)\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(`${HTTPS ? 'https' : '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","<?php\n\nreturn [\n\t'menu.cfg_wifi' => 'WiFi Settings',\n\t'menu.cfg_network' => 'Network Settings',\n\t'menu.cfg_term' => 'Terminal Settings',\n\t'menu.about' => 'About ESPTerm',\n\t'menu.help' => 'Quick Reference',\n\t'menu.term' => 'Back to Terminal',\n\t'menu.cfg_system' => 'System Settings',\n\t'menu.cfg_wifi_conn' => 'Connecting to Network',\n\t'menu.settings' => 'Settings',\n\n\t// Terminal page\n\n\t'title.term' => 'Terminal', // page title of the terminal page\n\n\t'term_nav.fullscreen' => 'Fullscreen',\n\t'term_nav.config' => 'Config',\n\t'term_nav.wifi' => 'WiFi',\n\t'term_nav.help' => 'Help',\n\t'term_nav.about' => 'About',\n\t'term_nav.paste' => 'Paste',\n\t'term_nav.upload' => 'Upload',\n\t'term_nav.keybd' => 'Keyboard',\n\t'term_nav.paste_prompt' => 'Paste text to send:',\n\n\t'term_conn.connecting' => 'Connecting',\n\t'term_conn.waiting_content' => 'Waiting for content',\n\t'term_conn.disconnected' => 'Disconnected',\n\t'term_conn.waiting_server' => 'Waiting for server',\n\t'term_conn.reconnecting' => 'Reconnecting',\n\n\t// Terminal settings page\n\n\t'term.defaults' => 'Initial Settings',\n\t'term.expert' => 'Expert Options',\n\t'term.explain_initials' => '\n\t\tThose are the initial settings used after ESPTerm powers on, \n\t\tor when the screen reset command is received (<code>\\ec</code>).\n\t\tThey can be changed by the terminal application using escape sequences.\n\t\t',\n\t'term.explain_expert' => '\n\t\tThose are advanced config options that usually don\\'t need to be changed.\n\t\tEdit them only if you know what you\\'re doing.',\n\n\t'term.example' => 'Default colors preview',\n\n\t'term.explain_scheme' => '\n\t\tTo select default text and background color, click on the\n\t\tpreview palette. Alternatively, use numbers 0-15 for theme colors,\n\t\t16-255 for standard colors and hex (#FFFFFF) for True Color (24-bit).\n\t\t',\n\n\t'term.fgbg_presets' => 'Defaults Presets',\n\t'term.color_scheme' => 'Color Scheme',\n\t'term.reset_screen' => 'Reset screen & parser',\n\t'term.term_title' => 'Header Text',\n\t'term.term_width' => 'Width',\n\t'term.term_height' => 'Height',\n\t'term.buttons' => 'Button Labels',\n\t'term.theme' => 'Color Palette',\n\t'term.cursor_shape' => 'Cursor Style',\n\t'term.parser_tout_ms' => 'Parser Timeout',\n\t'term.display_tout_ms' => 'Redraw Delay',\n\t'term.display_cooldown_ms' => 'Redraw Cooldown',\n\t'term.allow_decopt_12' => 'Allow \\e?12h/l',\n\t'term.fn_alt_mode' => 'SS3 Fn keys',\n\t'term.show_config_links' => 'Show nav links',\n\t'term.show_buttons' => 'Show buttons',\n\t'term.loopback' => 'Local Echo (<span style=\"text-decoration:overline\">SRM</span>)',\n\t'term.crlf_mode' => 'Enter = CR+LF (LNM)',\n\t'term.want_all_fn' => 'Capture F5, F11, F12',\n\t'term.button_msgs' => 'Button codes<br>(ASCII, dec, CSV)',\n\t'term.color_fg' => 'Default Fg.',\n\t'term.color_bg' => 'Default Bg.',\n\t'term.color_fg_prev' => 'Foreground',\n\t'term.color_bg_prev' => 'Background',\n\t'term.colors_preview' => '',\n\t'term.debugbar' => 'Debug internal state',\n\t'term.ascii_debug' => 'Display control codes',\n\t'term.backdrop' => 'Background image URL',\n\t'term.button_count' => 'Button count',\n\t'term.button_colors' => 'Button colors',\n\t'term.font_stack' => 'Font stack',\n\t'term.font_size' => 'Font size',\n\n\t'cursor.block_blink' => 'Block, blinking',\n 'cursor.block_steady' => 'Block, steady',\n 'cursor.underline_blink' => 'Underline, blinking',\n 'cursor.underline_steady' => 'Underline, steady',\n 'cursor.bar_blink' => 'I-bar, blinking',\n 'cursor.bar_steady' => 'I-bar, steady',\n\n\t// Text upload dialog\n\n\t'upload.title' => 'Text Upload',\n\t'upload.prompt' => 'Load a text file:',\n\t'upload.endings' => 'Line endings:',\n\t'upload.endings.cr' => 'CR (Enter key)',\n\t'upload.endings.crlf' => 'CR LF (Windows)',\n\t'upload.endings.lf' => 'LF (Linux)',\n\t'upload.chunk_delay' => 'Chunk delay (ms):',\n\t'upload.chunk_size' => 'Chunk size (0=line):',\n\t'upload.progress' => 'Upload:',\n\n\t// Network config page\n\n\t'net.explain_sta' => '\n\t\tSwitch off Dynamic IP to configure the static IP address.',\n\n\t'net.explain_ap' => '\n\t\tThose settings affect the built-in DHCP server in AP mode.',\n\n\t'net.ap_dhcp_time' => 'Lease time',\n\t'net.ap_dhcp_start' => 'Pool start IP',\n\t'net.ap_dhcp_end' => 'Pool end IP',\n\t'net.ap_addr_ip' => 'Own IP address',\n\t'net.ap_addr_mask' => 'Subnet mask',\n\n\t'net.sta_dhcp_enable' => 'Use dynamic IP',\n\t'net.sta_addr_ip' => 'ESPTerm static IP',\n\t'net.sta_addr_mask' => 'Subnet mask',\n\t'net.sta_addr_gw' => 'Gateway IP',\n\n\t'net.ap' => 'DHCP Server (AP)',\n\t'net.sta' => 'DHCP Client (Station)',\n\t'net.sta_mac' => 'Station MAC',\n\t'net.ap_mac' => 'AP MAC',\n\t'net.details' => 'MAC addresses',\n\n\t// Wifi config page\n\n\t'wifi.ap' => 'Built-in Access Point',\n\t'wifi.sta' => 'Join Existing Network',\n\n\t'wifi.enable' => 'Enabled',\n\t'wifi.tpw' => 'Transmit power',\n\t'wifi.ap_channel' => 'Channel',\n\t'wifi.ap_ssid' => 'AP SSID',\n\t'wifi.ap_password' => 'Password',\n\t'wifi.ap_hidden' => 'Hide SSID',\n\t'wifi.sta_info' => 'Selected',\n\n\t'wifi.not_conn' => 'Not connected.',\n\t'wifi.sta_none' => 'None',\n\t'wifi.sta_active_pw' => '🔒 Password saved',\n\t'wifi.sta_active_nopw' => '🔓 Open access',\n\t'wifi.connected_ip_is' => 'Connected, IP is ',\n\t'wifi.sta_password' => 'Password:',\n\n\t'wifi.scanning' => 'Scanning',\n\t'wifi.scan_now' => 'Click here to start scanning!',\n\t'wifi.cant_scan_no_sta' => 'Click here to enable client mode and start scanning!',\n\t'wifi.select_ssid' => 'Available networks:',\n\t'wifi.enter_passwd' => 'Enter password for \":ssid:\"',\n\t'wifi.sta_explain' => 'After selecting a network, press Apply to connect.',\n\n\t// Wifi connecting status page\n\n\t'wificonn.status' => 'Status:',\n\t'wificonn.back_to_config' => 'Back to WiFi config',\n\t'wificonn.telemetry_lost' => 'Telemetry lost; something went wrong, or your device disconnected.',\n\t'wificonn.explain_android_sucks' => '\n\t\tIf you\\'re configuring ESPTerm via a smartphone, or were connected \n\t\tfrom another external network, your device may lose connection and \n\t\tthis progress indicator won\\'t work. Please wait a while (~ 15 seconds), \n\t\tthen check if the connection succeeded.',\n\n\t'wificonn.explain_reset' => '\n\t\tTo force enable the built-in AP, hold the BOOT button until the blue LED \n\t\tstarts flashing. Hold the button longer (until the LED flashes rapidly) \n\t\tfor a \"factory reset\".',\n\n\t'wificonn.disabled' =>\"Station mode is disabled.\",\n\t'wificonn.idle' =>\"Idle, not connected and has no IP.\",\n\t'wificonn.success' => \"Connected! Received IP \",\n\t'wificonn.working' => \"Connecting to selected AP\",\n\t'wificonn.fail' => \"Connection failed, check settings & try again. Cause: \",\n\n\t// Access restrictions form\n\n\t'pwlock.title' => 'Access Restrictions',\n\t'pwlock.explain' => '\n\t\tSome parts, or all of the web interface can be protected by a password prompt.\n\t\tLeave the new password fields empty if you do not wish to change it.<br>\n\t\tThe default password is \"%def_access_pw%\".\n\t',\n\t'pwlock.region' => 'Protected pages',\n\t'pwlock.region.none' => 'None, all open',\n\t'pwlock.region.settings_noterm' => 'WiFi, Net & System settings',\n\t'pwlock.region.settings' => 'All settings pages',\n\t'pwlock.region.menus' => 'This entire menu section',\n\t'pwlock.region.all' => 'Everything, even terminal',\n\t'pwlock.new_access_pw' => 'New password',\n\t'pwlock.new_access_pw2' => 'Repeat',\n\t'pwlock.admin_pw' => 'Admin password',\n\t'pwlock.access_name' => 'Username',\n\n\t// Setting admin password\n\n\t'adminpw.title' => 'Change Admin Password',\n\t'adminpw.explain' =>\n\t\t'\n\t\tThe \"admin password\" is used to manipulate the stored default settings \n\t\tand to change access restrictions. This password is not saved as part \n\t\tof the main config, i.e. using save / restore does not affect this \n\t\tpassword. When the admin password is forgotten, the easiest way to \n\t\tre-gain access is to wipe and re-flash the chip.<br>\n\t\tThe default admin password is \"%def_admin_pw%\".\n\t\t',\n\t'adminpw.new_admin_pw' => 'New admin password',\n\t'adminpw.new_admin_pw2' => 'Repeat',\n\t'adminpw.old_admin_pw' => 'Old admin password',\n\n\t// Persist form\n\n\t'persist.title' => 'Save & Restore',\n\t'persist.explain' => '\n\t\tESPTerm saves all settings in Flash. The active settings can be copied to\n\t\tthe \"defaults area\" and restored later using the blue button below.\n\t\t',\n\t'persist.confirm_restore' => 'Restore all settings to their default values?',\n\t'persist.confirm_restore_hard' =>\n\t\t'Restore to firmware default settings? This will reset ' .\n\t\t'all active settings and switch to AP mode with the default SSID.',\n\t'persist.confirm_store_defaults' =>\n\t\t'Enter admin password to confirm you want to overwrite the default settings.',\n\t'persist.password' => 'Admin password:',\n\t'persist.restore_defaults' => 'Reset to saved defaults',\n\t'persist.write_defaults' => 'Save active settings as defaults',\n\t'persist.restore_hard' => 'Reset active settings to factory defaults',\n\t'persist.restore_hard_explain' =>\n\t\t'(This clears the WiFi config! Does not affect saved defaults or admin password.)',\n\n\t'backup.title' => 'Back-up Config File',\n\t'backup.explain' => 'All config except the admin password can be backed up and restored using an INI file.',\n\t'backup.export' => 'Export to file',\n\t'backup.import' => 'Import!',\n\n\t// UART settings form\n\n\t'uart.title' => 'Serial Port Parameters',\n\t'uart.explain' => '\n\t\tThis form controls the communication UART. The debug UART is fixed\n\t\tat 115.200 baud, one stop-bit and no parity.\n\t\t',\n\t'uart.baud' => 'Baud rate',\n\t'uart.parity' => 'Parity',\n\t'uart.parity.none' => 'None',\n\t'uart.parity.odd' => 'Odd',\n\t'uart.parity.even' => 'Even',\n\t'uart.stop_bits' => 'Stop-bits',\n\t'uart.stop_bits.one' => 'One',\n\t'uart.stop_bits.one_and_half' => 'One and half',\n\t'uart.stop_bits.two' => 'Two',\n\n\t// HW tuning form\n\n\t'hwtuning.title' => 'Hardware Tuning',\n\t'hwtuning.explain' => '\n\t\tESP8266 can be overclocked from 80&nbsp;MHz to 160&nbsp;MHz. This will make \n\t\tit more responsive and allow faster screen updates at the expense of slightly \n\t\thigher power consumption. This can also make it more susceptible to interference.\n\t\tUse with care.\n\t\t',\n\t'hwtuning.overclock' => 'Overclock to 160MHz',\n\n\t// Generic button / dialog labels\n\n\t'apply' => 'Apply!',\n\t'start' => 'Start',\n\t'cancel' => 'Cancel',\n\t'enabled' => 'Enabled',\n\t'disabled' => 'Disabled',\n\t'yes' => 'Yes',\n\t'no' => 'No',\n\t'confirm' => 'OK',\n\t'copy' => 'Copy',\n\t'form_errors' => 'Validation errors for:',\n];\n\n\n\n// WEBPACK FOOTER //\n// ./lang/en.php","const $ = require('../lib/chibi')\nconst { 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 attachDebugger = require('./debug')\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 input.termUpload = termUpload\n\n // forward screen input events\n screen.on('mousedown', (...args) => input.onMouseDown(...args))\n screen.on('mousemove', (...args) => input.onMouseMove(...args))\n screen.on('mouseup', (...args) => input.onMouseUp(...args))\n screen.on('mousewheel', (...args) => input.onMouseWheel(...args))\n screen.on('input-alts', (...args) => input.setAlts(...args))\n screen.on('mouse-mode', (...args) => input.setMouseMode(...args))\n\n // touch selection menu (the Copy button)\n $.ready(() => {\n const touchSelectMenu = qs('#touch-select-menu')\n screen.on('show-touch-select-menu', (x, y) => {\n let rect = touchSelectMenu.getBoundingClientRect()\n x -= rect.width / 2\n y -= rect.height / 2\n\n touchSelectMenu.classList.add('open')\n touchSelectMenu.style.transform = `translate(${x}px,${y}px)`\n })\n screen.on('hide-touch-select-menu', () => touchSelectMenu.classList.remove('open'))\n\n const copyButton = qs('#touch-select-copy-btn')\n if (copyButton) {\n copyButton.addEventListener('click', () => {\n screen.copySelectionToClipboard()\n })\n }\n })\n\n // buttons\n const buttons = initButtons(input)\n screen.on('buttons-update', update => {\n buttons.labels = update.labels\n buttons.colors = update.colors\n })\n // TODO: don't access the renderer here\n buttons.palette = screen.layout.renderer.palette\n screen.layout.renderer.on('palette-update', palette => {\n buttons.palette = palette\n })\n\n screen.on('full-load', () => {\n let scr = qs('#screen')\n let errmsg = qs('#load-failed')\n if (scr) scr.classList.remove('failed')\n if (errmsg) errmsg.parentNode.removeChild(errmsg)\n })\n\n let setLinkVisibility = visible => {\n let buttons = [...document.querySelectorAll('.x-term-conf-btn')]\n if (visible) buttons.forEach(x => x.classList.remove('hidden'))\n else buttons.forEach(x => x.classList.add('hidden'))\n }\n let setButtonVisibility = visible => {\n if (visible) qs('#action-buttons').classList.remove('hidden')\n else qs('#action-buttons').classList.add('hidden')\n }\n\n screen.on('opts-update', () => {\n setLinkVisibility(screen.showLinks)\n setButtonVisibility(screen.showButtons)\n })\n\n screen.on('title-update', text => {\n qs('#screen-title').textContent = text\n if (!text) text = 'Terminal'\n qs('title').textContent = `${text} :: ESPTerm`\n })\n\n // connection status\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 screen.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.layout.canvas)\n\n initSoftKeyboard(screen, input)\n if (attachDebugger) attachDebugger(screen, conn)\n\n // fullscreen mode\n\n let fullscreenIcon = {} // dummy\n let isFullscreen = false\n let properFullscreen = false\n let fitScreen = false\n let screenPadding = screen.layout.window.padding\n let fitScreenIfNeeded = function fitScreenIfNeeded () {\n if (isFullscreen) {\n fullscreenIcon.className = 'icn-resize-small'\n if (properFullscreen) {\n screen.layout.window.fitIntoWidth = window.screen.width\n screen.layout.window.fitIntoHeight = window.screen.height\n screen.layout.window.padding = 0\n } else {\n screen.layout.window.fitIntoWidth = window.innerWidth\n if (qs('#term-nav').classList.contains('hidden')) {\n screen.layout.window.fitIntoHeight = window.innerHeight\n } else {\n screen.layout.window.fitIntoHeight = window.innerHeight - 24\n }\n screen.layout.window.padding = 0\n }\n } else {\n fullscreenIcon.className = 'icn-resize-full'\n screen.layout.window.fitIntoWidth = fitScreen ? window.innerWidth - 4 : 0\n screen.layout.window.fitIntoHeight = fitScreen ? window.innerHeight : 0\n screen.layout.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.layout.updateSize()\n\n if (properFullscreen) {\n if (screen.layout.canvas.requestFullscreen) screen.layout.canvas.requestFullscreen()\n else screen.layout.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.buttons = buttons\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 { mk } = require('../utils')\nconst notify = require('../notif')\nconst ScreenParser = require('./screen_parser')\nconst ScreenLayout = require('./screen_layout')\nconst { ATTR_BLINK } = require('./screen_attr_bits')\n\n/**\n * A terminal screen.\n */\nmodule.exports = class TermScreen extends EventEmitter {\n constructor () {\n super()\n\n this.parser = new ScreenParser()\n this.layout = new ScreenLayout()\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 this._window = {\n width: 0,\n height: 0,\n // two bits. LSB: debug enabled by user, MSB: debug enabled by server\n debug: 0,\n statusScreen: null\n }\n\n // make writing to window update size and draw\n this.window = new Proxy(this._window, {\n set (target, key, value) {\n if (target[key] !== value) {\n target[key] = value\n self.updateLayout()\n self.renderScreen(`window:${key}=${value}`)\n self.emit(`update-window:${key}`, value)\n }\n return true\n }\n })\n\n this.on('update-window:debug', debug => { this.layout.window.debug = !!debug })\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 const self = this\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: null,\n\n // selection start and end (x, y) tuples\n start: [0, 0],\n end: [0, 0],\n\n setSelectable (value) {\n if (value !== this.selectable) {\n this.selectable = self.layout.selectable = value\n }\n }\n }\n\n // mouse features\n this.mouseMode = { clicks: false, movement: false }\n\n this.showLinks = false\n this.showButtons = false\n this.title = ''\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 this.screenLines = []\n\n // For testing TODO remove\n // this.screenLines[0] = 0b001\n // this.screenLines[1] = 0b010\n // this.screenLines[2] = 0b100\n // this.screenLines[3] = 0b011\n // this.screenLines[4] = 0b101\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.layout.screenToGrid(x, y, true)\n this.renderScreen('select-start')\n }\n\n let selectMove = (x, y) => {\n if (!selecting) return\n this.selection.end = this.layout.screenToGrid(x, y, true)\n this.renderScreen('select-move')\n }\n\n let selectEnd = (x, y) => {\n if (!selecting) return\n selecting = false\n this.selection.end = this.layout.screenToGrid(x, y, true)\n this.renderScreen('select-end')\n Object.assign(this.selection, this.getNormalizedSelection())\n }\n\n // bind event listeners\n\n this.layout.on('mousedown', e => {\n this.emit('hide-touch-select-menu')\n if ((this.selection.selectable || e.altKey) && e.button === 0) {\n selectStart(e.offsetX, e.offsetY)\n } else {\n this.emit('mousedown', ...this.layout.screenToGrid(e.offsetX, e.offsetY), 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.layout.canvas.getBoundingClientRect()\n return [touch.clientX - rect.left, touch.clientY - rect.top]\n }\n\n this.layout.on('touchstart', e => {\n touchPosition = getTouchPositionOffset(e.touches[0])\n touchDidMove = false\n touchDownTime = Date.now()\n\n if (this.mouseMode.clicks) {\n this.emit('mousedown', ...this.layout.screenToGrid(...touchPosition), 1)\n e.preventDefault()\n }\n })\n\n this.layout.on('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 } else if (this.mouseMode.movement && !selecting) {\n this.emit('mousemove', ...this.layout.screenToGrid(...touchPosition))\n e.preventDefault()\n }\n\n touchDidMove = true\n })\n\n this.layout.on('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 // use middle position for x and one line above for y\n let selectionPos = this.layout.gridToScreen(\n (this.selection.start[0] + this.selection.end[0]) / 2,\n this.selection.start[1] - 1\n )\n\n this.emit('show-touch-select-menu', selectionPos[0], selectionPos[1])\n } else if (this.mouseMode.clicks) {\n this.emit('mouseup', ...this.layout.screenToGrid(...touchPosition), 1)\n e.preventDefault()\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 } else if (!touchDidMove) this.resetSelection()\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 this.resetSelection()\n } else {\n e.preventDefault()\n this.emit('open-soft-keyboard')\n }\n })\n\n this.layout.on('mousemove', e => {\n if (!selecting) {\n this.emit('mousemove', ...this.layout.screenToGrid(e.offsetX, e.offsetY))\n }\n })\n\n this.layout.on('mouseup', e => {\n if (!selecting) {\n this.emit('mouseup', ...this.layout.screenToGrid(e.offsetX, e.offsetY),\n e.button + 1)\n }\n })\n\n let aggregateWheelDelta = 0\n this.layout.on('wheel', e => {\n if (this.mouseMode.clicks) {\n if (Math.abs(e.wheelDeltaY) === 120) {\n // mouse wheel scrolling\n this.emit('mousewheel', ...this.layout.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.emit('mousewheel', ...this.layout.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.layout.on('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 resetScreen () {\n const { width, height } = this.window\n this.blinkingCellCount = 0\n this.screen.screen = new Array(width * height).fill(' ')\n this.screen.screenFG = new Array(width * height).fill(0)\n this.screen.screenBG = new Array(width * height).fill(0)\n this.screen.screenAttrs = new Array(width * height).fill(0)\n this.screen.screenLines = new Array(height).fill(0)\n }\n\n updateLayout () {\n this.layout.window.width = this.window.width\n this.layout.window.height = this.window.height\n }\n\n renderScreen (reason) {\n let selection = []\n\n for (let cell = 0; cell < this.screen.length; cell++) {\n selection.push(this.isInSelection(cell % this.window.width, Math.floor(cell / this.window.width)))\n }\n\n this.layout.render(reason, {\n width: this.window.width,\n height: this.window.height,\n screen: this.screen,\n screenFG: this.screenFG,\n screenBG: this.screenBG,\n screenSelection: selection,\n screenAttrs: this.screenAttrs,\n screenLines: this.screenLines,\n cursor: this.cursor,\n statusScreen: this.window.statusScreen,\n reverseVideo: this.reverseVideo,\n hasBlinkingCells: !!this.blinkingCellCount\n })\n }\n\n resetSelection () {\n this.selection.start = this.selection.end = [0, 0]\n this.emit('hide-touch-select-menu')\n this.renderScreen('select-reset')\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 const updates = this.parser.parse(...args)\n\n for (let update of updates) {\n switch (update.topic) {\n case 'screen-opts':\n if (update.width !== this.window.width || update.height !== this.window.height) {\n this.window.width = update.width\n this.window.height = update.height\n this.resetScreen()\n }\n this.layout.renderer.loadTheme(update.theme)\n this.layout.renderer.setDefaultColors(update.defFG, update.defBG)\n this.cursor.visible = update.cursorVisible\n this.emit('input-alts', ...update.inputAlts)\n this.mouseMode.clicks = update.trackMouseClicks\n this.mouseMode.movement = update.trackMouseMovement\n this.emit('mouse-mode', update.trackMouseClicks, update.trackMouseMovement)\n this.selection.setSelectable(!update.trackMouseClicks && !update.trackMouseMovement)\n if (this.cursor.blinking !== update.cursorBlinking) {\n this.cursor.blinking = update.cursorBlinking\n this.layout.renderer.resetCursorBlink()\n }\n this.cursor.style = update.cursorStyle\n this.bracketedPaste = update.bracketedPaste\n this.reverseVideo = update.reverseVideo\n this.window.debug &= 0b01\n this.window.debug |= (+update.debugEnabled << 1)\n\n this.showLinks = update.showConfigLinks\n this.showButtons = update.showButtons\n this.emit('opts-update')\n break\n\n case 'double-lines':\n this.screenLines = update.lines\n this.renderScreen('double-lines')\n break\n\n case 'static-opts':\n this.layout.window.fontFamily = update.fontStack || null\n this.layout.window.fontSize = update.fontSize\n break\n\n case 'cursor':\n if (this.cursor.x !== update.x || this.cursor.y !== update.y || this.cursor.hanging !== update.hanging) {\n this.cursor.x = update.x\n this.cursor.y = update.y\n this.cursor.hanging = update.hanging\n this.layout.renderer.resetCursorBlink()\n this.emit('cursor-moved')\n this.renderScreen('cursor-moved')\n }\n break\n\n case 'title':\n this.emit('title-update', this.title = update.title)\n break\n\n case 'buttons-update':\n this.emit('buttons-update', update)\n break\n\n case 'backdrop':\n this.backgroundImage = update.image\n break\n\n case 'bell':\n this.beep()\n break\n\n case 'internal':\n this.emit('internal', update)\n break\n\n case 'content':\n const { frameX, frameY, frameWidth, frameHeight, cells } = update\n\n if (this._debug && this.window.debug) {\n this._debug.pushFrame([frameX, frameY, frameWidth, frameHeight])\n }\n\n for (let cell = 0; cell < cells.length; cell++) {\n let data = cells[cell]\n\n let cellXInFrame = cell % frameWidth\n let cellYInFrame = Math.floor(cell / frameWidth)\n let index = (frameY + cellYInFrame) * this.window.width + frameX + cellXInFrame\n\n if ((this.screenAttrs[index] & ATTR_BLINK) !== (data[3] & ATTR_BLINK)) {\n if (data[3] & ATTR_BLINK) this.blinkingCellCount++\n else this.blinkingCellCount--\n }\n\n this.screen[index] = data[0]\n this.screenFG[index] = data[1]\n this.screenBG[index] = data[2]\n this.screenAttrs[index] = data[3]\n }\n\n if (this.window.debug) console.log(`Blinking cells: ${this.blinkingCellCount}`)\n\n this.renderScreen('load')\n this.emit('load')\n break\n\n case 'full-load-complete':\n this.emit('full-load')\n break\n\n case 'notification':\n this.showNotification(update.content)\n break\n\n default:\n console.warn('Unhandled update', update)\n }\n }\n\n this.emit('update')\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/screen.js","const {\n ATTR_FG,\n ATTR_BG,\n ATTR_BOLD,\n ATTR_UNDERLINE,\n ATTR_BLINK,\n ATTR_STRIKE,\n ATTR_OVERLINE,\n ATTR_FAINT\n} = require('./screen_attr_bits')\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\n// decode a number encoded as a unicode code point\nfunction du (str) {\n if (!str) return NaN\n let num = str.codePointAt(0)\n if (num > 0xDFFF) num -= 0x800\n return num - 1\n}\n\n/* eslint-disable no-multi-spaces */\n// mnemonic\nconst TOPIC_SCREEN_OPTS = 'O' // O-ptions\nconst TOPIC_STATIC_OPTS = 'P' // P-arams\nconst TOPIC_CONTENT = 'S' // S-creen\nconst TOPIC_TITLE = 'T' // T-itle\nconst TOPIC_BUTTONS = 'B' // B-uttons\nconst TOPIC_CURSOR = 'C' // C-ursor\nconst TOPIC_INTERNAL = 'D' // D-ebug\nconst TOPIC_BELL = '!' // !!!\nconst TOPIC_BACKDROP = 'W' // W-allpaper\nconst TOPIC_DOUBLE_LINES = 'H' // H-uge\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\n/* eslint-enable no-multi-spaces */\n\n/**\n * A parser for screen update messages\n */\nmodule.exports = class ScreenParser {\n constructor () {\n // true if full content was loaded\n this.contentLoaded = false\n }\n\n parseUpdate (str) {\n // console.log(`update ${str}`)\n\n // current index\n let ci = 0\n let strArray = Array.from ? Array.from(str) : str.split('')\n\n let text\n const topics = du(strArray[ci++])\n\n let collectOneTerminatedString = () => {\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 return text\n }\n\n let collectColor = () => {\n let c = du(strArray[ci++])\n if (c & 0x10000) { // support for trueColor\n c &= 0xFFF\n c |= (du(strArray[ci++]) & 0xFFF) << 12\n c += 256\n }\n return c\n }\n\n const updates = []\n\n while (ci < strArray.length) {\n const topic = strArray[ci++]\n\n if (topic === TOPIC_SCREEN_OPTS) {\n const height = du(strArray[ci++])\n const width = du(strArray[ci++])\n const theme = du(strArray[ci++])\n const defFG = collectColor()\n const defBG = collectColor()\n\n // process attributes\n const attributes = du(strArray[ci++])\n\n const cursorVisible = !!(attributes & OPT_CURSOR_VISIBLE)\n\n // HACK: input alts are formatted as arguments for Input#setAlts\n const inputAlts = [\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 let cursorStyle = cursorShape >> 1\n const cursorBlinking = !(cursorShape & 1)\n if (cursorStyle === 0) cursorStyle = 'block'\n else if (cursorStyle === 1) cursorStyle = 'line'\n else cursorStyle = 'bar'\n\n const showButtons = !!(attributes & OPT_SHOW_BUTTONS)\n const showConfigLinks = !!(attributes & OPT_SHOW_CONFIG_LINKS)\n\n const bracketedPaste = !!(attributes & OPT_BRACKETED_PASTE)\n const reverseVideo = !!(attributes & OPT_REVERSE_VIDEO)\n\n const debugEnabled = !!(attributes & OPT_DEBUGBAR)\n\n updates.push({\n topic: 'screen-opts',\n width,\n height,\n theme,\n defFG,\n defBG,\n cursorVisible,\n cursorBlinking,\n cursorStyle,\n inputAlts,\n trackMouseClicks,\n trackMouseMovement,\n showButtons,\n showConfigLinks,\n bracketedPaste,\n reverseVideo,\n debugEnabled\n })\n\n } else if (topic === TOPIC_CURSOR) {\n // cursor position\n const y = du(strArray[ci++])\n const x = du(strArray[ci++])\n const hanging = !!du(strArray[ci++])\n\n updates.push({\n topic: 'cursor',\n x,\n y,\n hanging\n })\n\n } else if (topic === TOPIC_STATIC_OPTS) {\n const fontStack = collectOneTerminatedString()\n const fontSize = du(strArray[ci++])\n\n updates.push({\n topic: 'static-opts',\n fontStack,\n fontSize\n })\n\n } else if (topic === TOPIC_DOUBLE_LINES) {\n let lines = []\n const count = du(strArray[ci++])\n for (let i = 0; i < count; i++) {\n // format: INDEX<<3 | (dbl-h-bot : dbl-h-top : dbl-w)\n let n = du(strArray[ci++])\n lines[n >> 3] = n & 0b111\n }\n updates.push({ topic: 'double-lines', lines: lines })\n\n } else if (topic === TOPIC_TITLE) {\n updates.push({ topic: 'title', title: collectOneTerminatedString() })\n\n } else if (topic === TOPIC_BUTTONS) {\n const count = du(strArray[ci++])\n\n let labels = []\n let colors = []\n for (let j = 0; j < count; j++) {\n colors.push(collectColor())\n labels.push(collectOneTerminatedString())\n }\n\n updates.push({\n topic: 'buttons-update',\n labels,\n colors\n })\n\n } else if (topic === TOPIC_BACKDROP) {\n updates.push({ topic: 'backdrop', image: collectOneTerminatedString() })\n\n } else if (topic === TOPIC_BELL) {\n updates.push({ topic: 'bell' })\n\n } else if (topic === TOPIC_INTERNAL) {\n // debug info\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\n let cursorFg = collectColor()\n let cursorBg = collectColor()\n\n const freeHeap = du(strArray[ci++])\n const clientCount = du(strArray[ci++])\n\n updates.push({\n topic: 'internal',\n flags,\n cursorAttrs,\n regionStart,\n regionEnd,\n charsetGx,\n charsetG0,\n charsetG1,\n cursorFg,\n cursorBg,\n freeHeap,\n clientCount\n })\n\n } else if (topic === TOPIC_CONTENT) {\n // set screen content\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 // 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\n const MASK_LINE_ATTR = ATTR_UNDERLINE | ATTR_OVERLINE | ATTR_STRIKE\n const MASK_BLINK = ATTR_BLINK\n\n const cells = []\n\n let pushCell = () => {\n let hasFG = attrs & ATTR_FG\n let hasBG = attrs & ATTR_BG\n let cellFG = fg\n let cellBG = bg\n let cellAttrs = attrs\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 // Remove blink attribute if it wouldn't have any effect\n if ((cellAttrs & MASK_BLINK) &&\n ((lastChar === ' ' && ((cellAttrs & MASK_LINE_ATTR) === 0)) || // no line styles\n (fg === bg && hasFG && hasBG) // invisible text\n )\n ) {\n cellAttrs ^= MASK_BLINK\n }\n\n // 8 dark system colors turn bright when bold\n if ((cellAttrs & ATTR_BOLD) && !(cellAttrs & ATTR_FAINT) && hasFG && cellFG < 8) {\n cellFG += 8\n }\n\n cells.push([lastChar, cellFG, cellBG, cellAttrs])\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 updates.push({\n topic: 'content',\n frameX,\n frameY,\n frameWidth,\n frameHeight,\n cells\n })\n }\n\n if (topics & 0x3B && !this.contentLoaded) {\n updates.push({ topic: 'full-load-complete' })\n this.contentLoaded = true\n }\n }\n\n return updates\n }\n\n /**\n * Parses a message from the server\n * @param {string} message - the message\n */\n parse (message) {\n const content = message.substr(1)\n const updates = []\n\n // This is a good place for debugging the message\n // console.log(message)\n\n switch (message[0]) {\n case 'U':\n updates.push(...this.parseUpdate(content))\n break\n\n case 'G':\n return [{\n topic: 'notification',\n content\n }]\n\n default:\n console.warn(`Bad data message type; ignoring.\\n${JSON.stringify(message)}`)\n }\n\n return updates\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/screen_parser.js","const EventEmitter = require('events')\nconst CanvasRenderer = require('./screen_renderer')\n\nconst DEFAULT_FONT = '\"DejaVu Sans Mono\", \"Liberation Mono\", \"Inconsolata\", \"Menlo\", monospace'\n\n/**\n * Manages terminal screen layout and sizing\n */\nmodule.exports = class ScreenLayout extends EventEmitter {\n constructor () {\n super()\n\n this.canvas = document.createElement('canvas')\n this.renderer = new CanvasRenderer(this.canvas)\n\n this._window = {\n width: 0,\n height: 0,\n devicePixelRatio: 1,\n fontFamily: DEFAULT_FONT,\n fontSize: 20,\n padding: 6,\n gridScaleX: 1.0,\n gridScaleY: 1.2,\n fitIntoWidth: 0,\n fitIntoHeight: 0,\n debug: false\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 this.charSize = { width: 0, height: 0 }\n\n const self = this\n\n // make writing to window update size and draw\n this.window = new Proxy(this._window, {\n set (target, key, value) {\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.on('update-window:debug', debug => { this.renderer.debug = debug })\n\n this.canvas.addEventListener('mousedown', e => this.emit('mousedown', e))\n this.canvas.addEventListener('mousemove', e => this.emit('mousemove', e))\n this.canvas.addEventListener('mouseup', e => this.emit('mouseup', e))\n this.canvas.addEventListener('touchstart', e => this.emit('touchstart', e))\n this.canvas.addEventListener('touchmove', e => this.emit('touchmove', e))\n this.canvas.addEventListener('touchend', e => this.emit('touchend', e))\n this.canvas.addEventListener('wheel', e => this.emit('wheel', e))\n this.canvas.addEventListener('contextmenu', e => this.emit('contextmenu', e))\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 get backgroundImage () {\n return this.canvas.style.backgroundImage\n }\n\n set backgroundImage (value) {\n this.canvas.style.backgroundImage = value ? `url(${value})` : ''\n if (this.renderer.backgroundImage !== !!value) {\n this.renderer.backgroundImage = !!value\n this.renderer.resetDrawn()\n this.renderer.scheduleDraw('background-image')\n }\n }\n\n get selectable () {\n return this.canvas.classList.contains('selectable')\n }\n\n set selectable (selectable) {\n if (selectable) this.canvas.classList.add('selectable')\n else this.canvas.classList.remove('selectable')\n }\n\n /**\n * Returns a CSS font string with the current font settings and the\n * specified 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 let fontFamily = this.window.fontFamily || ''\n if (fontFamily.length > 0) fontFamily += ','\n fontFamily += DEFAULT_FONT\n return `${fontStyle} normal ${fontWeight} ${this.window.fontSize}px ${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 y = Math.floor(y / cellSize.height)\n if (this.renderer.drawnScreenLines[y]) x /= 2 // double size\n x = Math.floor((x + (rounded ? cellSize.width / 2 : 0)) / cellSize.width)\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 if (this.renderer.drawnScreenLines[y]) x *= 2 // double size\n\n return [x * cellSize.width, y * cellSize.height].map(v => this._padding + (withScale ? v * this._windowScale : v))\n }\n\n /**\n * Update the character size, used for calculating the cell size.\n * The space character is used for measuring.\n * @returns {Object} the character size with `width` and `height` in pixels\n */\n updateCharSize () {\n this.charSize = {\n width: this.renderer.getCharWidthFor(this.getFont()),\n height: this.window.fontSize\n }\n\n return this.charSize\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 if (!this.charSize.height && this.window.fontSize) this.updateCharSize()\n\n return {\n width: Math.ceil(this.charSize.width * this.window.gridScaleX),\n height: Math.ceil(this.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\n this.updateCharSize()\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 this.renderer.render('update-size', this.serializeRenderData())\n\n this.emit('size-update')\n }\n }\n\n serializeRenderData () {\n return {\n padding: Math.round(this._padding),\n devicePixelRatio: this.window.devicePixelRatio,\n charSize: this.charSize,\n cellSize: this.getCellSize(),\n fonts: [\n this.getFont(),\n this.getFont({ weight: 'bold' }),\n this.getFont({ style: 'italic' }),\n this.getFont({ weight: 'bold', style: 'italic' })\n ]\n }\n }\n\n render (reason, data) {\n this.window.width = data.width\n this.window.height = data.height\n\n Object.assign(data, this.serializeRenderData())\n\n this.renderer.render(reason, data)\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/screen_layout.js","const EventEmitter = require('events')\nconst {\n themes,\n getColor\n} = require('./themes')\n\nconst {\n ATTR_FG,\n ATTR_BG,\n ATTR_BOLD,\n ATTR_UNDERLINE,\n ATTR_INVERSE,\n ATTR_BLINK,\n ATTR_ITALIC,\n ATTR_STRIKE,\n ATTR_OVERLINE,\n ATTR_FAINT,\n ATTR_FRAKTUR\n} = require('./screen_attr_bits')\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/**\n * A terminal screen renderer, using canvas 2D\n */\nmodule.exports = class CanvasRenderer extends EventEmitter {\n constructor (canvas) {\n super()\n\n this.canvas = canvas\n this.ctx = this.canvas.getContext('2d')\n\n this._palette = null // colors 0-15\n this.defaultBG = 0\n this.defaultFG = 7\n\n this.debug = false\n this._debug = null\n\n this.graphics = 0\n\n this.statusFont = \"-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif\"\n\n // screen data, considered immutable\n this.width = 0\n this.height = 0\n this.padding = 0\n this.charSize = { width: 0, height: 0 }\n this.cellSize = { width: 0, height: 0 }\n this.fonts = ['', '', '', ''] // normal, bold, italic, bold-italic\n this.screen = []\n this.screenFG = []\n this.screenBG = []\n this.screenAttrs = []\n this.screenSelection = []\n this.screenLines = []\n this.cursor = {}\n this.reverseVideo = false\n this.hasBlinkingCells = false\n this.statusScreen = null\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 render (reason, data) {\n if ('hasBlinkingCells' in data && data.hasBlinkingCells !== this.hasBlinkingCells) {\n if (data.hasBlinkingCells) this.resetBlink()\n else clearInterval(this.blinkInterval)\n }\n\n Object.assign(this, data)\n this.scheduleDraw(reason)\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.debug) console.log('Resetting drawn screen')\n\n this.drawnScreen = []\n this.drawnScreenFG = []\n this.drawnScreenBG = []\n this.drawnScreenAttrs = []\n this.drawnScreenLines = []\n this.drawnCursor = [-1, -1, '', false]\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.emit('palette-update', palette)\n this.scheduleDraw('palette')\n }\n }\n\n getCharWidthFor (font) {\n this.ctx.font = font\n return Math.floor(this.ctx.measureText(' ').width)\n }\n\n loadTheme (i) {\n if (i in themes) this.palette = themes[i]\n }\n\n setDefaultColors (fg, bg) {\n if (fg !== this.defaultFG || bg !== this.defaultBG) {\n this.resetDrawn()\n this.defaultFG = fg\n this.defaultBG = bg\n this.scheduleDraw('default-colors')\n\n // full bg with default color (goes behind the image)\n this.canvas.style.backgroundColor = this.getColor(bg)\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 getColor(i, this.palette)\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.cursor.blinking ? !this.cursorBlinkOn : true\n if (this.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.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 * @param {number} options.isDefaultBG - if true, will draw image background if available\n */\n drawBackground ({ x, y, cellWidth, cellHeight, bg, isDefaultBG }) {\n const { ctx, width, height, padding } = this\n\n // is a double-width/double-height line\n if (this.screenLines[y] & 0b001) cellWidth *= 2\n\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\n let fillX, fillY, fillWidth, fillHeight\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\n fillX = left\n fillY = top\n fillWidth = right - left\n fillHeight = bottom - top\n } else {\n fillX = screenX\n fillY = screenY\n fillWidth = cellWidth\n fillHeight = cellHeight\n }\n\n ctx.clearRect(fillX, fillY, fillWidth, fillHeight)\n\n if (!isDefaultBG || bg < 0 || !this.backgroundImage) {\n ctx.fillRect(fillX, fillY, fillWidth, fillHeight)\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, padding } = this\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 = CanvasRenderer.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 const dblWidth = this.screenLines[y] & 0b001\n const dblHeightTop = this.screenLines[y] & 0b010\n const dblHeightBot = this.screenLines[y] & 0b100\n\n if (this.screenLines[y]) {\n // is a double-width/double-height line\n if (dblWidth) cellWidth *= 2\n\n ctx.save()\n ctx.translate(padding, screenY + 0.5 * cellHeight)\n if (dblWidth) ctx.scale(2, 1)\n if (dblHeightTop) {\n // top half\n ctx.scale(1, 2)\n ctx.translate(0, cellHeight / 4)\n } else if (dblHeightBot) {\n // bottom half\n ctx.scale(1, 2)\n ctx.translate(0, -cellHeight / 4)\n }\n ctx.translate(-padding, -screenY - 0.5 * cellHeight)\n if (dblWidth) ctx.translate(-cellWidth / 4, 0)\n\n if (dblHeightBot || dblHeightTop) {\n // characters overflow -- needs clipping\n // TODO: clipping is really expensive\n ctx.beginPath()\n if (dblHeightTop) ctx.rect(screenX, screenY, cellWidth, cellHeight / 2)\n else ctx.rect(screenX, screenY + cellHeight / 2, cellWidth, cellHeight / 2)\n ctx.clip()\n }\n }\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 if (this.screenLines[y]) ctx.restore()\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\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\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.charSize\n const { width: cellWidth, height: cellHeight } = this.cellSize\n const screenLength = width * height\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0)\n\n if (this.debug && this._debug) this._debug.drawStart(why)\n\n ctx.font = this.fonts[0]\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.cursor.x === x &&\n this.cursor.y === y &&\n this.cursor.visible\n\n let wasCursor = x === this.drawnCursor[0] && y === this.drawnCursor[1]\n\n let text = this.screen[cell]\n let fg = this.screenFG[cell] | 0\n let bg = this.screenBG[cell] | 0\n let attrs = this.screenAttrs[cell] | 0\n let inSelection = this.screenSelection[cell]\n\n let isDefaultBG = false\n\n if (!(attrs & ATTR_FG)) fg = this.defaultFG\n if (!(attrs & ATTR_BG)) {\n bg = this.defaultBG\n isDefaultBG = true\n }\n\n if (attrs & ATTR_INVERSE) [fg, bg] = [bg, fg] // swap - reversed character colors\n if (this.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 only draws decoration\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 this.screenLines[y] !== this.drawnScreenLines[y] || // line updated\n // TODO: fix artifacts or keep this hack:\n isCursor || wasCursor || // cursor blink/position updated\n (isCursor && this.cursor.style !== this.drawnCursor[2]) || // cursor style updated\n (isCursor && this.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, isDefaultBG })\n updateMap.set(cell, didUpdate)\n }\n\n // set drawn screen lines\n this.drawnScreenLines = this.screenLines.slice()\n\n let debugFilledUpdates = []\n\n if (this.graphics >= 1) {\n // fancy graphics gets really slow when there's a lot of masks\n // so here's an algorithm that fills in holes in the update map\n\n for (let cell of updateMap.keys()) {\n if (updateMap.get(cell)) continue\n let previous = updateMap.get(cell - 1) || false\n let next = updateMap.get(cell + 1) || false\n\n if (previous && next) {\n // set cell to true of horizontally adjacent updated\n updateMap.set(cell, true)\n if (this.debug && this._debug) debugFilledUpdates.push(cell)\n }\n }\n }\n\n // Map of (cell index) -> boolean, whether or not a cell should be redrawn\n const redrawMap = new Map()\n const maskedCells = 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 for (let cell of updateMap.keys()) {\n let shouldUpdate = updateMap.get(cell) || redrawMap.get(cell) || false\n\n // TODO: fonts (necessary?)\n let text = this.screen[cell]\n let isWideCell = isTextWide(text)\n let checkRadius = isWideCell ? 2 : 1\n\n if (!shouldUpdate) {\n // check adjacent cells\n let adjacentDidUpdate = false\n\n for (let adjacentCell of this.getAdjacentCells(cell, checkRadius)) {\n // 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 // - this or the adjacent cell is not double-sized\n if (updateMap.get(adjacentCell) &&\n (this.graphics < 2 || isWideCell || isTextWide(this.screen[adjacentCell])) &&\n (!this.screenLines[Math.floor(cell / this.width)] && !this.screenLines[Math.floor(adjacentCell / this.width)])) {\n adjacentDidUpdate = true\n\n if (this.getAdjacentCells(cell, 1).includes(adjacentCell)) {\n // this is within a radius of 1, therefore this cell should be included in the mask as well\n maskedCells.set(cell, true)\n }\n break\n }\n }\n\n if (adjacentDidUpdate) shouldUpdate = true\n }\n\n if (updateMap.get(cell)) {\n // this was updated, it should definitely be included in the mask\n maskedCells.set(cell, true)\n }\n\n redrawMap.set(cell, shouldUpdate)\n }\n\n // mask to masked regions only\n if (this.graphics >= 1) {\n // TODO: include padding in border cells\n const padding = this.padding\n\n let regions = []\n\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 masked = maskedCells.get(cell)\n if (masked && regionStart === null) regionStart = x\n if (!masked && regionStart !== null) {\n regions.push([regionStart, y, x, y + 1])\n regionStart = null\n }\n }\n if (regionStart !== null) {\n regions.push([regionStart, y, width, y + 1])\n }\n }\n\n // join regions if possible (O(n^2-1), sorry)\n let i = 0\n while (i < regions.length) {\n let region = regions[i]\n let j = 0\n while (j < regions.length) {\n let other = regions[j]\n if (other === region) {\n j++\n continue\n }\n if (other[0] === region[0] && other[2] === region[2] && other[3] === region[1]) {\n region[1] = other[1]\n regions.splice(j, 1)\n if (i > j) i--\n j--\n }\n j++\n }\n i++\n }\n\n ctx.save()\n ctx.beginPath()\n for (let region of regions) {\n let [regionStart, y, endX, endY] = region\n let rectX = padding + regionStart * cellWidth\n let rectY = padding + y * cellHeight\n let rectWidth = (endX - regionStart) * cellWidth\n let rectHeight = (endY - y) * cellHeight\n\n // compensate for padding\n if (regionStart === 0) {\n rectX -= padding\n rectWidth += padding\n }\n if (y === 0) {\n rectY -= padding\n rectHeight += padding\n }\n if (endX === width - 1) rectWidth += padding\n if (y === height - 1) rectHeight += padding\n\n ctx.rect(rectX, rectY, rectWidth, rectHeight)\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, isDefaultBG } = data\n\n if (redrawMap.get(cell)) {\n this.drawBackground({ x, y, cellWidth, cellHeight, bg, isDefaultBG })\n\n if (this.debug) {\n // set cell flags\n let flags = (+redrawMap.get(cell))\n flags |= (+updateMap.get(cell)) << 1\n flags |= (+maskedCells.get(cell)) << 2\n flags |= (+isTextWide(text)) << 3\n flags |= (+debugFilledUpdates.includes(cell)) << 4\n this._debug.setCell(cell, flags)\n }\n }\n }\n }\n\n // reset drawn cursor\n this.drawnCursor = [-1, -1, '', false]\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 fontIndex = 0\n if (font & ATTR_BOLD) fontIndex |= 1\n if (font & ATTR_ITALIC) fontIndex |= 2\n ctx.font = this.fonts[fontIndex]\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.cursor.style, this.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 let cursorWidth = cellWidth // JS doesn't allow same-name assignment\n\n if (this.cursor.hanging) {\n // draw hanging cursor in the margin\n cursorX += 1\n }\n\n // double-width lines\n if (this.screenLines[cursorY] & 0b001) cursorWidth *= 2\n\n let screenX = cursorX * cursorWidth + this.padding\n let screenY = cursorY * cellHeight + this.padding\n\n if (this.cursor.style === 'block') {\n // block\n ctx.rect(screenX, screenY, cursorWidth, cellHeight)\n } else if (this.cursor.style === 'bar') {\n // vertical bar\n let barWidth = 2\n ctx.rect(screenX, screenY, barWidth, cellHeight)\n } else if (this.cursor.style === 'line') {\n // underline\n let lineHeight = 2\n ctx.rect(screenX, screenY + charSize.height, cursorWidth, 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.graphics >= 1) ctx.restore()\n\n if (this.debug && this._debug) this._debug.drawEnd()\n\n this.emit('draw', why)\n }\n\n drawStatus (statusScreen) {\n const { ctx, width, height, devicePixelRatio } = this\n\n // reset drawnScreen to force redraw when statusScreen is disabled\n this.drawnScreen = []\n\n const cellSize = this.cellSize\n const screenWidth = width * cellSize.width + 2 * this.padding\n const screenHeight = height * cellSize.height + 2 * this.padding\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0)\n ctx.fillStyle = this.getColor(this.defaultBG)\n ctx.fillRect(0, 0, screenWidth, screenHeight)\n\n ctx.font = `24px ${this.statusFont}`\n ctx.fillStyle = this.getColor(this.defaultFG)\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.defaultFG)\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\nconst HTTPS = window.location.protocol.match(/s:/)\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 this.queue = []\n\n try {\n this.blobReader = new window.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 // 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 this.flushQueue()\n }, 250)\n break\n\n case '+':\n // console.log('xon');\n this.xoff = false\n this.flushQueue()\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 console.log(\"Can't send, flood control. Queueing\")\n this.queue.push(message)\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 flushQueue () {\n console.log('Flushing input queue')\n for (let message of this.queue) this.send(message)\n this.queue = []\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(`${HTTPS ? 'wss' : '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 this.emit('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(`${HTTPS ? 'https' : '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 { encode2B } = require('../utils')\n\n/**\n * User input\n *\n * --- Rx messages: ---\n * S - screen content (binary encoding of the entire screen with simple compression)\n * T - text labels - Title and buttons, \\0x01-separated\n * B - beep\n * . - heartbeat\n *\n * --- Tx messages ---\n * s - string\n * b - action button\n * p - mb press\n * r - mb release\n * m - mouse move\n */\nmodule.exports = function (conn, screen) {\n // handle for input object\n let input\n\n const KEY_NAMES = {\n 0x03: 'Cancel',\n 0x06: 'Help',\n 0x08: 'Backspace',\n 0x09: 'Tab',\n 0x0C: 'Clear',\n 0x0D: 'Enter',\n 0x10: 'Shift',\n 0x11: 'Control',\n 0x12: 'Alt',\n 0x13: 'Pause',\n 0x14: 'CapsLock',\n 0x1B: 'Escape',\n 0x20: ' ',\n 0x21: 'PageUp',\n 0x22: 'PageDown',\n 0x23: 'End',\n 0x24: 'Home',\n 0x25: 'ArrowLeft',\n 0x26: 'ArrowUp',\n 0x27: 'ArrowRight',\n 0x28: 'ArrowDown',\n 0x29: 'Select',\n 0x2A: 'Print',\n 0x2B: 'Execute',\n 0x2C: 'PrintScreen',\n 0x2D: 'Insert',\n 0x2E: 'Delete',\n 0x3A: ':',\n 0x3B: ';',\n 0x3C: '<',\n 0x3D: '=',\n 0x3E: '>',\n 0x3F: '?',\n 0x40: '@',\n 0x5B: 'Meta',\n 0x5C: 'Meta',\n 0x5D: 'ContextMenu',\n 0x6A: 'Numpad*',\n 0x6B: 'Numpad+',\n 0x6D: 'Numpad-',\n 0x6E: 'Numpad.',\n 0x6F: 'Numpad/',\n 0x90: 'NumLock',\n 0x91: 'ScrollLock',\n 0xA0: '^',\n 0xA1: '!',\n 0xA2: '\"',\n 0xA3: '#',\n 0xA4: '$',\n 0xA5: '%',\n 0xA6: '&',\n 0xA7: '_',\n 0xA8: '(',\n 0xA9: ')',\n 0xAA: '*',\n 0xAB: '+',\n 0xAC: '|',\n 0xAD: '-',\n 0xAE: '{',\n 0xAF: '}',\n 0xB0: '~',\n 0xBA: ';',\n 0xBB: '=',\n 0xBC: 'Numpad,',\n 0xBD: '-',\n 0xBE: 'Numpad,',\n 0xC0: '`',\n 0xC2: 'Numpad,',\n 0xDB: '[',\n 0xDC: '\\\\',\n 0xDD: ']',\n 0xDE: \"'\",\n 0xE0: 'Meta'\n }\n // numbers 0-9\n for (let i = 0x30; i <= 0x39; i++) KEY_NAMES[i] = String.fromCharCode(i)\n // characters A-Z\n for (let i = 0x41; i <= 0x5A; i++) KEY_NAMES[i] = String.fromCharCode(i)\n // function F1-F20\n for (let i = 0x70; i <= 0x83; i++) KEY_NAMES[i] = `F${i - 0x70 + 1}`\n // numpad 0-9\n for (let i = 0x60; i <= 0x69; i++) KEY_NAMES[i] = `Numpad${i - 0x60}`\n\n let cfg = {\n np_alt: false, // Application Numpad Mode\n cu_alt: false, // Application Cursors Mode\n fn_alt: false, // SS3 function keys mode\n mt_click: false, // Mouse click tracking\n mt_move: false, // Mouse move tracking\n no_keys: false, // Suppress any key / clipboard event intercepting\n crlf_mode: false, // Enter sends CR LF\n all_fn: false // Capture also F5, F11 and F12\n }\n\n /** Fn alt choice for key message */\n const fa = (alt, normal) => cfg.fn_alt ? alt : normal\n\n /** Cursor alt choice for key message */\n const ca = (alt, normal) => cfg.cu_alt ? alt : normal\n\n /** Numpad alt choice for key message */\n const na = (alt, normal) => cfg.np_alt ? alt : normal\n\n const keymap = {\n /* eslint-disable key-spacing */\n 'Backspace': '\\x08',\n 'Tab': '\\x09',\n 'Enter': () => cfg.crlf_mode ? '\\x0d\\x0a' : '\\x0d',\n 'Control+Enter': '\\x0a',\n 'Escape': '\\x1b',\n 'ArrowUp': () => ca('\\x1bOA', '\\x1b[A'),\n 'ArrowDown': () => ca('\\x1bOB', '\\x1b[B'),\n 'ArrowRight': () => ca('\\x1bOC', '\\x1b[C'),\n 'ArrowLeft': () => ca('\\x1bOD', '\\x1b[D'),\n 'Home': () => ca('\\x1bOH', fa('\\x1b[H', '\\x1b[1~')),\n 'Insert': '\\x1b[2~',\n 'Delete': '\\x1b[3~',\n 'End': () => ca('\\x1bOF', fa('\\x1b[F', '\\x1b[4~')),\n 'PageUp': '\\x1b[5~',\n 'PageDown': '\\x1b[6~',\n 'F1': () => fa('\\x1bOP', '\\x1b[11~'),\n 'F2': () => fa('\\x1bOQ', '\\x1b[12~'),\n 'F3': () => fa('\\x1bOR', '\\x1b[13~'),\n 'F4': () => fa('\\x1bOS', '\\x1b[14~'),\n 'F5': '\\x1b[15~', // note the disconnect\n 'F6': '\\x1b[17~',\n 'F7': '\\x1b[18~',\n 'F8': '\\x1b[19~',\n 'F9': '\\x1b[20~',\n 'F10': '\\x1b[21~', // note the disconnect\n 'F11': '\\x1b[23~',\n 'F12': '\\x1b[24~',\n 'Shift+F1': () => fa('\\x1bO1;2P', '\\x1b[25~'),\n 'Shift+F2': () => fa('\\x1bO1;2Q', '\\x1b[26~'), // note the disconnect\n 'Shift+F3': () => fa('\\x1bO1;2R', '\\x1b[28~'),\n 'Shift+F4': () => fa('\\x1bO1;2S', '\\x1b[29~'), // note the disconnect\n 'Shift+F5': () => fa('\\x1b[15;2~', '\\x1b[31~'),\n 'Shift+F6': () => fa('\\x1b[17;2~', '\\x1b[32~'),\n 'Shift+F7': () => fa('\\x1b[18;2~', '\\x1b[33~'),\n 'Shift+F8': () => fa('\\x1b[19;2~', '\\x1b[34~'),\n 'Shift+F9': () => fa('\\x1b[20;2~', '\\x1b[35~'), // 35-38 are not standard - but what is?\n 'Shift+F10': () => fa('\\x1b[21;2~', '\\x1b[36~'),\n 'Shift+F11': () => fa('\\x1b[22;2~', '\\x1b[37~'),\n 'Shift+F12': () => fa('\\x1b[23;2~', '\\x1b[38~'),\n 'Numpad0': () => na('\\x1bOp', '0'),\n 'Numpad1': () => na('\\x1bOq', '1'),\n 'Numpad2': () => na('\\x1bOr', '2'),\n 'Numpad3': () => na('\\x1bOs', '3'),\n 'Numpad4': () => na('\\x1bOt', '4'),\n 'Numpad5': () => na('\\x1bOu', '5'),\n 'Numpad6': () => na('\\x1bOv', '6'),\n 'Numpad7': () => na('\\x1bOw', '7'),\n 'Numpad8': () => na('\\x1bOx', '8'),\n 'Numpad9': () => na('\\x1bOy', '9'),\n 'Numpad*': () => na('\\x1bOR', '*'),\n 'Numpad+': () => na('\\x1bOl', '+'),\n 'Numpad-': () => na('\\x1bOS', '-'),\n 'Numpad.': () => na('\\x1bOn', '.'),\n 'Numpad/': () => na('\\x1bOQ', '/'),\n // we don't implement numlock key (should change in numpad_alt mode,\n // but it's even more useless than the rest and also has the side\n // effect of changing the user's numlock state)\n\n // shortcuts\n 'Control+]': '\\x1b', // alternate way to enter ESC\n 'Control+\\\\': '\\x1c',\n 'Control+[': '\\x1d',\n 'Control+^': '\\x1e',\n 'Control+_': '\\x1f',\n\n // extra controls\n 'Control+ArrowLeft': '\\x1f[1;5D',\n 'Control+ArrowRight': '\\x1f[1;5C',\n 'Control+ArrowUp': '\\x1f[1;5A',\n 'Control+ArrowDown': '\\x1f[1;5B',\n 'Control+Home': '\\x1f[1;5H',\n 'Control+End': '\\x1f[1;5F',\n\n // extra shift controls\n 'Shift+ArrowLeft': '\\x1f[1;2D',\n 'Shift+ArrowRight': '\\x1f[1;2C',\n 'Shift+ArrowUp': '\\x1f[1;2A',\n 'Shift+ArrowDown': '\\x1f[1;2B',\n 'Shift+Home': '\\x1f[1;2H',\n 'Shift+End': '\\x1f[1;2F',\n\n // macOS text editing commands\n 'Alt+ArrowLeft': '\\x1bb', // ⌥← to go back a word (^[b)\n 'Alt+ArrowRight': '\\x1bf', // ⌥→ to go forward one word (^[f)\n 'Meta+ArrowLeft': '\\x01', // ⌘← to go to the beginning of a line (^A)\n 'Meta+ArrowRight': '\\x05', // ⌘→ to go to the end of a line (^E)\n 'Alt+Backspace': '\\x17', // ⌥⌫ to delete a word (^W)\n 'Meta+Backspace': '\\x15', // ⌘⌫ to delete to the beginning of a line (^U)\n\n // copy to clipboard\n 'Control+Shift+C' () {\n screen.copySelectionToClipboard()\n },\n 'Control+Insert' () {\n screen.copySelectionToClipboard()\n },\n\n // toggle debug mode\n 'Control+F12' () {\n screen.window.debug ^= 1\n }\n /* eslint-enable key-spacing */\n }\n\n // ctrl+[A-Z] sent as simple low ASCII codes\n for (let i = 1; i <= 26; i++) {\n keymap[`Control+${String.fromCharCode(0x40 + i)}`] = String.fromCharCode(i)\n }\n\n /** Send a literal message */\n function sendString (str) {\n return conn.send('s' + str)\n }\n\n /** Send a button event */\n function sendButton (index) {\n conn.send('b' + String.fromCharCode(index + 1))\n }\n\n const shouldAcceptEvent = function () {\n if (cfg.no_keys) return false\n if (document.activeElement instanceof window.HTMLTextAreaElement) return false\n return true\n }\n\n const keyBlacklist = [\n 'F5', 'F11', 'F12', 'Shift+F5'\n ]\n\n let softModifiers = {\n alt: false,\n ctrl: false,\n meta: false,\n shift: false\n }\n\n const handleKeyDown = function (e) {\n if (!shouldAcceptEvent()) return\n\n let modifiers = []\n // sorted alphabetically\n if (e.altKey || softModifiers.alt) modifiers.push('Alt')\n if (e.ctrlKey || softModifiers.ctrl) modifiers.push('Control')\n if (e.metaKey || softModifiers.meta) modifiers.push('Meta')\n if (e.shiftKey || softModifiers.shift) modifiers.push('Shift')\n\n let key = KEY_NAMES[e.which] || e.key\n\n // ignore clipboard events\n if ((e.ctrlKey || e.metaKey) && key === 'V') return\n\n let binding = null\n\n for (let name in keymap) {\n let itemModifiers = name.split('+')\n let itemKey = itemModifiers.pop()\n\n if (itemKey === key && itemModifiers.sort().join() === modifiers.join()) {\n if (keyBlacklist.includes(name) && !cfg.all_fn) continue\n binding = keymap[name]\n break\n }\n }\n\n if (binding) {\n if (binding instanceof Function) binding = binding()\n e.preventDefault()\n if (typeof binding === 'string') {\n sendString(binding)\n }\n }\n }\n\n /** Bind/rebind key messages */\n function initKeys ({ allFn }) {\n // This takes care of text characters typed\n window.addEventListener('keypress', function (evt) {\n if (!shouldAcceptEvent()) return\n if (evt.ctrlKey || evt.metaKey) return\n\n let str = ''\n if (evt.key && evt.key.length === 1) str = evt.key\n else if (evt.which && evt.which !== 229) str = String.fromCodePoint(evt.which)\n\n if (str.length > 0 && str.charCodeAt(0) >= 32) {\n // prevent space from scrolling\n if (evt.which === 32) evt.preventDefault()\n sendString(str)\n }\n })\n\n window.addEventListener('keydown', handleKeyDown)\n window.addEventListener('copy', e => {\n if (!shouldAcceptEvent()) return\n let selectedText = screen.getSelectedText()\n if (selectedText) {\n e.preventDefault()\n e.clipboardData.setData('text/plain', selectedText)\n }\n })\n window.addEventListener('paste', e => {\n if (!shouldAcceptEvent()) return\n e.preventDefault()\n let string = e.clipboardData.getData('text/plain')\n if (string.includes('\\n') || string.length > 90) {\n if (!input.termUpload) console.error('input.termUpload is undefined')\n input.termUpload.setContent(string)\n input.termUpload.open()\n } else {\n // simple string, just paste it\n if (screen.bracketedPaste) string = `\\x1b[200~${string}\\x1b[201~`\n sendString(string)\n }\n })\n\n cfg.all_fn = allFn\n }\n\n // mouse button states\n let mb1 = 0\n let mb2 = 0\n let mb3 = 0\n\n /** Init the Input module */\n function init (opts) {\n initKeys(opts)\n\n // global mouse state tracking - for motion reporting\n window.addEventListener('mousedown', evt => {\n if (evt.button === 0) mb1 = 1\n if (evt.button === 1) mb2 = 1\n if (evt.button === 2) mb3 = 1\n })\n\n window.addEventListener('mouseup', evt => {\n if (evt.button === 0) mb1 = 0\n if (evt.button === 1) mb2 = 0\n if (evt.button === 2) mb3 = 0\n })\n }\n\n // record modifier keys\n // bits: Meta, Alt, Shift, Ctrl\n let modifiers = 0b0000\n\n window.addEventListener('keydown', e => {\n if (e.ctrlKey) modifiers |= 1\n if (e.shiftKey) modifiers |= 2\n if (e.altKey) modifiers |= 4\n if (e.metaKey) modifiers |= 8\n })\n window.addEventListener('keyup', e => {\n modifiers = 0\n if (e.ctrlKey) modifiers |= 1\n if (e.shiftKey) modifiers |= 2\n if (e.altKey) modifiers |= 4\n if (e.metaKey) modifiers |= 8\n })\n\n /** Prepare modifiers byte for mouse message */\n function packModifiersForMouse () {\n return modifiers\n }\n\n input = {\n /** Init the Input module */\n init,\n\n /** Send a literal string message */\n sendString,\n sendButton,\n\n /** Enable alternate key modes (cursors, numpad, fn) */\n setAlts: function (cu, np, fn, crlf) {\n if (cfg.cu_alt !== cu || cfg.np_alt !== np || cfg.fn_alt !== fn || cfg.crlf_mode !== crlf) {\n cfg.cu_alt = cu\n cfg.np_alt = np\n cfg.fn_alt = fn\n cfg.crlf_mode = crlf\n }\n },\n\n setMouseMode (click, move) {\n cfg.mt_click = click\n cfg.mt_move = move\n },\n\n // Mouse events\n onMouseMove (x, y) {\n if (!cfg.mt_move) return\n const b = mb1 ? 1 : mb2 ? 2 : mb3 ? 3 : 0\n const m = packModifiersForMouse()\n conn.send('m' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n },\n\n onMouseDown (x, y, b) {\n if (!cfg.mt_click) return\n if (b > 3 || b < 1) return\n const m = packModifiersForMouse()\n conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n },\n\n onMouseUp (x, y, b) {\n if (!cfg.mt_click) return\n if (b > 3 || b < 1) return\n const m = packModifiersForMouse()\n conn.send('r' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n // console.log(\"B \",b,\" M \",m);\n },\n\n onMouseWheel (x, y, dir) {\n if (!cfg.mt_click) return\n // -1 ... btn 4 (away from user)\n // +1 ... btn 5 (towards user)\n const m = packModifiersForMouse()\n const b = (dir < 0 ? 4 : 5)\n conn.send('p' + encode2B(y) + encode2B(x) + encode2B(b) + encode2B(m))\n // console.log(\"B \",b,\" M \",m);\n },\n\n /**\n * Prevent capturing keys. This is used for text input\n * modals on the terminal screen\n */\n blockKeys (yes) {\n cfg.no_keys = yes\n },\n\n handleKeyDown,\n softModifiers\n }\n return input\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/input.js","const $ = require('../lib/chibi')\nconst { qs } = require('../utils')\nconst modal = require('../modal')\n\n/** File upload utility */\nmodule.exports = function (conn, input, screen) {\n let lines, // array of lines without newlines\n line_i, // current line index\n fuTout, // timeout handle for line sending\n send_delay_ms, // delay between lines (ms)\n nl_str, // newline string to use\n curLine, // current line (when using fuOil)\n inline_pos // Offset in line (for long lines)\n\n // lines longer than this are split to chunks\n // sending a super-ling string through the socket is not a good idea\n const MAX_LINE_LEN = 128\n\n function openUploadDialog () {\n updateStatus('Ready...')\n modal.show('#fu_modal', onDialogClose)\n $('#fu_form').toggleClass('busy', false)\n input.blockKeys(true)\n }\n\n function onDialogClose () {\n console.log('Upload modal closed.')\n clearTimeout(fuTout)\n line_i = 0\n input.blockKeys(false)\n }\n\n function updateStatus (msg) {\n qs('#fu_prog').textContent = msg\n }\n\n function startUpload () {\n let v = qs('#fu_text').value\n if (!v.length) {\n fuClose()\n return\n }\n\n lines = v.split('\\n')\n line_i = 0\n inline_pos = 0 // offset in line\n send_delay_ms = +qs('#fu_delay').value\n\n // sanitize - 0 causes overflows\n if (send_delay_ms < 0) {\n send_delay_ms = 0\n qs('#fu_delay').value = send_delay_ms\n }\n\n nl_str = {\n 'CR': '\\r',\n 'LF': '\\n',\n 'CRLF': '\\r\\n'\n }[qs('#fu_crlf').value]\n\n $('#fu_form').toggleClass('busy', true)\n updateStatus('Starting...')\n uploadLine()\n }\n\n function uploadLine () {\n if (!$('#fu_modal').hasClass('visible')) {\n // Modal is closed, cancel\n return\n }\n\n if (!conn.canSend()) {\n // postpone\n fuTout = setTimeout(uploadLine, 1)\n return\n }\n\n if (inline_pos === 0) {\n curLine = ''\n if (line_i === 0) {\n if (screen.bracketedPaste) {\n curLine = '\\x1b[200~'\n }\n }\n\n curLine += lines[line_i++] + nl_str\n\n if (line_i === lines.length) {\n if (screen.bracketedPaste) {\n curLine += '\\x1b[201~'\n }\n }\n }\n\n let maxChunk = +qs('#fu_chunk').value\n if (maxChunk === 0 || maxChunk > MAX_LINE_LEN) {\n maxChunk = MAX_LINE_LEN\n }\n\n let chunk\n if ((curLine.length - inline_pos) <= maxChunk) {\n chunk = curLine.substr(inline_pos, maxChunk)\n inline_pos = 0\n } else {\n chunk = curLine.substr(inline_pos, maxChunk)\n inline_pos += maxChunk\n }\n\n if (!input.sendString(chunk)) {\n updateStatus('FAILED!')\n return\n }\n\n let pt = Math.round((line_i / lines.length) * 1000) / 10\n updateStatus(`${line_i} / ${lines.length} (${pt}%)`)\n\n if (lines.length > line_i || inline_pos > 0) {\n fuTout = setTimeout(uploadLine, send_delay_ms)\n } else {\n closeWhenReady()\n }\n }\n\n function closeWhenReady () {\n if (!conn.canSend()) {\n // stuck in XOFF still, wait to process...\n updateStatus('Waiting for Tx buffer...')\n setTimeout(closeWhenReady, 100)\n } else {\n updateStatus('Done.')\n // delay to show it\n fuClose()\n }\n }\n\n function fuClose () {\n modal.hide('#fu_modal')\n }\n\n return {\n init: function () {\n qs('#fu_file').addEventListener('change', function (evt) {\n let reader = new window.FileReader()\n let file = evt.target.files[0]\n let ftype = file.type || 'application/octet-stream'\n console.log('Selected file type: ' + ftype)\n if (!ftype.match(/text\\/.*|application\\/(json|csv|.*xml.*|.*script.*|x-php)/)) {\n // Deny load of blobs like img - can crash browser and will get corrupted anyway\n if (!window.confirm(`This does not look like a text file: ${ftype}\\nReally load?`)) {\n qs('#fu_file').value = ''\n return\n }\n }\n reader.onload = function (e) {\n const txt = e.target.result.replace(/[\\r\\n]+/, '\\n')\n qs('#fu_text').value = txt\n }\n console.log('Loading file...')\n reader.readAsText(file)\n }, false)\n\n qs('#term-fu-open').addEventListener('click', e => {\n e.preventDefault()\n openUploadDialog()\n })\n\n qs('#term-fu-start').addEventListener('click', e => {\n e.preventDefault()\n startUpload()\n })\n\n qs('#term-fu-close').addEventListener('click', e => {\n e.preventDefault()\n fuClose()\n })\n },\n open: openUploadDialog,\n setContent (content) {\n qs('#fu_text').value = content\n }\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/upload.js","const { qs } = require('../utils')\n\nmodule.exports = function (screen, input) {\n const keyInput = qs('#softkb-input')\n if (!keyInput) return // abort, we're not on the terminal page\n\n const shortcutBar = document.createElement('div')\n shortcutBar.id = 'keyboard-shortcut-bar'\n if (navigator.userAgent.match(/iPad|iPhone|iPod/)) {\n qs('#screen').appendChild(shortcutBar)\n }\n\n let keyboardOpen = false\n\n // moves the input to where the cursor is on the canvas.\n // this is because most browsers will always scroll to wherever the focused\n // input is\n let updateInputPosition = function () {\n if (!keyboardOpen) return\n\n let [x, y] = screen.layout.gridToScreen(screen.cursor.x, screen.cursor.y, true)\n keyInput.style.transform = `translate(${x}px, ${y}px)`\n }\n\n keyInput.addEventListener('focus', () => {\n keyboardOpen = true\n updateInputPosition()\n shortcutBar.classList.add('open')\n })\n\n keyInput.addEventListener('blur', () => {\n keyboardOpen = false\n shortcutBar.classList.remove('open')\n })\n\n screen.on('cursor-moved', updateInputPosition)\n\n qs('#term-kb-open').addEventListener('click', e => {\n e.preventDefault()\n keyInput.focus()\n })\n\n // Chrome for Android doesn't send proper keydown/keypress events with\n // real key values instead of 229 “Unidentified,” so here's a workaround\n // that deals with the input composition events.\n\n let lastCompositionString = ''\n\n // sends the difference between the last and the new composition string\n let sendInputDelta = function (newValue) {\n if (newValue === null) newValue = '' // this sometimes happens, why?\n let resend = false\n if (newValue.length > lastCompositionString.length) {\n if (newValue.startsWith(lastCompositionString)) {\n // characters have been added at the end\n input.sendString(newValue.substr(lastCompositionString.length))\n } else resend = true\n } else if (newValue.length < lastCompositionString.length) {\n if (lastCompositionString.startsWith(newValue)) {\n // characters have been removed at the end\n input.sendString('\\b'.repeat(lastCompositionString.length -\n newValue.length))\n } else resend = true\n } else if (newValue !== lastCompositionString) resend = true\n\n if (resend) {\n // the entire string changed; resend everything\n input.sendString('\\b'.repeat(lastCompositionString.length) +\n newValue)\n }\n lastCompositionString = newValue\n }\n\n keyInput.addEventListener('keydown', e => {\n if (e.key === 'Unidentified') return\n\n keyInput.value = ''\n\n e.stopPropagation()\n input.handleKeyDown(e)\n })\n\n keyInput.addEventListener('keypress', e => {\n // prevent key duplication on iOS (because Safari *does* send proper events)\n e.stopPropagation()\n })\n\n keyInput.addEventListener('input', e => {\n e.stopPropagation()\n\n if (e.isComposing && 'data' in e) {\n sendInputDelta(e.data)\n } else if (e.isComposing) {\n // Firefox Mobile doesn't support InputEvent#data, so here's a hack\n // that just takes the input value and uses that\n sendInputDelta(keyInput.value)\n } else {\n if (e.inputType === 'insertCompositionText') input.sendString(e.data)\n else if (e.inputType === 'deleteContentBackward') {\n lastCompositionString = ''\n sendInputDelta('')\n } else if (e.inputType === 'insertText') {\n input.sendString(e.data)\n }\n }\n })\n\n keyInput.addEventListener('compositionstart', e => {\n lastCompositionString = ''\n })\n\n keyInput.addEventListener('compositionend', e => {\n lastCompositionString = ''\n keyInput.value = ''\n })\n\n screen.on('open-soft-keyboard', () => keyInput.focus())\n\n // shortcut bar\n const shortcuts = {\n Control: 'ctrl',\n Esc: 0x1b,\n Tab: 0x09,\n '←': 0x25,\n '↓': 0x28,\n '↑': 0x26,\n '→': 0x27\n }\n\n let touchMoved = false\n\n for (const shortcut in shortcuts) {\n const button = document.createElement('button')\n button.classList.add('shortcut-button')\n button.textContent = shortcut\n shortcutBar.appendChild(button)\n\n const key = shortcuts[shortcut]\n if (typeof key === 'string') button.classList.add('modifier')\n button.addEventListener('touchstart', e => {\n touchMoved = false\n if (typeof key === 'string') {\n // modifier button\n input.softModifiers[key] = true\n button.classList.add('enabled')\n\n // prevent default. This prevents scrolling, but also prevents the\n // selection popup\n e.preventDefault()\n }\n })\n window.addEventListener('touchmove', e => {\n touchMoved = true\n })\n button.addEventListener('touchend', e => {\n e.preventDefault()\n if (typeof key === 'number') {\n if (touchMoved) return\n let fakeEvent = { which: key, preventDefault: () => {} }\n input.handleKeyDown(fakeEvent)\n } else if (typeof key === 'string') {\n button.classList.remove('enabled')\n input.softModifiers[key] = false\n }\n })\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/soft_keyboard.js","const { getColor } = require('./themes')\nconst {\n ATTR_FG,\n ATTR_BG,\n ATTR_BOLD,\n ATTR_UNDERLINE,\n ATTR_BLINK,\n ATTR_ITALIC,\n ATTR_STRIKE,\n ATTR_OVERLINE,\n ATTR_FAINT,\n ATTR_FRAKTUR\n} = require('./screen_attr_bits')\n\n// debug toolbar, tooltip and screen\nmodule.exports = function attachDebugger (screen, connection) {\n // debug screen overlay\n const debugCanvas = document.createElement('canvas')\n debugCanvas.classList.add('debug-canvas')\n const ctx = debugCanvas.getContext('2d')\n\n // debug toolbar\n const toolbar = document.createElement('div')\n toolbar.classList.add('debug-toolbar')\n\n // debug tooltip\n const tooltip = document.createElement('div')\n tooltip.classList.add('debug-tooltip')\n tooltip.classList.add('hidden')\n\n // update functions, defined somewhere below\n let updateTooltip\n let updateToolbar\n\n // tooltip cell\n let selectedCell = null\n\n // update tooltip cell when mouse moves\n const onMouseMove = (e) => {\n if (e.target !== screen.layout.canvas) {\n selectedCell = null\n return\n }\n selectedCell = screen.layout.screenToGrid(e.offsetX, e.offsetY)\n updateTooltip()\n }\n\n // hide tooltip when mouse leaves\n const onMouseOut = (e) => {\n selectedCell = null\n tooltip.classList.add('hidden')\n }\n\n // updates debug canvas size\n const updateCanvasSize = function () {\n let { width, height, devicePixelRatio } = screen.layout.window\n let cellSize = screen.layout.getCellSize()\n let padding = Math.round(screen.layout._padding)\n debugCanvas.width = (width * cellSize.width + 2 * padding) * devicePixelRatio\n debugCanvas.height = (height * cellSize.height + 2 * padding) * devicePixelRatio\n debugCanvas.style.width = `${width * cellSize.width + 2 * screen.layout._padding}px`\n debugCanvas.style.height = `${height * cellSize.height + 2 * screen.layout._padding}px`\n }\n\n // defined somewhere below\n let startDrawLoop\n\n let screenAttached = false\n\n // node to which events were bound (kept here for when they need to be removed)\n let eventNode\n\n // attaches/detaches debug screen overlay to/from DOM\n const setScreenAttached = function (attached) {\n if (attached && !debugCanvas.parentNode) {\n screen.layout.canvas.parentNode.appendChild(debugCanvas)\n eventNode = debugCanvas.parentNode\n eventNode.addEventListener('mousemove', onMouseMove)\n eventNode.addEventListener('mouseout', onMouseOut)\n screen.layout.on('size-update', updateCanvasSize)\n updateCanvasSize()\n screenAttached = true\n startDrawLoop()\n } else if (!attached && debugCanvas.parentNode) {\n debugCanvas.parentNode.removeChild(debugCanvas)\n eventNode.removeEventListener('mousemove', onMouseMove)\n eventNode.removeEventListener('mouseout', onMouseOut)\n screen.layout.removeListener('size-update', updateCanvasSize)\n screenAttached = false\n }\n }\n\n // attaches/detaches toolbar and tooltip to/from DOM\n const setToolbarAttached = function (attached) {\n if (attached && !toolbar.parentNode) {\n screen.layout.canvas.parentNode.appendChild(toolbar)\n screen.layout.canvas.parentNode.appendChild(tooltip)\n updateToolbar()\n } else if (!attached && toolbar.parentNode) {\n screen.layout.canvas.parentNode.removeChild(toolbar)\n screen.layout.canvas.parentNode.removeChild(tooltip)\n }\n }\n\n // attach/detach toolbar when debug mode is enabled/disabled\n screen.on('update-window:debug', enabled => {\n setToolbarAttached(enabled)\n })\n\n // ditto ^\n screen.layout.on('update-window:debug', enabled => {\n setScreenAttached(enabled)\n })\n\n let drawData = {\n // last draw reason\n reason: '',\n\n // when true, will show colored cell update overlays\n showUpdates: false,\n\n // draw start time in milliseconds\n startTime: 0,\n\n // end time\n endTime: 0,\n\n // partial update frames\n frames: [],\n\n // cell data\n cells: new Map(),\n\n // scroll region\n scrollRegion: null\n }\n\n // debug interface\n screen._debug = screen.layout.renderer._debug = {\n drawStart (reason) {\n drawData.reason = reason\n drawData.startTime = window.performance.now()\n },\n drawEnd () {\n drawData.endTime = window.performance.now()\n },\n setCell (cell, flags) {\n drawData.cells.set(cell, [flags, window.performance.now()])\n },\n pushFrame (frame) {\n drawData.frames.push([...frame, window.performance.now()])\n }\n }\n\n let isDrawing = false\n let drawLoop = function () {\n // draw while the screen is attached\n if (screenAttached) window.requestAnimationFrame(drawLoop)\n else isDrawing = false\n\n let now = window.performance.now()\n\n let { width, height, devicePixelRatio } = screen.layout.window\n let padding = Math.round(screen.layout._padding)\n let cellSize = screen.layout.getCellSize()\n\n ctx.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0)\n ctx.clearRect(0, 0, width * cellSize.width + 2 * padding, height * cellSize.height + 2 * padding)\n ctx.translate(padding, padding)\n\n ctx.lineWidth = 2\n ctx.lineJoin = 'round'\n\n if (drawData.showUpdates) {\n const cells = drawData.cells\n for (let cell = 0; cell < width * height; cell++) {\n // cell does not exist or has no flags set\n if (!cells.has(cell) || cells.get(cell)[0] === 0) continue\n\n const [flags, timestamp] = cells.get(cell)\n let elapsedTime = (now - timestamp) / 1000\n\n if (elapsedTime > 1) {\n cells.delete(cell)\n continue\n }\n\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 & 2) {\n // updated\n ctx.fillStyle = '#0f0'\n } else if (flags & 1) {\n // redrawn\n ctx.fillStyle = '#f0f'\n }\n\n if (!(flags & 4)) {\n // outside a clipped region\n ctx.fillStyle = '#0ff'\n }\n\n if (flags & 16) {\n // was filled to speed up rendering\n ctx.globalAlpha /= 2\n }\n\n ctx.fillRect(x * cellSize.width, y * cellSize.height, cellSize.width, cellSize.height)\n\n if (flags & 8) {\n // wide cell\n ctx.strokeStyle = '#f00'\n ctx.beginPath()\n ctx.moveTo(x * cellSize.width, (y + 1) * cellSize.height)\n ctx.lineTo((x + 1) * cellSize.width, (y + 1) * cellSize.height)\n ctx.stroke()\n }\n }\n\n let framesToDelete = []\n for (let frame of drawData.frames) {\n let timestamp = frame[4]\n let elapsedTime = (now - timestamp) / 1000\n if (elapsedTime > 1) framesToDelete.push(frame)\n else {\n ctx.globalAlpha = 1 - elapsedTime\n ctx.strokeStyle = '#ff0'\n ctx.strokeRect(frame[0] * cellSize.width, frame[1] * cellSize.height,\n frame[2] * cellSize.width, frame[3] * cellSize.height)\n }\n }\n for (let frame of framesToDelete) {\n drawData.frames.splice(drawData.frames.indexOf(frame), 1)\n }\n }\n\n if (selectedCell !== null) {\n // draw a dashed outline around the selected cell\n let [x, y] = selectedCell\n\n ctx.save()\n ctx.globalAlpha = 0.5\n ctx.lineWidth = 1\n\n // draw X line\n ctx.beginPath()\n ctx.moveTo(0, y * cellSize.height)\n ctx.lineTo(x * cellSize.width, y * cellSize.height)\n ctx.strokeStyle = '#f00'\n ctx.setLineDash([cellSize.width])\n ctx.stroke()\n\n // draw Y line\n ctx.beginPath()\n ctx.moveTo(x * cellSize.width, 0)\n ctx.lineTo(x * cellSize.width, y * cellSize.height)\n ctx.strokeStyle = '#0f0'\n ctx.setLineDash([cellSize.height])\n ctx.stroke()\n\n ctx.globalAlpha = 1\n ctx.lineWidth = 1 + 0.5 * Math.sin((now / 1000) * 10)\n ctx.strokeStyle = '#fff'\n ctx.lineJoin = 'round'\n ctx.setLineDash([2, 2])\n ctx.lineDashOffset = (now / 1000) * 10\n ctx.strokeRect(x * cellSize.width, y * cellSize.height, cellSize.width, cellSize.height)\n ctx.lineDashOffset += 2\n ctx.strokeStyle = '#000'\n ctx.strokeRect(x * cellSize.width, y * cellSize.height, cellSize.width, cellSize.height)\n ctx.restore()\n }\n\n if (drawData.scrollRegion !== null) {\n // draw two lines marking the scroll region bounds\n let [start, end] = drawData.scrollRegion\n\n ctx.save()\n ctx.globalAlpha = 1\n ctx.strokeStyle = '#00f'\n ctx.lineWidth = 2\n ctx.setLineDash([2, 2])\n\n ctx.beginPath()\n ctx.moveTo(0, start * cellSize.height)\n ctx.lineTo(width * cellSize.width, start * cellSize.height)\n ctx.stroke()\n\n ctx.beginPath()\n ctx.moveTo(0, (end + 1) * cellSize.height)\n ctx.lineTo(width * cellSize.width, (end + 1) * cellSize.height)\n ctx.stroke()\n\n ctx.restore()\n }\n }\n\n startDrawLoop = function () {\n if (isDrawing) return\n isDrawing = true\n drawLoop()\n }\n\n let pad2 = i => ('00' + i.toString()).substr(-2)\n let formatColor = color => color < 256\n ? color.toString()\n : '#' + pad2(color >> 16) + pad2((color >> 8) & 0xFF) + pad2(color & 0xFF)\n\n let makeSpan = (text, styles) => {\n let span = document.createElement('span')\n span.textContent = text\n Object.assign(span.style, styles || {})\n return span\n }\n let formatAttributes = (target, attrs) => {\n if (attrs & ATTR_FG) target.appendChild(makeSpan('HasFG'))\n if (attrs & ATTR_BG) target.appendChild(makeSpan('HasBG'))\n if (attrs & ATTR_BOLD) target.appendChild(makeSpan('Bold', { fontWeight: 'bold' }))\n if (attrs & ATTR_UNDERLINE) target.appendChild(makeSpan('Uline', { textDecoration: 'underline' }))\n if (attrs & ATTR_BLINK) target.appendChild(makeSpan('Blink'))\n if (attrs & ATTR_ITALIC) target.appendChild(makeSpan('Italic', { fontStyle: 'italic' }))\n if (attrs & ATTR_STRIKE) target.appendChild(makeSpan('Strike', { textDecoration: 'line-through' }))\n if (attrs & ATTR_OVERLINE) target.appendChild(makeSpan('Oline', { textDecoration: 'overline' }))\n if (attrs & ATTR_FAINT) target.appendChild(makeSpan('Faint', { opacity: 0.5 }))\n if (attrs & ATTR_FRAKTUR) target.appendChild(makeSpan('Fraktur'))\n }\n\n updateTooltip = function () {\n // TODO: make this not destroy and recreate the same nodes every time\n tooltip.classList.remove('hidden')\n tooltip.innerHTML = ''\n let cell = selectedCell[1] * screen.window.width + selectedCell[0]\n if (!screen.screen[cell]) return\n\n let foreground = document.createElement('span')\n foreground.textContent = formatColor(screen.screenFG[cell])\n let preview = document.createElement('span')\n preview.textContent = ' ●'\n preview.style.color = getColor(screen.screenFG[cell], screen.layout.renderer.palette)\n foreground.appendChild(preview)\n\n let background = document.createElement('span')\n background.textContent = formatColor(screen.screenBG[cell])\n let bgPreview = document.createElement('span')\n bgPreview.textContent = ' ●'\n bgPreview.style.color = getColor(screen.screenBG[cell], screen.layout.renderer.palette)\n background.appendChild(bgPreview)\n\n let character = screen.screen[cell]\n let codePoint = character.codePointAt(0)\n let formattedCodePoint = codePoint.toString(16).length <= 4\n ? `0000${codePoint.toString(16)}`.substr(-4)\n : codePoint.toString(16)\n\n let attributes = document.createElement('span')\n attributes.classList.add('attributes')\n formatAttributes(attributes, screen.screenAttrs[cell])\n\n let data = {\n Cell: `col ${selectedCell[0] + 1}, ln ${selectedCell[1] + 1} (${cell})`,\n Foreground: foreground,\n Background: background,\n Character: `U+${formattedCodePoint}`,\n Attributes: attributes\n }\n\n let table = document.createElement('table')\n\n for (let name in data) {\n let row = document.createElement('tr')\n let label = document.createElement('td')\n label.appendChild(new window.Text(name))\n label.classList.add('label')\n\n let value = document.createElement('td')\n value.appendChild(typeof data[name] === 'string' ? new window.Text(data[name]) : data[name])\n value.classList.add('value')\n\n row.appendChild(label)\n row.appendChild(value)\n table.appendChild(row)\n }\n\n tooltip.appendChild(table)\n\n let cellSize = screen.layout.getCellSize()\n // add 3 to the position because for some reason the corner is off\n let posX = (selectedCell[0] + 1) * cellSize.width + 3\n let posY = (selectedCell[1] + 1) * cellSize.height + 3\n tooltip.style.transform = `translate(${posX}px, ${posY}px)`\n }\n\n let toolbarData = null\n let toolbarNodes = {}\n\n // construct the toolbar if it wasn't already\n const initToolbar = function () {\n if (toolbarData) return\n\n let showUpdates = document.createElement('input')\n showUpdates.type = 'checkbox'\n showUpdates.addEventListener('change', e => {\n drawData.showUpdates = showUpdates.checked\n })\n\n let fancyGraphics = document.createElement('input')\n fancyGraphics.type = 'checkbox'\n fancyGraphics.value = !!screen.layout.renderer.graphics\n fancyGraphics.addEventListener('change', e => {\n screen.layout.renderer.graphics = +fancyGraphics.checked\n })\n\n toolbarData = {\n cursor: {\n title: 'Cursor',\n Position: '',\n Style: '',\n Visible: true,\n Hanging: false\n },\n internal: {\n Flags: '',\n 'Cursor Attributes': '',\n 'Code Page': '',\n Heap: 0,\n Clients: 0\n },\n drawing: {\n title: 'Drawing',\n 'Last Update': '',\n 'Show Updates': showUpdates,\n 'Fancy Graphics': fancyGraphics,\n 'Redraw Screen': () => {\n screen.layout.renderer.resetDrawn()\n screen.layout.renderer.draw('debug-redraw')\n }\n }\n }\n\n for (let i in toolbarData) {\n let group = toolbarData[i]\n let table = document.createElement('table')\n table.classList.add('toolbar-group')\n\n toolbarNodes[i] = {}\n\n for (let key in group) {\n let item = document.createElement('tr')\n let name = document.createElement('td')\n name.classList.add('name')\n let value = document.createElement('td')\n value.classList.add('value')\n\n toolbarNodes[i][key] = { name, value }\n\n if (key === 'title') {\n name.textContent = group[key]\n name.classList.add('title')\n } else {\n name.textContent = key\n if (group[key] instanceof Function) {\n name.textContent = ''\n let button = document.createElement('button')\n name.classList.add('has-button')\n name.appendChild(button)\n button.textContent = key\n button.addEventListener('click', e => group[key](e))\n } else if (group[key] instanceof window.Node) value.appendChild(group[key])\n else value.textContent = group[key]\n }\n\n item.appendChild(name)\n item.appendChild(value)\n table.appendChild(item)\n }\n\n toolbar.appendChild(table)\n }\n\n let heartbeat = toolbarNodes.heartbeat = document.createElement('div')\n heartbeat.classList.add('heartbeat')\n heartbeat.textContent = '❤'\n toolbar.appendChild(heartbeat)\n }\n\n connection.on('heartbeat', () => {\n if (screenAttached && toolbarNodes.heartbeat) {\n toolbarNodes.heartbeat.classList.remove('beat')\n window.requestAnimationFrame(() => {\n toolbarNodes.heartbeat.classList.add('beat')\n })\n }\n })\n\n updateToolbar = function () {\n initToolbar()\n\n Object.assign(toolbarData.cursor, {\n Position: `col ${screen.cursor.x + 1}, ln ${screen.cursor.y + 1}`,\n Style: screen.cursor.style + (screen.cursor.blinking ? ', blink' : ''),\n Visible: screen.cursor.visible,\n Hanging: screen.cursor.hanging\n })\n\n let drawTime = Math.round((drawData.endTime - drawData.startTime) * 100) / 100\n toolbarData.drawing['Last Update'] = `${drawData.reason} (${drawTime}ms)`\n toolbarData.drawing['Fancy Graphics'].checked = !!screen.layout.renderer.graphics\n\n for (let i in toolbarData) {\n let group = toolbarData[i]\n let nodes = toolbarNodes[i]\n for (let key in group) {\n if (key === 'title') continue\n let value = nodes[key].value\n if (!(group[key] instanceof window.Node) && !(group[key] instanceof Function)) {\n value.textContent = group[key]\n }\n }\n }\n }\n\n screen.on('update', updateToolbar)\n screen.on('internal', data => {\n if (screenAttached && toolbarData) {\n Object.assign(toolbarData.internal, {\n Flags: data.flags.toString(2),\n 'Cursor Attributes': data.cursorAttrs.toString(2),\n 'Code Page': `${data.charsetGx} (${data.charsetG0}, ${data.charsetG1})`,\n Heap: data.freeHeap,\n Clients: data.clientCount\n })\n drawData.scrollRegion = [data.regionStart, data.regionEnd]\n updateToolbar()\n }\n })\n}\n\n\n\n// WEBPACK FOOTER //\n// ./js/term/debug.js","const { getColor } = require('./themes')\nconst { qs } = require('../utils')\nconst { rgb2hsl, hex2rgb, rgb2hex, hsl2rgb } = require('../lib/color_utils')\n\nmodule.exports = function initButtons (input) {\n let container = qs('#action-buttons')\n\n // current color palette\n let palette = []\n\n // button labels\n let labels = []\n\n // button colors\n let colors = {}\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 e.target.blur() // if it keeps focus, spacebar will push it\n })\n\n // this prevents button retaining focus after half-click/drag-away\n button.addEventListener('mouseleave', e => {\n e.target.blur()\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 = buttons.length; i > labels.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 let color = colors[i]\n\n button.textContent = label || '\\u00a0' // label or nbsp\n\n if (!label) button.classList.add('inactive')\n else button.classList.remove('inactive')\n\n // 0 or undefined can be used to disable custom color\n if (Number.isFinite(color) && color !== 0) {\n const clr = getColor(color, palette)\n button.style.background = clr\n\n // darken the color a bit for the 3D side\n const hsl = rgb2hsl(...hex2rgb(clr))\n const hex = rgb2hex(...hsl2rgb(hsl[0], hsl[1], hsl[2] * 0.7))\n button.style.boxShadow = `0 3px 0 ${hex}`\n } else {\n button.style.background = null\n button.style.boxShadow = null\n }\n }\n }\n\n return {\n update,\n get labels () {\n return labels\n },\n set labels (value) {\n labels = value\n update()\n },\n get colors () {\n return colors\n },\n set colors (value) {\n colors = value\n update()\n },\n get palette () {\n return palette\n },\n set palette (value) {\n palette = value\n update()\n }\n }\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 $('#default_fg,#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 for (let i = 1; i <= 5; i++) {\n ColorTriangle.initInput(qs(`#bc${i}`), opts)\n }\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":""}