rvt 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. checksums.yaml +5 -5
  2. data/app/assets/javascripts/rvt/console_sessions.js +18 -32
  3. data/app/assets/stylesheets/rvt/application.css +1 -0
  4. data/app/assets/stylesheets/rvt/console_sessions.css.erb +7 -4
  5. data/app/controllers/rvt/application_controller.rb +3 -0
  6. data/app/views/rvt/console_sessions/index.html.erb +9 -4
  7. data/lib/assets/javascripts/rvt.js +66 -23
  8. data/lib/assets/stylesheets/rvt.css +4 -0
  9. data/lib/rvt.rb +0 -1
  10. data/lib/rvt/engine.rb +1 -13
  11. data/lib/rvt/version.rb +1 -1
  12. data/test/dummy/config/application.rb +2 -15
  13. data/test/dummy/config/secrets.yml +32 -0
  14. data/test/dummy/db/test.sqlite3 +0 -0
  15. data/test/dummy/log/development.log +35102 -0
  16. data/test/dummy/log/test.log +6635 -0
  17. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Mc/McQLAeERc8_h2GV4r_RSiTspx4ScOecJluPorLvWQv0.cache → -k/-kWsWgMXl2ZAF8zZv4r8PS6rm6ffMtUd-Ma8pAT_OJ4.cache} +0 -0
  18. data/test/dummy/tmp/cache/assets/sprockets/v3.0/08/08beTQHREIhjRtoBrxMZ6FHaxhlLwKQqnEPYIVND5ms.cache +1 -0
  19. data/test/dummy/tmp/cache/assets/sprockets/v3.0/0Y/0YioaTGG5pPIt_8ZprcTZY9grFYXnvHrWwAm0D-2DvM.cache +1 -0
  20. data/test/dummy/tmp/cache/assets/sprockets/v3.0/0p/0plJ6fG2bnSD-EltE32bpvmWlzM_EJ6rAbl_gfA6a_g.cache +1 -0
  21. data/test/dummy/tmp/cache/assets/sprockets/v3.0/1-/1-iOGSnAfu5QzZ-CHEdTitP-5Af_kzPI-bDp0AB7w-w.cache +1 -0
  22. data/test/dummy/tmp/cache/assets/sprockets/v3.0/10/10VuBAk2tYbshM7nzg2PmLcyxqn79im6uV-fWNNHSnY.cache +1 -0
  23. data/test/dummy/tmp/cache/assets/sprockets/v3.0/13/13agLhf4vTx_mCWtPD-Osx7zQB3hATdVB99LwfZ2osQ.cache +1 -0
  24. data/test/dummy/tmp/cache/assets/sprockets/v3.0/15/15ok-KPHBDqe4Be1S1cMFedG2R7-SN0yX6yXr-_Wt1A.cache +1 -0
  25. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{G1/G1bLOMv8ry4OZIOE6yamFeLyspUWFH7F5uHQsvx3L-Q.cache → 19/19qxhXovOaykzRzWP6LTFWxznQKx2Vjw9v0cwFeRjko.cache} +1 -1
  26. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Wr/WriPF39G9moRbujaXvonAiEHjjgypR1iqYJrCkxmCpw.cache → 1E/1Ei9hs8evGGBWvHfxqmbeAhzLwAwfctd96ReP9B3YHs.cache} +0 -0
  27. data/test/dummy/tmp/cache/assets/sprockets/v3.0/1a/1aYx8_5kppRwU4tKqFENf59WMr-P_9GPMBEhWSt5D-8.cache +0 -0
  28. data/test/dummy/tmp/cache/assets/sprockets/v3.0/1i/1ihFGdkP4w8NQXWMtxQ5hyYR1oey0Repp8pnF-h3nPs.cache +1 -0
  29. data/test/dummy/tmp/cache/assets/sprockets/v3.0/28/28HQBuBhEKOo4yX8iIWFaWRdRqDOig7S9cSvvD4YLBs.cache +1 -0
  30. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{rp/rpULJhACB9dPnbqAlVkrmJY1TtBillfIpwXuHEJW90w.cache → 2A/2Aahz8qIBZ2aqPIl-oqU1cHu77fJCw0Ej5tRsgpQQPE.cache} +0 -0
  31. data/test/dummy/tmp/cache/assets/sprockets/v3.0/30/30n33voi8xrNL1NGZker1EvTpGZ-cp1ZwGkF-fwX9ck.cache +1 -0
  32. data/test/dummy/tmp/cache/assets/sprockets/v3.0/3h/3hFbdb8PCPxwgaSG184S_f3_9YiLjPcz7acEsKvDfnc.cache +1 -0
  33. data/test/dummy/tmp/cache/assets/sprockets/v3.0/4g/4gWBKyXKrhIERJHmER7u3skVARiiO8CuDaobzsh5hrY.cache +1 -0
  34. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{tC/tCEBLgzem7g5HdQk880uJ0dZ_VP4LjyVByw6MszTkjk.cache → 4x/4x4SfJ8POcn_5GroGRCTXRl0R74-my-hSiWmw23gD_I.cache} +0 -0
  35. data/test/dummy/tmp/cache/assets/sprockets/v3.0/52/52dj5_sQqYMdp-Jq__CRuim_UPaWd_SVUeoAUhXhk9o.cache +1 -0
  36. data/test/dummy/tmp/cache/assets/sprockets/v3.0/56/56SaNws-UaxyLsj8oMU8dfsUZtzJPqSuWcS6sRy7ZL8.cache +1 -0
  37. data/test/dummy/tmp/cache/assets/sprockets/v3.0/59/59Iv0zYsO0kAjBBmTxvYbLZVI927cQTdpxMz4SkxcsA.cache +1 -0
  38. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5D/5Dol0kRZNNycXHrUO8ZUfYseFukTciD88UYkntPvpcE.cache +1 -0
  39. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Fx/FxJAcBo8p4ampqzXZFkXwX2Xx58e9sA2MznNT4tSb4k.cache → 5Z/5ZXwjMKqJ-A2yXE3a0dbIrikKYZVnk3fui4DMmz48lk.cache} +0 -0
  40. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5k/5kRJ4sH7y3qd1k6DTUoC0gbStd0OWKHN1BC44Vo_jMY.cache +1 -0
  41. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5s/5Sn1CbCVqNNz4NjoX4qkPHq_wtTq8UHU5UZiw8UOirk.cache +1 -0
  42. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5s/5sZ1gCXEFuPIOk-b4vWbEKq85JXMK8TffZzNKl8pNDA.cache +0 -0
  43. data/test/dummy/tmp/cache/assets/sprockets/v3.0/63/63lIk133HZt8Qk4bvvZop2l3fE82b0Dzg7v8rIJMA-E.cache +0 -0
  44. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{UL/UL8LL9y5J1u3L9SdvG8_G_gHLE_rKFsUeAlq54HNNqE.cache → 6P/6Pvzfk4ZiEy6JwysTpNkcpGc6ZxqZmnhrOe341PJ7xE.cache} +0 -0
  45. data/test/dummy/tmp/cache/assets/sprockets/v3.0/6S/6SlQBk1nmBw_S2wU9RDxn4VC-QEPgkzrKDIcfWoWNQk.cache +1 -0
  46. data/test/dummy/tmp/cache/assets/sprockets/v3.0/6V/6VZ7A4vtU3hzw90wVY8hbrWStQ_CVuKbMpTs9tyES5E.cache +0 -0
  47. data/test/dummy/tmp/cache/assets/sprockets/v3.0/6r/6rhsKfTxfHYeMdDJC0WTG5MoSqYnTIm3cUbsSunotic.cache +1 -0
  48. data/test/dummy/tmp/cache/assets/sprockets/v3.0/6u/6utay7VkqNIFbt3iHF-zcMOH74369hxhR3JYj3T6ADA.cache +4 -0
  49. data/test/dummy/tmp/cache/assets/sprockets/v3.0/70/700yl_vOvT8zWvOGRyEnKt8jbCoudw2winTEXq1kQWs.cache +1 -0
  50. data/test/dummy/tmp/cache/assets/sprockets/v3.0/77/77hNrjw_SVwPzr2bBM3hEeq9cBLn_60qU7LxnDeulwE.cache +0 -0
  51. data/test/dummy/tmp/cache/assets/sprockets/v3.0/7S/7S66JDS9bYQrUkMmnDw14MqwN7tUDvBeITf23hXK_mU.cache +0 -0
  52. data/test/dummy/tmp/cache/assets/sprockets/v3.0/7b/7bah6AfpQNLmcPzUhdVOjJwj-utQzT4Gp13yyUG1-os.cache +1 -0
  53. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Pq/Pq9EEQ_PUKpcnBH_AwZ_F30lvjSNXlN1hwaTn5zBllI.cache → 7d/7dbFmSW4fCX2-qvOoLwhhfhJJTPdLWjeHizxdcBda3Q.cache} +1 -1
  54. data/test/dummy/tmp/cache/assets/sprockets/v3.0/7h/7h1SnthU_xgPEVAK3XafohnIRw5ztiyDMq4urK46TIQ.cache +1 -0
  55. data/test/dummy/tmp/cache/assets/sprockets/v3.0/7i/7ilbgWjHSvpT2wOZYyaQ80wDLezPYjQZW5yHfpFyuyc.cache +1 -0
  56. data/test/dummy/tmp/cache/assets/sprockets/v3.0/7w/7wB7Vul6Lch0qdkWDW8X8SzSi2-VR0PDKIStuas_jmk.cache +0 -0
  57. data/test/dummy/tmp/cache/assets/sprockets/v3.0/8V/8VuwNr6zDnVJWE58Xnep80kdc7WeKJSTOFjdn1hLwAY.cache +1 -0
  58. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{k0/k0Sfk3cETJbZWYz1xsnnpgAn8xbzpBM8rJT9ffkdqnk.cache → 9A/9ArW7CZi8OYRdOUyWUq2ghAXLAqesLT0zF66ys8xS9Q.cache} +0 -0
  59. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{td/tdnEBVuuDY8qxEUccGN9gIoQ4UgdMlDCBFjSlTtOh68.cache → 9K/9KsWd_r6PFFDBiRGxGr_lCfV5sFTVN7MuaRRgoM9aBM.cache} +0 -0
  60. data/test/dummy/tmp/cache/assets/sprockets/v3.0/9M/9M8NdCdd4J5xZPOf5nbgcdAuWfqzH3Pi0m95Fi0cCX4.cache +1 -0
  61. data/test/dummy/tmp/cache/assets/sprockets/v3.0/9c/9c58KfTtMtK_q0IRLv4Ohe6Ku9NR8cTvzNsUUwvFh3o.cache +1 -0
  62. data/test/dummy/tmp/cache/assets/sprockets/v3.0/9c/9cLL-WwQAfVZYDPvfbpdtcnYqB0twxXZFAIYo_bIwDg.cache +1 -0
  63. data/test/dummy/tmp/cache/assets/sprockets/v3.0/9f/9fjyLS5QJER_ouDjFs9r44-2NpIWEr_ARVS7Ejl5uVI.cache +0 -0
  64. data/test/dummy/tmp/cache/assets/sprockets/v3.0/A7/A7TBW10ylh4nLlUBMquQ9KQeYJXe7C7tJPNSXKpoBxc.cache +0 -0
  65. data/test/dummy/tmp/cache/assets/sprockets/v3.0/AA/AAiRDGe6f3TnpziRJTw28NMq1gtnkZ5W3mbxowNTj1M.cache +0 -0
  66. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Qy/Qyi4pqtXinXLNBYkB-lXsfCpaw560tlqG997Omt9hjc.cache → AR/ARKOmH6p6jVxoayq2bHzhdLGaYTd8KpX6Tu3QQQAPww.cache} +0 -0
  67. data/test/dummy/tmp/cache/assets/sprockets/v3.0/AS/ASWkkDKVcpfAiOu3B0KOejzVhAxxhYxqOQKBcZlm290.cache +0 -0
  68. data/test/dummy/tmp/cache/assets/sprockets/v3.0/AT/ATEqECN4BijOQ993FAXv3MoryNacaylv073Jv9UeIOQ.cache +1 -0
  69. data/test/dummy/tmp/cache/assets/sprockets/v3.0/AT/aT6_oAHJCuWhpkmdiQ70MxzEDA9i9fnO6kOUJuqLttY.cache +0 -0
  70. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ad/AdR0Qt_GcCj_0fxwl4lvjCAfJXJT8iwZb5RzeJt7X-g.cache +1 -0
  71. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{Yk/YkC1ANqSFWUmQhl7MGjSK_iCs_lP8mVO5QaIjn-Mdy4.cache → Ae/Aeswx4jbWYCQZlAPoZ6eOpckcVwEIQaCdyIEZ4yZ1vo.cache} +0 -0
  72. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ae/Aez3Ln5GSo40ydxFzrQOFnySToV0-GnCIqhX3Z8PxjU.cache +1 -0
  73. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Az/Az-XOnvmnNddxIz4XLZ1I4DleC9n1REONV4xGg_QDA0.cache +0 -0
  74. data/test/dummy/tmp/cache/assets/sprockets/v3.0/BN/BNKTHM0qczl5J1srx4QT-at4EuqAA5SSEVeTmxjdUYc.cache +1 -0
  75. data/test/dummy/tmp/cache/assets/sprockets/v3.0/BW/BW1UGENNCOM3Axx_ShFZhHwm4_bcDP1QyQCk98WBayY.cache +1 -0
  76. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Be/Beyr-TRQYnkjEqSn8chN2Hhh3kVAbSR2_IhK9orJ9Xk.cache +1 -0
  77. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Bv/BvSr8HnNGZCLi7shOVomsQuAT5dX8IPGkepQ6tNxGUI.cache +0 -0
  78. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Bv/bVWlBMMWMQVoW83IV4Qf9L-ABRxEV6rmp6xhGgd2VNU.cache +0 -0
  79. data/test/dummy/tmp/cache/assets/sprockets/v3.0/C0/C005GHkGmz6P2P0YZaw73NcUTDviWT_hspo2V3zRqv8.cache +0 -0
  80. data/test/dummy/tmp/cache/assets/sprockets/v3.0/C0/c06NLyQZGWQsdwVXih7CfDBuHWmFSM2LspPVvPxrMIc.cache +1 -0
  81. data/test/dummy/tmp/cache/assets/sprockets/v3.0/CB/CB4g53dw2z-x-93N-W6AahS8wt4x7QwelZK2b61FUXA.cache +1 -0
  82. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ch/ChP_e519Fej_qZBClVpu8-bJm11J7UZJaN2wgaXNa94.cache +1 -0
  83. data/test/dummy/tmp/cache/assets/sprockets/v3.0/D7/D7AIWNFq0HwRCrpFDzdbYrc8vmqErySsARjPklXlAPg.cache +2 -0
  84. data/test/dummy/tmp/cache/assets/sprockets/v3.0/D7/D7s3i6wBxXKuXgmEi_xluk4ktUowNkkMSuUk72Qnd3c.cache +0 -0
  85. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{2l/2lShAF_y3QIpyv7eGEC1oi2ks8II1yOglQYzZuI3GlU.cache → D8/D8A7QhUYhnXJ3LEEFw9NrHww1rN4Ky-LdBB0bOtK9Z0.cache} +0 -0
  86. data/test/dummy/tmp/cache/assets/sprockets/v3.0/DW/DWIt1aCKlWxnd-4npDlqWMFBAjSrCinlmfA_TCZeslE.cache +1 -0
  87. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{1e/1esrtnLnKK8hR4ALg2UF3qhvLJB3u75jgYYlwr3BtiE.cache → DY/DY2J3UwXRTs-2Q6VBmon8K0OQJTPsamoZwijp7X-bm0.cache} +0 -0
  88. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Da/Das9TcLHrt3FfmNKQgMbCTg8BsYF06X7x2gFXvoVsJg.cache +1 -0
  89. data/test/dummy/tmp/cache/assets/sprockets/v3.0/De/DermXth9dmU_XWCFEysWqQ3lL8KQhEi-GkHKs2iFWNU.cache +1 -0
  90. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{80/80iuGcmJDTntKnnQNhnTc6BWK-fhydrU0ll3jrc-jxE.cache → Dl/DlxaZWt1F6jcMlrBLNIamMP8LUsPdcGoCQBjQsqknlA.cache} +0 -0
  91. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Dn/Dna81lRfs6LHDdI5NVoLGXYJeCMPN4zfWXe-PwqMzAg.cache +1 -0
  92. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Dn/dn8JjucKlRBMIvmKNSXxQ6j1zuvW_Wy8yyP_2_uNBt8.cache +0 -0
  93. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Do/DoZ1miHFIc0Zu4xRyikxRSM3bAXfrYlVbFNTB1qY9Os.cache +1 -0
  94. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Dr/DrolWmSngZwPNXKJkGrfADLMhMbJdhfqbtihKKUM4cU.cache +0 -0
  95. data/test/dummy/tmp/cache/assets/sprockets/v3.0/E6/E6yy5KPw_faIzyJ98hK9jPM-3cRJjtqPJ_TUJENGcn8.cache +1 -0
  96. data/test/dummy/tmp/cache/assets/sprockets/v3.0/EG/EGsDHaXyy-tzcZjX3wOgKkSTq_leXqT-PkOPUUdfWdM.cache +1 -0
  97. data/test/dummy/tmp/cache/assets/sprockets/v3.0/EG/eGRA2iRfMMROTcuFKjGHZSN9YXMRnUBKC5KururoKEQ.cache +0 -0
  98. data/test/dummy/tmp/cache/assets/sprockets/v3.0/EP/EPCJCAFRp5SWXenODKp7J3-LOEeQHXH3sPfaf1bHSSo.cache +1 -0
  99. data/test/dummy/tmp/cache/assets/sprockets/v3.0/EP/ePBoUwOrluPhUdXqfhIpGf3zPddq1_3-Vg2oNLOewMA.cache +0 -0
  100. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ES/ES0i3T-gPmh0k4JHBm8e0636XUPegF0Y6PFm1KqrOpw.cache +0 -0
  101. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{w1/w17AnoGy2EExgSUDbqpQ9wTF6Gsyo45geeQhF2wllRU.cache → ES/EsVsWF0kxtr2d8p46pBHT_F438kHPSBPgW2Cn9cIEvo.cache} +0 -0
  102. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ex/ExLUPQPUvttBUmDRlP6aWd7GP5yCWI1o8eKoCeCw3z4.cache +1 -0
  103. data/test/dummy/tmp/cache/assets/sprockets/v3.0/F0/F04RlQd4Wku__flRg9gkM00g8mfjuKzQKlvsrhcXqXc.cache +1 -0
  104. data/test/dummy/tmp/cache/assets/sprockets/v3.0/FA/FAA3VIY3nCH5gKoynhtYbxrahKETLcwURlXKa8K8jE4.cache +1 -0
  105. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Fz/FzQ7uGnfl3Suky99OCP5Y9_chV3zDJ_ls8pg_YpdeQY.cache +1 -0
  106. data/test/dummy/tmp/cache/assets/sprockets/v3.0/GC/GCNnkrIFxTx1GDkpGHVfRDuq5Lmh91Hl_y1Cuuvydtw.cache +1 -0
  107. data/test/dummy/tmp/cache/assets/sprockets/v3.0/GH/GHMro7l5elRwkZW6ocgvpEWdY-bCMla0J0BPd_6hqoE.cache +1 -0
  108. data/test/dummy/tmp/cache/assets/sprockets/v3.0/GH/gHYDXMvegdiaMifmauTVm8Qy1gOSnoiKAnsCwAmMM6Y.cache +0 -0
  109. data/test/dummy/tmp/cache/assets/sprockets/v3.0/GQ/GQGhdmNekxHTcK4z8c8_0XABvO_V3GU-ka52v-m1w7w.cache +0 -0
  110. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gd/GdWzOBp-czgmy2Rby_RDhnKc9DuCOp6bu89sRvLKjgg.cache +1 -0
  111. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gd/gDYut7mu03J1DXr8TuWSBtWUo6SCV8j21oKygbTMlqY.cache +0 -0
  112. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gz/Gzbr2w7v4jG0Hk3mkrGRhUAVf074dfK-SbaCRp1BPqU.cache +1 -0
  113. data/test/dummy/tmp/cache/assets/sprockets/v3.0/H7/H7I9oc3DUcu1Fgug4P9wL2L5hFD6o_2GA1QN9Og7sEI.cache +0 -0
  114. data/test/dummy/tmp/cache/assets/sprockets/v3.0/HO/HOcl3-vJpAuPrL4hm8vHDlGplCavb3ddOz4TrmAZlXM.cache +1 -0
  115. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Hk/HkwIX77oB82LdxxnXQtQR8zqpUlYQ9sTRNSAaRkvLtA.cache +1 -0
  116. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ht/HtmK3dFHJrhu5J-TC1JcX6mYcujL4FIJ06D3YD4XTbQ.cache +1 -0
  117. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Hy/HyBjVqV93QJMiSmyiNNHd8W7bwg3gZl-hf5grEk-wgw.cache +2 -0
  118. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Hy/hYomtUCsrKd36M73vuN6TqMogPeLrU6NIOu1wAKRxf8.cache +0 -0
  119. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Hz/HzVr6Nm_b4eztKl1iNtoTbiUJg8YovXVVx309ooGcN8.cache +1 -0
  120. data/test/dummy/tmp/cache/assets/sprockets/v3.0/IK/IK_yJ4hlfIoYaLmA3gsgUHcRwQD8URO9Sk7Pi9qQWAA.cache +0 -0
  121. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ii/IiSw3rEjcPrbR7bHmv79rnIeihj6Ood5ZNVsxwKYqVk.cache +1 -0
  122. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Io/IoNdrAbIQw_WQQw1yvFl7FgAf-WGvZ2NM0r64hJolVQ.cache +0 -0
  123. data/test/dummy/tmp/cache/assets/sprockets/v3.0/JG/JGaR6S0bzqxKeawxt10Lzcm7TfUd3uQytf3jSxEWw48.cache +4 -0
  124. data/test/dummy/tmp/cache/assets/sprockets/v3.0/JQ/JQlWE0blDCjSPcJnQC7j_jIHh1pyP4EG3RewaazEdv0.cache +0 -0
  125. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Js/JsgdFJryO0r77umcztaF9gLlmMfEbMilAOjggdfgc60.cache +1 -0
  126. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Js/jsZpWqO6fd3TZYojdhzziiohSmF0ENGFCUg-aw4s-eQ.cache +0 -0
  127. data/test/dummy/tmp/cache/assets/sprockets/v3.0/KU/KU2gDD4G4XnXpghZBiXE1dWnF2RfbX-upKi-50zWTpY.cache +1 -0
  128. data/test/dummy/tmp/cache/assets/sprockets/v3.0/KU/Ku40yz8Vw0tWfXutEd9XACE8NupAyP9XqkCE0XAo4iA.cache +0 -0
  129. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Kl/KltQXiJL-E-5FOYGticndlKA3HlOHmK6bmXS2sSgpK8.cache +0 -0
  130. data/test/dummy/tmp/cache/assets/sprockets/v3.0/L0/L0iEiBEuw_cn9Kl1E14SeJqUHWhmwEkm4ALcv6-FUag.cache +0 -0
  131. data/test/dummy/tmp/cache/assets/sprockets/v3.0/LA/LAeWo8kRKzTAYnVcryAE38boNz6PwaGm0cLbYvEzeSA.cache +1 -0
  132. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Lk/LkyGhvZlAhiEAeLfI-S9BiXygetNMNsflyOPQuoruDo.cache +0 -0
  133. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Lm/Lm4AZ7UdsY463umaLuG6r9t_FwjjmXyOoLZe65t5Lgw.cache +0 -0
  134. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Lm/Lm4LVfF3ZLeTOosUYRZ02bLL9eJ_ufm65YSM57c_iLw.cache +1 -0
  135. data/test/dummy/tmp/cache/assets/sprockets/v3.0/M2/M2oif3DO_vNyYmPwq_4pSDMO2cr6C7aAnZ30QFarcqE.cache +0 -0
  136. data/test/dummy/tmp/cache/assets/sprockets/v3.0/MT/MTBWM31BtwMKG_GwIhNdso8ZCuY8XQJbsSdHL8K8B1w.cache +1 -0
  137. data/test/dummy/tmp/cache/assets/sprockets/v3.0/NL/NL2zRwmr1IQtyc8yRugLhbMmFguaFd25SoYml1o0puI.cache +1 -0
  138. data/test/dummy/tmp/cache/assets/sprockets/v3.0/NL/Nl7ScaktvaTV9fv6KnpRA5L4nhOYFIe602IcnZnRdn4.cache +0 -0
  139. data/test/dummy/tmp/cache/assets/sprockets/v3.0/NO/NOSTEerYscJRYOB0fDhXWg8n2Ubns32JK_g_XeyZzEg.cache +0 -0
  140. data/test/dummy/tmp/cache/assets/sprockets/v3.0/NQ/NQ5GwtrjHgrF979TJAJAIbyn_UBEAME1bZW0xMX5DnY.cache +0 -0
  141. data/test/dummy/tmp/cache/assets/sprockets/v3.0/NW/NWyrH43hxzGBxfB9ZKdryDPlHeh2Djz9CvJqNJ9iLKk.cache +1 -0
  142. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ni/NiUFiKzq5amff2RZ37XuDkcPgTcuD49nRbZgDY_PhoY.cache +1 -0
  143. data/test/dummy/tmp/cache/assets/sprockets/v3.0/O9/O9n18FPyB5Aff7Ag87dJAlgAnvT9TWBnHCiiZms98SQ.cache +1 -0
  144. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Od/Odngw58z1w-IdGloSutkpEAhke6MVPpv7hpgz0-136Q.cache +1 -0
  145. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ou/OuWuLlXvGlYcE6paOZI8sh0cYX4aodsDz6GDY3TNqME.cache +1 -0
  146. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ov/OveMcuYy1aRyjiisX9H7lQzO7THrJnObrUmbln8Ih2k.cache +0 -0
  147. data/test/dummy/tmp/cache/assets/sprockets/v3.0/PZ/PZyyxCG7Tl8VboaCD1eRsoY6cvDpHu19qJE0KWHl5Jk.cache +0 -0
  148. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Pg/PgG_33ASxui8rv0pM1HsQPrp3QNZbddKMD9jwPdFYdc.cache +1 -0
  149. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Pv/PvtPIvLHDp8JiNt2UJYleFfw-pkzgfMqtthHiroXjes.cache +0 -0
  150. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Pv/pVsGEIR7lq-PoM18-0M-xxR1YI5AgKN2v4J_3R4gXI8.cache +1 -0
  151. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Pw/Pwh4JIc1ad7UEbvoZEs9fa2MoW-Xp9NdDX4eN13EaHY.cache +0 -0
  152. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Q1/Q1UtBSZNuYVzeZLWkWpmm-o7HSOx5D2754JyC1LMGNg.cache +1 -0
  153. data/test/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHMR18NuNdQf-g0IxbBD2fEmhSLqd0y1IKyylyutK8k.cache +1 -0
  154. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Qd/Qd5DKDJM6Qi-RUkfGBW1F5jyIbeblwo8SdKmJq5ZJeY.cache +0 -0
  155. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Qd/QdpJoa9mkC5EWXpbhYB75TCPJMbNvI7L2eaJz3XhrkI.cache +1 -0
  156. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Qi/Qi73ofNALTcqUT_EgM2MsJO4uof-GO4xf8TBnwUA92Y.cache +0 -0
  157. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Qu/QuJlvJ4kcq52_cknXo5PEpKT8XVOm7dt2ceHpfbQ_iQ.cache +1 -0
  158. data/test/dummy/tmp/cache/assets/sprockets/v3.0/R4/R4hlf0uqIy39ANsEhv1XO510kFbe-F-60F7v_gPgq00.cache +0 -0
  159. data/test/dummy/tmp/cache/assets/sprockets/v3.0/R5/R5Qn7BZIE1RLU4p8Zd9obkcPZOFCxBGxihXR7ReB9GA.cache +0 -0
  160. data/test/dummy/tmp/cache/assets/sprockets/v3.0/R8/R86o4eyDkpLNiROsURzRj_ImLR1RVlX5noVgz7zNqDY.cache +0 -0
  161. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ro/RoSh3eZzzx7lBF28H0b_lMEE9O5XQEZJaeF7O9FhhRM.cache +1 -0
  162. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Rp/Rp0kuYqE5Oz_-FE2srLOTB6hrcIY0lkQxLVCAFw_pbA.cache +1 -0
  163. data/test/dummy/tmp/cache/assets/sprockets/v3.0/S6/S6VyQhnt514LFU9JWjGg_rT62-EJy4QH5n9Bl7REvPY.cache +1 -0
  164. data/test/dummy/tmp/cache/assets/sprockets/v3.0/SK/SKXDgh9EyOqMCaRQDvUFTq6OorSkeqj2XIJ4uZlEWQg.cache +1 -0
  165. data/test/dummy/tmp/cache/assets/sprockets/v3.0/SK/sK4Ow1R-Wh4ug8uCzmjHxk66Idr1-nrEEKCP352aD6I.cache +0 -0
  166. data/test/dummy/tmp/cache/assets/sprockets/v3.0/SV/SV1EOoJ3cic6j5f4MaYQUFeqzLuSBzJAklpvDlpj-Cg.cache +1 -0
  167. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Sj/SjIvNMfbTzxUiVzh1O6oIQopMViI1R-4kngOcPfzd1g.cache +0 -0
  168. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{MY/MYYdkkZJkduDmx4PCuuPiiFBaKv90qOpaPFoon-wg1Y.cache → Ss/Ss0Xu8tk_PS3RXr_TtbmhnhVeAyE7MCxrPTOTRDVFeI.cache} +0 -0
  169. data/test/dummy/tmp/cache/assets/sprockets/v3.0/TP/TPlY8VwBzC6ccuQjmMY7h9G78_cm7Bu721rrL003R3o.cache +1 -0
  170. data/test/dummy/tmp/cache/assets/sprockets/v3.0/TR/TRfkq054uIjoKd2RkGPjJyr7y8NoRAjvgRhnqm50lSk.cache +0 -0
  171. data/test/dummy/tmp/cache/assets/sprockets/v3.0/TT/TTLu0ztO4_uQ-WjivJx1FZLkIfeRRPNTxX5PndJ8zLY.cache +0 -0
  172. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Tj/TjFaYwMvTy3DR--WZkLLwXGd_xGrfJQJ_ZlNodTFEx8.cache +1 -0
  173. data/test/dummy/tmp/cache/assets/sprockets/v3.0/To/ToVW_LwLfoMA7qkgomaV3ffF-SDvemmBPZkHTKzSnZw.cache +1 -0
  174. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Tu/TuSVUvSt5BY4-q598J6p2dHwl-uhQnb5mZDmzLpkL4g.cache +0 -0
  175. data/test/dummy/tmp/cache/assets/sprockets/v3.0/UC/UCqUT1Xbp58STjhhZ-sMkyqEJ8PvIn59WNJzUPwwt18.cache +1 -0
  176. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{mJ/mJ_7-eeiChJdsNIN2gU0C9i_AaqnBmj6SaqV3I7nCe0.cache → UD/UD4gCZ4M7BhSfwd4hVOqHo_e_m72n8GA6jiSsR5fZWg.cache} +0 -0
  177. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Uf/Uf9tPce43D393aktdyXRO5iSVQ0wUrFcZHWbxIFfVfY.cache +1 -0
  178. data/test/dummy/tmp/cache/assets/sprockets/v3.0/V_/V_BAjWq0DWEzo0Q9NxcSp1nTj7iAm1rSDgxuJtOeuxM.cache +0 -0
  179. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Vk/VkDp8B06fjIECtYuMeMBZhK07emntw6eGBH9l-CrJPk.cache +1 -0
  180. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Vm/VMD-a78buNTA9zY_iHxPIquL81oFoiZRyUUUTLLifI0.cache +0 -0
  181. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Vm/Vm7RBeQL13acXlvnlmzQAOR2-3n4sMzD81wvnDi7WjI.cache +1 -0
  182. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Vw/Vw8hPD2-WLFPWQrRrL0zhoQOWWBnulRJLh_yqph6VIA.cache +1 -0
  183. data/test/dummy/tmp/cache/assets/sprockets/v3.0/W-/W-l_iL21hjDik06px3y0cNxwRax-wcyMHqCYU44IbCs.cache +0 -0
  184. data/test/dummy/tmp/cache/assets/sprockets/v3.0/WL/WLeGA295T4fKL__kob_oUqylByYlyIXbyZXVXQ7fEBI.cache +4 -0
  185. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Wr/WrdmWGzSUAyKEx67shH_XK7LI7OeC2GipDGzU3zfMiQ.cache +0 -0
  186. data/test/dummy/tmp/cache/assets/sprockets/v3.0/XM/XMHn7vqwVvLWj2RwNhVLEylzbG_PeBLHroQfJEWajBI.cache +0 -0
  187. data/test/dummy/tmp/cache/assets/sprockets/v3.0/XW/XWzxn70WfV6gI0dBMktR9kVbjBCvLXn2Ft3ZM_AdMuI.cache +0 -0
  188. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Y0/Y0p_hBGflJWS11onCiUbkg3YGi2hbQOLA7Xy4sZ5h-g.cache +1 -0
  189. data/test/dummy/tmp/cache/assets/sprockets/v3.0/YA/yA__0V_x7k0yKI212qKiZJYVV1SlqnAUjo8xA9lETYM.cache +1 -0
  190. data/test/dummy/tmp/cache/assets/sprockets/v3.0/YD/YDoprxxinr4AALGFMWIqUKHOsP1uajTUXYifinKaPfo.cache +1 -0
  191. data/test/dummy/tmp/cache/assets/sprockets/v3.0/YI/YIJ8wGXFsbFBBiPImfLMXYUm0TdGG2INe036faITzDk.cache +0 -0
  192. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Yv/YvXQz5sZHtXCVO0wvmHeQxJHheo5GeID88vKbtpn1vQ.cache +1 -0
  193. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Yv/yVbylE1uhnqOlfStbQfwubjvWQMoFD1q3oNBG_fjefs.cache +0 -0
  194. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZA/ZA3vRhJyNOLHkdrjGGdAxQn56Q6yOTPlQ_uDuzmynag.cache +0 -0
  195. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZB/ZBXrd5AdUsWldhFyk1EVuVGU2yXlFGyhVMjxiEiqMD0.cache +2 -0
  196. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZD/ZDKXHhzn4B_u92sZ8xLetjlnyNFvYzKaNkLm1BSPmVw.cache +0 -0
  197. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZD/ZDvHyfCXyEa5qWOXwktQRcABbe8waPNPw4fY5Z_D5Ak.cache +0 -0
  198. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZT/ZTU_yG8w31YT8Ba71RrGOcDwlSx9oClaYgveZp4ZBVA.cache +1 -0
  199. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Zl/ZlzLk4d2MKNw7UD22N9MXbsv30UXQxKBdZV1Bf7ngvc.cache +1 -0
  200. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_I/_I3O1hBJhyYQ1ZgFT81XRhXgoG4pqNxgfAGaWklXzTM.cache +1 -0
  201. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_K/_KcWiE5nAEDQpqJfZFqMtPhaeMhihp4UCN4vR5I1S0c.cache +1 -0
  202. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_W/_WVL6zcvlXgbkhRMslHtA0rvqTwr9xLq28GF6DoMd0Q.cache +1 -0
  203. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_n/_N2fgzGU5Oqu3S-Vn-Msc_0cpHMP_nshxJ9WFOviKbs.cache +0 -0
  204. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_n/_nWbvBOATVfCe68YFH9Smg9ownps3aoUyyN-9NQRtQo.cache +1 -0
  205. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_o/_ohnYmY_vC_G7Vqan8sUzJmaquB6QhcLYGc77DKtc4s.cache +1 -0
  206. data/test/dummy/tmp/cache/assets/sprockets/v3.0/_y/_y9FD6kDSeAa5zzj1LFiz-PF8FV_0jr-gK6iDsKWvXk.cache +0 -0
  207. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{1H/1Hh7ihf7wCWWVBUS9Uoixm6HpfyOHzMv-2Tp36h5sAc.cache → _z/_zs_atfF7ypRzG5AvIBCfqZdYM0PBLuvYjNWpDI6BV8.cache} +0 -0
  208. data/test/dummy/tmp/cache/assets/sprockets/v3.0/a3/a3Cwa31etUxox1CqQ6uxNrEpbGHLDJYFfG7Nm3fhHlg.cache +0 -0
  209. data/test/dummy/tmp/cache/assets/sprockets/v3.0/a4/a4bEtdZMtr3Rt6Y0CVkFV0sIWWx3Bv86mWyfkbaeFfo.cache +1 -0
  210. data/test/dummy/tmp/cache/assets/sprockets/v3.0/aF/aFcBC07vbjBdmiW0TmtwWRMQ5Vn3vZTZiCGp4BylQkg.cache +0 -0
  211. data/test/dummy/tmp/cache/assets/sprockets/v3.0/aP/aP_Mu42a9d_0j4KTczl266PjVyHmZEqgvJYTFCB3JUo.cache +2 -0
  212. data/test/dummy/tmp/cache/assets/sprockets/v3.0/a_/a__X31_jf2sHL-xJYEpoKWWhiXSNkWrTNJYhc7l9Gt8.cache +0 -0
  213. data/test/dummy/tmp/cache/assets/sprockets/v3.0/aj/ajcmeCxc24RkfJfq10l_S42XKGIwjKLG_fS5qG-xhHM.cache +1 -0
  214. data/test/dummy/tmp/cache/assets/sprockets/v3.0/av/avZJH3ARnrLfgPgYHP8HVxOLiVh4EzcrKakkNXmsahw.cache +0 -0
  215. data/test/dummy/tmp/cache/assets/sprockets/v3.0/aw/awYTeITVFdmTsuRvIYv9CdXF__4X7EsFq0F-dq8geFQ.cache +0 -0
  216. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ay/ay-1nEAOxGhFWl_HkBancemF5i0_jTIDS288Lob9ro4.cache +1 -0
  217. data/test/dummy/tmp/cache/assets/sprockets/v3.0/b6/b6a9B8W2cWgchjK3aSNjvwbf0xfEYWeTMa5CJCj2Un8.cache +1 -0
  218. data/test/dummy/tmp/cache/assets/sprockets/v3.0/bB/bBHfqPuo9gcrr8VUkavCPSBGbUF-q7vj4cc_p-fiylw.cache +1 -0
  219. data/test/dummy/tmp/cache/assets/sprockets/v3.0/bB/bBj0Q2GCK3NR7kP5sTE38luc6soBv7DS5tcWB-4etfI.cache +1 -0
  220. data/test/dummy/tmp/cache/assets/sprockets/v3.0/bJ/bJkQ_dSwbtkZYujIu24wH5tu8HiLFig-qHDp8Wt-Zps.cache +0 -0
  221. data/test/dummy/tmp/cache/assets/sprockets/v3.0/bk/bkim99ppC3FdpJTtMaGS8CllO5Jsbuf8GWYZeaarv5Q.cache +0 -0
  222. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cF/CfSIn6eMEXDtmjrr7oPouTR1KePajS2uqioW2_gQELI.cache +0 -0
  223. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cF/cF1_z7co1UqOeJh2s_aVQlB05tBGdaNDNi346EGWMbU.cache +1 -0
  224. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cN/cNI6iuD_nmI1oyibhmC2qXY4pWeTn9IfdkLkQSoPg5g.cache +1 -0
  225. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cc/cceVLx5AGYnLErPT_zXq8wCafz02ViM5B7e0J_hfCsA.cache +1 -0
  226. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ci/cicVHpT-BWeQrpUOhGl0awCCV-kddJZ06zia5IPuMas.cache +0 -0
  227. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cw/cwgwqvm0fDhWNsca03U1OyT-vzClEMfANDlKKjNcxXc.cache +0 -0
  228. data/test/dummy/tmp/cache/assets/sprockets/v3.0/dD/dDo8M_nyU7maBGfXwZRMKF_00JeV4QaiKCDXUdtj5yY.cache +0 -0
  229. data/test/dummy/tmp/cache/assets/sprockets/v3.0/{dd → dD}/ddQSSbSqtYqXeXJfq9MgkETEBISNXYRzE-wIPkcv9s4.cache +0 -0
  230. data/test/dummy/tmp/cache/assets/sprockets/v3.0/dm/dm__3FYto_fFH4IwEG4qAjhgAQGZuh0zPCzqgZ3bsP8.cache +1 -0
  231. data/test/dummy/tmp/cache/assets/sprockets/v3.0/dx/DxnCtGUnAQmWQ7Tfzy2kc-YcYwMvz4PrgvrQBgaIQSw.cache +0 -0
  232. data/test/dummy/tmp/cache/assets/sprockets/v3.0/dx/dxlUHAaODLiwtgh6MYuhmrJF13BAshewUD8k9_5k2a0.cache +0 -0
  233. data/test/dummy/tmp/cache/assets/sprockets/v3.0/eE/eE0TmXZi5NoBQ6Li02OT-EMu_GU4EvIhiMa-0Nqls3U.cache +1 -0
  234. data/test/dummy/tmp/cache/assets/sprockets/v3.0/eU/eUtPUlUJHVQxMuD4vIem9_N2HUkAPO4aVxjNdFVxACc.cache +0 -0
  235. data/test/dummy/tmp/cache/assets/sprockets/v3.0/eV/eVcQYhEcDW8oispYNiL-Po01tfC2bqPxFHua7qDB3vQ.cache +0 -0
  236. data/test/dummy/tmp/cache/assets/sprockets/v3.0/eZ/eZ8o0ZRPhdXLYUbFI1GdB4FQBDnlWM43nHgpH5_47QY.cache +0 -0
  237. data/test/dummy/tmp/cache/assets/sprockets/v3.0/f4/f43dOSIXprZE-wii_NU6nSxA9LvTdEe8MPpQ7jvBk38.cache +1 -0
  238. data/test/dummy/tmp/cache/assets/sprockets/v3.0/fB/fBcyS9tNmJu_9foxN5eenuH18Jumnw0uTMwPQHORUTU.cache +0 -0
  239. data/test/dummy/tmp/cache/assets/sprockets/v3.0/fS/fScKQfCZDnNi0jKvowBp0jP5dnLP5hiJjAEryoc4dn8.cache +0 -0
  240. data/test/dummy/tmp/cache/assets/sprockets/v3.0/fX/fX_OzRutFSBkeYwpekI2H5cO-eS9CcXIXE6dyFj3E5U.cache +1 -0
  241. data/test/dummy/tmp/cache/assets/sprockets/v3.0/g0/g0APGuGiB1phtXXtTsLBLkQ-k8h0GLn13mEMVmsWoik.cache +1 -0
  242. data/test/dummy/tmp/cache/assets/sprockets/v3.0/gL/gLSHSgXhdqJvlFY1r2EipTUTXI6Z2QBb_pgQ4A4FBhk.cache +0 -0
  243. data/test/dummy/tmp/cache/assets/sprockets/v3.0/hX/hX_1Br_XYMH3o5EDrBCM7jD4AR9iJhUNHzhUUMAksV8.cache +0 -0
  244. data/test/dummy/tmp/cache/assets/sprockets/v3.0/jN/jNaneI4p8mnSH0z3QpTwlCdeWbFSUWV_C_mRAg5hDXw.cache +0 -0
  245. data/test/dummy/tmp/cache/assets/sprockets/v3.0/jo/JobbYwsoKbjQxVXQz7IQbMX23HEyDbSA_zrRPPKhiUc.cache +1 -0
  246. data/test/dummy/tmp/cache/assets/sprockets/v3.0/jo/jo96mxml_RK1qUCEXd0yVf5dnSLoPqp00LEbETIIb2s.cache +1 -0
  247. data/test/dummy/tmp/cache/assets/sprockets/v3.0/k1/k1-Vu1bnBwnOu3y_QFBFyAtSGlUdvb4uhgM8xsB-_Tg.cache +1 -0
  248. data/test/dummy/tmp/cache/assets/sprockets/v3.0/k1/k1NKoz-AMR9xzRByivuGFkyp0MWQ3heaVviggtIrdK8.cache +4 -0
  249. data/test/dummy/tmp/cache/assets/sprockets/v3.0/kg/kgn1MwDe-7_T00earCMuIoRMLaeOt7S4r7769Pp8M-c.cache +1 -0
  250. data/test/dummy/tmp/cache/assets/sprockets/v3.0/l4/l4uI_1HekPy0WPa8gOz8XmbUxJCl334KSYSlpFEdSfM.cache +1 -0
  251. data/test/dummy/tmp/cache/assets/sprockets/v3.0/l6/l6KEh8r-KKee9rVKcxqIEeF5TqUwW2VqYb7paP0gCQ0.cache +1 -0
  252. data/test/dummy/tmp/cache/assets/sprockets/v3.0/lB/lBegfVYn4A81In0Ld3bvxg31hzp6sjlOr7dmdJXGjSU.cache +1 -0
  253. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ld/ldfozoSusCzw0GM19A6-LvzzAfrx_RQrGmDDLogloFs.cache +1 -0
  254. data/test/dummy/tmp/cache/assets/sprockets/v3.0/m4/m4-SSFfa1SYGt723CkTWQYbtaT7MBp8szC3rPFbOPuU.cache +2 -0
  255. data/test/dummy/tmp/cache/assets/sprockets/v3.0/mG/mGHo3qDusQEKkkocFHTDR0J5EMIlrzROC_2ghaZYAgk.cache +0 -0
  256. data/test/dummy/tmp/cache/assets/sprockets/v3.0/mO/mOP3Sm9m1M6TmWps33skF4hvd092don0dHlobn9ems0.cache +1 -0
  257. data/test/dummy/tmp/cache/assets/sprockets/v3.0/mf/mfK3V0cWrlgG3paJRNUczrUppBoIWAam-b6p-J_WlQk.cache +1 -0
  258. data/test/dummy/tmp/cache/assets/sprockets/v3.0/mz/mzKBIxymZpXit4v2iRnRXIK5uUIS6uUZjI0W9LZ2Bh0.cache +1 -0
  259. data/test/dummy/tmp/cache/assets/sprockets/v3.0/n2/n20Gp--0D3PUtpFMitv38Kp8LlMft5UOkTRoNHO2Tsk.cache +1 -0
  260. data/test/dummy/tmp/cache/assets/sprockets/v3.0/nB/nBH2-bAlepNFvXTSF-tmll0Rc5qvcVumktcl1KYydgI.cache +0 -0
  261. data/test/dummy/tmp/cache/assets/sprockets/v3.0/np/np0_MPHZcS-cPB69C1GzPDnipzfTk84FOeH9QXioyUw.cache +1 -0
  262. data/test/dummy/tmp/cache/assets/sprockets/v3.0/nr/nr4V60agkWIjRWDV23Auh41K0GRcXp5ctSoOyfQ1ANM.cache +2 -0
  263. data/test/dummy/tmp/cache/assets/sprockets/v3.0/oF/oF1leWgLg8_fDwI2qhBAo-V4f9ZODIH5mHd0PugDsNs.cache +0 -0
  264. data/test/dummy/tmp/cache/assets/sprockets/v3.0/oR/oRE5A6xr4tZ7gQD2Rwr9V_Z0l5vagZKNRe23f-TL7b4.cache +1 -0
  265. data/test/dummy/tmp/cache/assets/sprockets/v3.0/oh/ohJ4Vsjgs6q6LfnHd8vG2TI65-F-l8BYiRWwjcsFso8.cache +1 -0
  266. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pI/pIvfsBJlCo1lQR93RpavkgL1N4G3Kikd1Qs4Pl-zjNU.cache +1 -0
  267. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pP/pPyIvuoG5HNslNZnl6WuQyv0GTL50R4LB6MkifeioTU.cache +0 -0
  268. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pe/peB66vL_jJOczpV2_nGLjkEysGH1NhHdDGl_ZS_v7hk.cache +1 -0
  269. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pf/pFmcB3iWgwr2YrgnAyzYh8THxlAVyR2mFfvTYHH-YyM.cache +1 -0
  270. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pf/pfMqjshoLtd1XSMyglJefgksJD4UXBHcZQNawdXm1VY.cache +0 -0
  271. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pm/pmgvDDjavDz10BkFzD-EJtoEinfdu3nJQbbRhXwUNaE.cache +1 -0
  272. data/test/dummy/tmp/cache/assets/sprockets/v3.0/pq/pqpMzQ1IGWV58QESaBli5VpFIdwysPKJJcvDwSjJTYA.cache +0 -0
  273. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ps/psQe2VtxoTgu7PHDADBGZ1cVzeCrGQIdXf7_0DEK4Dk.cache +1 -0
  274. data/test/dummy/tmp/cache/assets/sprockets/v3.0/py/pyoxXth3hjzgIEciAO90l0vIVCTJgEXsT4OZCMgq2Sk.cache +1 -0
  275. data/test/dummy/tmp/cache/assets/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache +0 -0
  276. data/test/dummy/tmp/cache/assets/sprockets/v3.0/q8/q8fTGiTy76lCLNbNwWWd9l7vwZj-7UQAOILzuNpyPYE.cache +1 -0
  277. data/test/dummy/tmp/cache/assets/sprockets/v3.0/qC/qC9rgHGmZKwnZ8QdZB2jEU3T7-_a-ZwdCP-cse12hcQ.cache +0 -0
  278. data/test/dummy/tmp/cache/assets/sprockets/v3.0/qG/qGAmOmX47-Od1oIVpNpRm0QtluFKIG_YDrBxg92f_Qk.cache +0 -0
  279. data/test/dummy/tmp/cache/assets/sprockets/v3.0/qa/qa3eRLDemADWcqVjtdOy1Rn3QtrRcIxpEm-GJQK8VIw.cache +1 -0
  280. data/test/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9BXtR-nk0bHNNjdnm89FiY3vzg326WQ0cozcR7MAVs.cache +1 -0
  281. data/test/dummy/tmp/cache/assets/sprockets/v3.0/rX/RX0qkXXVT2XvXlxf2UC2FX1cNADKfsTUaoqdW0XdgvU.cache +1 -0
  282. data/test/dummy/tmp/cache/assets/sprockets/v3.0/rX/rXOJ0KA20NEA1hDNnr9Vhh7tAjsRU6oFuC9b2xSX7Wg.cache +1 -0
  283. data/test/dummy/tmp/cache/assets/sprockets/v3.0/rm/rmSkgYSgACYLjfteWUTVHgLRF015ih5Ghn5hPGzr6l4.cache +0 -0
  284. data/test/dummy/tmp/cache/assets/sprockets/v3.0/rt/rtmN66UYiZRgWN-5O6RltSKgB5FfJjrpo6WGuITzsak.cache +1 -0
  285. data/test/dummy/tmp/cache/assets/sprockets/v3.0/sA/sAJQRjCY3ZHLydFrYlHqT7wIPCHWKxekLe1n7pFZXSc.cache +0 -0
  286. data/test/dummy/tmp/cache/assets/sprockets/v3.0/sm/smClQJEaXbOXsJz0VnFW9TkFrmIyIXf_iC6PVz61bzo.cache +1 -0
  287. data/test/dummy/tmp/cache/assets/sprockets/v3.0/sy/syQjP7AEbQA9Rtv5DQwdHhgxOttKIr0bTu-fkgastLc.cache +1 -0
  288. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ti/tiXJRasL-8irn9-ucULKRcizf-T5j6chc9o9TiGbLg4.cache +0 -0
  289. data/test/dummy/tmp/cache/assets/sprockets/v3.0/tm/TMgw-aQC9dgBPc1BXBy62shB9NoqoN9W_ExXyTJ2lmg.cache +1 -0
  290. data/test/dummy/tmp/cache/assets/sprockets/v3.0/tm/tmQCbe3HULQeoxiX25lw9r9G-l0x3N0GUBd3Q3E_Gg4.cache +1 -0
  291. data/test/dummy/tmp/cache/assets/sprockets/v3.0/u4/u4yRYa-sHfUpWhua-XHN5xqt-JDg27-7PCqWYOZ224s.cache +1 -0
  292. data/test/dummy/tmp/cache/assets/sprockets/v3.0/uR/uRsMGxtpdSbYT4BnABXQz1hmlUPS0ni3GZRhNilmVTw.cache +0 -0
  293. data/test/dummy/tmp/cache/assets/sprockets/v3.0/uk/ukyUQTHe6_q46nFt1pNk8lHJ7yMXClSkvMKEITn8fXw.cache +1 -0
  294. data/test/dummy/tmp/cache/assets/sprockets/v3.0/uq/uqqkZXvLr_0jkDyOG0Y7A6eKYk4NMV5wkIjfV_Bjluk.cache +1 -0
  295. data/test/dummy/tmp/cache/assets/sprockets/v3.0/vA/vANYosMYbDyO0OInbCnKkq5uvcQxvkOvhEyRDu7wa0Y.cache +0 -0
  296. data/test/dummy/tmp/cache/assets/sprockets/v3.0/vL/vLGD24TdjMqkMC9OulNocvIxraeSSi9ZkIyBImgABnw.cache +0 -0
  297. data/test/dummy/tmp/cache/assets/sprockets/v3.0/vy/vyYy1Bc7NhRijtwmLDahiYL4cbniLDW8FDb15jHT62I.cache +0 -0
  298. data/test/dummy/tmp/cache/assets/sprockets/v3.0/w0/w0eQItpBpGPhWcCLqMgaLY0JLZXutLWFcsUTn1qR5pk.cache +0 -0
  299. data/test/dummy/tmp/cache/assets/sprockets/v3.0/wF/wFlOPYS4FNz7cD-_U_rwg8F8PUn13yaWFooOxfJo4P0.cache +1 -0
  300. data/test/dummy/tmp/cache/assets/sprockets/v3.0/wc/wc8UYUZjewZhupzm83IS5YSBKTIWJ_JNEqnHY7YxFMc.cache +2 -0
  301. data/test/dummy/tmp/cache/assets/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache +0 -0
  302. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xF/xFZYxCrU064E66OKGh51d8_W4JWUwaoWLBq1AFAZPIU.cache +0 -0
  303. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xL/xLXcC1BEJrDSHD7y1h23lTfN3Ipjl84ZykUSTAkjR9U.cache +1 -0
  304. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xN/xNdFjDVsGZY_vt30-9CATW_bnmspkJv5B2qWzbO8u9U.cache +1 -0
  305. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xT/xTFokDlBnhGaP-69TnsrL746Sv_W8kX1v-ddbQK4P6U.cache +0 -0
  306. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xd/xd635CIGQo56JO8fL5i8Dy1msteAYQjpiFthBFWAUIY.cache +0 -0
  307. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xh/xhJCi-D9afo14RwqSYDWL1i747D8B6k9_jmRfJSoYGg.cache +1 -0
  308. data/test/dummy/tmp/cache/assets/sprockets/v3.0/xi/xiNNGLgEegeUG_f4ZTKGOh6ba_XNjRdnOcvboWindM4.cache +0 -0
  309. data/test/dummy/tmp/cache/assets/sprockets/v3.0/yJ/yJsY6xrDWnxzzJt93h8k-4GjMeSMrgoKkrTrV7xl17Y.cache +0 -0
  310. data/test/dummy/tmp/cache/assets/sprockets/v3.0/yL/yL0bdmM8VCSMv3PrRzxQuK97ryFH5AwWy-S1S6SPCV4.cache +0 -0
  311. data/test/dummy/tmp/cache/assets/sprockets/v3.0/y_/y_DWqm2YPyqW8nf9NKBld9BoSili1-763FurOXM--XM.cache +1 -0
  312. data/test/dummy/tmp/cache/assets/sprockets/v3.0/yo/yoAO2cAGL23s9uCXo3NeFZcXWdsm2is6LNPR9BTaz9E.cache +1 -0
  313. data/test/dummy/tmp/cache/assets/sprockets/v3.0/z5/z5xi0xizT_upzhmbLHIO97TA6HzJ4MmDwg5RKHDAuRQ.cache +0 -0
  314. data/test/dummy/tmp/cache/assets/sprockets/v3.0/zJ/zJqqUJchm4LP7TqM8CZ8ZjGkDrxe_k2_Yum4WUCIxjc.cache +0 -0
  315. data/test/dummy/tmp/cache/assets/sprockets/v3.0/zO/zOeLSHXDQa1VugXjg2x1RO19C5bav-CJ5e6el6syIcE.cache +0 -0
  316. data/test/dummy/tmp/cache/assets/sprockets/v3.0/zc/zCK3gD6LO48YyjRHsmCq52KaC6MfOcn-2PLhvdGgNpA.cache +1 -0
  317. data/test/dummy/tmp/cache/assets/sprockets/v3.0/zc/zcV1wOXds_ytFpSvePYmuQoXrSwPHLM8TuSfnyhmYuM.cache +0 -0
  318. data/test/dummy/tmp/cache/assets/sprockets/v3.0/zu/zuyy-EWaEKL5Sx0PP_173Hx62_I-53Q-yJrXsIYvZhc.cache +1 -0
  319. data/test/test_helper.rb +1 -1
  320. data/vendor/assets/javascripts/xterm.js +6234 -0
  321. data/vendor/assets/javascripts/xterm.js.map +1 -0
  322. data/vendor/assets/javascripts/xterm/addons/fit/fit.js +49 -0
  323. data/vendor/assets/javascripts/xterm/addons/fit/fit.js.map +1 -0
  324. data/vendor/assets/javascripts/xterm/addons/fullscreen/fullscreen.js +30 -0
  325. data/vendor/assets/javascripts/xterm/addons/fullscreen/fullscreen.js.map +1 -0
  326. data/vendor/assets/stylesheets/xterm.css +124 -0
  327. data/vendor/assets/stylesheets/xterm/addons/fullscreen/fullscreen.css +10 -0
  328. metadata +636 -213
  329. data/lib/rvt/colors.rb +0 -87
  330. data/lib/rvt/colors/light.rb +0 -24
  331. data/lib/rvt/colors/monokai.rb +0 -24
  332. data/lib/rvt/colors/solarized.rb +0 -47
  333. data/lib/rvt/colors/tango.rb +0 -24
  334. data/lib/rvt/colors/xterm.rb +0 -24
  335. data/test/controllers/rvt/console_sessions_controller_test.rb +0 -97
  336. data/test/dummy/config/initializers/secret_token.rb +0 -12
  337. data/test/dummy/tmp/cache/assets/development/sprockets/0509a6e0e75d9ac5a88bba7291b04686 +0 -0
  338. data/test/dummy/tmp/cache/assets/development/sprockets/2bd9d10dae311aa2dfb6dea9c1e0ad50 +0 -0
  339. data/test/dummy/tmp/cache/assets/development/sprockets/2f41a6a41d0a16db31cabd2b8689ca00 +0 -0
  340. data/test/dummy/tmp/cache/assets/development/sprockets/4de66e84a0d6f009fac50cd608fb8581 +0 -0
  341. data/test/dummy/tmp/cache/assets/development/sprockets/56e8026311075410507152df2aea4307 +0 -0
  342. data/test/dummy/tmp/cache/assets/development/sprockets/9542de15712d45f70221931bf78c00e5 +0 -0
  343. data/test/dummy/tmp/cache/assets/development/sprockets/98cea396a602c53d876e79bf4b89de3b +0 -0
  344. data/test/dummy/tmp/cache/assets/development/sprockets/9df3968b0f171feec749766fffa50b2e +0 -0
  345. data/test/dummy/tmp/cache/assets/development/sprockets/aa5fc4cb46c5294192c9d3af8824f88b +0 -0
  346. data/test/dummy/tmp/cache/assets/development/sprockets/ac7197dc7dd9ab362d915d19e37a8e01 +0 -0
  347. data/test/dummy/tmp/cache/assets/development/sprockets/b238befd6eff46b26d56322c1450ea45 +0 -0
  348. data/test/dummy/tmp/cache/assets/development/sprockets/c69b8b79c21fd48ad84c3fad87945a5c +0 -0
  349. data/test/dummy/tmp/cache/assets/development/sprockets/da4318a4d8364d0616edd706508371bc +0 -0
  350. data/test/dummy/tmp/cache/assets/development/sprockets/dd71b14df42fd6dc95355cded9e4d0f9 +0 -0
  351. data/test/dummy/tmp/cache/assets/development/sprockets/eb06cae1627276e46965809e766aff13 +0 -0
  352. data/test/dummy/tmp/cache/assets/development/sprockets/edffb5017d27ddb65965203636286405 +0 -0
  353. data/test/dummy/tmp/cache/assets/development/sprockets/f0ced5f3d4a75fce1c596d6c3f97a42d +0 -0
  354. data/test/dummy/tmp/cache/assets/development/sprockets/fb9e611526e612ba797f0c11b987826b +0 -0
  355. data/test/dummy/tmp/cache/assets/sprockets/v3.0/-K/-KiIicXUmKvS01lViUN0fVWjnk3WG8R7AU8KuOnsq8Q.cache +0 -1
  356. data/test/dummy/tmp/cache/assets/sprockets/v3.0/17/17pGZu57zKoZ94QZm4aKckh0sCZX8b7JQLSsbcOHHVk.cache +0 -0
  357. data/test/dummy/tmp/cache/assets/sprockets/v3.0/2p/2pfdtD4Unn94fgfTvW9IuHcslz_aC53bupzRnnBTjz8.cache +0 -1
  358. data/test/dummy/tmp/cache/assets/sprockets/v3.0/3V/3VuACKK5EZL0kFdIsulnRkj_H33Bhgt8rWXOQ3GtxK4.cache +0 -1
  359. data/test/dummy/tmp/cache/assets/sprockets/v3.0/4f/4fGELkMBNoXbrN_1xBFotqQ7TvvnD6wqNwzTIQxQoig.cache +0 -1
  360. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5E/5ESZnaE5qh0iYvz9xmZmrU99psPmVEF9xbaOmhKjVd0.cache +0 -1
  361. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5H/5HcK5g4Hf81q5eDV-D2FxWhFvU-FQC_0xXhORcReKFM.cache +0 -0
  362. data/test/dummy/tmp/cache/assets/sprockets/v3.0/5f/5f3EHjGVDFwHFPyQq5uKHDZpnzyuP21Bb2vs0abI_Uo.cache +0 -0
  363. data/test/dummy/tmp/cache/assets/sprockets/v3.0/6C/6CwrwCCdUsKoCchA9tI10DcEXTuTcCCvuaOWGBum96s.cache +0 -0
  364. data/test/dummy/tmp/cache/assets/sprockets/v3.0/74/74nSxlehXGJRbD0LU0Iba6VeJuNBCprOS7zalbnRXdQ.cache +0 -0
  365. data/test/dummy/tmp/cache/assets/sprockets/v3.0/8V/8VDZPz7iaeHUAFJM6c__4RL2qobs_HxEfh1cvN8X2tE.cache +0 -1
  366. data/test/dummy/tmp/cache/assets/sprockets/v3.0/8W/8WO5VcJOFOrSWseN2SKniU76vW4j6komRdMzmvQwHOQ.cache +0 -0
  367. data/test/dummy/tmp/cache/assets/sprockets/v3.0/AN/ANlzs9QWeQu6lYeBwGWFcK00sfOTLMsFsZaQzrzTEIA.cache +0 -1
  368. data/test/dummy/tmp/cache/assets/sprockets/v3.0/An/Ana-_KrSkUp0SHOpAG3yEY_792tMopenBFYRnrEemRQ.cache +0 -0
  369. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Bq/BqY9mFfdK9O4325lbO_-_QZCbEZuGiNguITrgGRIfNM.cache +0 -1
  370. data/test/dummy/tmp/cache/assets/sprockets/v3.0/GF/GFVuBv-xJC6l9uzpvIkeOzFpM_wrzgvn5gJpRJZJQYY.cache +0 -1
  371. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Gn/GnRhwIvx6FcsFco_Zaww1BSo7PCh-rHEJnmYByESMmk.cache +0 -1
  372. data/test/dummy/tmp/cache/assets/sprockets/v3.0/IR/IRkzGfhZ_j61PMxiMlMuiO5_8GJrPxVz_q1fUw8lELA.cache +0 -1
  373. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Ol/OlJLFMx2ecfQUa6QubAYEN6Nef_1Jk3rIggdhypnhKE.cache +0 -0
  374. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Or/OrmkzKYvYsup9pzrnDM4jqhxXtZ49RvP0eCaqe3chvA.cache +0 -0
  375. data/test/dummy/tmp/cache/assets/sprockets/v3.0/PV/PV-WmLYkFJdjKgVXpPxYl8nhQBu5frexNF5_DIbQKSM.cache +0 -1
  376. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Po/PoeLkPEvD2iajH_gaRh-sIFdCZ-jEaac8_Kdt5EnBH0.cache +0 -1
  377. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Rp/RphNp2ADQ6h0qpBMeRGccIFKL3cPNnEyRszHOHNcwV0.cache +0 -1
  378. data/test/dummy/tmp/cache/assets/sprockets/v3.0/UX/UXDhiw_eV2_5-uhXuG5hggT62vcTU3mRXVHdd8hwNtI.cache +0 -1
  379. data/test/dummy/tmp/cache/assets/sprockets/v3.0/X5/X5A2BcGLOrFB27HxUPfMTY1R9Pc_V4dlB49BKzEkbI4.cache +0 -1
  380. data/test/dummy/tmp/cache/assets/sprockets/v3.0/XW/XWSxy-Iv-mixLzAfY2etVgorBgWnKcDzPvc5JYtv8ZQ.cache +0 -1
  381. data/test/dummy/tmp/cache/assets/sprockets/v3.0/YU/YUnPOcXA7tScQSqfkzbf-VVnrkDph0mOtFRWXdA41CQ.cache +0 -1
  382. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Yg/YgzFmnUV-Bc8yd1PJan3HIFu4EI8kc4q220Ea3F-lnM.cache +0 -0
  383. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Z5/Z5LXG7HQ6dbcPnio52VUtebna6NdsQmvuJCMq01Vths.cache +0 -0
  384. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZJ/ZJjFVQk_XGGXlz4fvvlEWY-4Wy0ZaJ6WrBHSzpiBIm8.cache +0 -1
  385. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ZT/ZTsUUbGZ_rkYZ41o_lsp46dSuiGxGeOt4Q5BO3tRQHo.cache +0 -0
  386. data/test/dummy/tmp/cache/assets/sprockets/v3.0/Zy/ZyyIY2PVVJpW_kZNCpOdjl2WEzSM8NsQMisOdGTIO54.cache +0 -0
  387. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cJ/cJPDe92SSVjhN0aWjrgKTT4kS0Fok6FVUS6Ucf3CQ4k.cache +0 -0
  388. data/test/dummy/tmp/cache/assets/sprockets/v3.0/cW/cWtFGImKhUS7JYaEIBNPmFmtxIokpNEtprbrIu-KYLk.cache +0 -0
  389. data/test/dummy/tmp/cache/assets/sprockets/v3.0/eR/eRFxgeqg4P6SKIaqiHeDezODcKT_sMwFyGfqtPmu7vY.cache +0 -1
  390. data/test/dummy/tmp/cache/assets/sprockets/v3.0/g2/g2c3cRllZCQaG2kipoX1Cr40y7Lmne7Xp0JWV2rFVnk.cache +0 -1
  391. data/test/dummy/tmp/cache/assets/sprockets/v3.0/hO/hOh9hLhXju7HOOyQ22B04x2-tCSXXkAhbyXVbTWGwQM.cache +0 -0
  392. data/test/dummy/tmp/cache/assets/sprockets/v3.0/hg/hgu4xAfu5uOcafMf7-jA-qLNDcM7XgWFdwAfHjN4mQE.cache +0 -1
  393. data/test/dummy/tmp/cache/assets/sprockets/v3.0/le/lelLtTsvG67CE4gtCdbS_eRsDTCgrhSWFTg_t7gBbWI.cache +0 -1
  394. data/test/dummy/tmp/cache/assets/sprockets/v3.0/ql/ql0YZqZCZb93mAbIX-l1Ut97H7xFR7iqs2cLenFIMDY.cache +0 -1
  395. data/test/dummy/tmp/cache/assets/sprockets/v3.0/so/soQJaougFDETlHZ4JMK_lVbAnKBYVa5Bz-HT5zJRHu0.cache +0 -1
  396. data/test/dummy/tmp/cache/assets/sprockets/v3.0/u-/u-8MlgYJTKG5XosY4wBeyytbkS581QUBp6M3jwob82c.cache +0 -0
  397. data/test/dummy/tmp/cache/assets/sprockets/v3.0/vk/vkZdW5MBiFdQHWCaACKYNgJd9pD_heV3KjZs5pY4aIs.cache +0 -0
  398. data/test/dummy/tmp/cache/assets/sprockets/v3.0/yn/ynr5ukJ9QD4J7P9Of9s-s-NY_o659ZDZ_fOOr-M1G_w.cache +0 -1
  399. data/test/rvt/colors_test.rb +0 -58
  400. data/test/rvt/engine_test.rb +0 -136
  401. data/vendor/assets/javascripts/term.js +0 -5771
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xterm.js","sources":["../src/xterm.ts","../src/utils/Sounds.ts","../src/utils/MouseHelper.ts","../src/utils/Generic.ts","../src/utils/CircularList.ts","../src/utils/CharMeasure.ts","../src/utils/Browser.ts","../src/renderer/Types.ts","../src/renderer/TextRenderLayer.ts","../src/renderer/SelectionRenderLayer.ts","../src/renderer/Renderer.ts","../src/renderer/LinkRenderLayer.ts","../src/renderer/GridCache.ts","../src/renderer/CursorRenderLayer.ts","../src/renderer/ColorManager.ts","../src/renderer/CharAtlas.ts","../src/renderer/BaseRenderLayer.ts","../src/input/MouseZoneManager.ts","../src/handlers/Clipboard.ts","../src/Viewport.ts","../src/Types.ts","../src/Terminal.ts","../src/SelectionModel.ts","../src/SelectionManager.ts","../src/Parser.ts","../src/Linkifier.ts","../src/InputHandler.ts","../src/EventEmitter.ts","../src/EscapeSequences.ts","../src/CompositionHelper.ts","../src/Charsets.ts","../src/CharWidth.ts","../src/BufferSet.ts","../src/Buffer.ts","../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * This file is the entry point for browserify.\n */\n\nimport { Terminal } from './Terminal';\n\nmodule.exports = Terminal;\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n// Source: https://freesound.org/people/altemark/sounds/45759/\n// This sound is released under the Creative Commons Attribution 3.0 Unported\n// (CC BY 3.0) license. It was created by 'altemark'. No modifications have been\n// made, apart from the conversion to base64.\nexport const BellSound = 'data:audio/wav;base64,UklGRigBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQBAADpAFgCwAMlBZoG/wdmCcoKRAypDQ8PbRDBEQQTOxRtFYcWlBePGIUZXhoiG88bcBz7HHIdzh0WHlMeZx51HmkeUx4WHs8dah0AHXwc3hs9G4saxRnyGBIYGBcQFv8U4RPAEoYRQBACD70NWwwHC6gJOwjWBloF7gOBAhABkf8b/qv8R/ve+Xf4Ife79W/0JfPZ8Z/wde9N7ijtE+wU6xvqM+lb6H7nw+YX5mrlxuQz5Mzje+Ma49fioeKD4nXiYeJy4pHitOL04j/jn+MN5IPkFOWs5U3mDefM55/ogOl36m7rdOyE7abuyu8D8Unyj/Pg9D/2qfcb+Yn6/vuK/Qj/lAAlAg==';\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ICharMeasure } from '../Interfaces';\nimport { IRenderer } from '../renderer/Interfaces';\n\nexport class MouseHelper {\n constructor(private _renderer: IRenderer) {}\n\n public static getCoordsRelativeToElement(event: {pageX: number, pageY: number}, element: HTMLElement): [number, number] {\n // Ignore browsers that don't support MouseEvent.pageX\n if (event.pageX == null) {\n return null;\n }\n\n const originalElement = element;\n let x = event.pageX;\n let y = event.pageY;\n\n // Converts the coordinates from being relative to the document to being\n // relative to the terminal.\n while (element) {\n x -= element.offsetLeft;\n y -= element.offsetTop;\n element = 'offsetParent' in element ? <HTMLElement>element.offsetParent : <HTMLElement>element.parentElement;\n }\n element = originalElement;\n while (element && element !== element.ownerDocument.body) {\n x += element.scrollLeft;\n y += element.scrollTop;\n element = <HTMLElement>element.parentElement;\n }\n return [x, y];\n }\n\n /**\n * Gets coordinates within the terminal for a particular mouse event. The result\n * is returned as an array in the form [x, y] instead of an object as it's a\n * little faster and this function is used in some low level code.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param charMeasure The char measure object used to determine character sizes.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows n the terminal.\n * @param isSelection Whether the request is for the selection or not. This will\n * apply an offset to the x value such that the left half of the cell will\n * select that cell and the right half will select the next cell.\n */\n public getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number] {\n // Coordinates cannot be measured if charMeasure has not been initialized\n if (!charMeasure.width || !charMeasure.height) {\n return null;\n }\n\n const coords = MouseHelper.getCoordsRelativeToElement(event, element);\n if (!coords) {\n return null;\n }\n\n coords[0] = Math.ceil((coords[0] + (isSelection ? this._renderer.dimensions.actualCellWidth / 2 : 0)) / this._renderer.dimensions.actualCellWidth);\n coords[1] = Math.ceil(coords[1] / this._renderer.dimensions.actualCellHeight);\n\n // Ensure coordinates are within the terminal viewport. Note that selections\n // need an addition point of precision to cover the end point (as characters\n // cover half of one char and half of the next).\n coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));\n coords[1] = Math.min(Math.max(coords[1], 1), rowCount);\n\n return coords;\n }\n\n /**\n * Gets coordinates within the terminal for a particular mouse event, wrapping\n * them to the bounds of the terminal and adding 32 to both the x and y values\n * as expected by xterm.\n * @param event The mouse event.\n * @param element The terminal's container element.\n * @param charMeasure The char measure object used to determine character sizes.\n * @param colCount The number of columns in the terminal.\n * @param rowCount The number of rows in the terminal.\n */\n public getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number): { x: number, y: number } {\n const coords = this.getCoords(event, element, charMeasure, lineHeight, colCount, rowCount);\n let x = coords[0];\n let y = coords[1];\n\n // xterm sends raw bytes and starts at 32 (SP) for each.\n x += 32;\n y += 32;\n\n return { x, y };\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Return if the given array contains the given element\n * @param {Array} array The array to search for the given element.\n * @param {Object} el The element to look for into the array\n */\nexport function contains(arr: any[], el: any): boolean {\n return arr.indexOf(el) >= 0;\n};\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter';\nimport { ICircularList } from '../Interfaces';\n\n/**\n * Represents a circular list; a list with a maximum size that wraps around when push is called,\n * overriding values at the start of the list.\n */\nexport class CircularList<T> extends EventEmitter implements ICircularList<T> {\n protected _array: T[];\n private _startIndex: number;\n private _length: number;\n\n constructor(\n private _maxLength: number\n ) {\n super();\n this._array = new Array<T>(this._maxLength);\n this._startIndex = 0;\n this._length = 0;\n }\n\n public get maxLength(): number {\n return this._maxLength;\n }\n\n public set maxLength(newMaxLength: number) {\n // There was no change in maxLength, return early.\n if (this._maxLength === newMaxLength) {\n return;\n }\n\n // Reconstruct array, starting at index 0. Only transfer values from the\n // indexes 0 to length.\n let newArray = new Array<T>(newMaxLength);\n for (let i = 0; i < Math.min(newMaxLength, this.length); i++) {\n newArray[i] = this._array[this._getCyclicIndex(i)];\n }\n this._array = newArray;\n this._maxLength = newMaxLength;\n this._startIndex = 0;\n }\n\n public get length(): number {\n return this._length;\n }\n\n public set length(newLength: number) {\n if (newLength > this._length) {\n for (let i = this._length; i < newLength; i++) {\n this._array[i] = undefined;\n }\n }\n this._length = newLength;\n }\n\n public get forEach(): (callbackfn: (value: T, index: number) => void) => void {\n return (callbackfn: (value: T, index: number) => void) => {\n let i = 0;\n let length = this.length;\n for (let i = 0; i < length; i++) {\n callbackfn(this.get(i), i);\n }\n };\n }\n\n /**\n * Gets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index of the value to get.\n * @return The value corresponding to the index.\n */\n public get(index: number): T {\n return this._array[this._getCyclicIndex(index)];\n }\n\n /**\n * Sets the value at an index.\n *\n * Note that for performance reasons there is no bounds checking here, the index reference is\n * circular so this should always return a value and never throw.\n * @param index The index to set.\n * @param value The value to set.\n */\n public set(index: number, value: T): void {\n this._array[this._getCyclicIndex(index)] = value;\n }\n\n /**\n * Pushes a new value onto the list, wrapping around to the start of the array, overriding index 0\n * if the maximum length is reached.\n * @param value The value to push onto the list.\n */\n public push(value: T): void {\n this._array[this._getCyclicIndex(this._length)] = value;\n if (this._length === this._maxLength) {\n this._startIndex++;\n if (this._startIndex === this._maxLength) {\n this._startIndex = 0;\n }\n this.emit('trim', 1);\n } else {\n this._length++;\n }\n }\n\n /**\n * Removes and returns the last value on the list.\n * @return The popped value.\n */\n public pop(): T {\n return this._array[this._getCyclicIndex(this._length-- - 1)];\n }\n\n /**\n * Deletes and/or inserts items at a particular index (in that order). Unlike\n * Array.prototype.splice, this operation does not return the deleted items as a new array in\n * order to save creating a new array. Note that this operation may shift all values in the list\n * in the worst case.\n * @param start The index to delete and/or insert.\n * @param deleteCount The number of elements to delete.\n * @param items The items to insert.\n */\n public splice(start: number, deleteCount: number, ...items: T[]): void {\n // Delete items\n if (deleteCount) {\n for (let i = start; i < this._length - deleteCount; i++) {\n this._array[this._getCyclicIndex(i)] = this._array[this._getCyclicIndex(i + deleteCount)];\n }\n this._length -= deleteCount;\n }\n\n if (items && items.length) {\n // Add items\n for (let i = this._length - 1; i >= start; i--) {\n this._array[this._getCyclicIndex(i + items.length)] = this._array[this._getCyclicIndex(i)];\n }\n for (let i = 0; i < items.length; i++) {\n this._array[this._getCyclicIndex(start + i)] = items[i];\n }\n\n // Adjust length as needed\n if (this._length + items.length > this.maxLength) {\n const countToTrim = (this._length + items.length) - this.maxLength;\n this._startIndex += countToTrim;\n this._length = this.maxLength;\n this.emit('trim', countToTrim);\n } else {\n this._length += items.length;\n }\n }\n }\n\n /**\n * Trims a number of items from the start of the list.\n * @param count The number of items to remove.\n */\n public trimStart(count: number): void {\n if (count > this._length) {\n count = this._length;\n }\n this._startIndex += count;\n this._length -= count;\n this.emit('trim', count);\n }\n\n public shiftElements(start: number, count: number, offset: number): void {\n if (count <= 0) {\n return;\n }\n if (start < 0 || start >= this._length) {\n throw new Error('start argument out of range');\n }\n if (start + offset < 0) {\n throw new Error('Cannot shift elements in list beyond index 0');\n }\n\n if (offset > 0) {\n for (let i = count - 1; i >= 0; i--) {\n this.set(start + i + offset, this.get(start + i));\n }\n const expandListBy = (start + count + offset) - this._length;\n if (expandListBy > 0) {\n this._length += expandListBy;\n while (this._length > this.maxLength) {\n this._length--;\n this._startIndex++;\n this.emit('trim', 1);\n }\n }\n } else {\n for (let i = 0; i < count; i++) {\n this.set(start + i + offset, this.get(start + i));\n }\n }\n }\n\n /**\n * Gets the cyclic index for the specified regular index. The cyclic index can then be used on the\n * backing array to get the element associated with the regular index.\n * @param index The regular index.\n * @returns The cyclic index.\n */\n private _getCyclicIndex(index: number): number {\n return (this._startIndex + index) % this.maxLength;\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { EventEmitter } from '../EventEmitter';\nimport { ICharMeasure, ITerminal, ITerminalOptions } from '../Interfaces';\n\n/**\n * Utility class that measures the size of a character. Measurements are done in\n * the DOM rather than with a canvas context because support for extracting the\n * height of characters is patchy across browsers.\n */\nexport class CharMeasure extends EventEmitter implements ICharMeasure {\n private _document: Document;\n private _parentElement: HTMLElement;\n private _measureElement: HTMLElement;\n private _width: number;\n private _height: number;\n\n constructor(document: Document, parentElement: HTMLElement) {\n super();\n this._document = document;\n this._parentElement = parentElement;\n this._measureElement = this._document.createElement('span');\n this._measureElement.style.position = 'absolute';\n this._measureElement.style.top = '0';\n this._measureElement.style.left = '-9999em';\n this._measureElement.style.lineHeight = 'normal';\n this._measureElement.textContent = 'W';\n this._measureElement.setAttribute('aria-hidden', 'true');\n this._parentElement.appendChild(this._measureElement);\n }\n\n public get width(): number {\n return this._width;\n }\n\n public get height(): number {\n return this._height;\n }\n\n public measure(options: ITerminalOptions): void {\n this._measureElement.style.fontFamily = options.fontFamily;\n this._measureElement.style.fontSize = `${options.fontSize}px`;\n const geometry = this._measureElement.getBoundingClientRect();\n // The element is likely currently display:none, we should retain the\n // previous value.\n if (geometry.width === 0 || geometry.height === 0) {\n return;\n }\n if (this._width !== geometry.width || this._height !== geometry.height) {\n this._width = geometry.width;\n this._height = Math.ceil(geometry.height);\n this.emit('charsizechanged');\n }\n }\n\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { contains } from './Generic';\n\nconst isNode = (typeof navigator === 'undefined') ? true : false;\nconst userAgent = (isNode) ? 'node' : navigator.userAgent;\nconst platform = (isNode) ? 'node' : navigator.platform;\n\nexport const isFirefox = !!~userAgent.indexOf('Firefox');\nexport const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');\n\n// Find the users platform. We use this to interpret the meta key\n// and ISO third level shifts.\n// http://stackoverflow.com/q/19877924/577598\nexport const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);\nexport const isIpad = platform === 'iPad';\nexport const isIphone = platform === 'iPhone';\nexport const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);\nexport const isLinux = platform.indexOf('Linux') >= 0;\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n /**\n * Flags used to render terminal text properly.\n */\nexport enum FLAGS {\n BOLD = 1,\n UNDERLINE = 2,\n BLINK = 4,\n INVERSE = 8,\n INVISIBLE = 16,\n DIM = 32\n};\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorSet, IRenderDimensions } from './Interfaces';\nimport { IBuffer, ICharMeasure, ITerminal } from '../Interfaces';\nimport { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from '../Buffer';\nimport { FLAGS } from './Types';\nimport { GridCache } from './GridCache';\nimport { CharData } from '../Types';\nimport { BaseRenderLayer, INVERTED_DEFAULT_COLOR } from './BaseRenderLayer';\n\n/**\n * This CharData looks like a null character, which will forc a clear and render\n * when the character changes (a regular space ' ' character may not as it's\n * drawn state is a cleared cell).\n */\nconst OVERLAP_OWNED_CHAR_DATA: CharData = [null, '', 0, -1];\n\nexport class TextRenderLayer extends BaseRenderLayer {\n private _state: GridCache<CharData>;\n private _characterWidth: number;\n private _characterFont: string;\n private _characterOverlapCache: { [key: string]: boolean } = {};\n\n constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {\n super(container, 'text', zIndex, false, colors);\n this._state = new GridCache<CharData>();\n }\n\n public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void {\n super.resize(terminal, dim, charSizeChanged);\n\n // Clear the character width cache if the font or width has changed\n const terminalFont = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;\n if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) {\n this._characterWidth = dim.scaledCharWidth;\n this._characterFont = terminalFont;\n this._characterOverlapCache = {};\n }\n // Resizing the canvas discards the contents of the canvas so clear state\n this._state.clear();\n this._state.resize(terminal.cols, terminal.rows);\n }\n\n public reset(terminal: ITerminal): void {\n this._state.clear();\n this.clearAll();\n }\n\n public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {\n // Resize has not been called yet\n if (this._state.cache.length === 0) {\n return;\n }\n\n for (let y = startRow; y <= endRow; y++) {\n const row = y + terminal.buffer.ydisp;\n const line = terminal.buffer.lines.get(row);\n\n this.clearCells(0, y, terminal.cols, 1);\n // for (let x = 0; x < terminal.cols; x++) {\n // this._state.cache[x][y] = null;\n // }\n\n for (let x = 0; x < terminal.cols; x++) {\n const charData = line[x];\n const code: number = <number>charData[CHAR_DATA_CODE_INDEX];\n const char: string = charData[CHAR_DATA_CHAR_INDEX];\n const attr: number = charData[CHAR_DATA_ATTR_INDEX];\n let width: number = charData[CHAR_DATA_WIDTH_INDEX];\n\n // The character to the left is a wide character, drawing is owned by\n // the char at x-1\n if (width === 0) {\n // this._state.cache[x][y] = null;\n continue;\n }\n\n // If the character is a space and the character to the left is an\n // overlapping character, skip the character and allow the overlapping\n // char to take full control over this character's cell.\n if (code === 32 /*' '*/) {\n if (x > 0) {\n const previousChar: CharData = line[x - 1];\n if (this._isOverlapping(previousChar)) {\n continue;\n }\n }\n }\n\n // Skip rendering if the character is identical\n // const state = this._state.cache[x][y];\n // if (state && state[CHAR_DATA_CHAR_INDEX] === char && state[CHAR_DATA_ATTR_INDEX] === attr) {\n // // Skip render, contents are identical\n // this._state.cache[x][y] = charData;\n // continue;\n // }\n\n // Clear the old character was not a space with the default background\n // const wasInverted = !!(state && state[CHAR_DATA_ATTR_INDEX] && state[CHAR_DATA_ATTR_INDEX] >> 18 & FLAGS.INVERSE);\n // if (state && !(state[CHAR_DATA_CODE_INDEX] === 32 /*' '*/ && (state[CHAR_DATA_ATTR_INDEX] & 0x1ff) >= 256 && !wasInverted)) {\n // this._clearChar(x, y);\n // }\n // this._state.cache[x][y] = charData;\n\n const flags = attr >> 18;\n let bg = attr & 0x1ff;\n\n // Skip rendering if the character is invisible\n const isDefaultBackground = bg >= 256;\n const isInvisible = flags & FLAGS.INVISIBLE;\n const isInverted = flags & FLAGS.INVERSE;\n if (!code || (code === 32 /*' '*/ && isDefaultBackground && !isInverted) || isInvisible) {\n continue;\n }\n\n // If the character is an overlapping char and the character to the right is a\n // space, take ownership of the cell to the right.\n if (width !== 0 && this._isOverlapping(charData)) {\n // If the character is overlapping, we want to force a re-render on every\n // frame. This is specifically to work around the case where two\n // overlaping chars `a` and `b` are adjacent, the cursor is moved to b and a\n // space is added. Without this, the first half of `b` would never\n // get removed, and `a` would not re-render because it thinks it's\n // already in the correct state.\n // this._state.cache[x][y] = OVERLAP_OWNED_CHAR_DATA;\n if (x < line.length - 1 && line[x + 1][CHAR_DATA_CODE_INDEX] === 32 /*' '*/) {\n width = 2;\n // this._clearChar(x + 1, y);\n // The overlapping char's char data will force a clear and render when the\n // overlapping char is no longer to the left of the character and also when\n // the space changes to another character.\n // this._state.cache[x + 1][y] = OVERLAP_OWNED_CHAR_DATA;\n }\n }\n\n let fg = (attr >> 9) & 0x1ff;\n\n // If inverse flag is on, the foreground should become the background.\n if (isInverted) {\n const temp = bg;\n bg = fg;\n fg = temp;\n if (fg === 256) {\n fg = INVERTED_DEFAULT_COLOR;\n }\n if (bg === 257) {\n bg = INVERTED_DEFAULT_COLOR;\n }\n }\n\n // Clear the cell next to this character if it's wide\n if (width === 2) {\n // this.clearCells(x + 1, y, 1, 1);\n }\n\n // Draw background\n if (bg < 256) {\n this._ctx.save();\n this._ctx.fillStyle = (bg === INVERTED_DEFAULT_COLOR ? this._colors.foreground : this._colors.ansi[bg]);\n this.fillCells(x, y, width, 1);\n this._ctx.restore();\n }\n\n this._ctx.save();\n if (flags & FLAGS.BOLD) {\n this._ctx.font = `bold ${this._ctx.font}`;\n // Convert the FG color to the bold variant\n if (fg < 8) {\n fg += 8;\n }\n }\n\n if (flags & FLAGS.UNDERLINE) {\n if (fg === INVERTED_DEFAULT_COLOR) {\n this._ctx.fillStyle = this._colors.background;\n } else if (fg < 256) {\n // 256 color support\n this._ctx.fillStyle = this._colors.ansi[fg];\n } else {\n this._ctx.fillStyle = this._colors.foreground;\n }\n this.fillBottomLineAtCells(x, y);\n }\n\n this.drawChar(terminal, char, code, width, x, y, fg, bg, !!(flags & FLAGS.BOLD), !!(flags & FLAGS.DIM));\n\n this._ctx.restore();\n }\n }\n }\n\n\t/**\n\t * Whether a character is overlapping to the next cell.\n\t */\n private _isOverlapping(charData: CharData): boolean {\n // Only single cell characters can be overlapping, rendering issues can\n // occur without this check\n if (charData[CHAR_DATA_WIDTH_INDEX] !== 1) {\n return false;\n }\n\n // We assume that any ascii character will not overlap\n const code = charData[CHAR_DATA_CODE_INDEX];\n if (code < 256) {\n return false;\n }\n\n // Deliver from cache if available\n const char = charData[CHAR_DATA_CHAR_INDEX];\n if (this._characterOverlapCache.hasOwnProperty(char)) {\n return this._characterOverlapCache[char];\n }\n\n // Setup the font\n this._ctx.save();\n this._ctx.font = this._characterFont;\n\n // Measure the width of the character, but Math.floor it\n // because that is what the renderer does when it calculates\n // the character dimensions we are comparing against\n const overlaps = Math.floor(this._ctx.measureText(char).width) > this._characterWidth;\n\n // Restore the original context\n this._ctx.restore();\n\n // Cache and return\n this._characterOverlapCache[char] = overlaps;\n return overlaps;\n }\n\n /**\n * Clear the charcater at the cell specified.\n * @param x The column of the char.\n * @param y The row of the char.\n */\n private _clearChar(x: number, y: number): void {\n let colsToClear = 1;\n // Clear the adjacent character if it was wide\n const state = this._state.cache[x][y];\n if (state && state[CHAR_DATA_WIDTH_INDEX] === 2) {\n colsToClear = 2;\n }\n this.clearCells(x, y, colsToClear, 1);\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorSet, IRenderDimensions } from './Interfaces';\nimport { IBuffer, ICharMeasure, ITerminal } from '../Interfaces';\nimport { CHAR_DATA_ATTR_INDEX } from '../Buffer';\nimport { GridCache } from './GridCache';\nimport { FLAGS } from './Types';\nimport { BaseRenderLayer } from './BaseRenderLayer';\n\nexport class SelectionRenderLayer extends BaseRenderLayer {\n private _state: {start: [number, number], end: [number, number]};\n\n constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {\n super(container, 'selection', zIndex, true, colors);\n this._state = {\n start: null,\n end: null\n };\n }\n\n public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void {\n super.resize(terminal, dim, charSizeChanged);\n // Resizing the canvas discards the contents of the canvas so clear state\n this._state = {\n start: null,\n end: null\n };\n }\n\n public reset(terminal: ITerminal): void {\n if (this._state.start && this._state.end) {\n this._state = {\n start: null,\n end: null\n };\n this.clearAll();\n }\n }\n\n public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void {\n // Selection has not changed\n if (this._state.start === start || this._state.end === end) {\n return;\n }\n\n // Remove all selections\n this.clearAll();\n\n // Selection does not exist\n if (!start || !end) {\n return;\n }\n\n // Translate from buffer position to viewport position\n const viewportStartRow = start[1] - terminal.buffer.ydisp;\n const viewportEndRow = end[1] - terminal.buffer.ydisp;\n const viewportCappedStartRow = Math.max(viewportStartRow, 0);\n const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);\n\n // No need to draw the selection\n if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) {\n return;\n }\n\n // Draw first row\n const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;\n const startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols;\n this._ctx.fillStyle = this._colors.selection;\n this.fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1);\n\n // Draw middle rows\n const middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0);\n this.fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount);\n\n // Draw final row\n if (viewportCappedStartRow !== viewportCappedEndRow) {\n // Only draw viewportEndRow if it's not the same as viewportStartRow\n const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols;\n this.fillCells(0, viewportCappedEndRow, endCol, 1);\n }\n\n // Save state for next render\n this._state.start = [start[0], start[1]];\n this._state.end = [end[0], end[1]];\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, ITheme } from '../Interfaces';\nimport { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer';\nimport { TextRenderLayer } from './TextRenderLayer';\nimport { SelectionRenderLayer } from './SelectionRenderLayer';\nimport { CursorRenderLayer } from './CursorRenderLayer';\nimport { ColorManager } from './ColorManager';\nimport { BaseRenderLayer } from './BaseRenderLayer';\nimport { IRenderLayer, IColorSet, IRenderer, IRenderDimensions } from './Interfaces';\nimport { LinkRenderLayer } from './LinkRenderLayer';\nimport { EventEmitter } from '../EventEmitter';\n\nexport class Renderer extends EventEmitter implements IRenderer {\n /** A queue of the rows to be refreshed */\n private _refreshRowsQueue: {start: number, end: number}[] = [];\n private _refreshAnimationFrame = null;\n\n private _renderLayers: IRenderLayer[];\n private _devicePixelRatio: number;\n\n public colorManager: ColorManager;\n public dimensions: IRenderDimensions;\n\n constructor(private _terminal: ITerminal, theme: ITheme) {\n super();\n this.colorManager = new ColorManager();\n if (theme) {\n this.colorManager.setTheme(theme);\n }\n this._renderLayers = [\n new TextRenderLayer(this._terminal.element, 0, this.colorManager.colors),\n new SelectionRenderLayer(this._terminal.element, 1, this.colorManager.colors),\n new LinkRenderLayer(this._terminal.element, 2, this.colorManager.colors, this._terminal),\n new CursorRenderLayer(this._terminal.element, 3, this.colorManager.colors)\n ];\n this.dimensions = {\n scaledCharWidth: null,\n scaledCharHeight: null,\n scaledCellWidth: null,\n scaledCellHeight: null,\n scaledCharLeft: null,\n scaledCharTop: null,\n scaledCanvasWidth: null,\n scaledCanvasHeight: null,\n canvasWidth: null,\n canvasHeight: null,\n actualCellWidth: null,\n actualCellHeight: null\n };\n this._devicePixelRatio = window.devicePixelRatio;\n this._updateDimensions();\n this.onOptionsChanged();\n }\n\n public onWindowResize(devicePixelRatio: number): void {\n // If the device pixel ratio changed, the char atlas needs to be regenerated\n // and the terminal needs to refreshed\n if (this._devicePixelRatio !== devicePixelRatio) {\n this._devicePixelRatio = devicePixelRatio;\n this.onResize(this._terminal.cols, this._terminal.rows, true);\n }\n }\n\n public setTheme(theme: ITheme): IColorSet {\n this.colorManager.setTheme(theme);\n\n // Clear layers and force a full render\n this._renderLayers.forEach(l => {\n l.onThemeChanged(this._terminal, this.colorManager.colors);\n l.reset(this._terminal);\n });\n\n this._terminal.refresh(0, this._terminal.rows - 1);\n\n return this.colorManager.colors;\n }\n\n public onResize(cols: number, rows: number, didCharSizeChange: boolean): void {\n // Update character and canvas dimensions\n this._updateDimensions();\n\n // Resize all render layers\n this._renderLayers.forEach(l => l.resize(this._terminal, this.dimensions, didCharSizeChange));\n\n // Force a refresh\n this._terminal.refresh(0, this._terminal.rows - 1);\n\n this.emit('resize', {\n width: this.dimensions.canvasWidth,\n height: this.dimensions.canvasHeight\n });\n }\n\n public onCharSizeChanged(): void {\n this.onResize(this._terminal.cols, this._terminal.rows, true);\n }\n\n public onBlur(): void {\n this._renderLayers.forEach(l => l.onBlur(this._terminal));\n }\n\n public onFocus(): void {\n this._renderLayers.forEach(l => l.onFocus(this._terminal));\n }\n\n public onSelectionChanged(start: [number, number], end: [number, number]): void {\n this._renderLayers.forEach(l => l.onSelectionChanged(this._terminal, start, end));\n }\n\n public onCursorMove(): void {\n this._renderLayers.forEach(l => l.onCursorMove(this._terminal));\n }\n\n public onOptionsChanged(): void {\n this._renderLayers.forEach(l => l.onOptionsChanged(this._terminal));\n }\n\n public clear(): void {\n this._renderLayers.forEach(l => l.reset(this._terminal));\n }\n\n /**\n * Queues a refresh between two rows (inclusive), to be done on next animation\n * frame.\n * @param {number} start The start row.\n * @param {number} end The end row.\n */\n public queueRefresh(start: number, end: number): void {\n this._refreshRowsQueue.push({ start: start, end: end });\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(this._refreshLoop.bind(this));\n }\n }\n\n /**\n * Performs the refresh loop callback, calling refresh only if a refresh is\n * necessary before queueing up the next one.\n */\n private _refreshLoop(): void {\n let start;\n let end;\n if (this._refreshRowsQueue.length > 4) {\n // Just do a full refresh when 5+ refreshes are queued\n start = 0;\n end = this._terminal.rows - 1;\n } else {\n // Get start and end rows that need refreshing\n start = this._refreshRowsQueue[0].start;\n end = this._refreshRowsQueue[0].end;\n for (let i = 1; i < this._refreshRowsQueue.length; i++) {\n if (this._refreshRowsQueue[i].start < start) {\n start = this._refreshRowsQueue[i].start;\n }\n if (this._refreshRowsQueue[i].end > end) {\n end = this._refreshRowsQueue[i].end;\n }\n }\n }\n this._refreshRowsQueue = [];\n this._refreshAnimationFrame = null;\n\n // Render\n start = Math.max(start, 0);\n end = Math.min(end, this._terminal.rows - 1);\n this._renderLayers.forEach(l => l.onGridChanged(this._terminal, start, end));\n this._terminal.emit('refresh', {start, end});\n }\n\n /**\n * Recalculates the character and canvas dimensions.\n */\n private _updateDimensions(): void {\n // Perform a new measure if the CharMeasure dimensions are not yet available\n if (!this._terminal.charMeasure.width || !this._terminal.charMeasure.height) {\n return;\n }\n\n // Calculate the scaled character width. Width is floored as it must be\n // drawn to an integer grid in order for the CharAtlas \"stamps\" to not be\n // blurry. When text is drawn to the grid not using the CharAtlas, it is\n // clipped to ensure there is no overlap with the next cell.\n this.dimensions.scaledCharWidth = Math.floor(this._terminal.charMeasure.width * window.devicePixelRatio);\n\n // Calculate the scaled character height. Height is ceiled in case\n // devicePixelRatio is a floating point number in order to ensure there is\n // enough space to draw the character to the cell.\n this.dimensions.scaledCharHeight = Math.ceil(this._terminal.charMeasure.height * window.devicePixelRatio);\n\n // Calculate the scaled cell height, if lineHeight is not 1 then the value\n // will be floored because since lineHeight can never be lower then 1, there\n // is a guarentee that the scaled line height will always be larger than\n // scaled char height.\n this.dimensions.scaledCellHeight = Math.floor(this.dimensions.scaledCharHeight * this._terminal.options.lineHeight);\n\n // Calculate the y coordinate within a cell that text should draw from in\n // order to draw in the center of a cell.\n this.dimensions.scaledCharTop = this._terminal.options.lineHeight === 1 ? 0 : Math.round((this.dimensions.scaledCellHeight - this.dimensions.scaledCharHeight) / 2);\n\n // Calculate the scaled cell width, taking the letterSpacing into account.\n this.dimensions.scaledCellWidth = this.dimensions.scaledCharWidth + Math.round(this._terminal.options.letterSpacing);\n\n // Calculate the x coordinate with a cell that text should draw from in\n // order to draw in the center of a cell.\n this.dimensions.scaledCharLeft = Math.floor(this._terminal.options.letterSpacing / 2);\n\n // Recalculate the canvas dimensions; scaled* define the actual number of\n // pixel in the canvas\n this.dimensions.scaledCanvasHeight = this._terminal.rows * this.dimensions.scaledCellHeight;\n this.dimensions.scaledCanvasWidth = this._terminal.cols * this.dimensions.scaledCellWidth;\n\n // The the size of the canvas on the page. It's very important that this\n // rounds to nearest integer and not ceils as browsers often set\n // window.devicePixelRatio as something like 1.100000023841858, when it's\n // actually 1.1. Ceiling causes blurriness as the backing canvas image is 1\n // pixel too large for the canvas element size.\n this.dimensions.canvasHeight = Math.round(this.dimensions.scaledCanvasHeight / window.devicePixelRatio);\n this.dimensions.canvasWidth = Math.round(this.dimensions.scaledCanvasWidth / window.devicePixelRatio);\n\n // Get the _actual_ dimensions of an individual cell. This needs to be\n // derived from the canvasWidth/Height calculated above which takes into\n // account window.devicePixelRatio. CharMeasure.width/height by itself is\n // insufficient when the page is not at 100% zoom level as CharMeasure is\n // measured in CSS pixels, but the actual char size on the canvas can\n // differ.\n this.dimensions.actualCellHeight = this.dimensions.canvasHeight / this._terminal.rows;\n this.dimensions.actualCellWidth = this.dimensions.canvasWidth / this._terminal.cols;\n\n }\n\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorSet, IRenderDimensions } from './Interfaces';\nimport { IBuffer, ICharMeasure, ITerminal, ILinkifierAccessor } from '../Interfaces';\nimport { CHAR_DATA_ATTR_INDEX } from '../Buffer';\nimport { GridCache } from './GridCache';\nimport { FLAGS } from './Types';\nimport { BaseRenderLayer, INVERTED_DEFAULT_COLOR } from './BaseRenderLayer';\nimport { LinkHoverEvent, LinkHoverEventTypes } from '../Types';\n\nexport class LinkRenderLayer extends BaseRenderLayer {\n private _state: LinkHoverEvent = null;\n\n constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ILinkifierAccessor) {\n super(container, 'link', zIndex, true, colors);\n terminal.linkifier.on(LinkHoverEventTypes.HOVER, (e: LinkHoverEvent) => this._onLinkHover(e));\n terminal.linkifier.on(LinkHoverEventTypes.LEAVE, (e: LinkHoverEvent) => this._onLinkLeave(e));\n }\n\n public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void {\n super.resize(terminal, dim, charSizeChanged);\n // Resizing the canvas discards the contents of the canvas so clear state\n this._state = null;\n }\n\n public reset(terminal: ITerminal): void {\n this._clearCurrentLink();\n }\n\n private _clearCurrentLink(): void {\n if (this._state) {\n this.clearCells(this._state.x, this._state.y, this._state.length, 1);\n this._state = null;\n }\n }\n\n private _onLinkHover(e: LinkHoverEvent): void {\n this._ctx.fillStyle = this._colors.foreground;\n this.fillBottomLineAtCells(e.x, e.y, e.length);\n this._state = e;\n }\n\n private _onLinkLeave(e: LinkHoverEvent): void {\n this._clearCurrentLink();\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport class GridCache<T> {\n public cache: T[][];\n\n public constructor() {\n this.cache = [];\n }\n\n public resize(width: number, height: number): void {\n for (let x = 0; x < width; x++) {\n if (this.cache.length <= x) {\n this.cache.push([]);\n }\n for (let y = this.cache[x].length; y < height; y++) {\n this.cache[x].push(null);\n }\n this.cache[x].length = height;\n }\n this.cache.length = width;\n }\n\n public clear(): void {\n for (let x = 0; x < this.cache.length; x++) {\n for (let y = 0; y < this.cache[x].length; y++) {\n this.cache[x][y] = null;\n }\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorSet, IRenderDimensions } from './Interfaces';\nimport { IBuffer, ICharMeasure, ITerminal, ITerminalOptions } from '../Interfaces';\nimport { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer';\nimport { GridCache } from './GridCache';\nimport { FLAGS } from './Types';\nimport { BaseRenderLayer } from './BaseRenderLayer';\nimport { CharData } from '../Types';\n\ninterface CursorState {\n x: number;\n y: number;\n isFocused: boolean;\n style: string;\n width: number;\n}\n\n/**\n * The time between cursor blinks.\n */\nconst BLINK_INTERVAL = 600;\n\nexport class CursorRenderLayer extends BaseRenderLayer {\n private _state: CursorState;\n private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, charData: CharData) => void};\n private _cursorBlinkStateManager: CursorBlinkStateManager;\n private _isFocused: boolean;\n\n constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {\n super(container, 'cursor', zIndex, true, colors);\n this._state = {\n x: null,\n y: null,\n isFocused: null,\n style: null,\n width: null,\n };\n this._cursorRenderers = {\n 'bar': this._renderBarCursor.bind(this),\n 'block': this._renderBlockCursor.bind(this),\n 'underline': this._renderUnderlineCursor.bind(this)\n };\n // TODO: Consider initial options? Maybe onOptionsChanged should be called at the end of open?\n }\n\n public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void {\n super.resize(terminal, dim, charSizeChanged);\n // Resizing the canvas discards the contents of the canvas so clear state\n this._state = {\n x: null,\n y: null,\n isFocused: null,\n style: null,\n width: null,\n };\n }\n\n public reset(terminal: ITerminal): void {\n this._clearCursor();\n if (this._cursorBlinkStateManager) {\n this._cursorBlinkStateManager.dispose();\n this._cursorBlinkStateManager = null;\n this.onOptionsChanged(terminal);\n }\n }\n\n public onBlur(terminal: ITerminal): void {\n if (this._cursorBlinkStateManager) {\n this._cursorBlinkStateManager.pause();\n }\n terminal.refresh(terminal.buffer.y, terminal.buffer.y);\n }\n\n public onFocus(terminal: ITerminal): void {\n if (this._cursorBlinkStateManager) {\n this._cursorBlinkStateManager.resume(terminal);\n } else {\n terminal.refresh(terminal.buffer.y, terminal.buffer.y);\n }\n }\n\n public onOptionsChanged(terminal: ITerminal): void {\n if (terminal.options.cursorBlink) {\n if (!this._cursorBlinkStateManager) {\n this._cursorBlinkStateManager = new CursorBlinkStateManager(terminal, () => {\n this._render(terminal, true);\n });\n }\n } else {\n if (this._cursorBlinkStateManager) {\n this._cursorBlinkStateManager.dispose();\n this._cursorBlinkStateManager = null;\n }\n // Request a refresh from the terminal as management of rendering is being\n // moved back to the terminal\n terminal.refresh(terminal.buffer.y, terminal.buffer.y);\n }\n }\n\n public onCursorMove(terminal: ITerminal): void {\n if (this._cursorBlinkStateManager) {\n this._cursorBlinkStateManager.restartBlinkAnimation(terminal);\n }\n }\n\n public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {\n // Only render if the animation frame is not active\n if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) {\n this._render(terminal, false);\n }\n }\n\n private _render(terminal: ITerminal, triggeredByAnimationFrame: boolean): void {\n // Don't draw the cursor if it's hidden\n if (!terminal.cursorState || terminal.cursorHidden) {\n this._clearCursor();\n return;\n }\n\n const cursorY = terminal.buffer.ybase + terminal.buffer.y;\n const viewportRelativeCursorY = cursorY - terminal.buffer.ydisp;\n\n // Don't draw the cursor if it's off-screen\n if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= terminal.rows) {\n this._clearCursor();\n return;\n }\n\n const charData = terminal.buffer.lines.get(cursorY)[terminal.buffer.x];\n if (!charData) {\n return;\n }\n\n if (!terminal.isFocused) {\n this._clearCursor();\n this._ctx.save();\n this._ctx.fillStyle = this._colors.cursor;\n this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, charData);\n this._ctx.restore();\n this._state.x = terminal.buffer.x;\n this._state.y = viewportRelativeCursorY;\n this._state.isFocused = false;\n this._state.style = terminal.options.cursorStyle;\n this._state.width = charData[CHAR_DATA_WIDTH_INDEX];\n return;\n }\n\n // Don't draw the cursor if it's blinking\n if (this._cursorBlinkStateManager && !this._cursorBlinkStateManager.isCursorVisible) {\n this._clearCursor();\n return;\n }\n\n if (this._state) {\n // The cursor is already in the correct spot, don't redraw\n if (this._state.x === terminal.buffer.x &&\n this._state.y === viewportRelativeCursorY &&\n this._state.isFocused === terminal.isFocused &&\n this._state.style === terminal.options.cursorStyle &&\n this._state.width === charData[CHAR_DATA_WIDTH_INDEX]) {\n return;\n }\n this._clearCursor();\n }\n\n this._ctx.save();\n this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, charData);\n this._ctx.restore();\n\n this._state.x = terminal.buffer.x;\n this._state.y = viewportRelativeCursorY;\n this._state.isFocused = false;\n this._state.style = terminal.options.cursorStyle;\n this._state.width = charData[CHAR_DATA_WIDTH_INDEX];\n }\n\n private _clearCursor(): void {\n if (this._state) {\n this.clearCells(this._state.x, this._state.y, this._state.width, 1);\n this._state = {\n x: null,\n y: null,\n isFocused: null,\n style: null,\n width: null,\n };\n }\n }\n\n private _renderBarCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {\n this._ctx.save();\n this._ctx.fillStyle = this._colors.cursor;\n this.fillLeftLineAtCell(x, y);\n this._ctx.restore();\n }\n\n private _renderBlockCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {\n this._ctx.save();\n this._ctx.fillStyle = this._colors.cursor;\n this.fillCells(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1);\n this._ctx.fillStyle = this._colors.cursorAccent;\n this.fillCharTrueColor(terminal, charData, x, y);\n this._ctx.restore();\n }\n\n private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {\n this._ctx.save();\n this._ctx.fillStyle = this._colors.cursor;\n this.fillBottomLineAtCells(x, y);\n this._ctx.restore();\n }\n\n private _renderBlurCursor(terminal: ITerminal, x: number, y: number, charData: CharData): void {\n this._ctx.save();\n this._ctx.strokeStyle = this._colors.cursor;\n this.strokeRectAtCell(x, y, charData[CHAR_DATA_WIDTH_INDEX], 1);\n this._ctx.restore();\n }\n}\n\nclass CursorBlinkStateManager {\n public isCursorVisible: boolean;\n\n private _animationFrame: number;\n private _blinkStartTimeout: number;\n private _blinkInterval: number;\n\n /**\n * The time at which the animation frame was restarted, this is used on the\n * next render to restart the timers so they don't need to restart the timers\n * multiple times over a short period.\n */\n private _animationTimeRestarted: number;\n\n constructor(\n terminal: ITerminal,\n private renderCallback: () => void\n ) {\n this.isCursorVisible = true;\n if (terminal.isFocused) {\n this._restartInterval();\n }\n }\n\n public get isPaused(): boolean { return !(this._blinkStartTimeout || this._blinkInterval); }\n\n public dispose(): void {\n if (this._blinkInterval) {\n window.clearInterval(this._blinkInterval);\n this._blinkInterval = null;\n }\n if (this._blinkStartTimeout) {\n window.clearTimeout(this._blinkStartTimeout);\n this._blinkStartTimeout = null;\n }\n if (this._animationFrame) {\n window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = null;\n }\n }\n\n public restartBlinkAnimation(terminal: ITerminal): void {\n if (this.isPaused) {\n return;\n }\n // Save a timestamp so that the restart can be done on the next interval\n this._animationTimeRestarted = Date.now();\n // Force a cursor render to ensure it's visible and in the correct position\n this.isCursorVisible = true;\n if (!this._animationFrame) {\n this._animationFrame = window.requestAnimationFrame(() => {\n this.renderCallback();\n this._animationFrame = null;\n });\n }\n }\n\n private _restartInterval(timeToStart: number = BLINK_INTERVAL): void {\n // Clear any existing interval\n if (this._blinkInterval) {\n window.clearInterval(this._blinkInterval);\n }\n\n // Setup the initial timeout which will hide the cursor, this is done before\n // the regular interval is setup in order to support restarting the blink\n // animation in a lightweight way (without thrashing clearInterval and\n // setInterval).\n this._blinkStartTimeout = <number><any>setTimeout(() => {\n // Check if another animation restart was requested while this was being\n // started\n if (this._animationTimeRestarted) {\n const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted);\n this._animationTimeRestarted = null;\n if (time > 0) {\n this._restartInterval(time);\n return;\n }\n }\n\n // Hide the cursor\n this.isCursorVisible = false;\n this._animationFrame = window.requestAnimationFrame(() => {\n this.renderCallback();\n this._animationFrame = null;\n });\n\n // Setup the blink interval\n this._blinkInterval = <number><any>setInterval(() => {\n // Adjust the animation time if it was restarted\n if (this._animationTimeRestarted) {\n // calc time diff\n // Make restart interval do a setTimeout initially?\n const time = BLINK_INTERVAL - (Date.now() - this._animationTimeRestarted);\n this._animationTimeRestarted = null;\n this._restartInterval(time);\n return;\n }\n\n // Invert visibility and render\n this.isCursorVisible = !this.isCursorVisible;\n this._animationFrame = window.requestAnimationFrame(() => {\n this.renderCallback();\n this._animationFrame = null;\n });\n }, BLINK_INTERVAL);\n }, timeToStart);\n }\n\n public pause(): void {\n this.isCursorVisible = true;\n if (this._blinkInterval) {\n window.clearInterval(this._blinkInterval);\n this._blinkInterval = null;\n }\n if (this._blinkStartTimeout) {\n window.clearTimeout(this._blinkStartTimeout);\n this._blinkStartTimeout = null;\n }\n if (this._animationFrame) {\n window.cancelAnimationFrame(this._animationFrame);\n this._animationFrame = null;\n }\n }\n\n public resume(terminal: ITerminal): void {\n this._animationTimeRestarted = null;\n this._restartInterval();\n this.restartBlinkAnimation(terminal);\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColorSet, IColorManager } from './Interfaces';\nimport { ITheme } from '../Interfaces';\n\nconst DEFAULT_FOREGROUND = '#ffffff';\nconst DEFAULT_BACKGROUND = '#000000';\nconst DEFAULT_CURSOR = '#ffffff';\nconst DEFAULT_CURSOR_ACCENT = '#000000';\nconst DEFAULT_SELECTION = 'rgba(255, 255, 255, 0.3)';\nexport const DEFAULT_ANSI_COLORS = [\n // dark:\n '#2e3436',\n '#cc0000',\n '#4e9a06',\n '#c4a000',\n '#3465a4',\n '#75507b',\n '#06989a',\n '#d3d7cf',\n // bright:\n '#555753',\n '#ef2929',\n '#8ae234',\n '#fce94f',\n '#729fcf',\n '#ad7fa8',\n '#34e2e2',\n '#eeeeec'\n];\n\n/**\n * Fills an existing 16 length string with the remaining 240 ANSI colors.\n * @param first16Colors The first 16 ANSI colors.\n */\nfunction generate256Colors(first16Colors: string[]): string[] {\n let colors = first16Colors.slice();\n\n // Generate colors (16-231)\n let v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = toPaddedHex(v[(i / 36) % 6 | 0]);\n const g = toPaddedHex(v[(i / 6) % 6 | 0]);\n const b = toPaddedHex(v[i % 6]);\n colors.push(`#${r}${g}${b}`);\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = toPaddedHex(8 + i * 10);\n colors.push(`#${c}${c}${c}`);\n }\n\n return colors;\n}\n\nfunction toPaddedHex(c: number): string {\n let s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Manages the source of truth for a terminal's colors.\n */\nexport class ColorManager implements IColorManager {\n public colors: IColorSet;\n\n constructor() {\n this.colors = {\n foreground: DEFAULT_FOREGROUND,\n background: DEFAULT_BACKGROUND,\n cursor: DEFAULT_CURSOR,\n cursorAccent: DEFAULT_CURSOR_ACCENT,\n selection: DEFAULT_SELECTION,\n ansi: generate256Colors(DEFAULT_ANSI_COLORS)\n };\n }\n\n /**\n * Sets the terminal's theme.\n * @param theme The theme to use. If a partial theme is provided then default\n * colors will be used where colors are not defined.\n */\n public setTheme(theme: ITheme): void {\n this.colors.foreground = theme.foreground || DEFAULT_FOREGROUND;\n this.colors.background = this._validateColor(theme.background, DEFAULT_BACKGROUND);\n this.colors.cursor = theme.cursor || DEFAULT_CURSOR;\n this.colors.cursorAccent = theme.cursorAccent || DEFAULT_CURSOR_ACCENT;\n this.colors.selection = theme.selection || DEFAULT_SELECTION;\n this.colors.ansi[0] = theme.black || DEFAULT_ANSI_COLORS[0];\n this.colors.ansi[1] = theme.red || DEFAULT_ANSI_COLORS[1];\n this.colors.ansi[2] = theme.green || DEFAULT_ANSI_COLORS[2];\n this.colors.ansi[3] = theme.yellow || DEFAULT_ANSI_COLORS[3];\n this.colors.ansi[4] = theme.blue || DEFAULT_ANSI_COLORS[4];\n this.colors.ansi[5] = theme.magenta || DEFAULT_ANSI_COLORS[5];\n this.colors.ansi[6] = theme.cyan || DEFAULT_ANSI_COLORS[6];\n this.colors.ansi[7] = theme.white || DEFAULT_ANSI_COLORS[7];\n this.colors.ansi[8] = theme.brightBlack || DEFAULT_ANSI_COLORS[8];\n this.colors.ansi[9] = theme.brightRed || DEFAULT_ANSI_COLORS[9];\n this.colors.ansi[10] = theme.brightGreen || DEFAULT_ANSI_COLORS[10];\n this.colors.ansi[11] = theme.brightYellow || DEFAULT_ANSI_COLORS[11];\n this.colors.ansi[12] = theme.brightBlue || DEFAULT_ANSI_COLORS[12];\n this.colors.ansi[13] = theme.brightMagenta || DEFAULT_ANSI_COLORS[13];\n this.colors.ansi[14] = theme.brightCyan || DEFAULT_ANSI_COLORS[14];\n this.colors.ansi[15] = theme.brightWhite || DEFAULT_ANSI_COLORS[15];\n }\n\n private _validateColor(color: string, fallback: string): string {\n if (!color) {\n return fallback;\n }\n if (color.length === 7 && color.charAt(0) === '#') {\n return color;\n }\n if (color.length === 4 && color.charAt(0) === '#') {\n const r = color.charAt(1);\n const g = color.charAt(2);\n const b = color.charAt(3);\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return fallback;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, ITheme } from '../Interfaces';\nimport { IColorSet } from '../renderer/Interfaces';\nimport { isFirefox } from '../utils/Browser';\n\nexport const CHAR_ATLAS_CELL_SPACING = 1;\n\ninterface ICharAtlasConfig {\n fontSize: number;\n fontFamily: string;\n scaledCharWidth: number;\n scaledCharHeight: number;\n colors: IColorSet;\n}\n\ninterface ICharAtlasCacheEntry {\n bitmap: HTMLCanvasElement | Promise<ImageBitmap>;\n config: ICharAtlasConfig;\n ownedBy: ITerminal[];\n}\n\nlet charAtlasCache: ICharAtlasCacheEntry[] = [];\n\n/**\n * Acquires a char atlas, either generating a new one or returning an existing\n * one that is in use by another terminal.\n * @param terminal The terminal.\n * @param colors The colors to use.\n */\nexport function acquireCharAtlas(terminal: ITerminal, colors: IColorSet, scaledCharWidth: number, scaledCharHeight: number): HTMLCanvasElement | Promise<ImageBitmap> {\n const newConfig = generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors);\n\n // Check to see if the terminal already owns this config\n for (let i = 0; i < charAtlasCache.length; i++) {\n const entry = charAtlasCache[i];\n const ownedByIndex = entry.ownedBy.indexOf(terminal);\n if (ownedByIndex >= 0) {\n if (configEquals(entry.config, newConfig)) {\n return entry.bitmap;\n } else {\n // The configs differ, release the terminal from the entry\n if (entry.ownedBy.length === 1) {\n charAtlasCache.splice(i, 1);\n } else {\n entry.ownedBy.splice(ownedByIndex, 1);\n }\n break;\n }\n }\n }\n\n // Try match a char atlas from the cache\n for (let i = 0; i < charAtlasCache.length; i++) {\n const entry = charAtlasCache[i];\n if (configEquals(entry.config, newConfig)) {\n // Add the terminal to the cache entry and return\n entry.ownedBy.push(terminal);\n return entry.bitmap;\n }\n }\n\n const newEntry: ICharAtlasCacheEntry = {\n bitmap: generator.generate(scaledCharWidth, scaledCharHeight, terminal.options.fontSize, terminal.options.fontFamily, colors.background, colors.foreground, colors.ansi),\n config: newConfig,\n ownedBy: [terminal]\n };\n charAtlasCache.push(newEntry);\n return newEntry.bitmap;\n}\n\nfunction generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig {\n const clonedColors = {\n foreground: colors.foreground,\n background: colors.background,\n cursor: null,\n cursorAccent: null,\n selection: null,\n ansi: colors.ansi.slice(0, 16)\n };\n return {\n scaledCharWidth,\n scaledCharHeight,\n fontFamily: terminal.options.fontFamily,\n fontSize: terminal.options.fontSize,\n colors: clonedColors\n };\n}\n\nfunction configEquals(a: ICharAtlasConfig, b: ICharAtlasConfig): boolean {\n for (let i = 0; i < a.colors.ansi.length; i++) {\n if (a.colors.ansi[i] !== b.colors.ansi[i]) {\n return false;\n }\n }\n return a.fontFamily === b.fontFamily &&\n a.fontSize === b.fontSize &&\n a.scaledCharWidth === b.scaledCharWidth &&\n a.scaledCharHeight === b.scaledCharHeight &&\n a.colors.foreground === b.colors.foreground &&\n a.colors.background === b.colors.background;\n}\n\nlet generator: CharAtlasGenerator;\n\n/**\n * Initializes the char atlas generator.\n * @param document The document.\n */\nexport function initialize(document: Document): void {\n if (!generator) {\n generator = new CharAtlasGenerator(document);\n }\n}\n\nclass CharAtlasGenerator {\n private _canvas: HTMLCanvasElement;\n private _ctx: CanvasRenderingContext2D;\n\n constructor(private _document: Document) {\n this._canvas = this._document.createElement('canvas');\n this._ctx = this._canvas.getContext('2d', {alpha: false});\n this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n }\n\n public generate(scaledCharWidth: number, scaledCharHeight: number, fontSize: number, fontFamily: string, background: string, foreground: string, ansiColors: string[]): HTMLCanvasElement | Promise<ImageBitmap> {\n const cellWidth = scaledCharWidth + CHAR_ATLAS_CELL_SPACING;\n const cellHeight = scaledCharHeight + CHAR_ATLAS_CELL_SPACING;\n this._canvas.width = 255 * cellWidth;\n this._canvas.height = (/*default+default bold*/2 + /*0-15*/16) * cellHeight;\n\n this._ctx.fillStyle = background;\n this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\n this._ctx.save();\n this._ctx.fillStyle = foreground;\n this._ctx.font = `${fontSize * window.devicePixelRatio}px ${fontFamily}`;\n this._ctx.textBaseline = 'top';\n\n // Default color\n for (let i = 0; i < 256; i++) {\n this._ctx.save();\n this._ctx.beginPath();\n this._ctx.rect(i * cellWidth, 0, cellWidth, cellHeight);\n this._ctx.clip();\n this._ctx.fillText(String.fromCharCode(i), i * cellWidth, 0);\n this._ctx.restore();\n }\n // Default color bold\n this._ctx.save();\n this._ctx.font = `bold ${this._ctx.font}`;\n for (let i = 0; i < 256; i++) {\n this._ctx.save();\n this._ctx.beginPath();\n this._ctx.rect(i * cellWidth, cellHeight, cellWidth, cellHeight);\n this._ctx.clip();\n this._ctx.fillText(String.fromCharCode(i), i * cellWidth, cellHeight);\n this._ctx.restore();\n }\n this._ctx.restore();\n\n // Colors 0-15\n this._ctx.font = `${fontSize * window.devicePixelRatio}px ${fontFamily}`;\n for (let colorIndex = 0; colorIndex < 16; colorIndex++) {\n // colors 8-15 are bold\n if (colorIndex === 8) {\n this._ctx.font = `bold ${this._ctx.font}`;\n }\n const y = (colorIndex + 2) * cellHeight;\n // Draw ascii characters\n for (let i = 0; i < 256; i++) {\n this._ctx.save();\n this._ctx.beginPath();\n this._ctx.rect(i * cellWidth, y, cellWidth, cellHeight);\n this._ctx.clip();\n this._ctx.fillStyle = ansiColors[colorIndex];\n this._ctx.fillText(String.fromCharCode(i), i * cellWidth, y);\n this._ctx.restore();\n }\n }\n this._ctx.restore();\n\n // Support is patchy for createImageBitmap at the moment, pass a canvas back\n // if support is lacking as drawImage works there too. Firefox is also\n // included here as ImageBitmap appears both buggy and has horrible\n // performance (tested on v55).\n if (!('createImageBitmap' in window) || isFirefox) {\n // Regenerate canvas and context as they are now owned by the char atlas\n const result = this._canvas;\n this._canvas = this._document.createElement('canvas');\n this._ctx = this._canvas.getContext('2d');\n this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n return result;\n }\n\n const charAtlasImageData = this._ctx.getImageData(0, 0, this._canvas.width, this._canvas.height);\n\n // Remove the background color from the image so characters may overlap\n const r = parseInt(background.substr(1, 2), 16);\n const g = parseInt(background.substr(3, 2), 16);\n const b = parseInt(background.substr(5, 2), 16);\n this._clearColor(charAtlasImageData, r, g, b);\n\n const promise = window.createImageBitmap(charAtlasImageData);\n // Clear the rect while the promise is in progress\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n return promise;\n }\n\n private _clearColor(imageData: ImageData, r: number, g: number, b: number): void {\n for (let offset = 0; offset < imageData.data.length; offset += 4) {\n if (imageData.data[offset] === r &&\n imageData.data[offset + 1] === g &&\n imageData.data[offset + 2] === b) {\n imageData.data[offset + 3] = 0;\n }\n }\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IRenderLayer, IColorSet, IRenderDimensions } from './Interfaces';\nimport { ITerminal, ITerminalOptions } from '../Interfaces';\nimport { acquireCharAtlas, CHAR_ATLAS_CELL_SPACING } from './CharAtlas';\nimport { CharData } from '../Types';\nimport { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer';\n\nexport const INVERTED_DEFAULT_COLOR = -1;\nconst DIM_OPACITY = 0.5;\n\nexport abstract class BaseRenderLayer implements IRenderLayer {\n private _canvas: HTMLCanvasElement;\n protected _ctx: CanvasRenderingContext2D;\n private _scaledCharWidth: number = 0;\n private _scaledCharHeight: number = 0;\n private _scaledCellWidth: number = 0;\n private _scaledCellHeight: number = 0;\n private _scaledCharLeft: number = 0;\n private _scaledCharTop: number = 0;\n\n private _charAtlas: HTMLCanvasElement | ImageBitmap;\n\n constructor(\n container: HTMLElement,\n id: string,\n zIndex: number,\n private _alpha: boolean,\n protected _colors: IColorSet\n ) {\n this._canvas = document.createElement('canvas');\n this._canvas.id = `xterm-${id}-layer`;\n this._canvas.style.zIndex = zIndex.toString();\n this._ctx = this._canvas.getContext('2d', {alpha: _alpha});\n this._ctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n // Draw the background if this is an opaque layer\n if (!_alpha) {\n this.clearAll();\n }\n container.appendChild(this._canvas);\n }\n\n public onOptionsChanged(terminal: ITerminal): void {}\n public onBlur(terminal: ITerminal): void {}\n public onFocus(terminal: ITerminal): void {}\n public onCursorMove(terminal: ITerminal): void {}\n public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {}\n public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void {}\n\n public onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void {\n this._refreshCharAtlas(terminal, colorSet);\n }\n\n /**\n * Refreshes the char atlas, aquiring a new one if necessary.\n * @param terminal The terminal.\n * @param colorSet The color set to use for the char atlas.\n */\n private _refreshCharAtlas(terminal: ITerminal, colorSet: IColorSet): void {\n if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) {\n return;\n }\n this._charAtlas = null;\n const result = acquireCharAtlas(terminal, this._colors, this._scaledCharWidth, this._scaledCharHeight);\n if (result instanceof HTMLCanvasElement) {\n this._charAtlas = result;\n } else {\n result.then(bitmap => this._charAtlas = bitmap);\n }\n }\n\n public resize(terminal: ITerminal, dim: IRenderDimensions, charSizeChanged: boolean): void {\n this._scaledCellWidth = dim.scaledCellWidth;\n this._scaledCellHeight = dim.scaledCellHeight;\n this._scaledCharWidth = dim.scaledCharWidth;\n this._scaledCharHeight = dim.scaledCharHeight;\n this._scaledCharLeft = dim.scaledCharLeft;\n this._scaledCharTop = dim.scaledCharTop;\n this._canvas.width = dim.scaledCanvasWidth;\n this._canvas.height = dim.scaledCanvasHeight;\n this._canvas.style.width = `${dim.canvasWidth}px`;\n this._canvas.style.height = `${dim.canvasHeight}px`;\n\n // Draw the background if this is an opaque layer\n if (!this._alpha) {\n this.clearAll();\n }\n\n if (charSizeChanged) {\n this._refreshCharAtlas(terminal, this._colors);\n }\n }\n\n public abstract reset(terminal: ITerminal): void;\n\n /**\n * Fills 1+ cells completely. This uses the existing fillStyle on the context.\n * @param x The column to start at.\n * @param y The row to start at\n * @param width The number of columns to fill.\n * @param height The number of rows to fill.\n */\n protected fillCells(x: number, y: number, width: number, height: number): void {\n this._ctx.fillRect(\n x * this._scaledCellWidth,\n y * this._scaledCellHeight,\n width * this._scaledCellWidth,\n height * this._scaledCellHeight);\n }\n\n /**\n * Fills a 1px line (2px on HDPI) at the bottom of the cell. This uses the\n * existing fillStyle on the context.\n * @param x The column to fill.\n * @param y The row to fill.\n */\n protected fillBottomLineAtCells(x: number, y: number, width: number = 1): void {\n this._ctx.fillRect(\n x * this._scaledCellWidth,\n (y + 1) * this._scaledCellHeight - window.devicePixelRatio - 1 /* Ensure it's drawn within the cell */,\n width * this._scaledCellWidth,\n window.devicePixelRatio);\n }\n\n /**\n * Fills a 1px line (2px on HDPI) at the left of the cell. This uses the\n * existing fillStyle on the context.\n * @param x The column to fill.\n * @param y The row to fill.\n */\n protected fillLeftLineAtCell(x: number, y: number): void {\n this._ctx.fillRect(\n x * this._scaledCellWidth,\n y * this._scaledCellHeight,\n window.devicePixelRatio,\n this._scaledCellHeight);\n }\n\n /**\n * Strokes a 1px rectangle (2px on HDPI) around a cell. This uses the existing\n * strokeStyle on the context.\n * @param x The column to fill.\n * @param y The row to fill.\n */\n protected strokeRectAtCell(x: number, y: number, width: number, height: number): void {\n this._ctx.lineWidth = window.devicePixelRatio;\n this._ctx.strokeRect(\n x * this._scaledCellWidth + window.devicePixelRatio / 2,\n y * this._scaledCellHeight + (window.devicePixelRatio / 2),\n width * this._scaledCellWidth - window.devicePixelRatio,\n (height * this._scaledCellHeight) - window.devicePixelRatio);\n }\n\n /**\n * Clears the entire canvas.\n */\n protected clearAll(): void {\n if (this._alpha) {\n this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n } else {\n this._ctx.fillStyle = this._colors.background;\n this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n }\n }\n\n /**\n * Clears 1+ cells completely.\n * @param x The column to start at.\n * @param y The row to start at.\n * @param width The number of columns to clear.\n * @param height The number of rows to clear.\n */\n protected clearCells(x: number, y: number, width: number, height: number): void {\n if (this._alpha) {\n this._ctx.clearRect(\n x * this._scaledCellWidth,\n y * this._scaledCellHeight,\n width * this._scaledCellWidth,\n height * this._scaledCellHeight);\n } else {\n this._ctx.fillStyle = this._colors.background;\n this._ctx.fillRect(\n x * this._scaledCellWidth,\n y * this._scaledCellHeight,\n width * this._scaledCellWidth,\n height * this._scaledCellHeight);\n }\n }\n\n /**\n * Draws a truecolor character at the cell. The character will be clipped to\n * ensure that it fits with the cell, including the cell to the right if it's\n * a wide character. This uses the existing fillStyle on the context.\n * @param terminal The terminal.\n * @param charData The char data for the character to draw.\n * @param x The column to draw at.\n * @param y The row to draw at.\n * @param color The color of the character.\n */\n protected fillCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number): void {\n this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;\n this._ctx.textBaseline = 'top';\n this._clipRow(terminal, y);\n this._ctx.fillText(\n charData[CHAR_DATA_CHAR_INDEX],\n x * this._scaledCellWidth + this._scaledCharLeft,\n y * this._scaledCellHeight + this._scaledCharTop);\n }\n\n /**\n * Draws a character at a cell. If possible this will draw using the character\n * atlas to reduce draw time.\n * @param terminal The terminal.\n * @param char The character.\n * @param code The character code.\n * @param width The width of the character.\n * @param x The column to draw at.\n * @param y The row to draw at.\n * @param fg The foreground color, in the format stored within the attributes.\n * @param bg The background color, in the format stored within the attributes.\n * This is used to validate whether a cached image can be used.\n * @param bold Whether the text is bold.\n */\n protected drawChar(terminal: ITerminal, char: string, code: number, width: number, x: number, y: number, fg: number, bg: number, bold: boolean, dim: boolean): void {\n let colorIndex = 0;\n if (fg < 256) {\n colorIndex = fg + 2;\n } else {\n // If default color and bold\n if (bold && terminal.options.enableBold) {\n colorIndex = 1;\n }\n }\n const isAscii = code < 256;\n // A color is basic if it is one of the standard normal or bold weight\n // colors of the characters held in the char atlas. Note that this excludes\n // the normal weight _light_ color characters.\n const isBasicColor = (colorIndex > 1 && fg < 16) && (fg < 8 || bold);\n const isDefaultColor = fg >= 256;\n const isDefaultBackground = bg >= 256;\n if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground) {\n // ImageBitmap's draw about twice as fast as from a canvas\n const charAtlasCellWidth = this._scaledCharWidth + CHAR_ATLAS_CELL_SPACING;\n const charAtlasCellHeight = this._scaledCharHeight + CHAR_ATLAS_CELL_SPACING;\n\n // Apply alpha to dim the character\n if (dim) {\n this._ctx.globalAlpha = DIM_OPACITY;\n }\n\n // Draw the non-bold version of the same color if bold is not enabled\n if (bold && !terminal.options.enableBold) {\n // Ignore default color as it's not touched above\n if (colorIndex > 1) {\n colorIndex -= 8;\n }\n }\n\n this._ctx.drawImage(this._charAtlas,\n code * charAtlasCellWidth,\n colorIndex * charAtlasCellHeight,\n charAtlasCellWidth,\n this._scaledCharHeight,\n x * this._scaledCellWidth + this._scaledCharLeft,\n y * this._scaledCellHeight + this._scaledCharTop,\n charAtlasCellWidth,\n this._scaledCharHeight);\n } else {\n this._drawUncachedChar(terminal, char, width, fg, x, y, bold, dim);\n }\n // This draws the atlas (for debugging purposes)\n // this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n // this._ctx.drawImage(this._charAtlas, 0, 0);\n }\n\n /**\n * Draws a character at a cell. The character will be clipped to\n * ensure that it fits with the cell, including the cell to the right if it's\n * a wide character.\n * @param terminal The terminal.\n * @param char The character.\n * @param width The width of the character.\n * @param fg The foreground color, in the format stored within the attributes.\n * @param x The column to draw at.\n * @param y The row to draw at.\n */\n private _drawUncachedChar(terminal: ITerminal, char: string, width: number, fg: number, x: number, y: number, bold: boolean, dim: boolean): void {\n this._ctx.save();\n this._ctx.font = `${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`;\n if (bold && terminal.options.enableBold) {\n this._ctx.font = `bold ${this._ctx.font}`;\n }\n this._ctx.textBaseline = 'top';\n\n if (fg === INVERTED_DEFAULT_COLOR) {\n this._ctx.fillStyle = this._colors.background;\n } else if (fg < 256) {\n // 256 color support\n this._ctx.fillStyle = this._colors.ansi[fg];\n } else {\n this._ctx.fillStyle = this._colors.foreground;\n }\n\n this._clipRow(terminal, y);\n\n // Apply alpha to dim the character\n if (dim) {\n this._ctx.globalAlpha = DIM_OPACITY;\n }\n // Draw the character\n this._ctx.fillText(\n char,\n x * this._scaledCellWidth + this._scaledCharLeft,\n y * this._scaledCellHeight + this._scaledCharTop);\n this._ctx.restore();\n }\n\n /**\n * Clips a row to ensure no pixels will be drawn outside the cells in the row.\n * @param terminal The terminal.\n * @param y The row to clip.\n */\n private _clipRow(terminal: ITerminal, y: number): void {\n this._ctx.beginPath();\n this._ctx.rect(\n 0,\n y * this._scaledCellHeight,\n terminal.cols * this._scaledCellWidth,\n this._scaledCellHeight);\n this._ctx.clip();\n }\n}\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IMouseZoneManager, IMouseZone } from './Interfaces';\nimport { ITerminal } from '../Interfaces';\n\nconst HOVER_DURATION = 500;\n\n/**\n * The MouseZoneManager allows components to register zones within the terminal\n * that trigger hover and click callbacks.\n *\n * This class was intentionally made not so robust initially as the only case it\n * needed to support was single-line links which never overlap. Improvements can\n * be made in the future.\n */\nexport class MouseZoneManager implements IMouseZoneManager {\n private _zones: IMouseZone[] = [];\n\n private _areZonesActive: boolean = false;\n private _mouseMoveListener: (e: MouseEvent) => any;\n private _clickListener: (e: MouseEvent) => any;\n\n private _tooltipTimeout: number = null;\n private _currentZone: IMouseZone = null;\n private _lastHoverCoords: [number, number] = [null, null];\n\n constructor(\n private _terminal: ITerminal\n ) {\n this._terminal.element.addEventListener('mousedown', e => this._onMouseDown(e));\n\n // These events are expensive, only listen to it when mouse zones are active\n this._mouseMoveListener = e => this._onMouseMove(e);\n this._clickListener = e => this._onClick(e);\n }\n\n public add(zone: IMouseZone): void {\n this._zones.push(zone);\n if (this._zones.length === 1) {\n this._activate();\n }\n }\n\n public clearAll(start?: number, end?: number): void {\n // Exit if there's nothing to clear\n if (this._zones.length === 0) {\n return;\n }\n\n // Clear all if start/end weren't set\n if (!end) {\n start = 0;\n end = this._terminal.rows - 1;\n }\n\n // Iterate through zones and clear them out if they're within the range\n for (let i = 0; i < this._zones.length; i++) {\n const zone = this._zones[i];\n if (zone.y > start && zone.y <= end + 1) {\n if (this._currentZone && this._currentZone === zone) {\n this._currentZone.leaveCallback();\n this._currentZone = null;\n }\n this._zones.splice(i--, 1);\n }\n }\n\n // Deactivate the mouse zone manager if all the zones have been removed\n if (this._zones.length === 0) {\n this._deactivate();\n }\n }\n\n private _activate(): void {\n if (!this._areZonesActive) {\n this._areZonesActive = true;\n this._terminal.element.addEventListener('mousemove', this._mouseMoveListener);\n this._terminal.element.addEventListener('click', this._clickListener);\n }\n }\n\n private _deactivate(): void {\n if (this._areZonesActive) {\n this._areZonesActive = false;\n this._terminal.element.removeEventListener('mousemove', this._mouseMoveListener);\n this._terminal.element.removeEventListener('click', this._clickListener);\n }\n }\n\n private _onMouseMove(e: MouseEvent): void {\n // TODO: Ideally this would only clear the hover state when the mouse moves\n // outside of the mouse zone\n if (this._lastHoverCoords[0] !== e.pageX || this._lastHoverCoords[1] !== e.pageY) {\n this._onHover(e);\n // Record the current coordinates\n this._lastHoverCoords = [e.pageX, e.pageY];\n }\n }\n\n private _onHover(e: MouseEvent): void {\n const zone = this._findZoneEventAt(e);\n\n // Do nothing if the zone is the same\n if (zone === this._currentZone) {\n return;\n }\n\n // Fire the hover end callback and cancel any existing timer if a new zone\n // is being hovered\n if (this._currentZone) {\n this._currentZone.leaveCallback();\n this._currentZone = null;\n if (this._tooltipTimeout) {\n clearTimeout(this._tooltipTimeout);\n }\n }\n\n // Exit if there is not zone\n if (!zone) {\n return;\n }\n this._currentZone = zone;\n\n // Trigger the hover callback\n if (zone.hoverCallback) {\n zone.hoverCallback(e);\n }\n\n // Restart the tooltip timeout\n this._tooltipTimeout = <number><any>setTimeout(() => this._onTooltip(e), HOVER_DURATION);\n }\n\n private _onTooltip(e: MouseEvent): void {\n this._tooltipTimeout = null;\n const zone = this._findZoneEventAt(e);\n if (zone && zone.tooltipCallback) {\n zone.tooltipCallback(e);\n }\n }\n\n private _onMouseDown(e: MouseEvent): void {\n // Ignore the event if there are no zones active\n if (!this._areZonesActive) {\n return;\n }\n\n // Find the active zone, prevent event propagation if found to prevent other\n // components from handling the mouse event.\n const zone = this._findZoneEventAt(e);\n if (zone) {\n // TODO: When link modifier support is added, the event should only be\n // cancelled when the modifier is held (see #1021)\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n }\n\n private _onClick(e: MouseEvent): void {\n // Find the active zone and click it if found\n const zone = this._findZoneEventAt(e);\n if (zone) {\n zone.clickCallback(e);\n e.preventDefault();\n e.stopImmediatePropagation();\n }\n }\n\n private _findZoneEventAt(e: MouseEvent): IMouseZone {\n const coords = this._terminal.mouseHelper.getCoords(e, this._terminal.element, this._terminal.charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows);\n if (!coords) {\n return null;\n }\n for (let i = 0; i < this._zones.length; i++) {\n const zone = this._zones[i];\n if (zone.y === coords[1] && zone.x1 <= coords[0] && zone.x2 > coords[0]) {\n return zone;\n }\n };\n return null;\n }\n}\n\nexport class MouseZone implements IMouseZone {\n constructor(\n public x1: number,\n public x2: number,\n public y: number,\n public clickCallback: (e: MouseEvent) => any,\n public hoverCallback?: (e: MouseEvent) => any,\n public tooltipCallback?: (e: MouseEvent) => any,\n public leaveCallback?: () => void\n ) {\n }\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, ISelectionManager } from '../Interfaces';\n\ninterface IWindow extends Window {\n clipboardData?: {\n getData(format: string): string;\n setData(format: string, data: string): void;\n };\n}\n\ndeclare var window: IWindow;\n\n/**\n * Prepares text to be pasted into the terminal by normalizing the line endings\n * @param text The pasted text that needs processing before inserting into the terminal\n */\nexport function prepareTextForTerminal(text: string, isMSWindows: boolean): string {\n if (isMSWindows) {\n return text.replace(/\\r?\\n/g, '\\r');\n }\n return text;\n}\n\n/**\n * Bracket text for paste, if necessary, as per https://cirw.in/blog/bracketed-paste\n * @param text The pasted text to bracket\n */\nexport function bracketTextForPaste(text: string, bracketedPasteMode: boolean): string {\n if (bracketedPasteMode) {\n return '\\x1b[200~' + text + '\\x1b[201~';\n }\n return text;\n}\n\n/**\n * Binds copy functionality to the given terminal.\n * @param {ClipboardEvent} ev The original copy event to be handled\n */\nexport function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManager: ISelectionManager): void {\n if (term.browser.isMSIE) {\n window.clipboardData.setData('Text', selectionManager.selectionText);\n } else {\n ev.clipboardData.setData('text/plain', selectionManager.selectionText);\n }\n\n // Prevent or the original text will be copied.\n ev.preventDefault();\n}\n\n/**\n * Redirect the clipboard's data to the terminal's input handler.\n * @param {ClipboardEvent} ev The original paste event to be handled\n * @param {Terminal} term The terminal on which to apply the handled paste event\n */\nexport function pasteHandler(ev: ClipboardEvent, term: ITerminal): void {\n ev.stopPropagation();\n\n let text: string;\n\n let dispatchPaste = function(text: string): void {\n text = prepareTextForTerminal(text, term.browser.isMSWindows);\n text = bracketTextForPaste(text, term.bracketedPasteMode);\n term.handler(text);\n term.textarea.value = '';\n term.emit('paste', text);\n term.cancel(ev);\n };\n\n if (term.browser.isMSIE) {\n if (window.clipboardData) {\n text = window.clipboardData.getData('Text');\n dispatchPaste(text);\n }\n } else {\n if (ev.clipboardData) {\n text = ev.clipboardData.getData('text/plain');\n dispatchPaste(text);\n }\n }\n}\n\n/**\n * Moves the textarea under the mouse cursor and focuses it.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n */\nexport function moveTextAreaUnderMouseCursor(ev: MouseEvent, textarea: HTMLTextAreaElement): void {\n // Bring textarea at the cursor position\n textarea.style.position = 'fixed';\n textarea.style.width = '20px';\n textarea.style.height = '20px';\n textarea.style.left = (ev.clientX - 10) + 'px';\n textarea.style.top = (ev.clientY - 10) + 'px';\n textarea.style.zIndex = '1000';\n\n textarea.focus();\n\n // Reset the terminal textarea's styling\n setTimeout(() => {\n textarea.style.position = null;\n textarea.style.width = null;\n textarea.style.height = null;\n textarea.style.left = null;\n textarea.style.top = null;\n textarea.style.zIndex = null;\n }, 4);\n}\n\n/**\n * Bind to right-click event and allow right-click copy and paste.\n * @param ev The original right click event to be handled.\n * @param textarea The terminal's textarea.\n * @param selectionManager The terminal's selection manager.\n */\nexport function rightClickHandler(ev: MouseEvent, textarea: HTMLTextAreaElement, selectionManager: ISelectionManager): void {\n moveTextAreaUnderMouseCursor(ev, textarea);\n\n // Get textarea ready to copy from the context menu\n textarea.value = selectionManager.selectionText;\n textarea.select();\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, IViewport } from './Interfaces';\nimport { CharMeasure } from './utils/CharMeasure';\nimport { IColorSet } from './renderer/Interfaces';\n\n/**\n * Represents the viewport of a terminal, the visible area within the larger buffer of output.\n * Logic for the virtual scroll bar is included in this object.\n */\nexport class Viewport implements IViewport {\n private currentRowHeight: number = 0;\n private lastRecordedBufferLength: number = 0;\n private lastRecordedViewportHeight: number = 0;\n private lastRecordedBufferHeight: number = 0;\n private lastTouchY: number;\n\n /**\n * Creates a new Viewport.\n * @param terminal The terminal this viewport belongs to.\n * @param viewportElement The DOM element acting as the viewport.\n * @param scrollArea The DOM element acting as the scroll area.\n * @param charMeasure A DOM element used to measure the character size of. the terminal.\n */\n constructor(\n private terminal: ITerminal,\n private viewportElement: HTMLElement,\n private scrollArea: HTMLElement,\n private charMeasure: CharMeasure\n ) {\n this.viewportElement.addEventListener('scroll', this.onScroll.bind(this));\n\n // Perform this async to ensure the CharMeasure is ready.\n setTimeout(() => this.syncScrollArea(), 0);\n }\n\n public onThemeChanged(colors: IColorSet): void {\n this.viewportElement.style.backgroundColor = colors.background;\n }\n\n /**\n * Refreshes row height, setting line-height, viewport height and scroll area height if\n * necessary.\n */\n private refresh(): void {\n if (this.charMeasure.height > 0) {\n this.currentRowHeight = this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio;\n\n if (this.lastRecordedViewportHeight !== this.terminal.renderer.dimensions.canvasHeight) {\n this.lastRecordedViewportHeight = this.terminal.renderer.dimensions.canvasHeight;\n this.viewportElement.style.height = this.lastRecordedViewportHeight + 'px';\n }\n\n const newBufferHeight = Math.round(this.currentRowHeight * this.lastRecordedBufferLength);\n if (this.lastRecordedBufferHeight !== newBufferHeight) {\n this.lastRecordedBufferHeight = newBufferHeight;\n this.scrollArea.style.height = this.lastRecordedBufferHeight + 'px';\n }\n }\n }\n\n /**\n * Updates dimensions and synchronizes the scroll area if necessary.\n */\n public syncScrollArea(): void {\n if (this.lastRecordedBufferLength !== this.terminal.buffer.lines.length) {\n // If buffer height changed\n this.lastRecordedBufferLength = this.terminal.buffer.lines.length;\n this.refresh();\n } else if (this.lastRecordedViewportHeight !== (<any>this.terminal).renderer.dimensions.canvasHeight) {\n // If viewport height changed\n this.refresh();\n } else {\n // If size has changed, refresh viewport\n if (this.terminal.renderer.dimensions.scaledCellHeight / window.devicePixelRatio !== this.currentRowHeight) {\n this.refresh();\n }\n }\n\n // Sync scrollTop\n const scrollTop = this.terminal.buffer.ydisp * this.currentRowHeight;\n if (this.viewportElement.scrollTop !== scrollTop) {\n this.viewportElement.scrollTop = scrollTop;\n }\n }\n\n /**\n * Handles scroll events on the viewport, calculating the new viewport and requesting the\n * terminal to scroll to it.\n * @param ev The scroll event.\n */\n private onScroll(ev: Event): void {\n const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);\n const diff = newRow - this.terminal.buffer.ydisp;\n this.terminal.scrollLines(diff, true);\n }\n\n /**\n * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual\n * scrolling to `onScroll`, this event needs to be attached manually by the consumer of\n * `Viewport`.\n * @param ev The mouse wheel event.\n */\n public onWheel(ev: WheelEvent): void {\n if (ev.deltaY === 0) {\n // Do nothing if it's not a vertical scroll event\n return;\n }\n // Fallback to WheelEvent.DOM_DELTA_PIXEL\n let multiplier = 1;\n if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n multiplier = this.currentRowHeight;\n } else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {\n multiplier = this.currentRowHeight * this.terminal.rows;\n }\n this.viewportElement.scrollTop += ev.deltaY * multiplier;\n // Prevent the page from scrolling when the terminal scrolls\n ev.preventDefault();\n };\n\n /**\n * Handles the touchstart event, recording the touch occurred.\n * @param ev The touch event.\n */\n public onTouchStart(ev: TouchEvent): void {\n this.lastTouchY = ev.touches[0].pageY;\n };\n\n /**\n * Handles the touchmove event, scrolling the viewport if the position shifted.\n * @param ev The touch event.\n */\n public onTouchMove(ev: TouchEvent): void {\n let deltaY = this.lastTouchY - ev.touches[0].pageY;\n this.lastTouchY = ev.touches[0].pageY;\n if (deltaY === 0) {\n return;\n }\n this.viewportElement.scrollTop += deltaY;\n ev.preventDefault();\n };\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport type LinkMatcher = {\n id: number,\n regex: RegExp,\n handler: LinkMatcherHandler,\n hoverTooltipCallback?: LinkMatcherHandler,\n hoverLeaveCallback?: () => void,\n matchIndex?: number,\n validationCallback?: LinkMatcherValidationCallback,\n priority?: number\n};\nexport type LinkMatcherHandler = (event: MouseEvent, uri: string) => boolean | void;\nexport type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void;\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type Charset = {[key: string]: string};\n\nexport type CharData = [number, string, number, number];\nexport type LineData = CharData[];\n\nexport type LinkHoverEvent = {\n x: number,\n y: number,\n length: number\n};\n\nexport enum LinkHoverEventTypes {\n HOVER = 'linkhover',\n TOOLTIP = 'linktooltip',\n LEAVE = 'linkleave'\n};\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n *\n * Originally forked from (with the author's permission):\n * Fabrice Bellard's javascript vt100 for jslinux:\n * http://bellard.org/jslinux/\n * Copyright (c) 2011 Fabrice Bellard\n * The original design remains. The terminal itself\n * has been extended to include xterm CSI codes, among\n * other features.\n *\n * Terminal Emulation References:\n * http://vt100.net/\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * http://invisible-island.net/vttest/\n * http://www.inwap.com/pdp10/ansicode.txt\n * http://linux.die.net/man/4/console_codes\n * http://linux.die.net/man/7/urxvt\n */\n\nimport { BufferSet } from './BufferSet';\nimport { Buffer, MAX_BUFFER_SIZE } from './Buffer';\nimport { CompositionHelper } from './CompositionHelper';\nimport { EventEmitter } from './EventEmitter';\nimport { Viewport } from './Viewport';\nimport { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './handlers/Clipboard';\nimport { CircularList } from './utils/CircularList';\nimport { C0 } from './EscapeSequences';\nimport { InputHandler } from './InputHandler';\nimport { Parser } from './Parser';\nimport { Renderer } from './renderer/Renderer';\nimport { Linkifier } from './Linkifier';\nimport { SelectionManager } from './SelectionManager';\nimport { CharMeasure } from './utils/CharMeasure';\nimport * as Browser from './utils/Browser';\nimport { MouseHelper } from './utils/MouseHelper';\nimport { CHARSETS } from './Charsets';\nimport { CustomKeyEventHandler, Charset, LinkMatcherHandler, LinkMatcherValidationCallback, CharData, LineData } from './Types';\nimport { ITerminal, IBrowser, ITerminalOptions, IInputHandlingTerminal, ILinkMatcherOptions, IViewport, ICompositionHelper, ITheme, ILinkifier } from './Interfaces';\nimport { BellSound } from './utils/Sounds';\nimport { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';\nimport { IMouseZoneManager } from './input/Interfaces';\nimport { MouseZoneManager } from './input/MouseZoneManager';\nimport { initialize as initializeCharAtlas } from './renderer/CharAtlas';\nimport { IRenderer } from './renderer/Interfaces';\n\n// Let it work inside Node.js for automated testing purposes.\nconst document = (typeof window !== 'undefined') ? window.document : null;\n\n/**\n * The amount of write requests to queue before sending an XOFF signal to the\n * pty process. This number must be small in order for ^C and similar sequences\n * to be responsive.\n */\nconst WRITE_BUFFER_PAUSE_THRESHOLD = 5;\n\n/**\n * The number of writes to perform in a single batch before allowing the\n * renderer to catch up with a 0ms setTimeout.\n */\nconst WRITE_BATCH_SIZE = 300;\n\nconst DEFAULT_OPTIONS: ITerminalOptions = {\n cols: 80,\n rows: 24,\n convertEol: false,\n termName: 'xterm',\n cursorBlink: false,\n cursorStyle: 'block',\n bellSound: BellSound,\n bellStyle: 'none',\n enableBold: true,\n fontFamily: 'courier-new, courier, monospace',\n fontSize: 15,\n lineHeight: 1.0,\n letterSpacing: 0,\n scrollback: 1000,\n screenKeys: false,\n debug: false,\n cancelEvents: false,\n disableStdin: false,\n useFlowControl: false,\n tabStopWidth: 8,\n theme: null\n // programFeatures: false,\n // focusKeys: false,\n};\n\nexport class Terminal extends EventEmitter implements ITerminal, IInputHandlingTerminal {\n public textarea: HTMLTextAreaElement;\n public element: HTMLElement;\n\n /**\n * The HTMLElement that the terminal is created in, set by Terminal.open.\n */\n private parent: HTMLElement;\n private context: Window;\n private document: Document;\n private body: HTMLBodyElement;\n private viewportScrollArea: HTMLElement;\n private viewportElement: HTMLElement;\n private helperContainer: HTMLElement;\n private compositionView: HTMLElement;\n private charSizeStyleElement: HTMLStyleElement;\n private bellAudioElement: HTMLAudioElement;\n private visualBellTimer: number;\n\n public browser: IBrowser = <any>Browser;\n\n public options: ITerminalOptions;\n private colors: any;\n\n // TODO: This can be changed to an enum or boolean, 0 and 1 seem to be the only options\n public cursorState: number;\n public cursorHidden: boolean;\n public convertEol: boolean;\n\n private sendDataQueue: string;\n private customKeyEventHandler: CustomKeyEventHandler;\n\n // modes\n public applicationKeypad: boolean;\n public applicationCursor: boolean;\n public originMode: boolean;\n public insertMode: boolean;\n public wraparoundMode: boolean; // defaults: xterm - true, vt100 - false\n public bracketedPasteMode: boolean;\n\n // charset\n // The current charset\n public charset: Charset;\n public gcharset: number;\n public glevel: number;\n public charsets: Charset[];\n\n // mouse properties\n private decLocator: boolean; // This is unstable and never set\n public x10Mouse: boolean;\n public vt200Mouse: boolean;\n private vt300Mouse: boolean; // This is unstable and never set\n public normalMouse: boolean;\n public mouseEvents: boolean;\n public sendFocus: boolean;\n public utfMouse: boolean;\n public sgrMouse: boolean;\n public urxvtMouse: boolean;\n\n // misc\n private refreshStart: number;\n private refreshEnd: number;\n public savedCols: number;\n\n // stream\n private readable: boolean;\n private writable: boolean;\n\n public defAttr: number;\n public curAttr: number;\n\n public params: (string | number)[];\n public currentParam: string | number;\n public prefix: string;\n public postfix: string;\n\n // user input states\n public writeBuffer: string[];\n private writeInProgress: boolean;\n\n /**\n * Whether _xterm.js_ sent XOFF in order to catch up with the pty process.\n * This is a distinct state from writeStopped so that if the user requested\n * XOFF via ^S that it will not automatically resume when the writeBuffer goes\n * below threshold.\n */\n private xoffSentToCatchUp: boolean;\n\n /** Whether writing has been stopped as a result of XOFF */\n private writeStopped: boolean;\n\n // leftover surrogate high from previous write invocation\n private surrogate_high: string;\n\n // Store if user went browsing history in scrollback\n private userScrolling: boolean;\n\n private inputHandler: InputHandler;\n private parser: Parser;\n public renderer: IRenderer;\n public selectionManager: SelectionManager;\n public linkifier: ILinkifier;\n public buffers: BufferSet;\n public buffer: Buffer;\n public viewport: IViewport;\n private compositionHelper: ICompositionHelper;\n public charMeasure: CharMeasure;\n private _mouseZoneManager: IMouseZoneManager;\n public mouseHelper: MouseHelper;\n\n public cols: number;\n public rows: number;\n\n /**\n * Creates a new `Terminal` object.\n *\n * @param {object} options An object containing a set of options, the available options are:\n * - `cursorBlink` (boolean): Whether the terminal cursor blinks\n * - `cols` (number): The number of columns of the terminal (horizontal size)\n * - `rows` (number): The number of rows of the terminal (vertical size)\n *\n * @public\n * @class Xterm Xterm\n * @alias module:xterm/src/xterm\n */\n constructor(\n options: ITerminalOptions = {}\n ) {\n super();\n this.options = options;\n this.setup();\n }\n\n private setup(): void {\n Object.keys(DEFAULT_OPTIONS).forEach((key) => {\n if (this.options[key] == null) {\n this.options[key] = DEFAULT_OPTIONS[key];\n }\n // TODO: We should move away from duplicate options on the Terminal object\n this[key] = this.options[key];\n });\n\n // this.context = options.context || window;\n // this.document = options.document || document;\n // TODO: WHy not document.body?\n this.parent = document ? document.body : null;\n\n this.cols = this.options.cols;\n this.rows = this.options.rows;\n\n if (this.options.handler) {\n this.on('data', this.options.handler);\n }\n\n this.cursorState = 0;\n this.cursorHidden = false;\n this.sendDataQueue = '';\n this.customKeyEventHandler = null;\n\n // modes\n this.applicationKeypad = false;\n this.applicationCursor = false;\n this.originMode = false;\n this.insertMode = false;\n this.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this.bracketedPasteMode = false;\n\n // charset\n this.charset = null;\n this.gcharset = null;\n this.glevel = 0;\n // TODO: Can this be just []?\n this.charsets = [null];\n\n this.readable = true;\n this.writable = true;\n\n this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);\n this.curAttr = (0 << 18) | (257 << 9) | (256 << 0);\n\n this.params = [];\n this.currentParam = 0;\n this.prefix = '';\n this.postfix = '';\n\n // user input states\n this.writeBuffer = [];\n this.writeInProgress = false;\n\n this.xoffSentToCatchUp = false;\n this.writeStopped = false;\n this.surrogate_high = '';\n this.userScrolling = false;\n\n this.inputHandler = new InputHandler(this);\n this.parser = new Parser(this.inputHandler, this);\n // Reuse renderer if the Terminal is being recreated via a reset call.\n this.renderer = this.renderer || null;\n this.selectionManager = this.selectionManager || null;\n this.linkifier = this.linkifier || new Linkifier(this);\n this._mouseZoneManager = this._mouseZoneManager || null;\n\n // Create the terminal's buffers and set the current buffer\n this.buffers = new BufferSet(this);\n this.buffer = this.buffers.active; // Convenience shortcut;\n this.buffers.on('activate', (buffer: Buffer) => {\n this.buffer = buffer;\n });\n\n // Ensure the selection manager has the correct buffer\n if (this.selectionManager) {\n this.selectionManager.setBuffer(this.buffer);\n }\n }\n\n /**\n * back_color_erase feature for xterm.\n */\n public eraseAttr(): number {\n // if (this.is('screen')) return this.defAttr;\n return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff);\n }\n\n /**\n * Focus the terminal. Delegates focus handling to the terminal's DOM element.\n */\n public focus(): void {\n if (this.textarea) {\n this.textarea.focus();\n }\n }\n\n public get isFocused(): boolean {\n return document.activeElement === this.textarea;\n }\n\n /**\n * Retrieves an option's value from the terminal.\n * @param {string} key The option key.\n */\n public getOption(key: string): any {\n if (!(key in DEFAULT_OPTIONS)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n\n if (typeof this.options[key] !== 'undefined') {\n return this.options[key];\n }\n\n return this[key];\n }\n\n /**\n * Sets an option on the terminal.\n * @param {string} key The option key.\n * @param {any} value The option value.\n */\n public setOption(key: string, value: any): void {\n if (!(key in DEFAULT_OPTIONS)) {\n throw new Error('No option with key \"' + key + '\"');\n }\n switch (key) {\n case 'bellStyle':\n if (!value) {\n value = 'none';\n }\n break;\n case 'cursorStyle':\n if (!value) {\n value = 'block';\n }\n break;\n case 'lineHeight':\n if (value < 1) {\n console.warn(`${key} cannot be less than 1, value: ${value}`);\n return;\n }\n case 'tabStopWidth':\n if (value < 1) {\n console.warn(`${key} cannot be less than 1, value: ${value}`);\n return;\n }\n break;\n case 'theme':\n // If open has been called we do not want to set options.theme as the\n // source of truth is owned by the renderer.\n if (this.renderer) {\n this._setTheme(<ITheme>value);\n return;\n }\n break;\n case 'scrollback':\n value = Math.min(value, MAX_BUFFER_SIZE);\n\n if (value < 0) {\n console.warn(`${key} cannot be less than 0, value: ${value}`);\n return;\n }\n if (this.options[key] !== value) {\n const newBufferLength = this.rows + value;\n if (this.buffer.lines.length > newBufferLength) {\n const amountToTrim = this.buffer.lines.length - newBufferLength;\n const needsRefresh = (this.buffer.ydisp - amountToTrim < 0);\n this.buffer.lines.trimStart(amountToTrim);\n this.buffer.ybase = Math.max(this.buffer.ybase - amountToTrim, 0);\n this.buffer.ydisp = Math.max(this.buffer.ydisp - amountToTrim, 0);\n if (needsRefresh) {\n this.refresh(0, this.rows - 1);\n }\n }\n }\n break;\n }\n this[key] = value;\n this.options[key] = value;\n switch (key) {\n case 'fontFamily':\n case 'fontSize':\n // When the font changes the size of the cells may change which requires a renderer clear\n this.renderer.clear();\n this.charMeasure.measure(this.options);\n break;\n case 'enableBold':\n case 'letterSpacing':\n case 'lineHeight':\n // When the font changes the size of the cells may change which requires a renderer clear\n this.renderer.clear();\n this.renderer.onResize(this.cols, this.rows, false);\n this.refresh(0, this.rows - 1);\n // this.charMeasure.measure(this.options);\n case 'scrollback':\n this.buffers.resize(this.cols, this.rows);\n this.viewport.syncScrollArea();\n break;\n case 'tabStopWidth': this.buffers.setupTabStops(); break;\n case 'bellSound':\n case 'bellStyle': this.syncBellSound(); break;\n }\n // Inform renderer of changes\n if (this.renderer) {\n this.renderer.onOptionsChanged();\n }\n }\n\n /**\n * Binds the desired focus behavior on a given terminal object.\n */\n private _onTextAreaFocus(): void {\n if (this.sendFocus) {\n this.send(C0.ESC + '[I');\n }\n this.element.classList.add('focus');\n this.showCursor();\n this.emit('focus');\n };\n\n /**\n * Blur the terminal, calling the blur function on the terminal's underlying\n * textarea.\n */\n public blur(): void {\n return this.textarea.blur();\n }\n\n /**\n * Binds the desired blur behavior on a given terminal object.\n */\n private _onTextAreaBlur(): void {\n this.refresh(this.buffer.y, this.buffer.y);\n if (this.sendFocus) {\n this.send(C0.ESC + '[O');\n }\n this.element.classList.remove('focus');\n this.emit('blur');\n }\n\n /**\n * Initialize default behavior\n */\n private initGlobal(): void {\n this.bindKeys();\n\n // Bind clipboard functionality\n on(this.element, 'copy', (event: ClipboardEvent) => {\n // If mouse events are active it means the selection manager is disabled and\n // copy should be handled by the host program.\n if (!this.hasSelection()) {\n return;\n }\n copyHandler(event, this, this.selectionManager);\n });\n const pasteHandlerWrapper = event => pasteHandler(event, this);\n on(this.textarea, 'paste', pasteHandlerWrapper);\n on(this.element, 'paste', pasteHandlerWrapper);\n\n // Handle right click context menus\n if (Browser.isFirefox) {\n // Firefox doesn't appear to fire the contextmenu event on right click\n on(this.element, 'mousedown', (event: MouseEvent) => {\n if (event.button === 2) {\n rightClickHandler(event, this.textarea, this.selectionManager);\n }\n });\n } else {\n on(this.element, 'contextmenu', (event: MouseEvent) => {\n rightClickHandler(event, this.textarea, this.selectionManager);\n });\n }\n\n // Move the textarea under the cursor when middle clicking on Linux to ensure\n // middle click to paste selection works. This only appears to work in Chrome\n // at the time is writing.\n if (Browser.isLinux) {\n // Use auxclick event over mousedown the latter doesn't seem to work. Note\n // that the regular click event doesn't fire for the middle mouse button.\n on(this.element, 'auxclick', (event: MouseEvent) => {\n if (event.button === 1) {\n moveTextAreaUnderMouseCursor(event, this.textarea);\n }\n });\n }\n }\n\n /**\n * Apply key handling to the terminal\n */\n private bindKeys(): void {\n const self = this;\n on(this.element, 'keydown', function (ev: KeyboardEvent): void {\n if (document.activeElement !== this) {\n return;\n }\n self._keyDown(ev);\n }, true);\n\n on(this.element, 'keypress', function (ev: KeyboardEvent): void {\n if (document.activeElement !== this) {\n return;\n }\n self._keyPress(ev);\n }, true);\n\n on(this.element, 'keyup', (ev: KeyboardEvent) => {\n if (!wasMondifierKeyOnlyEvent(ev)) {\n this.focus();\n }\n }, true);\n\n on(this.textarea, 'keydown', (ev: KeyboardEvent) => {\n this._keyDown(ev);\n }, true);\n\n on(this.textarea, 'keypress', (ev: KeyboardEvent) => {\n this._keyPress(ev);\n // Truncate the textarea's value, since it is not needed\n this.textarea.value = '';\n }, true);\n\n on(this.textarea, 'compositionstart', () => this.compositionHelper.compositionstart());\n on(this.textarea, 'compositionupdate', (e: CompositionEvent) => this.compositionHelper.compositionupdate(e));\n on(this.textarea, 'compositionend', () => this.compositionHelper.compositionend());\n this.on('refresh', () => this.compositionHelper.updateCompositionElements());\n this.on('refresh', (data) => this.queueLinkification(data.start, data.end));\n }\n\n /**\n * Opens the terminal within an element.\n *\n * @param {HTMLElement} parent The element to create the terminal within.\n */\n public open(parent: HTMLElement): void {\n let i = 0;\n let div;\n\n this.parent = parent || this.parent;\n\n if (!this.parent) {\n throw new Error('Terminal requires a parent element.');\n }\n\n // Grab global elements\n this.context = this.parent.ownerDocument.defaultView;\n this.document = this.parent.ownerDocument;\n this.body = <HTMLBodyElement>this.document.body;\n\n initializeCharAtlas(this.document);\n\n // Create main element container\n this.element = this.document.createElement('div');\n this.element.classList.add('terminal');\n this.element.classList.add('xterm');\n this.element.setAttribute('tabindex', '0');\n this.parent.appendChild(this.element);\n\n // Performance: Use a document fragment to build the terminal\n // viewport and helper elements detached from the DOM\n const fragment = document.createDocumentFragment();\n this.viewportElement = document.createElement('div');\n this.viewportElement.classList.add('xterm-viewport');\n fragment.appendChild(this.viewportElement);\n this.viewportScrollArea = document.createElement('div');\n this.viewportScrollArea.classList.add('xterm-scroll-area');\n this.viewportElement.appendChild(this.viewportScrollArea);\n\n this._mouseZoneManager = new MouseZoneManager(this);\n this.on('scroll', () => this._mouseZoneManager.clearAll());\n this.linkifier.attachToDom(this._mouseZoneManager);\n\n // Create the container that will hold helpers like the textarea for\n // capturing DOM Events. Then produce the helpers.\n this.helperContainer = document.createElement('div');\n this.helperContainer.classList.add('xterm-helpers');\n fragment.appendChild(this.helperContainer);\n\n this.textarea = document.createElement('textarea');\n this.textarea.classList.add('xterm-helper-textarea');\n this.textarea.setAttribute('autocorrect', 'off');\n this.textarea.setAttribute('autocapitalize', 'off');\n this.textarea.setAttribute('spellcheck', 'false');\n this.textarea.tabIndex = 0;\n this.textarea.addEventListener('focus', () => this._onTextAreaFocus());\n this.textarea.addEventListener('blur', () => this._onTextAreaBlur());\n this.helperContainer.appendChild(this.textarea);\n\n this.compositionView = document.createElement('div');\n this.compositionView.classList.add('composition-view');\n this.compositionHelper = new CompositionHelper(this.textarea, this.compositionView, this);\n this.helperContainer.appendChild(this.compositionView);\n\n this.charSizeStyleElement = document.createElement('style');\n this.helperContainer.appendChild(this.charSizeStyleElement);\n this.charMeasure = new CharMeasure(document, this.helperContainer);\n\n // Preload audio, this relied on helperContainer\n this.syncBellSound();\n\n // Performance: Add viewport and helper elements from the fragment\n this.element.appendChild(fragment);\n\n this.renderer = new Renderer(this, this.options.theme);\n this.options.theme = null;\n this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);\n this.viewport.onThemeChanged(this.renderer.colorManager.colors);\n\n this.on('cursormove', () => this.renderer.onCursorMove());\n this.on('resize', () => this.renderer.onResize(this.cols, this.rows, false));\n this.on('blur', () => this.renderer.onBlur());\n this.on('focus', () => this.renderer.onFocus());\n window.addEventListener('resize', () => this.renderer.onWindowResize(window.devicePixelRatio));\n this.charMeasure.on('charsizechanged', () => this.renderer.onResize(this.cols, this.rows, true));\n this.renderer.on('resize', (dimensions) => this.viewport.syncScrollArea());\n\n this.selectionManager = new SelectionManager(this, this.buffer, this.charMeasure);\n this.element.addEventListener('mousedown', (e: MouseEvent) => this.selectionManager.onMouseDown(e));\n this.selectionManager.on('refresh', data => this.renderer.onSelectionChanged(data.start, data.end));\n this.selectionManager.on('newselection', text => {\n // If there's a new selection, put it into the textarea, focus and select it\n // in order to register it as a selection on the OS. This event is fired\n // only on Linux to enable middle click to paste selection.\n this.textarea.value = text;\n this.textarea.focus();\n this.textarea.select();\n });\n this.on('scroll', () => {\n this.viewport.syncScrollArea();\n this.selectionManager.refresh();\n });\n this.viewportElement.addEventListener('scroll', () => this.selectionManager.refresh());\n\n this.mouseHelper = new MouseHelper(this.renderer);\n\n // Measure the character size\n this.charMeasure.measure(this.options);\n\n // Setup loop that draws to screen\n this.refresh(0, this.rows - 1);\n\n // Initialize global actions that need to be taken on the document.\n this.initGlobal();\n\n // Listen for mouse events and translate\n // them into terminal mouse protocols.\n this.bindMouse();\n\n }\n\n /**\n * Sets the theme on the renderer. The renderer must have been initialized.\n * @param theme The theme to ste.\n */\n private _setTheme(theme: ITheme): void {\n const colors = this.renderer.setTheme(theme);\n if (this.viewport) {\n this.viewport.onThemeChanged(colors);\n }\n }\n\n /**\n * Apply the provided addon on the `Terminal` class.\n * @param addon The addon to apply.\n */\n public static applyAddon(addon: any): void {\n addon.apply(Terminal);\n }\n\n /**\n * XTerm mouse events\n * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking\n * To better understand these\n * the xterm code is very helpful:\n * Relevant files:\n * button.c, charproc.c, misc.c\n * Relevant functions in xterm/button.c:\n * BtnCode, EmitButtonCode, EditorButton, SendMousePosition\n */\n public bindMouse(): void {\n const el = this.element;\n const self = this;\n let pressed = 32;\n\n // mouseup, mousedown, wheel\n // left click: ^[[M 3<^[[M#3<\n // wheel up: ^[[M`3>\n function sendButton(ev: MouseEvent | WheelEvent): void {\n let button;\n let pos;\n\n // get the xterm-style button\n button = getButton(ev);\n\n // get mouse coordinates\n pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows);\n if (!pos) return;\n\n sendEvent(button, pos);\n\n switch ((<any>ev).overrideType || ev.type) {\n case 'mousedown':\n pressed = button;\n break;\n case 'mouseup':\n // keep it at the left\n // button, just in case.\n pressed = 32;\n break;\n case 'wheel':\n // nothing. don't\n // interfere with\n // `pressed`.\n break;\n }\n }\n\n // motion example of a left click:\n // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<\n function sendMove(ev: MouseEvent): void {\n let button = pressed;\n let pos = self.mouseHelper.getRawByteCoords(ev, self.element, self.charMeasure, self.options.lineHeight, self.cols, self.rows);\n if (!pos) return;\n\n // buttons marked as motions\n // are incremented by 32\n button += 32;\n\n sendEvent(button, pos);\n }\n\n // encode button and\n // position to characters\n function encode(data: number[], ch: number): void {\n if (!self.utfMouse) {\n if (ch === 255) {\n data.push(0);\n return;\n }\n if (ch > 127) ch = 127;\n data.push(ch);\n } else {\n if (ch === 2047) {\n data.push(0);\n return;\n }\n if (ch < 127) {\n data.push(ch);\n } else {\n if (ch > 2047) ch = 2047;\n data.push(0xC0 | (ch >> 6));\n data.push(0x80 | (ch & 0x3F));\n }\n }\n }\n\n // send a mouse event:\n // regular/utf8: ^[[M Cb Cx Cy\n // urxvt: ^[[ Cb ; Cx ; Cy M\n // sgr: ^[[ Cb ; Cx ; Cy M/m\n // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \\r\n // locator: CSI P e ; P b ; P r ; P c ; P p & w\n function sendEvent(button: number, pos: {x: number, y: number}): void {\n // self.emit('mouse', {\n // x: pos.x - 32,\n // y: pos.x - 32,\n // button: button\n // });\n\n if (self.vt300Mouse) {\n // NOTE: Unstable.\n // http://www.vt100.net/docs/vt3xx-gp/chapter15.html\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n let data = C0.ESC + '[24';\n if (button === 0) data += '1';\n else if (button === 1) data += '3';\n else if (button === 2) data += '5';\n else if (button === 3) return;\n else data += '0';\n data += '~[' + pos.x + ',' + pos.y + ']\\r';\n self.send(data);\n return;\n }\n\n if (self.decLocator) {\n // NOTE: Unstable.\n button &= 3;\n pos.x -= 32;\n pos.y -= 32;\n if (button === 0) button = 2;\n else if (button === 1) button = 4;\n else if (button === 2) button = 6;\n else if (button === 3) button = 3;\n self.send(C0.ESC + '['\n + button\n + ';'\n + (button === 3 ? 4 : 0)\n + ';'\n + pos.y\n + ';'\n + pos.x\n + ';'\n // Not sure what page is meant to be\n + (<any>pos).page || 0\n + '&w');\n return;\n }\n\n if (self.urxvtMouse) {\n pos.x -= 32;\n pos.y -= 32;\n pos.x++;\n pos.y++;\n self.send(C0.ESC + '[' + button + ';' + pos.x + ';' + pos.y + 'M');\n return;\n }\n\n if (self.sgrMouse) {\n pos.x -= 32;\n pos.y -= 32;\n self.send(C0.ESC + '[<'\n + (((button & 3) === 3 ? button & ~3 : button) - 32)\n + ';'\n + pos.x\n + ';'\n + pos.y\n + ((button & 3) === 3 ? 'm' : 'M'));\n return;\n }\n\n let data: number[] = [];\n\n encode(data, button);\n encode(data, pos.x);\n encode(data, pos.y);\n\n self.send(C0.ESC + '[M' + String.fromCharCode.apply(String, data));\n }\n\n function getButton(ev: MouseEvent): number {\n let button;\n let shift;\n let meta;\n let ctrl;\n let mod;\n\n // two low bits:\n // 0 = left\n // 1 = middle\n // 2 = right\n // 3 = release\n // wheel up/down:\n // 1, and 2 - with 64 added\n switch ((<any>ev).overrideType || ev.type) {\n case 'mousedown':\n button = ev.button != null\n ? +ev.button\n : ev.which != null\n ? ev.which - 1\n : null;\n\n if (Browser.isMSIE) {\n button = button === 1 ? 0 : button === 4 ? 1 : button;\n }\n break;\n case 'mouseup':\n button = 3;\n break;\n case 'DOMMouseScroll':\n button = ev.detail < 0\n ? 64\n : 65;\n break;\n case 'wheel':\n button = (<WheelEvent>ev).wheelDeltaY > 0\n ? 64\n : 65;\n break;\n }\n\n // next three bits are the modifiers:\n // 4 = shift, 8 = meta, 16 = control\n shift = ev.shiftKey ? 4 : 0;\n meta = ev.metaKey ? 8 : 0;\n ctrl = ev.ctrlKey ? 16 : 0;\n mod = shift | meta | ctrl;\n\n // no mods\n if (self.vt200Mouse) {\n // ctrl only\n mod &= ctrl;\n } else if (!self.normalMouse) {\n mod = 0;\n }\n\n // increment to SP\n button = (32 + (mod << 2)) + button;\n\n return button;\n }\n\n on(el, 'mousedown', (ev: MouseEvent) => {\n\n // Prevent the focus on the textarea from getting lost\n // and make sure we get focused on mousedown\n ev.preventDefault();\n this.focus();\n\n // Don't send the mouse button to the pty if mouse events are disabled or\n // if the selection manager is having selection forced (ie. a modifier is\n // held).\n if (!this.mouseEvents || this.selectionManager.shouldForceSelection(ev)) {\n return;\n }\n\n // send the button\n sendButton(ev);\n\n // fix for odd bug\n // if (this.vt200Mouse && !this.normalMouse) {\n if (this.vt200Mouse) {\n (<any>ev).overrideType = 'mouseup';\n sendButton(ev);\n return this.cancel(ev);\n }\n\n // bind events\n if (this.normalMouse) on(this.document, 'mousemove', sendMove);\n\n // x10 compatibility mode can't send button releases\n if (!this.x10Mouse) {\n const handler = (ev: MouseEvent) => {\n sendButton(ev);\n // TODO: Seems dangerous calling this on document?\n if (this.normalMouse) off(this.document, 'mousemove', sendMove);\n off(this.document, 'mouseup', handler);\n return this.cancel(ev);\n };\n // TODO: Seems dangerous calling this on document?\n on(this.document, 'mouseup', handler);\n }\n\n return this.cancel(ev);\n });\n\n // if (this.normalMouse) {\n // on(this.document, 'mousemove', sendMove);\n // }\n\n on(el, 'wheel', (ev: WheelEvent) => {\n if (!this.mouseEvents) return;\n if (this.x10Mouse || this.vt300Mouse || this.decLocator) return;\n sendButton(ev);\n ev.preventDefault();\n });\n\n // allow wheel scrolling in\n // the shell for example\n on(el, 'wheel', (ev: WheelEvent) => {\n if (this.mouseEvents) return;\n this.viewport.onWheel(ev);\n return this.cancel(ev);\n });\n\n on(el, 'touchstart', (ev: TouchEvent) => {\n if (this.mouseEvents) return;\n this.viewport.onTouchStart(ev);\n return this.cancel(ev);\n });\n\n on(el, 'touchmove', (ev: TouchEvent) => {\n if (this.mouseEvents) return;\n this.viewport.onTouchMove(ev);\n return this.cancel(ev);\n });\n }\n\n /**\n * Destroys the terminal.\n */\n public destroy(): void {\n super.destroy();\n this.readable = false;\n this.writable = false;\n this.handler = () => {};\n this.write = () => {};\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n // this.emit('close');\n }\n\n /**\n * Tells the renderer to refresh terminal content between two rows (inclusive) at the next\n * opportunity.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\n public refresh(start: number, end: number): void {\n if (this.renderer) {\n this.renderer.queueRefresh(start, end);\n }\n }\n\n /**\n * Queues linkification for the specified rows.\n * @param {number} start The row to start from (between 0 and this.rows - 1).\n * @param {number} end The row to end at (between start and this.rows - 1).\n */\n private queueLinkification(start: number, end: number): void {\n if (this.linkifier) {\n this.linkifier.linkifyRows(start, end);\n }\n }\n\n /**\n * Display the cursor element\n */\n public showCursor(): void {\n if (!this.cursorState) {\n this.cursorState = 1;\n this.refresh(this.buffer.y, this.buffer.y);\n }\n }\n\n /**\n * Scroll the terminal down 1 row, creating a blank line.\n * @param isWrapped Whether the new line is wrapped from the previous line.\n */\n public scroll(isWrapped?: boolean): void {\n const newLine = this.blankLine(undefined, isWrapped);\n const topRow = this.buffer.ybase + this.buffer.scrollTop;\n let bottomRow = this.buffer.ybase + this.buffer.scrollBottom;\n\n if (this.buffer.scrollTop === 0) {\n // Determine whether the buffer is going to be trimmed after insertion.\n const willBufferBeTrimmed = this.buffer.lines.length === this.buffer.lines.maxLength;\n\n // Insert the line using the fastest method\n if (bottomRow === this.buffer.lines.length - 1) {\n this.buffer.lines.push(newLine);\n } else {\n this.buffer.lines.splice(bottomRow + 1, 0, newLine);\n }\n\n // Only adjust ybase and ydisp when the buffer is not trimmed\n if (!willBufferBeTrimmed) {\n this.buffer.ybase++;\n // Only scroll the ydisp with ybase if the user has not scrolled up\n if (!this.userScrolling) {\n this.buffer.ydisp++;\n }\n } else {\n // When the buffer is full and the user has scrolled up, keep the text\n // stable unless ydisp is right at the top\n if (this.userScrolling) {\n this.buffer.ydisp = Math.max(this.buffer.ydisp - 1, 0);\n }\n }\n } else {\n // scrollTop is non-zero which means no line will be going to the\n // scrollback, instead we can just shift them in-place.\n const scrollRegionHeight = bottomRow - topRow + 1/*as it's zero-based*/;\n this.buffer.lines.shiftElements(topRow + 1, scrollRegionHeight - 1, -1);\n this.buffer.lines.set(bottomRow, newLine);\n }\n\n // Move the viewport to the bottom of the buffer unless the user is\n // scrolling.\n if (!this.userScrolling) {\n this.buffer.ydisp = this.buffer.ybase;\n }\n\n // Flag rows that need updating\n this.updateRange(this.buffer.scrollTop);\n this.updateRange(this.buffer.scrollBottom);\n\n /**\n * This event is emitted whenever the terminal is scrolled.\n * The one parameter passed is the new y display position.\n *\n * @event scroll\n */\n this.emit('scroll', this.buffer.ydisp);\n }\n\n /**\n * Scroll the display of the terminal\n * @param {number} disp The number of lines to scroll down (negative scroll up).\n * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollLines. This is used\n * to avoid unwanted events being handled by the viewport when the event was triggered from the\n * viewport originally.\n */\n public scrollLines(disp: number, suppressScrollEvent?: boolean): void {\n if (disp < 0) {\n if (this.buffer.ydisp === 0) {\n return;\n }\n this.userScrolling = true;\n } else if (disp + this.buffer.ydisp >= this.buffer.ybase) {\n this.userScrolling = false;\n }\n\n const oldYdisp = this.buffer.ydisp;\n this.buffer.ydisp = Math.max(Math.min(this.buffer.ydisp + disp, this.buffer.ybase), 0);\n\n // No change occurred, don't trigger scroll/refresh\n if (oldYdisp === this.buffer.ydisp) {\n return;\n }\n\n if (!suppressScrollEvent) {\n this.emit('scroll', this.buffer.ydisp);\n }\n\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Scroll the display of the terminal by a number of pages.\n * @param {number} pageCount The number of pages to scroll (negative scrolls up).\n */\n public scrollPages(pageCount: number): void {\n this.scrollLines(pageCount * (this.rows - 1));\n }\n\n /**\n * Scrolls the display of the terminal to the top.\n */\n public scrollToTop(): void {\n this.scrollLines(-this.buffer.ydisp);\n }\n\n /**\n * Scrolls the display of the terminal to the bottom.\n */\n public scrollToBottom(): void {\n this.scrollLines(this.buffer.ybase - this.buffer.ydisp);\n }\n\n /**\n * Writes text to the terminal.\n * @param {string} data The text to write to the terminal.\n */\n public write(data: string): void {\n this.writeBuffer.push(data);\n\n // Send XOFF to pause the pty process if the write buffer becomes too large so\n // xterm.js can catch up before more data is sent. This is necessary in order\n // to keep signals such as ^C responsive.\n if (this.options.useFlowControl && !this.xoffSentToCatchUp && this.writeBuffer.length >= WRITE_BUFFER_PAUSE_THRESHOLD) {\n // XOFF - stop pty pipe\n // XON will be triggered by emulator before processing data chunk\n this.send(C0.DC3);\n this.xoffSentToCatchUp = true;\n }\n\n if (!this.writeInProgress && this.writeBuffer.length > 0) {\n // Kick off a write which will write all data in sequence recursively\n this.writeInProgress = true;\n // Kick off an async innerWrite so more writes can come in while processing data\n setTimeout(() => {\n this.innerWrite();\n });\n }\n }\n\n private innerWrite(): void {\n const writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);\n while (writeBatch.length > 0) {\n const data = writeBatch.shift();\n\n // If XOFF was sent in order to catch up with the pty process, resume it if\n // the writeBuffer is empty to allow more data to come in.\n if (this.xoffSentToCatchUp && writeBatch.length === 0 && this.writeBuffer.length === 0) {\n this.send(C0.DC1);\n this.xoffSentToCatchUp = false;\n }\n\n this.refreshStart = this.buffer.y;\n this.refreshEnd = this.buffer.y;\n\n // HACK: Set the parser state based on it's state at the time of return.\n // This works around the bug #662 which saw the parser state reset in the\n // middle of parsing escape sequence in two chunks. For some reason the\n // state of the parser resets to 0 after exiting parser.parse. This change\n // just sets the state back based on the correct return statement.\n const state = this.parser.parse(data);\n this.parser.setState(state);\n\n this.updateRange(this.buffer.y);\n this.refresh(this.refreshStart, this.refreshEnd);\n }\n if (this.writeBuffer.length > 0) {\n // Allow renderer to catch up before processing the next batch\n setTimeout(() => this.innerWrite(), 0);\n } else {\n this.writeInProgress = false;\n }\n }\n\n /**\n * Writes text to the terminal, followed by a break line character (\\n).\n * @param {string} data The text to write to the terminal.\n */\n public writeln(data: string): void {\n this.write(data + '\\r\\n');\n }\n\n /**\n * Attaches a custom key event handler which is run before keys are processed,\n * giving consumers of xterm.js ultimate control as to what keys should be\n * processed by the terminal and what keys should not.\n * @param customKeyEventHandler The custom KeyboardEvent handler to attach.\n * This is a function that takes a KeyboardEvent, allowing consumers to stop\n * propogation and/or prevent the default action. The function returns whether\n * the event should be processed by xterm.js.\n */\n public attachCustomKeyEventHandler(customKeyEventHandler: CustomKeyEventHandler): void {\n this.customKeyEventHandler = customKeyEventHandler;\n }\n\n /**\n * Attaches a http(s) link handler, forcing web links to behave differently to\n * regular <a> tags. This will trigger a refresh as links potentially need to be\n * reconstructed. Calling this with null will remove the handler.\n * @param handler The handler callback function.\n */\n public setHypertextLinkHandler(handler: LinkMatcherHandler): void {\n if (!this.linkifier) {\n throw new Error('Cannot attach a hypertext link handler before Terminal.open is called');\n }\n this.linkifier.setHypertextLinkHandler(handler);\n // Refresh to force links to refresh\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Attaches a validation callback for hypertext links. This is useful to use\n * validation logic or to do something with the link's element and url.\n * @param callback The callback to use, this can\n * be cleared with null.\n */\n public setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void {\n if (!this.linkifier) {\n throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called');\n }\n this.linkifier.setHypertextValidationCallback(callback);\n // // Refresh to force links to refresh\n this.refresh(0, this.rows - 1);\n }\n\n /**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param regex The regular expression to search for, specifically\n * this searches the textContent of the rows. You will want to use \\s to match\n * a space ' ' character for example.\n * @param handler The callback when the link is called.\n * @param options Options for the link matcher.\n * @return The ID of the new matcher, this can be used to deregister.\n */\n public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number {\n if (this.linkifier) {\n const matcherId = this.linkifier.registerLinkMatcher(regex, handler, options);\n this.refresh(0, this.rows - 1);\n return matcherId;\n }\n return 0;\n }\n\n /**\n * Deregisters a link matcher if it has been registered.\n * @param matcherId The link matcher's ID (returned after register)\n */\n public deregisterLinkMatcher(matcherId: number): void {\n if (this.linkifier) {\n if (this.linkifier.deregisterLinkMatcher(matcherId)) {\n this.refresh(0, this.rows - 1);\n }\n }\n }\n\n /**\n * Gets whether the terminal has an active selection.\n */\n public hasSelection(): boolean {\n return this.selectionManager ? this.selectionManager.hasSelection : false;\n }\n\n /**\n * Gets the terminal's current selection, this is useful for implementing copy\n * behavior outside of xterm.js.\n */\n public getSelection(): string {\n return this.selectionManager ? this.selectionManager.selectionText : '';\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n if (this.selectionManager) {\n this.selectionManager.clearSelection();\n }\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n if (this.selectionManager) {\n this.selectionManager.selectAll();\n }\n }\n\n /**\n * Handle a keydown event\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keydown event to be handled.\n */\n protected _keyDown(ev: KeyboardEvent): boolean {\n if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) {\n return false;\n }\n\n if (!this.compositionHelper.keydown(ev)) {\n if (this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom();\n }\n return false;\n }\n\n const result = this._evaluateKeyEscapeSequence(ev);\n\n if (result.key === C0.DC3) { // XOFF\n this.writeStopped = true;\n } else if (result.key === C0.DC1) { // XON\n this.writeStopped = false;\n }\n\n if (result.scrollLines) {\n this.scrollLines(result.scrollLines);\n return this.cancel(ev, true);\n }\n\n if (isThirdLevelShift(this.browser, ev)) {\n return true;\n }\n\n if (result.cancel) {\n // The event is canceled at the end already, is this necessary?\n this.cancel(ev, true);\n }\n\n if (!result.key) {\n return true;\n }\n\n this.emit('keydown', ev);\n this.emit('key', result.key, ev);\n this.showCursor();\n this.handler(result.key);\n\n return this.cancel(ev, true);\n }\n\n /**\n * Returns an object that determines how a KeyboardEvent should be handled. The key of the\n * returned value is the new key code to pass to the PTY.\n *\n * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n * @param ev The keyboard event to be translated to key escape sequence.\n */\n protected _evaluateKeyEscapeSequence(ev: KeyboardEvent): {cancel: boolean, key: string, scrollLines: number} {\n const result: {cancel: boolean, key: string, scrollLines: number} = {\n // Whether to cancel event propogation (NOTE: this may not be needed since the event is\n // canceled at the end of keyDown\n cancel: false,\n // The new key even to emit\n key: undefined,\n // The number of characters to scroll, if this is defined it will cancel the event\n scrollLines: undefined\n };\n const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0);\n switch (ev.keyCode) {\n case 0:\n if (ev.key === 'UIKeyInputUpArrow') {\n if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n }\n else if (ev.key === 'UIKeyInputLeftArrow') {\n if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n }\n else if (ev.key === 'UIKeyInputRightArrow') {\n if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n }\n else if (ev.key === 'UIKeyInputDownArrow') {\n if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n }\n break;\n case 8:\n // backspace\n if (ev.shiftKey) {\n result.key = C0.BS; // ^H\n break;\n }\n result.key = C0.DEL; // ^?\n break;\n case 9:\n // tab\n if (ev.shiftKey) {\n result.key = C0.ESC + '[Z';\n break;\n }\n result.key = C0.HT;\n result.cancel = true;\n break;\n case 13:\n // return/enter\n result.key = C0.CR;\n result.cancel = true;\n break;\n case 27:\n // escape\n result.key = C0.ESC;\n result.cancel = true;\n break;\n case 37:\n // left-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'D';\n // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key === C0.ESC + '[1;3D') {\n result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OD';\n } else {\n result.key = C0.ESC + '[D';\n }\n break;\n case 39:\n // right-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'C';\n // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward\n // http://unix.stackexchange.com/a/108106\n // macOS uses different escape sequences than linux\n if (result.key === C0.ESC + '[1;3C') {\n result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OC';\n } else {\n result.key = C0.ESC + '[C';\n }\n break;\n case 38:\n // up-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'A';\n // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key === C0.ESC + '[1;3A') {\n result.key = C0.ESC + '[1;5A';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OA';\n } else {\n result.key = C0.ESC + '[A';\n }\n break;\n case 40:\n // down-arrow\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'B';\n // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow\n // http://unix.stackexchange.com/a/108106\n if (result.key === C0.ESC + '[1;3B') {\n result.key = C0.ESC + '[1;5B';\n }\n } else if (this.applicationCursor) {\n result.key = C0.ESC + 'OB';\n } else {\n result.key = C0.ESC + '[B';\n }\n break;\n case 45:\n // insert\n if (!ev.shiftKey && !ev.ctrlKey) {\n // <Ctrl> or <Shift> + <Insert> are used to\n // copy-paste on some systems.\n result.key = C0.ESC + '[2~';\n }\n break;\n case 46:\n // delete\n if (modifiers) {\n result.key = C0.ESC + '[3;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[3~';\n }\n break;\n case 36:\n // home\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OH';\n else\n result.key = C0.ESC + '[H';\n break;\n case 35:\n // end\n if (modifiers)\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F';\n else if (this.applicationCursor)\n result.key = C0.ESC + 'OF';\n else\n result.key = C0.ESC + '[F';\n break;\n case 33:\n // page up\n if (ev.shiftKey) {\n result.scrollLines = -(this.rows - 1);\n } else {\n result.key = C0.ESC + '[5~';\n }\n break;\n case 34:\n // page down\n if (ev.shiftKey) {\n result.scrollLines = this.rows - 1;\n } else {\n result.key = C0.ESC + '[6~';\n }\n break;\n case 112:\n // F1-F12\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'P';\n } else {\n result.key = C0.ESC + 'OP';\n }\n break;\n case 113:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'Q';\n } else {\n result.key = C0.ESC + 'OQ';\n }\n break;\n case 114:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'R';\n } else {\n result.key = C0.ESC + 'OR';\n }\n break;\n case 115:\n if (modifiers) {\n result.key = C0.ESC + '[1;' + (modifiers + 1) + 'S';\n } else {\n result.key = C0.ESC + 'OS';\n }\n break;\n case 116:\n if (modifiers) {\n result.key = C0.ESC + '[15;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[15~';\n }\n break;\n case 117:\n if (modifiers) {\n result.key = C0.ESC + '[17;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[17~';\n }\n break;\n case 118:\n if (modifiers) {\n result.key = C0.ESC + '[18;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[18~';\n }\n break;\n case 119:\n if (modifiers) {\n result.key = C0.ESC + '[19;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[19~';\n }\n break;\n case 120:\n if (modifiers) {\n result.key = C0.ESC + '[20;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[20~';\n }\n break;\n case 121:\n if (modifiers) {\n result.key = C0.ESC + '[21;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[21~';\n }\n break;\n case 122:\n if (modifiers) {\n result.key = C0.ESC + '[23;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[23~';\n }\n break;\n case 123:\n if (modifiers) {\n result.key = C0.ESC + '[24;' + (modifiers + 1) + '~';\n } else {\n result.key = C0.ESC + '[24~';\n }\n break;\n default:\n // a-z and space\n if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) {\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = String.fromCharCode(ev.keyCode - 64);\n } else if (ev.keyCode === 32) {\n // NUL\n result.key = String.fromCharCode(0);\n } else if (ev.keyCode >= 51 && ev.keyCode <= 55) {\n // escape, file sep, group sep, record sep, unit sep\n result.key = String.fromCharCode(ev.keyCode - 51 + 27);\n } else if (ev.keyCode === 56) {\n // delete\n result.key = String.fromCharCode(127);\n } else if (ev.keyCode === 219) {\n // ^[ - Control Sequence Introducer (CSI)\n result.key = String.fromCharCode(27);\n } else if (ev.keyCode === 220) {\n // ^\\ - String Terminator (ST)\n result.key = String.fromCharCode(28);\n } else if (ev.keyCode === 221) {\n // ^] - Operating System Command (OSC)\n result.key = String.fromCharCode(29);\n }\n } else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) {\n // On Mac this is a third level shift. Use <Esc> instead.\n if (ev.keyCode >= 65 && ev.keyCode <= 90) {\n result.key = C0.ESC + String.fromCharCode(ev.keyCode + 32);\n } else if (ev.keyCode === 192) {\n result.key = C0.ESC + '`';\n } else if (ev.keyCode >= 48 && ev.keyCode <= 57) {\n result.key = C0.ESC + (ev.keyCode - 48);\n }\n } else if (this.browser.isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) {\n if (ev.keyCode === 65) { // cmd + a\n this.selectAll();\n }\n }\n break;\n }\n\n return result;\n }\n\n /**\n * Set the G level of the terminal\n * @param g\n */\n public setgLevel(g: number): void {\n this.glevel = g;\n this.charset = this.charsets[g];\n }\n\n /**\n * Set the charset for the given G level of the terminal\n * @param g\n * @param charset\n */\n public setgCharset(g: number, charset: Charset): void {\n this.charsets[g] = charset;\n if (this.glevel === g) {\n this.charset = charset;\n }\n }\n\n /**\n * Handle a keypress event.\n * Key Resources:\n * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent\n * @param {KeyboardEvent} ev The keypress event to be handled.\n */\n protected _keyPress(ev: KeyboardEvent): boolean {\n let key;\n\n if (this.customKeyEventHandler && this.customKeyEventHandler(ev) === false) {\n return false;\n }\n\n this.cancel(ev);\n\n if (ev.charCode) {\n key = ev.charCode;\n } else if (ev.which == null) {\n key = ev.keyCode;\n } else if (ev.which !== 0 && ev.charCode !== 0) {\n key = ev.which;\n } else {\n return false;\n }\n\n if (!key || (\n (ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this.browser, ev)\n )) {\n return false;\n }\n\n key = String.fromCharCode(key);\n\n this.emit('keypress', key, ev);\n this.emit('key', key, ev);\n this.showCursor();\n this.handler(key);\n\n return true;\n }\n\n /**\n * Send data for handling to the terminal\n * @param {string} data\n */\n public send(data: string): void {\n if (!this.sendDataQueue) {\n setTimeout(() => {\n this.handler(this.sendDataQueue);\n this.sendDataQueue = '';\n }, 1);\n }\n\n this.sendDataQueue += data;\n }\n\n /**\n * Ring the bell.\n * Note: We could do sweet things with webaudio here\n */\n public bell(): void {\n this.emit('bell');\n if (this.soundBell()) this.bellAudioElement.play();\n\n if (this.visualBell()) {\n this.element.classList.add('visual-bell-active');\n clearTimeout(this.visualBellTimer);\n this.visualBellTimer = window.setTimeout(() => {\n this.element.classList.remove('visual-bell-active');\n }, 200);\n }\n }\n\n /**\n * Log the current state to the console.\n */\n public log(text: string, data?: any): void {\n if (!this.options.debug) return;\n if (!this.context.console || !this.context.console.log) return;\n this.context.console.log(text, data);\n }\n\n /**\n * Log the current state as error to the console.\n */\n public error(text: string, data?: any): void {\n if (!this.options.debug) return;\n if (!this.context.console || !this.context.console.error) return;\n this.context.console.error(text, data);\n }\n\n /**\n * Resizes the terminal.\n *\n * @param {number} x The number of columns to resize to.\n * @param {number} y The number of rows to resize to.\n */\n public resize(x: number, y: number): void {\n if (isNaN(x) || isNaN(y)) {\n return;\n }\n\n if (x === this.cols && y === this.rows) {\n // Check if we still need to measure the char size (fixes #785).\n if (!this.charMeasure.width || !this.charMeasure.height) {\n this.charMeasure.measure(this.options);\n }\n return;\n }\n\n if (x < 1) x = 1;\n if (y < 1) y = 1;\n\n this.buffers.resize(x, y);\n\n this.cols = x;\n this.rows = y;\n this.buffers.setupTabStops(this.cols);\n\n this.charMeasure.measure(this.options);\n\n this.refresh(0, this.rows - 1);\n this.emit('resize', {cols: x, rows: y});\n }\n\n /**\n * Updates the range of rows to refresh\n * @param {number} y The number of rows to refresh next.\n */\n public updateRange(y: number): void {\n if (y < this.refreshStart) this.refreshStart = y;\n if (y > this.refreshEnd) this.refreshEnd = y;\n // if (y > this.refreshEnd) {\n // this.refreshEnd = y;\n // if (y > this.rows - 1) {\n // this.refreshEnd = this.rows - 1;\n // }\n // }\n }\n\n /**\n * Set the range of refreshing to the maximum value\n */\n public maxRange(): void {\n this.refreshStart = 0;\n this.refreshEnd = this.rows - 1;\n }\n\n /**\n * Erase in the identified line everything from \"x\" to the end of the line (right).\n * @param {number} x The column from which to start erasing to the end of the line.\n * @param {number} y The line in which to operate.\n */\n public eraseRight(x: number, y: number): void {\n const line = this.buffer.lines.get(this.buffer.ybase + y);\n if (!line) {\n return;\n }\n const ch: CharData = [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; // xterm\n for (; x < this.cols; x++) {\n line[x] = ch;\n }\n this.updateRange(y);\n }\n\n /**\n * Erase in the identified line everything from \"x\" to the start of the line (left).\n * @param {number} x The column from which to start erasing to the start of the line.\n * @param {number} y The line in which to operate.\n */\n public eraseLeft(x: number, y: number): void {\n const line = this.buffer.lines.get(this.buffer.ybase + y);\n if (!line) {\n return;\n }\n const ch: CharData = [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */]; // xterm\n x++;\n while (x--) {\n line[x] = ch;\n }\n this.updateRange(y);\n }\n\n /**\n * Clear the entire buffer, making the prompt line the new first line.\n */\n public clear(): void {\n if (this.buffer.ybase === 0 && this.buffer.y === 0) {\n // Don't clear if it's already clear\n return;\n }\n this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y));\n this.buffer.lines.length = 1;\n this.buffer.ydisp = 0;\n this.buffer.ybase = 0;\n this.buffer.y = 0;\n for (let i = 1; i < this.rows; i++) {\n this.buffer.lines.push(this.blankLine());\n }\n this.refresh(0, this.rows - 1);\n this.emit('scroll', this.buffer.ydisp);\n }\n\n /**\n * Erase all content in the given line\n * @param {number} y The line to erase all of its contents.\n */\n public eraseLine(y: number): void {\n this.eraseRight(0, y);\n }\n\n /**\n * Return the data array of a blank line\n * @param {boolean} cur First bunch of data for each \"blank\" character.\n * @param {boolean} isWrapped Whether the new line is wrapped from the previous line.\n * @param {boolean} cols The number of columns in the terminal, if this is not\n * set, the terminal's current column count would be used.\n */\n public blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData {\n const attr = cur ? this.eraseAttr() : this.defAttr;\n\n const ch: CharData = [attr, ' ', 1, 32 /* ' '.charCodeAt(0) */]; // width defaults to 1 halfwidth character\n const line: LineData = [];\n\n // TODO: It is not ideal that this is a property on an array, a buffer line\n // class should be added that will hold this data and other useful functions.\n if (isWrapped) {\n (<any>line).isWrapped = isWrapped;\n }\n\n cols = cols || this.cols;\n for (let i = 0; i < cols; i++) {\n line[i] = ch;\n }\n\n return line;\n }\n\n /**\n * If cur return the back color xterm feature attribute. Else return defAttr.\n * @param cur\n */\n public ch(cur?: boolean): CharData {\n if (cur) {\n return [this.eraseAttr(), ' ', 1, 32 /* ' '.charCodeAt(0) */];\n }\n return [this.defAttr, ' ', 1, 32 /* ' '.charCodeAt(0) */];\n }\n\n /**\n * Evaluate if the current terminal is the given argument.\n * @param term The terminal name to evaluate\n */\n public is(term: string): boolean {\n return (this.options.termName + '').indexOf(term) === 0;\n }\n\n /**\n * Emit the 'data' event and populate the given data.\n * @param {string} data The data to populate in the event.\n */\n public handler(data: string): void {\n // Prevents all events to pty process if stdin is disabled\n if (this.options.disableStdin) {\n return;\n }\n\n // Clear the selection if the selection manager is available and has an active selection\n if (this.selectionManager && this.selectionManager.hasSelection) {\n this.selectionManager.clearSelection();\n }\n\n // Input is being sent to the terminal, the terminal should focus the prompt.\n if (this.buffer.ybase !== this.buffer.ydisp) {\n this.scrollToBottom();\n }\n this.emit('data', data);\n }\n\n /**\n * Emit the 'title' event and populate the given title.\n * @param {string} title The title to populate in the event.\n */\n private handleTitle(title: string): void {\n /**\n * This event is emitted when the title of the terminal is changed\n * from inside the terminal. The parameter is the new title.\n *\n * @event title\n */\n this.emit('title', title);\n }\n\n /**\n * ESC\n */\n\n /**\n * ESC D Index (IND is 0x84).\n */\n public index(): void {\n this.buffer.y++;\n if (this.buffer.y > this.buffer.scrollBottom) {\n this.buffer.y--;\n this.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this.buffer.x >= this.cols) {\n this.buffer.x--;\n }\n }\n\n /**\n * ESC M Reverse Index (RI is 0x8d).\n *\n * Move the cursor up one row, inserting a new blank line if necessary.\n */\n public reverseIndex(): void {\n if (this.buffer.y === this.buffer.scrollTop) {\n // possibly move the code below to term.reverseScroll();\n // test: echo -ne '\\e[1;1H\\e[44m\\eM\\e[0m'\n // blankLine(true) is xterm/linux behavior\n const scrollRegionHeight = this.buffer.scrollBottom - this.buffer.scrollTop;\n this.buffer.lines.shiftElements(this.buffer.y + this.buffer.ybase, scrollRegionHeight, 1);\n this.buffer.lines.set(this.buffer.y + this.buffer.ybase, this.blankLine(true));\n this.updateRange(this.buffer.scrollTop);\n this.updateRange(this.buffer.scrollBottom);\n } else {\n this.buffer.y--;\n }\n }\n\n /**\n * ESC c Full Reset (RIS).\n */\n public reset(): void {\n this.options.rows = this.rows;\n this.options.cols = this.cols;\n const customKeyEventHandler = this.customKeyEventHandler;\n const inputHandler = this.inputHandler;\n const buffers = this.buffers;\n this.setup();\n this.customKeyEventHandler = customKeyEventHandler;\n this.inputHandler = inputHandler;\n this.buffers = buffers;\n this.refresh(0, this.rows - 1);\n this.viewport.syncScrollArea();\n }\n\n\n /**\n * ESC H Tab Set (HTS is 0x88).\n */\n private tabSet(): void {\n this.buffer.tabs[this.buffer.x] = true;\n }\n\n // TODO: Remove cancel function and cancelEvents option\n public cancel(ev: Event, force?: boolean): boolean {\n if (!this.options.cancelEvents && !force) {\n return;\n }\n ev.preventDefault();\n ev.stopPropagation();\n return false;\n }\n\n // TODO: Remove when true color is implemented\n public matchColor(r1: number, g1: number, b1: number): number {\n return matchColor_(r1, g1, b1);\n }\n\n private visualBell(): boolean {\n return this.options.bellStyle === 'visual' ||\n this.options.bellStyle === 'both';\n }\n\n private soundBell(): boolean {\n return this.options.bellStyle === 'sound' ||\n this.options.bellStyle === 'both';\n }\n\n private syncBellSound(): void {\n // Don't update anything if the terminal has not been opened yet\n if (!this.element) {\n return;\n }\n\n if (this.soundBell() && this.bellAudioElement) {\n this.bellAudioElement.setAttribute('src', this.options.bellSound);\n } else if (this.soundBell()) {\n this.bellAudioElement = document.createElement('audio');\n this.bellAudioElement.setAttribute('preload', 'auto');\n this.bellAudioElement.setAttribute('src', this.options.bellSound);\n this.helperContainer.appendChild(this.bellAudioElement);\n } else if (this.bellAudioElement) {\n this.helperContainer.removeChild(this.bellAudioElement);\n }\n }\n}\n\n/**\n * Helpers\n */\n\nfunction globalOn(el: any, type: string, handler: (event: Event) => any, capture?: boolean): void {\n if (!Array.isArray(el)) {\n el = [el];\n }\n el.forEach((element: HTMLElement) => {\n element.addEventListener(type, handler, capture || false);\n });\n}\n// TODO: Remove once everything is typed\nconst on = globalOn;\n\nfunction off(el: any, type: string, handler: (event: Event) => any, capture: boolean = false): void {\n el.removeEventListener(type, handler, capture);\n}\n\nfunction isThirdLevelShift(browser: IBrowser, ev: KeyboardEvent): boolean {\n const thirdLevelKey =\n (browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) ||\n (browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey);\n\n if (ev.type === 'keypress') {\n return thirdLevelKey;\n }\n\n // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events)\n return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47);\n}\n\nfunction wasMondifierKeyOnlyEvent(ev: KeyboardEvent): boolean {\n return ev.keyCode === 16 || // Shift\n ev.keyCode === 17 || // Ctrl\n ev.keyCode === 18; // Alt\n}\n\n/**\n * TODO:\n * The below color-related code can be removed when true color is implemented.\n * It's only purpose is to match true color requests with the closest matching\n * ANSI color code.\n */\n\n// Colors 0-15 + 16-255\n// Much thanks to TooTallNate for writing this.\nconst vcolors: number[][] = (function(): number[][] {\n const result = DEFAULT_ANSI_COLORS.map(c => {\n c = c.substring(1);\n return [\n parseInt(c.substring(0, 2), 16),\n parseInt(c.substring(2, 4), 16),\n parseInt(c.substring(4, 6), 16)\n ];\n });\n const r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n\n // 16-231\n for (let i = 0; i < 216; i++) {\n result.push([\n r[(i / 36) % 6 | 0],\n r[(i / 6) % 6 | 0],\n r[i % 6]\n ]);\n }\n\n // 232-255 (grey)\n let c: number;\n for (let i = 0; i < 24; i++) {\n c = 8 + i * 10;\n result.push([c, c, c]);\n }\n\n return result;\n})();\n\nconst matchColorCache: {[colorRGBHash: number]: number} = {};\n\n// http://stackoverflow.com/questions/1633828\nfunction matchColorDistance(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number): number {\n return Math.pow(30 * (r1 - r2), 2)\n + Math.pow(59 * (g1 - g2), 2)\n + Math.pow(11 * (b1 - b2), 2);\n};\n\n\nfunction matchColor_(r1: number, g1: number, b1: number): number {\n const hash = (r1 << 16) | (g1 << 8) | b1;\n\n if (matchColorCache[hash] != null) {\n return matchColorCache[hash];\n }\n\n let ldiff = Infinity;\n let li = -1;\n let i = 0;\n let c: number[];\n let r2: number;\n let g2: number;\n let b2: number;\n let diff: number;\n\n for (; i < vcolors.length; i++) {\n c = vcolors[i];\n r2 = c[0];\n g2 = c[1];\n b2 = c[2];\n\n diff = matchColorDistance(r1, g1, b1, r2, g2, b2);\n\n if (diff === 0) {\n li = i;\n break;\n }\n\n if (diff < ldiff) {\n ldiff = diff;\n li = i;\n }\n }\n\n return matchColorCache[hash] = li;\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\n/**\n * Represents a selection within the buffer. This model only cares about column\n * and row coordinates, not wide characters.\n */\nexport class SelectionModel {\n /**\n * Whether select all is currently active.\n */\n public isSelectAllActive: boolean;\n\n /**\n * The [x, y] position the selection starts at.\n */\n public selectionStart: [number, number];\n\n /**\n * The minimal length of the selection from the start position. When double\n * clicking on a word, the word will be selected which makes the selection\n * start at the start of the word and makes this variable the length.\n */\n public selectionStartLength: number;\n\n /**\n * The [x, y] position the selection ends at.\n */\n public selectionEnd: [number, number];\n\n constructor(\n private _terminal: ITerminal\n ) {\n this.clearSelection();\n }\n\n /**\n * Clears the current selection.\n */\n public clearSelection(): void {\n this.selectionStart = null;\n this.selectionEnd = null;\n this.isSelectAllActive = false;\n this.selectionStartLength = 0;\n }\n\n /**\n * The final selection start, taking into consideration select all.\n */\n public get finalSelectionStart(): [number, number] {\n if (this.isSelectAllActive) {\n return [0, 0];\n }\n\n if (!this.selectionEnd || !this.selectionStart) {\n return this.selectionStart;\n }\n\n return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;\n }\n\n /**\n * The final selection end, taking into consideration select all, double click\n * word selection and triple click line selection.\n */\n public get finalSelectionEnd(): [number, number] {\n if (this.isSelectAllActive) {\n return [this._terminal.cols, this._terminal.buffer.ybase + this._terminal.rows - 1];\n }\n\n if (!this.selectionStart) {\n return null;\n }\n\n // Use the selection start if the end doesn't exist or they're reversed\n if (!this.selectionEnd || this.areSelectionValuesReversed()) {\n return [this.selectionStart[0] + this.selectionStartLength, this.selectionStart[1]];\n }\n\n // Ensure the the word/line is selected after a double/triple click\n if (this.selectionStartLength) {\n // Select the larger of the two when start and end are on the same line\n if (this.selectionEnd[1] === this.selectionStart[1]) {\n return [Math.max(this.selectionStart[0] + this.selectionStartLength, this.selectionEnd[0]), this.selectionEnd[1]];\n }\n }\n return this.selectionEnd;\n }\n\n /**\n * Returns whether the selection start and end are reversed.\n */\n public areSelectionValuesReversed(): boolean {\n const start = this.selectionStart;\n const end = this.selectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n * @return Whether a refresh is necessary.\n */\n public onTrim(amount: number): boolean {\n // Adjust the selection position based on the trimmed amount.\n if (this.selectionStart) {\n this.selectionStart[1] -= amount;\n }\n if (this.selectionEnd) {\n this.selectionEnd[1] -= amount;\n }\n\n // The selection has moved off the buffer, clear it.\n if (this.selectionEnd && this.selectionEnd[1] < 0) {\n this.clearSelection();\n return true;\n }\n\n // If the selection start is trimmed, ensure the start column is 0.\n if (this.selectionStart && this.selectionStart[1] < 0) {\n this.selectionStart[1] = 0;\n }\n return false;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { MouseHelper } from './utils/MouseHelper';\nimport * as Browser from './utils/Browser';\nimport { CharMeasure } from './utils/CharMeasure';\nimport { CircularList } from './utils/CircularList';\nimport { EventEmitter } from './EventEmitter';\nimport { ITerminal, ICircularList, ISelectionManager, IBuffer } from './Interfaces';\nimport { SelectionModel } from './SelectionModel';\nimport { LineData, CharData } from './Types';\nimport { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer';\n\n/**\n * The number of pixels the mouse needs to be above or below the viewport in\n * order to scroll at the maximum speed.\n */\nconst DRAG_SCROLL_MAX_THRESHOLD = 50;\n\n/**\n * The maximum scrolling speed\n */\nconst DRAG_SCROLL_MAX_SPEED = 15;\n\n/**\n * The number of milliseconds between drag scroll updates.\n */\nconst DRAG_SCROLL_INTERVAL = 50;\n\n/**\n * A string containing all characters that are considered word separated by the\n * double click to select work logic.\n */\nconst WORD_SEPARATORS = ' ()[]{}\\'\"';\n\nconst NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);\nconst ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');\n\n/**\n * Represents a position of a word on a line.\n */\ninterface IWordPosition {\n start: number;\n length: number;\n}\n\n/**\n * A selection mode, this drives how the selection behaves on mouse move.\n */\nenum SelectionMode {\n NORMAL,\n WORD,\n LINE\n}\n\n/**\n * A class that manages the selection of the terminal. With help from\n * SelectionModel, SelectionManager handles with all logic associated with\n * dealing with the selection, including handling mouse interaction, wide\n * characters and fetching the actual text within the selection. Rendering is\n * not handled by the SelectionManager but a 'refresh' event is fired when the\n * selection is ready to be redrawn.\n */\nexport class SelectionManager extends EventEmitter implements ISelectionManager {\n protected _model: SelectionModel;\n\n /**\n * The amount to scroll every drag scroll update (depends on how far the mouse\n * drag is above or below the terminal).\n */\n private _dragScrollAmount: number;\n\n /**\n * The current selection mode.\n */\n private _activeSelectionMode: SelectionMode;\n\n /**\n * A setInterval timer that is active while the mouse is down whose callback\n * scrolls the viewport when necessary.\n */\n private _dragScrollIntervalTimer: NodeJS.Timer;\n\n /**\n * The animation frame ID used for refreshing the selection.\n */\n private _refreshAnimationFrame: number;\n\n /**\n * Whether selection is enabled.\n */\n private _enabled = true;\n\n private _mouseMoveListener: EventListener;\n private _mouseUpListener: EventListener;\n\n constructor(\n private _terminal: ITerminal,\n private _buffer: IBuffer,\n private _charMeasure: CharMeasure\n ) {\n super();\n this._initListeners();\n this.enable();\n\n this._model = new SelectionModel(_terminal);\n this._activeSelectionMode = SelectionMode.NORMAL;\n }\n\n /**\n * Initializes listener variables.\n */\n private _initListeners(): void {\n this._mouseMoveListener = event => this._onMouseMove(<MouseEvent>event);\n this._mouseUpListener = event => this._onMouseUp(<MouseEvent>event);\n\n // Only adjust the selection on trim, shiftElements is rarely used (only in\n // reverseIndex) and delete in a splice is only ever used when the same\n // number of elements was just added. Given this is could actually be\n // beneficial to leave the selection as is for these cases.\n this._buffer.lines.on('trim', (amount: number) => this._onTrim(amount));\n }\n\n /**\n * Disables the selection manager. This is useful for when terminal mouse\n * are enabled.\n */\n public disable(): void {\n this.clearSelection();\n this._enabled = false;\n }\n\n /**\n * Enable the selection manager.\n */\n public enable(): void {\n this._enabled = true;\n }\n\n /**\n * Sets the active buffer, this should be called when the alt buffer is\n * switched in or out.\n * @param buffer The active buffer.\n */\n public setBuffer(buffer: IBuffer): void {\n this._buffer = buffer;\n this.clearSelection();\n }\n\n public get selectionStart(): [number, number] { return this._model.finalSelectionStart; }\n public get selectionEnd(): [number, number] { return this._model.finalSelectionEnd; }\n\n /**\n * Gets whether there is an active text selection.\n */\n public get hasSelection(): boolean {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return false;\n }\n return start[0] !== end[0] || start[1] !== end[1];\n }\n\n /**\n * Gets the text currently selected.\n */\n public get selectionText(): string {\n const start = this._model.finalSelectionStart;\n const end = this._model.finalSelectionEnd;\n if (!start || !end) {\n return '';\n }\n\n // Get first row\n const startRowEndCol = start[1] === end[1] ? end[0] : null;\n let result: string[] = [];\n result.push(this._buffer.translateBufferLineToString(start[1], true, start[0], startRowEndCol));\n\n // Get middle rows\n for (let i = start[1] + 1; i <= end[1] - 1; i++) {\n const bufferLine = this._buffer.lines.get(i);\n const lineText = this._buffer.translateBufferLineToString(i, true);\n if ((<any>bufferLine).isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Get final row\n if (start[1] !== end[1]) {\n const bufferLine = this._buffer.lines.get(end[1]);\n const lineText = this._buffer.translateBufferLineToString(end[1], true, 0, end[0]);\n if ((<any>bufferLine).isWrapped) {\n result[result.length - 1] += lineText;\n } else {\n result.push(lineText);\n }\n }\n\n // Format string by replacing non-breaking space chars with regular spaces\n // and joining the array into a multi-line string.\n const formattedResult = result.map(line => {\n return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');\n }).join(Browser.isMSWindows ? '\\r\\n' : '\\n');\n\n return formattedResult;\n }\n\n /**\n * Clears the current terminal selection.\n */\n public clearSelection(): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this.refresh();\n }\n\n /**\n * Queues a refresh, redrawing the selection on the next opportunity.\n * @param isNewSelection Whether the selection should be registered as a new\n * selection on Linux.\n */\n public refresh(isNewSelection?: boolean): void {\n // Queue the refresh for the renderer\n if (!this._refreshAnimationFrame) {\n this._refreshAnimationFrame = window.requestAnimationFrame(() => this._refresh());\n }\n\n // If the platform is Linux and the refresh call comes from a mouse event,\n // we need to update the selection for middle click to paste selection.\n if (Browser.isLinux && isNewSelection) {\n const selectionText = this.selectionText;\n if (selectionText.length) {\n this.emit('newselection', this.selectionText);\n }\n }\n }\n\n /**\n * Fires the refresh event, causing consumers to pick it up and redraw the\n * selection state.\n */\n private _refresh(): void {\n this._refreshAnimationFrame = null;\n this.emit('refresh', { start: this._model.finalSelectionStart, end: this._model.finalSelectionEnd });\n }\n\n /**\n * Selects all text within the terminal.\n */\n public selectAll(): void {\n this._model.isSelectAllActive = true;\n this.refresh();\n this._terminal.emit('selection');\n }\n\n /**\n * Handle the buffer being trimmed, adjust the selection position.\n * @param amount The amount the buffer is being trimmed.\n */\n private _onTrim(amount: number): void {\n const needsRefresh = this._model.onTrim(amount);\n if (needsRefresh) {\n this.refresh();\n }\n }\n\n /**\n * Gets the 0-based [x, y] buffer coordinates of the current mouse event.\n * @param event The mouse event.\n */\n private _getMouseBufferCoords(event: MouseEvent): [number, number] {\n const coords = this._terminal.mouseHelper.getCoords(event, this._terminal.element, this._charMeasure, this._terminal.options.lineHeight, this._terminal.cols, this._terminal.rows, true);\n if (!coords) {\n return null;\n }\n\n // Convert to 0-based\n coords[0]--;\n coords[1]--;\n\n // Convert viewport coords to buffer coords\n coords[1] += this._terminal.buffer.ydisp;\n return coords;\n }\n\n /**\n * Gets the amount the viewport should be scrolled based on how far out of the\n * terminal the mouse is.\n * @param event The mouse event.\n */\n private _getMouseEventScrollAmount(event: MouseEvent): number {\n let offset = MouseHelper.getCoordsRelativeToElement(event, this._terminal.element)[1];\n const terminalHeight = this._terminal.rows * Math.ceil(this._charMeasure.height * this._terminal.options.lineHeight);\n if (offset >= 0 && offset <= terminalHeight) {\n return 0;\n }\n if (offset > terminalHeight) {\n offset -= terminalHeight;\n }\n\n offset = Math.min(Math.max(offset, -DRAG_SCROLL_MAX_THRESHOLD), DRAG_SCROLL_MAX_THRESHOLD);\n offset /= DRAG_SCROLL_MAX_THRESHOLD;\n return (offset / Math.abs(offset)) + Math.round(offset * (DRAG_SCROLL_MAX_SPEED - 1));\n }\n\n /**\n * Returns whether the selection manager should force selection, regardless of\n * whether the terminal is in mouse events mode.\n * @param event The mouse event.\n */\n public shouldForceSelection(event: MouseEvent): boolean {\n return Browser.isMac ? event.altKey : event.shiftKey;\n }\n\n /**\n * Handles te mousedown event, setting up for a new selection.\n * @param event The mousedown event.\n */\n public onMouseDown(event: MouseEvent): void {\n // If we have selection, we want the context menu on right click even if the\n // terminal is in mouse mode.\n if (event.button === 2 && this.hasSelection) {\n return;\n }\n\n // Only action the primary button\n if (event.button !== 0) {\n return;\n }\n\n // Allow selection when using a specific modifier key, even when disabled\n if (!this._enabled) {\n if (!this.shouldForceSelection(event)) {\n return;\n }\n\n // Don't send the mouse down event to the current process, we want to select\n event.stopPropagation();\n }\n\n // Tell the browser not to start a regular selection\n event.preventDefault();\n\n // Reset drag scroll state\n this._dragScrollAmount = 0;\n\n if (this._enabled && event.shiftKey) {\n this._onIncrementalClick(event);\n } else {\n if (event.detail === 1) {\n this._onSingleClick(event);\n } else if (event.detail === 2) {\n this._onDoubleClick(event);\n } else if (event.detail === 3) {\n this._onTripleClick(event);\n }\n }\n\n this._addMouseDownListeners();\n this.refresh(true);\n }\n\n /**\n * Adds listeners when mousedown is triggered.\n */\n private _addMouseDownListeners(): void {\n // Listen on the document so that dragging outside of viewport works\n this._terminal.element.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);\n this._terminal.element.ownerDocument.addEventListener('mouseup', this._mouseUpListener);\n this._dragScrollIntervalTimer = setInterval(() => this._dragScroll(), DRAG_SCROLL_INTERVAL);\n }\n\n /**\n * Removes the listeners that are registered when mousedown is triggered.\n */\n private _removeMouseDownListeners(): void {\n this._terminal.element.ownerDocument.removeEventListener('mousemove', this._mouseMoveListener);\n this._terminal.element.ownerDocument.removeEventListener('mouseup', this._mouseUpListener);\n clearInterval(this._dragScrollIntervalTimer);\n this._dragScrollIntervalTimer = null;\n }\n\n /**\n * Performs an incremental click, setting the selection end position to the mouse\n * position.\n * @param event The mouse event.\n */\n private _onIncrementalClick(event: MouseEvent): void {\n if (this._model.selectionStart) {\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n }\n }\n\n /**\n * Performs a single click, resetting relevant state and setting the selection\n * start position.\n * @param event The mouse event.\n */\n private _onSingleClick(event: MouseEvent): void {\n this._model.selectionStartLength = 0;\n this._model.isSelectAllActive = false;\n this._activeSelectionMode = SelectionMode.NORMAL;\n\n // Initialize the new selection\n this._model.selectionStart = this._getMouseBufferCoords(event);\n if (!this._model.selectionStart) {\n return;\n }\n this._model.selectionEnd = null;\n\n // Ensure the line exists\n const line = this._buffer.lines.get(this._model.selectionStart[1]);\n if (!line) {\n return;\n }\n\n // Return early if the click event is not in the buffer (eg. in scroll bar)\n if (line.length >= this._model.selectionStart[0]) {\n return;\n }\n\n // If the mouse is over the second half of a wide character, adjust the\n // selection to cover the whole character\n const char = line[this._model.selectionStart[0]];\n if (char[CHAR_DATA_WIDTH_INDEX] === 0) {\n this._model.selectionStart[0]++;\n }\n }\n\n /**\n * Performs a double click, selecting the current work.\n * @param event The mouse event.\n */\n private _onDoubleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.WORD;\n this._selectWordAt(coords);\n }\n }\n\n /**\n * Performs a triple click, selecting the current line and activating line\n * select mode.\n * @param event The mouse event.\n */\n private _onTripleClick(event: MouseEvent): void {\n const coords = this._getMouseBufferCoords(event);\n if (coords) {\n this._activeSelectionMode = SelectionMode.LINE;\n this._selectLineAt(coords[1]);\n }\n }\n\n /**\n * Handles the mousemove event when the mouse button is down, recording the\n * end of the selection and refreshing the selection.\n * @param event The mousemove event.\n */\n private _onMouseMove(event: MouseEvent): void {\n // If the mousemove listener is active it means that a selection is\n // currently being made, we should stop propogation to prevent mouse events\n // to be sent to the pty.\n event.stopImmediatePropagation();\n\n // Record the previous position so we know whether to redraw the selection\n // at the end.\n const previousSelectionEnd = this._model.selectionEnd ? [this._model.selectionEnd[0], this._model.selectionEnd[1]] : null;\n\n // Set the initial selection end based on the mouse coordinates\n this._model.selectionEnd = this._getMouseBufferCoords(event);\n if (!this._model.selectionEnd) {\n this.refresh(true);\n return;\n }\n\n // Select the entire line if line select mode is active.\n if (this._activeSelectionMode === SelectionMode.LINE) {\n if (this._model.selectionEnd[1] < this._model.selectionStart[1]) {\n this._model.selectionEnd[0] = 0;\n } else {\n this._model.selectionEnd[0] = this._terminal.cols;\n }\n } else if (this._activeSelectionMode === SelectionMode.WORD) {\n this._selectToWordAt(this._model.selectionEnd);\n }\n\n // Determine the amount of scrolling that will happen.\n this._dragScrollAmount = this._getMouseEventScrollAmount(event);\n\n // If the cursor was above or below the viewport, make sure it's at the\n // start or end of the viewport respectively.\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd[0] = this._terminal.cols;\n } else if (this._dragScrollAmount < 0) {\n this._model.selectionEnd[0] = 0;\n }\n\n // If the character is a wide character include the cell to the right in the\n // selection. Note that selections at the very end of the line will never\n // have a character.\n if (this._model.selectionEnd[1] < this._buffer.lines.length) {\n const char = this._buffer.lines.get(this._model.selectionEnd[1])[this._model.selectionEnd[0]];\n if (char && char[CHAR_DATA_WIDTH_INDEX] === 0) {\n this._model.selectionEnd[0]++;\n }\n }\n\n // Only draw here if the selection changes.\n if (!previousSelectionEnd ||\n previousSelectionEnd[0] !== this._model.selectionEnd[0] ||\n previousSelectionEnd[1] !== this._model.selectionEnd[1]) {\n this.refresh(true);\n }\n }\n\n /**\n * The callback that occurs every DRAG_SCROLL_INTERVAL ms that does the\n * scrolling of the viewport.\n */\n private _dragScroll(): void {\n if (this._dragScrollAmount) {\n this._terminal.scrollLines(this._dragScrollAmount, false);\n // Re-evaluate selection\n if (this._dragScrollAmount > 0) {\n this._model.selectionEnd = [this._terminal.cols - 1, this._terminal.buffer.ydisp + this._terminal.rows];\n } else {\n this._model.selectionEnd = [0, this._terminal.buffer.ydisp];\n }\n this.refresh();\n }\n }\n\n /**\n * Handles the mouseup event, removing the mousedown listeners.\n * @param event The mouseup event.\n */\n private _onMouseUp(event: MouseEvent): void {\n this._removeMouseDownListeners();\n\n if (this.hasSelection)\n this._terminal.emit('selection');\n }\n\n /**\n * Converts a viewport column to the character index on the buffer line, the\n * latter takes into account wide characters.\n * @param coords The coordinates to find the 2 index for.\n */\n private _convertViewportColToCharacterIndex(bufferLine: any, coords: [number, number]): number {\n let charIndex = coords[0];\n for (let i = 0; coords[0] >= i; i++) {\n const char = bufferLine[i];\n if (char[CHAR_DATA_WIDTH_INDEX] === 0) {\n // Wide characters aren't included in the line string so decrement the\n // index so the index is back on the wide character.\n charIndex--;\n } else if (char[CHAR_DATA_CHAR_INDEX].length > 1 && coords[0] !== i) {\n // Emojis take up multiple characters, so adjust accordingly. For these\n // we don't want ot include the character at the column as we're\n // returning the start index in the string, not the end index.\n charIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;\n }\n }\n return charIndex;\n }\n\n public setSelection(col: number, row: number, length: number): void {\n this._model.clearSelection();\n this._removeMouseDownListeners();\n this._model.selectionStart = [col, row];\n this._model.selectionStartLength = length;\n this.refresh();\n }\n\n /**\n * Gets positional information for the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _getWordAt(coords: [number, number]): IWordPosition {\n const bufferLine = this._buffer.lines.get(coords[1]);\n if (!bufferLine) {\n return null;\n }\n\n const line = this._buffer.translateBufferLineToString(coords[1], false);\n\n // Get actual index, taking into consideration wide characters\n let startIndex = this._convertViewportColToCharacterIndex(bufferLine, coords);\n let endIndex = startIndex;\n\n // Record offset to be used later\n const charOffset = coords[0] - startIndex;\n let leftWideCharCount = 0;\n let rightWideCharCount = 0;\n let leftLongCharOffset = 0;\n let rightLongCharOffset = 0;\n\n if (line.charAt(startIndex) === ' ') {\n // Expand until non-whitespace is hit\n while (startIndex > 0 && line.charAt(startIndex - 1) === ' ') {\n startIndex--;\n }\n while (endIndex < line.length && line.charAt(endIndex + 1) === ' ') {\n endIndex++;\n }\n } else {\n // Expand until whitespace is hit. This algorithm works by scanning left\n // and right from the starting position, keeping both the index format\n // (line) and the column format (bufferLine) in sync. When a wide\n // character is hit, it is recorded and the column index is adjusted.\n let startCol = coords[0];\n let endCol = coords[0];\n\n // Consider the initial position, skip it and increment the wide char\n // variable\n if (bufferLine[startCol][CHAR_DATA_WIDTH_INDEX] === 0) {\n leftWideCharCount++;\n startCol--;\n }\n if (bufferLine[endCol][CHAR_DATA_WIDTH_INDEX] === 2) {\n rightWideCharCount++;\n endCol++;\n }\n\n // Adjust the end index for characters whose length are > 1 (emojis)\n if (bufferLine[endCol][CHAR_DATA_CHAR_INDEX].length > 1) {\n rightLongCharOffset += bufferLine[endCol][CHAR_DATA_CHAR_INDEX].length - 1;\n endIndex += bufferLine[endCol][CHAR_DATA_CHAR_INDEX].length - 1;\n }\n\n // Expand the string in both directions until a space is hit\n while (startCol > 0 && startIndex > 0 && !this._isCharWordSeparator(bufferLine[startCol - 1])) {\n const char = bufferLine[startCol - 1];\n if (char[CHAR_DATA_WIDTH_INDEX] === 0) {\n // If the next character is a wide char, record it and skip the column\n leftWideCharCount++;\n startCol--;\n } else if (char[CHAR_DATA_CHAR_INDEX].length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n leftLongCharOffset += char[CHAR_DATA_CHAR_INDEX].length - 1;\n startIndex -= char[CHAR_DATA_CHAR_INDEX].length - 1;\n }\n startIndex--;\n startCol--;\n }\n while (endCol < bufferLine.length && endIndex + 1 < line.length && !this._isCharWordSeparator(bufferLine[endCol + 1])) {\n const char = bufferLine[endCol + 1];\n if (char[CHAR_DATA_WIDTH_INDEX] === 2) {\n // If the next character is a wide char, record it and skip the column\n rightWideCharCount++;\n endCol++;\n } else if (char[CHAR_DATA_CHAR_INDEX].length > 1) {\n // If the next character's string is longer than 1 char (eg. emoji),\n // adjust the index\n rightLongCharOffset += char[CHAR_DATA_CHAR_INDEX].length - 1;\n endIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;\n }\n endIndex++;\n endCol++;\n }\n }\n\n // Incremenet the end index so it is at the start of the next character\n endIndex++;\n\n // Calculate the start _column_, converting the the string indexes back to\n // column coordinates.\n const start =\n startIndex // The index of the selection's start char in the line string\n + charOffset // The difference between the initial char's column and index\n - leftWideCharCount // The number of wide chars left of the initial char\n + leftLongCharOffset; // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n\n // Calculate the length in _columns_, converting the the string indexes back\n // to column coordinates.\n const length = Math.min(this._terminal.cols, // Disallow lengths larger than the terminal cols\n endIndex // The index of the selection's end char in the line string\n - startIndex // The index of the selection's start char in the line string\n + leftWideCharCount // The number of wide chars left of the initial char\n + rightWideCharCount // The number of wide chars right of the initial char (inclusive)\n - leftLongCharOffset // The number of additional chars left of the initial char added by columns with strings longer than 1 (emojis)\n - rightLongCharOffset); // The number of additional chars right of the initial char (inclusive) added by columns with strings longer than 1 (emojis)\n\n return { start, length };\n }\n\n /**\n * Selects the word at the coordinates specified.\n * @param coords The coordinates to get the word at.\n */\n protected _selectWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords);\n if (wordPosition) {\n this._model.selectionStart = [wordPosition.start, coords[1]];\n this._model.selectionStartLength = wordPosition.length;\n }\n }\n\n /**\n * Sets the selection end to the word at the coordinated specified.\n * @param coords The coordinates to get the word at.\n */\n private _selectToWordAt(coords: [number, number]): void {\n const wordPosition = this._getWordAt(coords);\n if (wordPosition) {\n this._model.selectionEnd = [this._model.areSelectionValuesReversed() ? wordPosition.start : (wordPosition.start + wordPosition.length), coords[1]];\n }\n }\n\n /**\n * Gets whether the character is considered a word separator by the select\n * word logic.\n * @param char The character to check.\n */\n private _isCharWordSeparator(charData: CharData): boolean {\n // Zero width characters are never separators as they are always to the\n // right of wide characters\n if (charData[CHAR_DATA_WIDTH_INDEX] === 0) {\n return false;\n }\n return WORD_SEPARATORS.indexOf(charData[CHAR_DATA_CHAR_INDEX]) >= 0;\n }\n\n /**\n * Selects the line specified.\n * @param line The line index.\n */\n protected _selectLineAt(line: number): void {\n this._model.selectionStart = [0, line];\n this._model.selectionStartLength = this._terminal.cols;\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { C0 } from './EscapeSequences';\nimport { IInputHandler } from './Interfaces';\nimport { CHARSETS, DEFAULT_CHARSET } from './Charsets';\n\nconst normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};\nnormalStateHandler[C0.BEL] = (parser, handler) => handler.bell();\nnormalStateHandler[C0.LF] = (parser, handler) => handler.lineFeed();\nnormalStateHandler[C0.VT] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.FF] = normalStateHandler[C0.LF];\nnormalStateHandler[C0.CR] = (parser, handler) => handler.carriageReturn();\nnormalStateHandler[C0.BS] = (parser, handler) => handler.backspace();\nnormalStateHandler[C0.HT] = (parser, handler) => handler.tab();\nnormalStateHandler[C0.SO] = (parser, handler) => handler.shiftOut();\nnormalStateHandler[C0.SI] = (parser, handler) => handler.shiftIn();\nnormalStateHandler[C0.ESC] = (parser, handler) => parser.setState(ParserState.ESCAPED);\n\n// TODO: Remove terminal when parser owns params and currentParam\nconst escapedStateHandler: {[key: string]: (parser: Parser, terminal: any) => void} = {};\nescapedStateHandler['['] = (parser, terminal) => {\n // ESC [ Control Sequence Introducer (CSI is 0x9b)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.CSI_PARAM);\n};\nescapedStateHandler[']'] = (parser, terminal) => {\n // ESC ] Operating System Command (OSC is 0x9d)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.OSC);\n};\nescapedStateHandler['P'] = (parser, terminal) => {\n // ESC P Device Control String (DCS is 0x90)\n terminal.params = [];\n terminal.currentParam = 0;\n parser.setState(ParserState.DCS);\n};\nescapedStateHandler['_'] = (parser, terminal) => {\n // ESC _ Application Program Command ( APC is 0x9f).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['^'] = (parser, terminal) => {\n // ESC ^ Privacy Message ( PM is 0x9e).\n parser.setState(ParserState.IGNORE);\n};\nescapedStateHandler['c'] = (parser, terminal) => {\n // ESC c Full Reset (RIS).\n terminal.reset();\n};\nescapedStateHandler['E'] = (parser, terminal) => {\n // ESC E Next Line ( NEL is 0x85).\n terminal.buffer.x = 0;\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['D'] = (parser, terminal) => {\n // ESC D Index ( IND is 0x84).\n terminal.index();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['M'] = (parser, terminal) => {\n // ESC M Reverse Index ( RI is 0x8d).\n terminal.reverseIndex();\n parser.setState(ParserState.NORMAL);\n};\nescapedStateHandler['%'] = (parser, terminal) => {\n // ESC % Select default/utf-8 character set.\n // @ = default, G = utf-8\n terminal.setgLevel(0);\n terminal.setgCharset(0, DEFAULT_CHARSET); // US (default)\n parser.setState(ParserState.NORMAL);\n parser.skipNextChar();\n};\nescapedStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiParamStateHandler: {[key: string]: (parser: Parser) => void} = {};\ncsiParamStateHandler['?'] = (parser) => parser.setPrefix('?');\ncsiParamStateHandler['>'] = (parser) => parser.setPrefix('>');\ncsiParamStateHandler['!'] = (parser) => parser.setPrefix('!');\ncsiParamStateHandler['0'] = (parser) => parser.setParam(parser.getParam() * 10);\ncsiParamStateHandler['1'] = (parser) => parser.setParam(parser.getParam() * 10 + 1);\ncsiParamStateHandler['2'] = (parser) => parser.setParam(parser.getParam() * 10 + 2);\ncsiParamStateHandler['3'] = (parser) => parser.setParam(parser.getParam() * 10 + 3);\ncsiParamStateHandler['4'] = (parser) => parser.setParam(parser.getParam() * 10 + 4);\ncsiParamStateHandler['5'] = (parser) => parser.setParam(parser.getParam() * 10 + 5);\ncsiParamStateHandler['6'] = (parser) => parser.setParam(parser.getParam() * 10 + 6);\ncsiParamStateHandler['7'] = (parser) => parser.setParam(parser.getParam() * 10 + 7);\ncsiParamStateHandler['8'] = (parser) => parser.setParam(parser.getParam() * 10 + 8);\ncsiParamStateHandler['9'] = (parser) => parser.setParam(parser.getParam() * 10 + 9);\ncsiParamStateHandler['$'] = (parser) => parser.setPostfix('$');\ncsiParamStateHandler['\"'] = (parser) => parser.setPostfix('\"');\ncsiParamStateHandler[' '] = (parser) => parser.setPostfix(' ');\ncsiParamStateHandler['\\''] = (parser) => parser.setPostfix('\\'');\ncsiParamStateHandler[';'] = (parser) => parser.finalizeParam();\ncsiParamStateHandler[C0.CAN] = (parser) => parser.setState(ParserState.NORMAL);\n\nconst csiStateHandler: {[key: string]: (handler: IInputHandler, params: number[], prefix: string, postfix: string, parser: Parser) => void} = {};\ncsiStateHandler['@'] = (handler, params, prefix) => handler.insertChars(params);\ncsiStateHandler['A'] = (handler, params, prefix) => handler.cursorUp(params);\ncsiStateHandler['B'] = (handler, params, prefix) => handler.cursorDown(params);\ncsiStateHandler['C'] = (handler, params, prefix) => handler.cursorForward(params);\ncsiStateHandler['D'] = (handler, params, prefix) => handler.cursorBackward(params);\ncsiStateHandler['E'] = (handler, params, prefix) => handler.cursorNextLine(params);\ncsiStateHandler['F'] = (handler, params, prefix) => handler.cursorPrecedingLine(params);\ncsiStateHandler['G'] = (handler, params, prefix) => handler.cursorCharAbsolute(params);\ncsiStateHandler['H'] = (handler, params, prefix) => handler.cursorPosition(params);\ncsiStateHandler['I'] = (handler, params, prefix) => handler.cursorForwardTab(params);\ncsiStateHandler['J'] = (handler, params, prefix) => handler.eraseInDisplay(params);\ncsiStateHandler['K'] = (handler, params, prefix) => handler.eraseInLine(params);\ncsiStateHandler['L'] = (handler, params, prefix) => handler.insertLines(params);\ncsiStateHandler['M'] = (handler, params, prefix) => handler.deleteLines(params);\ncsiStateHandler['P'] = (handler, params, prefix) => handler.deleteChars(params);\ncsiStateHandler['S'] = (handler, params, prefix) => handler.scrollUp(params);\ncsiStateHandler['T'] = (handler, params, prefix) => {\n if (params.length < 2 && !prefix) {\n handler.scrollDown(params);\n }\n};\ncsiStateHandler['X'] = (handler, params, prefix) => handler.eraseChars(params);\ncsiStateHandler['Z'] = (handler, params, prefix) => handler.cursorBackwardTab(params);\ncsiStateHandler['`'] = (handler, params, prefix) => handler.charPosAbsolute(params);\ncsiStateHandler['a'] = (handler, params, prefix) => handler.HPositionRelative(params);\ncsiStateHandler['b'] = (handler, params, prefix) => handler.repeatPrecedingCharacter(params);\ncsiStateHandler['c'] = (handler, params, prefix) => handler.sendDeviceAttributes(params);\ncsiStateHandler['d'] = (handler, params, prefix) => handler.linePosAbsolute(params);\ncsiStateHandler['e'] = (handler, params, prefix) => handler.VPositionRelative(params);\ncsiStateHandler['f'] = (handler, params, prefix) => handler.HVPosition(params);\ncsiStateHandler['g'] = (handler, params, prefix) => handler.tabClear(params);\ncsiStateHandler['h'] = (handler, params, prefix) => handler.setMode(params);\ncsiStateHandler['l'] = (handler, params, prefix) => handler.resetMode(params);\ncsiStateHandler['m'] = (handler, params, prefix) => handler.charAttributes(params);\ncsiStateHandler['n'] = (handler, params, prefix) => handler.deviceStatus(params);\ncsiStateHandler['p'] = (handler, params, prefix) => {\n switch (prefix) {\n case '!': handler.softReset(params); break;\n }\n};\ncsiStateHandler['q'] = (handler, params, prefix, postfix) => {\n if (postfix === ' ') {\n handler.setCursorStyle(params);\n }\n};\ncsiStateHandler['r'] = (handler, params) => handler.setScrollRegion(params);\ncsiStateHandler['s'] = (handler, params) => handler.saveCursor(params);\ncsiStateHandler['u'] = (handler, params) => handler.restoreCursor(params);\ncsiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL);\n\nexport enum ParserState {\n NORMAL = 0,\n ESCAPED = 1,\n CSI_PARAM = 2,\n CSI = 3,\n OSC = 4,\n CHARSET = 5,\n DCS = 6,\n IGNORE = 7\n}\n\n/**\n * The terminal's parser, all input into the terminal goes through the parser\n * which parses and defers the actual input handling the the IInputHandler\n * specified in the constructor.\n */\nexport class Parser {\n private _state: ParserState;\n private _position: number;\n\n // TODO: Remove terminal when handler can do everything\n constructor(\n private _inputHandler: IInputHandler,\n private _terminal: any\n ) {\n this._state = ParserState.NORMAL;\n }\n\n /**\n * Parse and handle data.\n *\n * @param data The data to parse.\n */\n public parse(data: string): ParserState {\n const l = data.length;\n let j;\n let cs;\n let ch;\n let code;\n let low;\n\n const cursorStartX = this._terminal.buffer.x;\n const cursorStartY = this._terminal.buffer.y;\n\n if (this._terminal.debug) {\n this._terminal.log('data: ' + data);\n }\n\n this._position = 0;\n // apply leftover surrogate high from last write\n if (this._terminal.surrogate_high) {\n data = this._terminal.surrogate_high + data;\n this._terminal.surrogate_high = '';\n }\n\n for (; this._position < l; this._position++) {\n ch = data[this._position];\n\n // FIXME: higher chars than 0xa0 are not allowed in escape sequences\n // --> maybe move to default\n code = data.charCodeAt(this._position);\n if (0xD800 <= code && code <= 0xDBFF) {\n // we got a surrogate high\n // get surrogate low (next 2 bytes)\n low = data.charCodeAt(this._position + 1);\n if (isNaN(low)) {\n // end of data stream, save surrogate high\n this._terminal.surrogate_high = ch;\n continue;\n }\n code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;\n ch += data.charAt(this._position + 1);\n }\n // surrogate low - already handled above\n if (0xDC00 <= code && code <= 0xDFFF)\n continue;\n\n switch (this._state) {\n case ParserState.NORMAL:\n if (ch in normalStateHandler) {\n normalStateHandler[ch](this, this._inputHandler);\n } else {\n this._inputHandler.addChar(ch, code);\n }\n break;\n case ParserState.ESCAPED:\n if (ch in escapedStateHandler) {\n escapedStateHandler[ch](this, this._terminal);\n // Skip switch as it was just handled\n break;\n }\n switch (ch) {\n\n // ESC (,),*,+,-,. Designate G0-G2 Character Set.\n case '(': // <-- this seems to get all the attention\n case ')':\n case '*':\n case '+':\n case '-':\n case '.':\n switch (ch) {\n case '(':\n this._terminal.gcharset = 0;\n break;\n case ')':\n this._terminal.gcharset = 1;\n break;\n case '*':\n this._terminal.gcharset = 2;\n break;\n case '+':\n this._terminal.gcharset = 3;\n break;\n case '-':\n this._terminal.gcharset = 1;\n break;\n case '.':\n this._terminal.gcharset = 2;\n break;\n }\n this._state = ParserState.CHARSET;\n break;\n\n // Designate G3 Character Set (VT300).\n // A = ISO Latin-1 Supplemental.\n // Not implemented.\n case '/':\n this._terminal.gcharset = 3;\n this._state = ParserState.CHARSET;\n this._position--;\n break;\n\n // ESC N\n // Single Shift Select of G2 Character Set\n // ( SS2 is 0x8e). This affects next character only.\n case 'N':\n break;\n // ESC O\n // Single Shift Select of G3 Character Set\n // ( SS3 is 0x8f). This affects next character only.\n case 'O':\n break;\n // ESC n\n // Invoke the G2 Character Set as GL (LS2).\n case 'n':\n this._terminal.setgLevel(2);\n break;\n // ESC o\n // Invoke the G3 Character Set as GL (LS3).\n case 'o':\n this._terminal.setgLevel(3);\n break;\n // ESC |\n // Invoke the G3 Character Set as GR (LS3R).\n case '|':\n this._terminal.setgLevel(3);\n break;\n // ESC }\n // Invoke the G2 Character Set as GR (LS2R).\n case '}':\n this._terminal.setgLevel(2);\n break;\n // ESC ~\n // Invoke the G1 Character Set as GR (LS1R).\n case '~':\n this._terminal.setgLevel(1);\n break;\n\n // ESC 7 Save Cursor (DECSC).\n case '7':\n this._inputHandler.saveCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC 8 Restore Cursor (DECRC).\n case '8':\n this._inputHandler.restoreCursor();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC # 3 DEC line height/width\n case '#':\n this._state = ParserState.NORMAL;\n this._position++;\n break;\n\n // ESC H Tab Set (HTS is 0x88).\n case 'H':\n this._terminal.tabSet();\n this._state = ParserState.NORMAL;\n break;\n\n // ESC = Application Keypad (DECKPAM).\n case '=':\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n if (this._terminal.viewport) {\n this._terminal.viewport.syncScrollArea();\n }\n this._state = ParserState.NORMAL;\n break;\n\n // ESC > Normal Keypad (DECKPNM).\n case '>':\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n if (this._terminal.viewport) {\n this._terminal.viewport.syncScrollArea();\n }\n this._state = ParserState.NORMAL;\n break;\n\n default:\n this._state = ParserState.NORMAL;\n this._terminal.error('Unknown ESC control: %s.', ch);\n break;\n }\n break;\n\n case ParserState.CHARSET:\n if (ch in CHARSETS) {\n cs = CHARSETS[ch];\n if (ch === '/') { // ISOLatin is actually /A\n this.skipNextChar();\n }\n } else {\n cs = DEFAULT_CHARSET;\n }\n this._terminal.setgCharset(this._terminal.gcharset, cs);\n this._terminal.gcharset = null;\n this._state = ParserState.NORMAL;\n break;\n\n case ParserState.OSC:\n // OSC Ps ; Pt ST\n // OSC Ps ; Pt BEL\n // Set Text Parameters.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n\n this._terminal.params.push(this._terminal.currentParam);\n\n switch (this._terminal.params[0]) {\n case 0:\n case 1:\n case 2:\n if (this._terminal.params[1]) {\n this._terminal.title = this._terminal.params[1];\n this._terminal.handleTitle(this._terminal.title);\n }\n break;\n case 3:\n // set X property\n break;\n case 4:\n case 5:\n // change dynamic colors\n break;\n case 10:\n case 11:\n case 12:\n case 13:\n case 14:\n case 15:\n case 16:\n case 17:\n case 18:\n case 19:\n // change dynamic ui colors\n break;\n case 46:\n // change log file\n break;\n case 50:\n // dynamic font\n break;\n case 51:\n // emacs shell\n break;\n case 52:\n // manipulate selection data\n break;\n case 104:\n case 105:\n case 110:\n case 111:\n case 112:\n case 113:\n case 114:\n case 115:\n case 116:\n case 117:\n case 118:\n // reset colors\n break;\n }\n\n this._terminal.params = [];\n this._terminal.currentParam = 0;\n this._state = ParserState.NORMAL;\n } else {\n if (!this._terminal.params.length) {\n if (ch >= '0' && ch <= '9') {\n this._terminal.currentParam =\n this._terminal.currentParam * 10 + ch.charCodeAt(0) - 48;\n } else if (ch === ';') {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = '';\n }\n } else {\n this._terminal.currentParam += ch;\n }\n }\n break;\n\n case ParserState.CSI_PARAM:\n if (ch in csiParamStateHandler) {\n csiParamStateHandler[ch](this);\n break;\n }\n this.finalizeParam();\n // Fall through the CSI as this character should be the CSI code.\n this._state = ParserState.CSI;\n\n case ParserState.CSI:\n if (ch in csiStateHandler) {\n if (this._terminal.debug) {\n this._terminal.log(`CSI ${this._terminal.prefix ? this._terminal.prefix : ''} ${this._terminal.params ? this._terminal.params.join(';') : ''} ${this._terminal.postfix ? this._terminal.postfix : ''} ${ch}`);\n }\n csiStateHandler[ch](this._inputHandler, this._terminal.params, this._terminal.prefix, this._terminal.postfix, this);\n } else {\n this._terminal.error('Unknown CSI code: %s.', ch);\n }\n\n this._state = ParserState.NORMAL;\n this._terminal.prefix = '';\n this._terminal.postfix = '';\n break;\n\n case ParserState.DCS:\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n let pt;\n let valid: boolean;\n\n switch (this._terminal.prefix) {\n // User-Defined Keys (DECUDK).\n case '':\n break;\n\n // Request Status String (DECRQSS).\n // test: echo -e '\\eP$q\"p\\e\\\\'\n case '$q':\n pt = this._terminal.currentParam;\n valid = false;\n\n switch (pt) {\n // DECSCA\n case '\"q':\n pt = '0\"q';\n break;\n\n // DECSCL\n case '\"p':\n pt = '61\"p';\n break;\n\n // DECSTBM\n case 'r':\n pt = ''\n + (this._terminal.buffer.scrollTop + 1)\n + ';'\n + (this._terminal.buffer.scrollBottom + 1)\n + 'r';\n break;\n\n // SGR\n case 'm':\n pt = '0m';\n break;\n\n default:\n this._terminal.error('Unknown DCS Pt: %s.', pt);\n pt = '';\n break;\n }\n\n this._terminal.send(C0.ESC + 'P' + +valid + '$r' + pt + C0.ESC + '\\\\');\n break;\n\n // Set Termcap/Terminfo Data (xterm, experimental).\n case '+p':\n break;\n\n // Request Termcap/Terminfo String (xterm, experimental)\n // Regular xterm does not even respond to this sequence.\n // This can cause a small glitch in vim.\n // test: echo -ne '\\eP+q6b64\\e\\\\'\n case '+q':\n pt = this._terminal.currentParam;\n valid = false;\n\n this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\\\');\n break;\n\n default:\n this._terminal.error('Unknown DCS prefix: %s.', this._terminal.prefix);\n break;\n }\n\n this._terminal.currentParam = 0;\n this._terminal.prefix = '';\n this._state = ParserState.NORMAL;\n } else if (!this._terminal.currentParam) {\n if (!this._terminal.prefix && ch !== '$' && ch !== '+') {\n this._terminal.currentParam = ch;\n } else if (this._terminal.prefix.length === 2) {\n this._terminal.currentParam = ch;\n } else {\n this._terminal.prefix += ch;\n }\n } else {\n this._terminal.currentParam += ch;\n }\n break;\n\n case ParserState.IGNORE:\n // For PM and APC.\n if (ch === C0.ESC || ch === C0.BEL) {\n if (ch === C0.ESC) this._position++;\n this._state = ParserState.NORMAL;\n }\n break;\n }\n }\n\n // Fire the cursormove event if it's moved. This is done inside the parser\n // as a render cannot happen in the middle of a parsing round.\n if (this._terminal.buffer.x !== cursorStartX || this._terminal.buffer.y !== cursorStartY) {\n this._terminal.emit('cursormove');\n }\n\n return this._state;\n }\n\n /**\n * Set the parser's current parsing state.\n *\n * @param state The new state.\n */\n public setState(state: ParserState): void {\n this._state = state;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have prefixes of '?', '>'\n * or '!'.\n *\n * @param prefix The prefix.\n */\n public setPrefix(prefix: string): void {\n this._terminal.prefix = prefix;\n }\n\n /**\n * Sets the parsier's current prefix. CSI codes can have postfixes of '$',\n * '\"', ' ', '\\''.\n *\n * @param postfix The postfix.\n */\n public setPostfix(postfix: string): void {\n this._terminal.postfix = postfix;\n }\n\n /**\n * Sets the parser's current parameter.\n *\n * @param param the parameter.\n */\n public setParam(param: number): void {\n this._terminal.currentParam = param;\n }\n\n /**\n * Gets the parser's current parameter.\n */\n public getParam(): number {\n return this._terminal.currentParam;\n }\n\n /**\n * Finalizes the parser's current parameter, adding it to the list of\n * parameters and setting the new current parameter to 0.\n */\n public finalizeParam(): void {\n this._terminal.params.push(this._terminal.currentParam);\n this._terminal.currentParam = 0;\n }\n\n /**\n * Tell the parser to skip the next character.\n */\n public skipNextChar(): void {\n this._position++;\n }\n\n /**\n * Tell the parser to repeat parsing the current character (for example if it\n * needs parsing using a different state.\n */\n // public repeatChar(): void {\n // this._position--;\n // }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Interfaces';\nimport { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEvent, LinkHoverEventTypes } from './Types';\nimport { IMouseZoneManager } from './input/Interfaces';\nimport { MouseZone } from './input/MouseZoneManager';\nimport { EventEmitter } from './EventEmitter';\n\nconst protocolClause = '(https?:\\\\/\\\\/)';\nconst domainCharacterSet = '[\\\\da-z\\\\.-]+';\nconst negatedDomainCharacterSet = '[^\\\\da-z\\\\.-]+';\nconst domainBodyClause = '(' + domainCharacterSet + ')';\nconst tldClause = '([a-z\\\\.]{2,6})';\nconst ipClause = '((\\\\d{1,3}\\\\.){3}\\\\d{1,3})';\nconst localHostClause = '(localhost)';\nconst portClause = '(:\\\\d{1,5})';\nconst hostClause = '((' + domainBodyClause + '\\\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?';\nconst pathClause = '(\\\\/[\\\\/\\\\w\\\\.\\\\-%~]*)*';\nconst queryStringHashFragmentCharacterSet = '[0-9\\\\w\\\\[\\\\]\\\\(\\\\)\\\\/\\\\?\\\\!#@$%&\\'*+,:;~\\\\=\\\\.\\\\-]*';\nconst queryStringClause = '(\\\\?' + queryStringHashFragmentCharacterSet + ')?';\nconst hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?';\nconst negatedPathCharacterSet = '[^\\\\/\\\\w\\\\.\\\\-%]+';\nconst bodyClause = hostClause + pathClause + queryStringClause + hashFragmentClause;\nconst start = '(?:^|' + negatedDomainCharacterSet + ')(';\nconst end = ')($|' + negatedPathCharacterSet + ')';\nconst strictUrlRegex = new RegExp(start + protocolClause + bodyClause + end);\n\n/**\n * The ID of the built in http(s) link matcher.\n */\nconst HYPERTEXT_LINK_MATCHER_ID = 0;\n\n/**\n * The Linkifier applies links to rows shortly after they have been refreshed.\n */\nexport class Linkifier extends EventEmitter implements ILinkifier {\n /**\n * The time to wait after a row is changed before it is linkified. This prevents\n * the costly operation of searching every row multiple times, potentially a\n * huge amount of times.\n */\n protected static TIME_BEFORE_LINKIFY = 200;\n\n protected _linkMatchers: LinkMatcher[] = [];\n\n private _mouseZoneManager: IMouseZoneManager;\n private _rowsTimeoutId: number;\n private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;\n private _rowsToLinkify: {start: number, end: number};\n\n constructor(\n protected _terminal: IBufferAccessor & IElementAccessor\n ) {\n super();\n this._rowsToLinkify = {\n start: null,\n end: null\n };\n this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 });\n }\n\n /**\n * Attaches the linkifier to the DOM, enabling linkification.\n * @param mouseZoneManager The mouse zone manager to register link zones with.\n */\n public attachToDom(mouseZoneManager: IMouseZoneManager): void {\n this._mouseZoneManager = mouseZoneManager;\n }\n\n /**\n * Queue linkification on a set of rows.\n * @param start The row to linkify from (inclusive).\n * @param end The row to linkify to (inclusive).\n */\n public linkifyRows(start: number, end: number): void {\n // Don't attempt linkify if not yet attached to DOM\n if (!this._mouseZoneManager) {\n return;\n }\n\n // Increase range to linkify\n if (!this._rowsToLinkify.start) {\n this._rowsToLinkify.start = start;\n this._rowsToLinkify.end = end;\n } else {\n this._rowsToLinkify.start = this._rowsToLinkify.start < start ? this._rowsToLinkify.start : start;\n this._rowsToLinkify.end = this._rowsToLinkify.end > end ? this._rowsToLinkify.end : end;\n }\n\n // Clear out any existing links on this row range\n this._mouseZoneManager.clearAll(start, end);\n\n // Restart timer\n if (this._rowsTimeoutId) {\n clearTimeout(this._rowsTimeoutId);\n }\n this._rowsTimeoutId = <number><any>setTimeout(() => this._linkifyRows(), Linkifier.TIME_BEFORE_LINKIFY);\n }\n\n /**\n * Linkifies the rows requested.\n */\n private _linkifyRows(): void {\n this._rowsTimeoutId = null;\n for (let i = this._rowsToLinkify.start; i <= this._rowsToLinkify.end; i++) {\n this._linkifyRow(i);\n }\n this._rowsToLinkify.start = null;\n this._rowsToLinkify.end = null;\n }\n\n /**\n * Attaches a handler for hypertext links, overriding default <a> behavior for\n * tandard http(s) links.\n * @param handler The handler to use, this can be cleared with null.\n */\n public setHypertextLinkHandler(handler: LinkMatcherHandler): void {\n this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].handler = handler;\n }\n\n /**\n * Attaches a validation callback for hypertext links.\n * @param callback The callback to use, this can be cleared with null.\n */\n public setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void {\n this._linkMatchers[HYPERTEXT_LINK_MATCHER_ID].validationCallback = callback;\n }\n\n /**\n * Registers a link matcher, allowing custom link patterns to be matched and\n * handled.\n * @param regex The regular expression to search for. Specifically, this\n * searches the textContent of the rows. You will want to use \\s to match a\n * space ' ' character for example.\n * @param handler The callback when the link is called.\n * @param options Options for the link matcher.\n * @return The ID of the new matcher, this can be used to deregister.\n */\n public registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options: ILinkMatcherOptions = {}): number {\n if (this._nextLinkMatcherId !== HYPERTEXT_LINK_MATCHER_ID && !handler) {\n throw new Error('handler must be defined');\n }\n const matcher: LinkMatcher = {\n id: this._nextLinkMatcherId++,\n regex,\n handler,\n matchIndex: options.matchIndex,\n validationCallback: options.validationCallback,\n hoverTooltipCallback: options.tooltipCallback,\n hoverLeaveCallback: options.leaveCallback,\n priority: options.priority || 0\n };\n this._addLinkMatcherToList(matcher);\n return matcher.id;\n }\n\n /**\n * Inserts a link matcher to the list in the correct position based on the\n * priority of each link matcher. New link matchers of equal priority are\n * considered after older link matchers.\n * @param matcher The link matcher to be added.\n */\n private _addLinkMatcherToList(matcher: LinkMatcher): void {\n if (this._linkMatchers.length === 0) {\n this._linkMatchers.push(matcher);\n return;\n }\n\n for (let i = this._linkMatchers.length - 1; i >= 0; i--) {\n if (matcher.priority <= this._linkMatchers[i].priority) {\n this._linkMatchers.splice(i + 1, 0, matcher);\n return;\n }\n }\n\n this._linkMatchers.splice(0, 0, matcher);\n }\n\n /**\n * Deregisters a link matcher if it has been registered.\n * @param matcherId The link matcher's ID (returned after register)\n * @return Whether a link matcher was found and deregistered.\n */\n public deregisterLinkMatcher(matcherId: number): boolean {\n // ID 0 is the hypertext link matcher which cannot be deregistered\n for (let i = 1; i < this._linkMatchers.length; i++) {\n if (this._linkMatchers[i].id === matcherId) {\n this._linkMatchers.splice(i, 1);\n return true;\n }\n }\n return false;\n }\n\n /**\n * Linkifies a row.\n * @param rowIndex The index of the row to linkify.\n */\n private _linkifyRow(rowIndex: number): void {\n const absoluteRowIndex = this._terminal.buffer.ydisp + rowIndex;\n if (absoluteRowIndex >= this._terminal.buffer.lines.length) {\n return;\n }\n const text = this._terminal.buffer.translateBufferLineToString(absoluteRowIndex, false);\n for (let i = 0; i < this._linkMatchers.length; i++) {\n this._doLinkifyRow(rowIndex, text, this._linkMatchers[i]);\n }\n }\n\n /**\n * Linkifies a row given a specific handler.\n * @param rowIndex The row index to linkify.\n * @param text The text of the row (excludes text in the row that's already\n * linkified).\n * @param matcher The link matcher for this line.\n * @param offset The how much of the row has already been linkified.\n * @return The link element(s) that were added.\n */\n private _doLinkifyRow(rowIndex: number, text: string, matcher: LinkMatcher, offset: number = 0): void {\n // Iterate over nodes as we want to consider text nodes\n let result = [];\n const isHttpLinkMatcher = matcher.id === HYPERTEXT_LINK_MATCHER_ID;\n\n // Find the first match\n let match = text.match(matcher.regex);\n if (!match || match.length === 0) {\n return;\n }\n let uri = match[typeof matcher.matchIndex !== 'number' ? 0 : matcher.matchIndex];\n\n // Get index, match.index is for the outer match which includes negated chars\n const index = text.indexOf(uri);\n\n // Ensure the link is valid before registering\n if (matcher.validationCallback) {\n matcher.validationCallback(uri, isValid => {\n // Discard link if the line has already changed\n if (this._rowsTimeoutId) {\n return;\n }\n if (isValid) {\n this._addLink(offset + index, rowIndex, uri, matcher);\n }\n });\n } else {\n this._addLink(offset + index, rowIndex, uri, matcher);\n }\n\n // Recursively check for links in the rest of the text\n const remainingStartIndex = index + uri.length;\n const remainingText = text.substr(remainingStartIndex);\n if (remainingText.length > 0) {\n this._doLinkifyRow(rowIndex, remainingText, matcher, offset + remainingStartIndex);\n }\n }\n\n /**\n * Registers a link to the mouse zone manager.\n * @param x The column the link starts.\n * @param y The row the link is on.\n * @param uri The URI of the link.\n * @param matcher The link matcher for the link.\n */\n private _addLink(x: number, y: number, uri: string, matcher: LinkMatcher): void {\n this._mouseZoneManager.add(new MouseZone(\n x + 1,\n x + 1 + uri.length,\n y + 1,\n e => {\n if (matcher.handler) {\n return matcher.handler(e, uri);\n }\n window.open(uri, '_blank');\n },\n e => {\n this.emit(LinkHoverEventTypes.HOVER, <LinkHoverEvent>{ x, y, length: uri.length});\n this._terminal.element.style.cursor = 'pointer';\n },\n e => {\n this.emit(LinkHoverEventTypes.TOOLTIP, <LinkHoverEvent>{ x, y, length: uri.length});\n if (matcher.hoverTooltipCallback) {\n matcher.hoverTooltipCallback(e, uri);\n }\n },\n () => {\n this.emit(LinkHoverEventTypes.LEAVE, <LinkHoverEvent>{ x, y, length: uri.length});\n this._terminal.element.style.cursor = '';\n if (matcher.hoverLeaveCallback) {\n matcher.hoverLeaveCallback();\n }\n }\n ));\n }\n}\n","/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)\n * @license MIT\n */\n\nimport { IInputHandler, ITerminal, IInputHandlingTerminal } from './Interfaces';\nimport { C0 } from './EscapeSequences';\nimport { DEFAULT_CHARSET } from './Charsets';\nimport { CharData } from './Types';\nimport { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer';\nimport { FLAGS } from './renderer/Types';\nimport { wcwidth } from './CharWidth';\n\n/**\n * The terminal's standard implementation of IInputHandler, this handles all\n * input from the Parser.\n *\n * Refer to http://invisible-island.net/xterm/ctlseqs/ctlseqs.html to understand\n * each function's header comment.\n */\nexport class InputHandler implements IInputHandler {\n constructor(private _terminal: IInputHandlingTerminal) { }\n\n public addChar(char: string, code: number): void {\n if (char >= ' ') {\n // calculate print space\n // expensive call, therefore we save width in line buffer\n const ch_width = wcwidth(code);\n\n if (this._terminal.charset && this._terminal.charset[char]) {\n char = this._terminal.charset[char];\n }\n\n let row = this._terminal.buffer.y + this._terminal.buffer.ybase;\n\n // insert combining char in last cell\n // FIXME: needs handling after cursor jumps\n if (!ch_width && this._terminal.buffer.x) {\n // dont overflow left\n if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1]) {\n if (!this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][CHAR_DATA_WIDTH_INDEX]) {\n // found empty cell after fullwidth, need to go 2 cells back\n if (this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2]) {\n this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][CHAR_DATA_CHAR_INDEX] += char;\n this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 2][3] = char.charCodeAt(0);\n }\n } else {\n this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][CHAR_DATA_CHAR_INDEX] += char;\n this._terminal.buffer.lines.get(row)[this._terminal.buffer.x - 1][3] = char.charCodeAt(0);\n }\n this._terminal.updateRange(this._terminal.buffer.y);\n }\n return;\n }\n\n // goto next line if ch would overflow\n // TODO: needs a global min terminal width of 2\n if (this._terminal.buffer.x + ch_width - 1 >= this._terminal.cols) {\n // autowrap - DECAWM\n if (this._terminal.wraparoundMode) {\n this._terminal.buffer.x = 0;\n this._terminal.buffer.y++;\n if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) {\n this._terminal.buffer.y--;\n this._terminal.scroll(true);\n } else {\n // The line already exists (eg. the initial viewport), mark it as a\n // wrapped line\n (<any>this._terminal.buffer.lines.get(this._terminal.buffer.y)).isWrapped = true;\n }\n } else {\n if (ch_width === 2) // FIXME: check for xterm behavior\n return;\n }\n }\n row = this._terminal.buffer.y + this._terminal.buffer.ybase;\n\n // insert mode: move characters to right\n if (this._terminal.insertMode) {\n // do this twice for a fullwidth char\n for (let moves = 0; moves < ch_width; ++moves) {\n // remove last cell, if it's width is 0\n // we have to adjust the second last cell as well\n const removed = this._terminal.buffer.lines.get(this._terminal.buffer.y + this._terminal.buffer.ybase).pop();\n if (removed[CHAR_DATA_WIDTH_INDEX] === 0\n && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2]\n && this._terminal.buffer.lines.get(row)[this._terminal.cols - 2][CHAR_DATA_WIDTH_INDEX] === 2) {\n this._terminal.buffer.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)];\n }\n\n // insert empty cell at cursor\n this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 0, [this._terminal.curAttr, ' ', 1, ' '.charCodeAt(0)]);\n }\n }\n\n this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, char, ch_width, char.charCodeAt(0)];\n this._terminal.buffer.x++;\n this._terminal.updateRange(this._terminal.buffer.y);\n\n // fullwidth char - set next cell width to zero and advance cursor\n if (ch_width === 2) {\n this._terminal.buffer.lines.get(row)[this._terminal.buffer.x] = [this._terminal.curAttr, '', 0, undefined];\n this._terminal.buffer.x++;\n }\n }\n }\n\n /**\n * BEL\n * Bell (Ctrl-G).\n */\n public bell(): void {\n this._terminal.bell();\n }\n\n /**\n * LF\n * Line Feed or New Line (NL). (LF is Ctrl-J).\n */\n public lineFeed(): void {\n if (this._terminal.convertEol) {\n this._terminal.buffer.x = 0;\n }\n this._terminal.buffer.y++;\n if (this._terminal.buffer.y > this._terminal.buffer.scrollBottom) {\n this._terminal.buffer.y--;\n this._terminal.scroll();\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x--;\n }\n /**\n * This event is emitted whenever the terminal outputs a LF or NL.\n *\n * @event linefeed\n */\n this._terminal.emit('linefeed');\n }\n\n /**\n * CR\n * Carriage Return (Ctrl-M).\n */\n public carriageReturn(): void {\n this._terminal.buffer.x = 0;\n }\n\n /**\n * BS\n * Backspace (Ctrl-H).\n */\n public backspace(): void {\n if (this._terminal.buffer.x > 0) {\n this._terminal.buffer.x--;\n }\n }\n\n /**\n * TAB\n * Horizontal Tab (HT) (Ctrl-I).\n */\n public tab(): void {\n this._terminal.buffer.x = this._terminal.buffer.nextStop();\n }\n\n /**\n * SO\n * Shift Out (Ctrl-N) -> Switch to Alternate Character Set. This invokes the\n * G1 character set.\n */\n public shiftOut(): void {\n this._terminal.setgLevel(1);\n }\n\n /**\n * SI\n * Shift In (Ctrl-O) -> Switch to Standard Character Set. This invokes the G0\n * character set (the default).\n */\n public shiftIn(): void {\n this._terminal.setgLevel(0);\n }\n\n /**\n * CSI Ps @\n * Insert Ps (Blank) Character(s) (default = 1) (ICH).\n */\n public insertChars(params: number[]): void {\n let param = params[0];\n if (param < 1) param = 1;\n\n const row = this._terminal.buffer.y + this._terminal.buffer.ybase;\n let j = this._terminal.buffer.x;\n const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.buffer.lines.get(row).splice(j++, 0, ch);\n this._terminal.buffer.lines.get(row).pop();\n }\n }\n\n /**\n * CSI Ps A\n * Cursor Up Ps Times (default = 1) (CUU).\n */\n public cursorUp(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.y -= param;\n if (this._terminal.buffer.y < 0) {\n this._terminal.buffer.y = 0;\n }\n }\n\n /**\n * CSI Ps B\n * Cursor Down Ps Times (default = 1) (CUD).\n */\n public cursorDown(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.y += param;\n if (this._terminal.buffer.y >= this._terminal.rows) {\n this._terminal.buffer.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x--;\n }\n }\n\n /**\n * CSI Ps C\n * Cursor Forward Ps Times (default = 1) (CUF).\n */\n public cursorForward(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.x += param;\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps D\n * Cursor Backward Ps Times (default = 1) (CUB).\n */\n public cursorBackward(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x--;\n }\n this._terminal.buffer.x -= param;\n if (this._terminal.buffer.x < 0) {\n this._terminal.buffer.x = 0;\n }\n }\n\n /**\n * CSI Ps E\n * Cursor Next Line Ps Times (default = 1) (CNL).\n * same as CSI Ps B ?\n */\n public cursorNextLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.y += param;\n if (this._terminal.buffer.y >= this._terminal.rows) {\n this._terminal.buffer.y = this._terminal.rows - 1;\n }\n this._terminal.buffer.x = 0;\n }\n\n\n /**\n * CSI Ps F\n * Cursor Preceding Line Ps Times (default = 1) (CNL).\n * reuse CSI Ps A ?\n */\n public cursorPrecedingLine(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.y -= param;\n if (this._terminal.buffer.y < 0) {\n this._terminal.buffer.y = 0;\n }\n this._terminal.buffer.x = 0;\n }\n\n\n /**\n * CSI Ps G\n * Cursor Character Absolute [column] (default = [row,1]) (CHA).\n */\n public cursorCharAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.x = param - 1;\n }\n\n /**\n * CSI Ps ; Ps H\n * Cursor Position [row;column] (default = [1,1]) (CUP).\n */\n public cursorPosition(params: number[]): void {\n let col: number;\n let row: number = params[0] - 1;\n\n if (params.length >= 2) {\n col = params[1] - 1;\n } else {\n col = 0;\n }\n\n if (row < 0) {\n row = 0;\n } else if (row >= this._terminal.rows) {\n row = this._terminal.rows - 1;\n }\n\n if (col < 0) {\n col = 0;\n } else if (col >= this._terminal.cols) {\n col = this._terminal.cols - 1;\n }\n\n this._terminal.buffer.x = col;\n this._terminal.buffer.y = row;\n }\n\n /**\n * CSI Ps I\n * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).\n */\n public cursorForwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.buffer.x = this._terminal.buffer.nextStop();\n }\n }\n\n /**\n * CSI Ps J Erase in Display (ED).\n * Ps = 0 -> Erase Below (default).\n * Ps = 1 -> Erase Above.\n * Ps = 2 -> Erase All.\n * Ps = 3 -> Erase Saved Lines (xterm).\n * CSI ? Ps J\n * Erase in Display (DECSED).\n * Ps = 0 -> Selective Erase Below (default).\n * Ps = 1 -> Selective Erase Above.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInDisplay(params: number[]): void {\n let j;\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y);\n j = this._terminal.buffer.y + 1;\n for (; j < this._terminal.rows; j++) {\n this._terminal.eraseLine(j);\n }\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y);\n j = this._terminal.buffer.y;\n while (j--) {\n this._terminal.eraseLine(j);\n }\n break;\n case 2:\n j = this._terminal.rows;\n while (j--) this._terminal.eraseLine(j);\n break;\n case 3:\n // Clear scrollback (everything not in viewport)\n const scrollBackSize = this._terminal.buffer.lines.length - this._terminal.rows;\n if (scrollBackSize > 0) {\n this._terminal.buffer.lines.trimStart(scrollBackSize);\n this._terminal.buffer.ybase = Math.max(this._terminal.buffer.ybase - scrollBackSize, 0);\n this._terminal.buffer.ydisp = Math.max(this._terminal.buffer.ydisp - scrollBackSize, 0);\n // Force a scroll event to refresh viewport\n this._terminal.emit('scroll', 0);\n }\n break;\n }\n }\n\n /**\n * CSI Ps K Erase in Line (EL).\n * Ps = 0 -> Erase to Right (default).\n * Ps = 1 -> Erase to Left.\n * Ps = 2 -> Erase All.\n * CSI ? Ps K\n * Erase in Line (DECSEL).\n * Ps = 0 -> Selective Erase to Right (default).\n * Ps = 1 -> Selective Erase to Left.\n * Ps = 2 -> Selective Erase All.\n */\n public eraseInLine(params: number[]): void {\n switch (params[0]) {\n case 0:\n this._terminal.eraseRight(this._terminal.buffer.x, this._terminal.buffer.y);\n break;\n case 1:\n this._terminal.eraseLeft(this._terminal.buffer.x, this._terminal.buffer.y);\n break;\n case 2:\n this._terminal.eraseLine(this._terminal.buffer.y);\n break;\n }\n }\n\n /**\n * CSI Ps L\n * Insert Ps Line(s) (default = 1) (IL).\n */\n public insertLines(params: number[]): void {\n let param: number = params[0];\n if (param < 1) {\n param = 1;\n }\n let row: number = this._terminal.buffer.y + this._terminal.buffer.ybase;\n\n let scrollBottomRowsOffset = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom;\n let scrollBottomAbsolute = this._terminal.rows - 1 + this._terminal.buffer.ybase - scrollBottomRowsOffset + 1;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1L\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.buffer.lines.splice(scrollBottomAbsolute - 1, 1);\n this._terminal.buffer.lines.splice(row, 0, this._terminal.blankLine(true));\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.buffer.y);\n this._terminal.updateRange(this._terminal.buffer.scrollBottom);\n }\n\n /**\n * CSI Ps M\n * Delete Ps Line(s) (default = 1) (DL).\n */\n public deleteLines(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n const row: number = this._terminal.buffer.y + this._terminal.buffer.ybase;\n\n let j: number;\n j = this._terminal.rows - 1 - this._terminal.buffer.scrollBottom;\n j = this._terminal.rows - 1 + this._terminal.buffer.ybase - j;\n while (param--) {\n // test: echo -e '\\e[44m\\e[1M\\e[0m'\n // blankLine(true) - xterm/linux behavior\n this._terminal.buffer.lines.splice(row, 1);\n this._terminal.buffer.lines.splice(j, 0, this._terminal.blankLine(true));\n }\n\n // this.maxRange();\n this._terminal.updateRange(this._terminal.buffer.y);\n this._terminal.updateRange(this._terminal.buffer.scrollBottom);\n }\n\n /**\n * CSI Ps P\n * Delete Ps Character(s) (default = 1) (DCH).\n */\n public deleteChars(params: number[]): void {\n let param: number = params[0];\n if (param < 1) {\n param = 1;\n }\n\n const row = this._terminal.buffer.y + this._terminal.buffer.ybase;\n const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm\n\n while (param--) {\n this._terminal.buffer.lines.get(row).splice(this._terminal.buffer.x, 1);\n this._terminal.buffer.lines.get(row).push(ch);\n }\n this._terminal.updateRange(this._terminal.buffer.y);\n }\n\n /**\n * CSI Ps S Scroll up Ps lines (default = 1) (SU).\n */\n public scrollUp(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 1);\n this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.buffer.scrollTop);\n this._terminal.updateRange(this._terminal.buffer.scrollBottom);\n }\n\n /**\n * CSI Ps T Scroll down Ps lines (default = 1) (SD).\n */\n public scrollDown(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollBottom, 1);\n this._terminal.buffer.lines.splice(this._terminal.buffer.ybase + this._terminal.buffer.scrollTop, 0, this._terminal.blankLine());\n }\n // this.maxRange();\n this._terminal.updateRange(this._terminal.buffer.scrollTop);\n this._terminal.updateRange(this._terminal.buffer.scrollBottom);\n }\n\n /**\n * CSI Ps X\n * Erase Ps Character(s) (default = 1) (ECH).\n */\n public eraseChars(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n\n const row = this._terminal.buffer.y + this._terminal.buffer.ybase;\n let j = this._terminal.buffer.x;\n const ch: CharData = [this._terminal.eraseAttr(), ' ', 1, 32]; // xterm\n\n while (param-- && j < this._terminal.cols) {\n this._terminal.buffer.lines.get(row)[j++] = ch;\n }\n }\n\n /**\n * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).\n */\n public cursorBackwardTab(params: number[]): void {\n let param = params[0] || 1;\n while (param--) {\n this._terminal.buffer.x = this._terminal.buffer.prevStop();\n }\n }\n\n /**\n * CSI Pm ` Character Position Absolute\n * [column] (default = [row,1]) (HPA).\n */\n public charPosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.x = param - 1;\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Pm a Character Position Relative\n * [columns] (default = [row,col+1]) (HPR)\n * reuse CSI Ps C ?\n */\n public HPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.x += param;\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps b Repeat the preceding graphic character Ps times (REP).\n */\n public repeatPrecedingCharacter(params: number[]): void {\n let param = params[0] || 1;\n const line = this._terminal.buffer.lines.get(this._terminal.buffer.ybase + this._terminal.buffer.y);\n const ch = line[this._terminal.buffer.x - 1] || [this._terminal.defAttr, ' ', 1, 32];\n\n while (param--) {\n line[this._terminal.buffer.x++] = ch;\n }\n }\n\n /**\n * CSI Ps c Send Device Attributes (Primary DA).\n * Ps = 0 or omitted -> request attributes from terminal. The\n * response depends on the decTerminalID resource setting.\n * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')\n * -> CSI ? 1 ; 0 c (``VT101 with No Options'')\n * -> CSI ? 6 c (``VT102'')\n * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')\n * The VT100-style response parameters do not mean anything by\n * themselves. VT220 parameters do, telling the host what fea-\n * tures the terminal supports:\n * Ps = 1 -> 132-columns.\n * Ps = 2 -> Printer.\n * Ps = 6 -> Selective erase.\n * Ps = 8 -> User-defined keys.\n * Ps = 9 -> National replacement character sets.\n * Ps = 1 5 -> Technical characters.\n * Ps = 2 2 -> ANSI color, e.g., VT525.\n * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).\n * CSI > Ps c\n * Send Device Attributes (Secondary DA).\n * Ps = 0 or omitted -> request the terminal's identification\n * code. The response depends on the decTerminalID resource set-\n * ting. It should apply only to VT220 and up, but xterm extends\n * this to VT100.\n * -> CSI > Pp ; Pv ; Pc c\n * where Pp denotes the terminal type\n * Pp = 0 -> ``VT100''.\n * Pp = 1 -> ``VT220''.\n * and Pv is the firmware version (for xterm, this was originally\n * the XFree86 patch number, starting with 95). In a DEC termi-\n * nal, Pc indicates the ROM cartridge registration number and is\n * always zero.\n * More information:\n * xterm/charproc.c - line 2012, for more information.\n * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)\n */\n public sendDeviceAttributes(params: number[]): void {\n if (params[0] > 0) {\n return;\n }\n\n if (!this._terminal.prefix) {\n if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[?1;2c');\n } else if (this._terminal.is('linux')) {\n this._terminal.send(C0.ESC + '[?6c');\n }\n } else if (this._terminal.prefix === '>') {\n // xterm and urxvt\n // seem to spit this\n // out around ~370 times (?).\n if (this._terminal.is('xterm')) {\n this._terminal.send(C0.ESC + '[>0;276;0c');\n } else if (this._terminal.is('rxvt-unicode')) {\n this._terminal.send(C0.ESC + '[>85;95;0c');\n } else if (this._terminal.is('linux')) {\n // not supported by linux console.\n // linux console echoes parameters.\n this._terminal.send(params[0] + 'c');\n } else if (this._terminal.is('screen')) {\n this._terminal.send(C0.ESC + '[>83;40003;0c');\n }\n }\n }\n\n /**\n * CSI Pm d Vertical Position Absolute (VPA)\n * [row] (default = [1,column])\n */\n public linePosAbsolute(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.y = param - 1;\n if (this._terminal.buffer.y >= this._terminal.rows) {\n this._terminal.buffer.y = this._terminal.rows - 1;\n }\n }\n\n /**\n * CSI Pm e Vertical Position Relative (VPR)\n * [rows] (default = [row+1,column])\n * reuse CSI Ps B ?\n */\n public VPositionRelative(params: number[]): void {\n let param = params[0];\n if (param < 1) {\n param = 1;\n }\n this._terminal.buffer.y += param;\n if (this._terminal.buffer.y >= this._terminal.rows) {\n this._terminal.buffer.y = this._terminal.rows - 1;\n }\n // If the end of the line is hit, prevent this action from wrapping around to the next line.\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x--;\n }\n }\n\n /**\n * CSI Ps ; Ps f\n * Horizontal and Vertical Position [row;column] (default =\n * [1,1]) (HVP).\n */\n public HVPosition(params: number[]): void {\n if (params[0] < 1) params[0] = 1;\n if (params[1] < 1) params[1] = 1;\n\n this._terminal.buffer.y = params[0] - 1;\n if (this._terminal.buffer.y >= this._terminal.rows) {\n this._terminal.buffer.y = this._terminal.rows - 1;\n }\n\n this._terminal.buffer.x = params[1] - 1;\n if (this._terminal.buffer.x >= this._terminal.cols) {\n this._terminal.buffer.x = this._terminal.cols - 1;\n }\n }\n\n /**\n * CSI Ps g Tab Clear (TBC).\n * Ps = 0 -> Clear Current Column (default).\n * Ps = 3 -> Clear All.\n * Potentially:\n * Ps = 2 -> Clear Stops on Line.\n * http://vt100.net/annarbor/aaa-ug/section6.html\n */\n public tabClear(params: number[]): void {\n let param = params[0];\n if (param <= 0) {\n delete this._terminal.buffer.tabs[this._terminal.buffer.x];\n } else if (param === 3) {\n this._terminal.buffer.tabs = {};\n }\n }\n\n /**\n * CSI Pm h Set Mode (SM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Insert Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Automatic Newline (LNM).\n * CSI ? Pm h\n * DEC Private Mode Set (DECSET).\n * Ps = 1 -> Application Cursor Keys (DECCKM).\n * Ps = 2 -> Designate USASCII for character sets G0-G3\n * (DECANM), and set VT100 mode.\n * Ps = 3 -> 132 Column Mode (DECCOLM).\n * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).\n * Ps = 5 -> Reverse Video (DECSCNM).\n * Ps = 6 -> Origin Mode (DECOM).\n * Ps = 7 -> Wraparound Mode (DECAWM).\n * Ps = 8 -> Auto-repeat Keys (DECARM).\n * Ps = 9 -> Send Mouse X & Y on button press. See the sec-\n * tion Mouse Tracking.\n * Ps = 1 0 -> Show toolbar (rxvt).\n * Ps = 1 2 -> Start Blinking Cursor (att610).\n * Ps = 1 8 -> Print form feed (DECPFF).\n * Ps = 1 9 -> Set print extent to full screen (DECPEX).\n * Ps = 2 5 -> Show Cursor (DECTCEM).\n * Ps = 3 0 -> Show scrollbar (rxvt).\n * Ps = 3 5 -> Enable font-shifting functions (rxvt).\n * Ps = 3 8 -> Enter Tektronix Mode (DECTEK).\n * Ps = 4 0 -> Allow 80 -> 132 Mode.\n * Ps = 4 1 -> more(1) fix (see curses resource).\n * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-\n * RCM).\n * Ps = 4 4 -> Turn On Margin Bell.\n * Ps = 4 5 -> Reverse-wraparound Mode.\n * Ps = 4 6 -> Start Logging. This is normally disabled by a\n * compile-time option.\n * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 6 6 -> Application keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends backspace (DECBKM).\n * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Enable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).\n * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Interpret \"meta\" key, sets eighth bit.\n * (enables the eightBitInput resource).\n * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-\n * Lock keys. (This enables the numLock resource).\n * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This\n * enables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete\n * key.\n * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This\n * enables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Keep selection even if not highlighted.\n * (This enables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Enable Urgency window manager hint when\n * Control-G is received. (This enables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Enable raising of the window when Control-G\n * is received. (enables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-\n * abled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate\n * Screen Buffer, clearing it first. (This may be disabled by\n * the titeInhibit resource). This combines the effects of the 1\n * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based\n * applications rather than the 4 7 mode.\n * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Set Sun function-key mode.\n * Ps = 1 0 5 2 -> Set HP function-key mode.\n * Ps = 1 0 5 3 -> Set SCO function-key mode.\n * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Set VT220 keyboard emulation.\n * Ps = 2 0 0 4 -> Set bracketed paste mode.\n * Modes:\n * http: *vt100.net/docs/vt220-rm/chapter4.html\n */\n public setMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.setMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = true;\n break;\n case 20:\n // this._t.convertEol = true;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = true;\n break;\n case 2:\n this._terminal.setgCharset(0, DEFAULT_CHARSET);\n this._terminal.setgCharset(1, DEFAULT_CHARSET);\n this._terminal.setgCharset(2, DEFAULT_CHARSET);\n this._terminal.setgCharset(3, DEFAULT_CHARSET);\n // set VT100 mode here\n break;\n case 3: // 132 col mode\n this._terminal.savedCols = this._terminal.cols;\n this._terminal.resize(132, this._terminal.rows);\n break;\n case 6:\n this._terminal.originMode = true;\n break;\n case 7:\n this._terminal.wraparoundMode = true;\n break;\n case 12:\n // this.cursorBlink = true;\n break;\n case 66:\n this._terminal.log('Serial port requested application keypad.');\n this._terminal.applicationKeypad = true;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n // no release, no motion, no wheel, no modifiers.\n case 1000: // vt200 mouse\n // no motion.\n // no modifiers, except control on the wheel.\n case 1002: // button event mouse\n case 1003: // any event mouse\n // any event - sends motion events,\n // even if there is no button held down.\n\n // TODO: Why are params[0] compares nested within a switch for params[0]?\n\n this._terminal.x10Mouse = params[0] === 9;\n this._terminal.vt200Mouse = params[0] === 1000;\n this._terminal.normalMouse = params[0] > 1000;\n this._terminal.mouseEvents = true;\n this._terminal.element.classList.add('enable-mouse-events');\n this._terminal.selectionManager.disable();\n this._terminal.log('Binding to mouse events.');\n break;\n case 1004: // send focusin/focusout events\n // focusin: ^[[I\n // focusout: ^[[O\n this._terminal.sendFocus = true;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = true;\n // for wide terminals\n // simply encodes large values as utf8 characters\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = true;\n // for wide terminals\n // does not add 32 to fields\n // press: ^[[<b;x;yM\n // release: ^[[<b;x;ym\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = true;\n // for wide terminals\n // numbers for fields\n // press: ^[[b;x;yM\n // motion: ^[[b;x;yT\n break;\n case 25: // show cursor\n this._terminal.cursorHidden = false;\n break;\n case 1049: // alt screen buffer cursor\n // TODO: Not sure if we need to save/restore after switching the buffer\n // this.saveCursor(params);\n // FALL-THROUGH\n case 47: // alt screen buffer\n case 1047: // alt screen buffer\n this._terminal.buffers.activateAltBuffer();\n this._terminal.selectionManager.setBuffer(this._terminal.buffer);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._terminal.bracketedPasteMode = true;\n break;\n }\n }\n }\n\n /**\n * CSI Pm l Reset Mode (RM).\n * Ps = 2 -> Keyboard Action Mode (AM).\n * Ps = 4 -> Replace Mode (IRM).\n * Ps = 1 2 -> Send/receive (SRM).\n * Ps = 2 0 -> Normal Linefeed (LNM).\n * CSI ? Pm l\n * DEC Private Mode Reset (DECRST).\n * Ps = 1 -> Normal Cursor Keys (DECCKM).\n * Ps = 2 -> Designate VT52 mode (DECANM).\n * Ps = 3 -> 80 Column Mode (DECCOLM).\n * Ps = 4 -> Jump (Fast) Scroll (DECSCLM).\n * Ps = 5 -> Normal Video (DECSCNM).\n * Ps = 6 -> Normal Cursor Mode (DECOM).\n * Ps = 7 -> No Wraparound Mode (DECAWM).\n * Ps = 8 -> No Auto-repeat Keys (DECARM).\n * Ps = 9 -> Don't send Mouse X & Y on button press.\n * Ps = 1 0 -> Hide toolbar (rxvt).\n * Ps = 1 2 -> Stop Blinking Cursor (att610).\n * Ps = 1 8 -> Don't print form feed (DECPFF).\n * Ps = 1 9 -> Limit print to scrolling region (DECPEX).\n * Ps = 2 5 -> Hide Cursor (DECTCEM).\n * Ps = 3 0 -> Don't show scrollbar (rxvt).\n * Ps = 3 5 -> Disable font-shifting functions (rxvt).\n * Ps = 4 0 -> Disallow 80 -> 132 Mode.\n * Ps = 4 1 -> No more(1) fix (see curses resource).\n * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-\n * NRCM).\n * Ps = 4 4 -> Turn Off Margin Bell.\n * Ps = 4 5 -> No Reverse-wraparound Mode.\n * Ps = 4 6 -> Stop Logging. (This is normally disabled by a\n * compile-time option).\n * Ps = 4 7 -> Use Normal Screen Buffer.\n * Ps = 6 6 -> Numeric keypad (DECNKM).\n * Ps = 6 7 -> Backarrow key sends delete (DECBKM).\n * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and\n * release. See the section Mouse Tracking.\n * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.\n * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.\n * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.\n * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.\n * Ps = 1 0 0 5 -> Disable Extended Mouse Mode.\n * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output\n * (rxvt).\n * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).\n * Ps = 1 0 3 4 -> Don't interpret \"meta\" key. (This disables\n * the eightBitInput resource).\n * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-\n * Lock keys. (This disables the numLock resource).\n * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.\n * (This disables the metaSendsEscape resource).\n * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad\n * Delete key.\n * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.\n * (This disables the altSendsEscape resource).\n * Ps = 1 0 4 0 -> Do not keep selection when not highlighted.\n * (This disables the keepSelection resource).\n * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables\n * the selectToClipboard resource).\n * Ps = 1 0 4 2 -> Disable Urgency window manager hint when\n * Control-G is received. (This disables the bellIsUrgent\n * resource).\n * Ps = 1 0 4 3 -> Disable raising of the window when Control-\n * G is received. (This disables the popOnBell resource).\n * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen\n * first if in the Alternate Screen. (This may be disabled by\n * the titeInhibit resource).\n * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be\n * disabled by the titeInhibit resource).\n * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor\n * as in DECRC. (This may be disabled by the titeInhibit\n * resource). This combines the effects of the 1 0 4 7 and 1 0\n * 4 8 modes. Use this with terminfo-based applications rather\n * than the 4 7 mode.\n * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.\n * Ps = 1 0 5 1 -> Reset Sun function-key mode.\n * Ps = 1 0 5 2 -> Reset HP function-key mode.\n * Ps = 1 0 5 3 -> Reset SCO function-key mode.\n * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).\n * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.\n * Ps = 2 0 0 4 -> Reset bracketed paste mode.\n */\n public resetMode(params: number[]): void {\n if (params.length > 1) {\n for (let i = 0; i < params.length; i++) {\n this.resetMode([params[i]]);\n }\n\n return;\n }\n\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 4:\n this._terminal.insertMode = false;\n break;\n case 20:\n // this._t.convertEol = false;\n break;\n }\n } else if (this._terminal.prefix === '?') {\n switch (params[0]) {\n case 1:\n this._terminal.applicationCursor = false;\n break;\n case 3:\n if (this._terminal.cols === 132 && this._terminal.savedCols) {\n this._terminal.resize(this._terminal.savedCols, this._terminal.rows);\n }\n delete this._terminal.savedCols;\n break;\n case 6:\n this._terminal.originMode = false;\n break;\n case 7:\n this._terminal.wraparoundMode = false;\n break;\n case 12:\n // this.cursorBlink = false;\n break;\n case 66:\n this._terminal.log('Switching back to normal keypad.');\n this._terminal.applicationKeypad = false;\n this._terminal.viewport.syncScrollArea();\n break;\n case 9: // X10 Mouse\n case 1000: // vt200 mouse\n case 1002: // button event mouse\n case 1003: // any event mouse\n this._terminal.x10Mouse = false;\n this._terminal.vt200Mouse = false;\n this._terminal.normalMouse = false;\n this._terminal.mouseEvents = false;\n this._terminal.element.classList.remove('enable-mouse-events');\n this._terminal.selectionManager.enable();\n break;\n case 1004: // send focusin/focusout events\n this._terminal.sendFocus = false;\n break;\n case 1005: // utf8 ext mode mouse\n this._terminal.utfMouse = false;\n break;\n case 1006: // sgr ext mode mouse\n this._terminal.sgrMouse = false;\n break;\n case 1015: // urxvt ext mode mouse\n this._terminal.urxvtMouse = false;\n break;\n case 25: // hide cursor\n this._terminal.cursorHidden = true;\n break;\n case 1049: // alt screen buffer cursor\n // FALL-THROUGH\n case 47: // normal screen buffer\n case 1047: // normal screen buffer - clearing it first\n // Ensure the selection manager has the correct buffer\n this._terminal.buffers.activateNormalBuffer();\n // TODO: Not sure if we need to save/restore after switching the buffer\n // if (params[0] === 1049) {\n // this.restoreCursor(params);\n // }\n this._terminal.selectionManager.setBuffer(this._terminal.buffer);\n this._terminal.refresh(0, this._terminal.rows - 1);\n this._terminal.viewport.syncScrollArea();\n this._terminal.showCursor();\n break;\n case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)\n this._terminal.bracketedPasteMode = false;\n break;\n }\n }\n }\n\n /**\n * CSI Pm m Character Attributes (SGR).\n * Ps = 0 -> Normal (default).\n * Ps = 1 -> Bold.\n * Ps = 2 -> Faint, decreased intensity (ISO 6429).\n * Ps = 4 -> Underlined.\n * Ps = 5 -> Blink (appears as Bold).\n * Ps = 7 -> Inverse.\n * Ps = 8 -> Invisible, i.e., hidden (VT300).\n * Ps = 2 2 -> Normal (neither bold nor faint).\n * Ps = 2 4 -> Not underlined.\n * Ps = 2 5 -> Steady (not blinking).\n * Ps = 2 7 -> Positive (not inverse).\n * Ps = 2 8 -> Visible, i.e., not hidden (VT300).\n * Ps = 3 0 -> Set foreground color to Black.\n * Ps = 3 1 -> Set foreground color to Red.\n * Ps = 3 2 -> Set foreground color to Green.\n * Ps = 3 3 -> Set foreground color to Yellow.\n * Ps = 3 4 -> Set foreground color to Blue.\n * Ps = 3 5 -> Set foreground color to Magenta.\n * Ps = 3 6 -> Set foreground color to Cyan.\n * Ps = 3 7 -> Set foreground color to White.\n * Ps = 3 9 -> Set foreground color to default (original).\n * Ps = 4 0 -> Set background color to Black.\n * Ps = 4 1 -> Set background color to Red.\n * Ps = 4 2 -> Set background color to Green.\n * Ps = 4 3 -> Set background color to Yellow.\n * Ps = 4 4 -> Set background color to Blue.\n * Ps = 4 5 -> Set background color to Magenta.\n * Ps = 4 6 -> Set background color to Cyan.\n * Ps = 4 7 -> Set background color to White.\n * Ps = 4 9 -> Set background color to default (original).\n *\n * If 16-color support is compiled, the following apply. Assume\n * that xterm's resources are set so that the ISO color codes are\n * the first 8 of a set of 16. Then the aixterm colors are the\n * bright versions of the ISO colors:\n * Ps = 9 0 -> Set foreground color to Black.\n * Ps = 9 1 -> Set foreground color to Red.\n * Ps = 9 2 -> Set foreground color to Green.\n * Ps = 9 3 -> Set foreground color to Yellow.\n * Ps = 9 4 -> Set foreground color to Blue.\n * Ps = 9 5 -> Set foreground color to Magenta.\n * Ps = 9 6 -> Set foreground color to Cyan.\n * Ps = 9 7 -> Set foreground color to White.\n * Ps = 1 0 0 -> Set background color to Black.\n * Ps = 1 0 1 -> Set background color to Red.\n * Ps = 1 0 2 -> Set background color to Green.\n * Ps = 1 0 3 -> Set background color to Yellow.\n * Ps = 1 0 4 -> Set background color to Blue.\n * Ps = 1 0 5 -> Set background color to Magenta.\n * Ps = 1 0 6 -> Set background color to Cyan.\n * Ps = 1 0 7 -> Set background color to White.\n *\n * If xterm is compiled with the 16-color support disabled, it\n * supports the following, from rxvt:\n * Ps = 1 0 0 -> Set foreground and background color to\n * default.\n *\n * If 88- or 256-color support is compiled, the following apply.\n * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second\n * Ps.\n * Ps = 4 8 ; 5 ; Ps -> Set background color to the second\n * Ps.\n */\n public charAttributes(params: number[]): void {\n // Optimize a single SGR0.\n if (params.length === 1 && params[0] === 0) {\n this._terminal.curAttr = this._terminal.defAttr;\n return;\n }\n\n const l = params.length;\n let flags = this._terminal.curAttr >> 18;\n let fg = (this._terminal.curAttr >> 9) & 0x1ff;\n let bg = this._terminal.curAttr & 0x1ff;\n let p;\n\n for (let i = 0; i < l; i++) {\n p = params[i];\n if (p >= 30 && p <= 37) {\n // fg color 8\n fg = p - 30;\n } else if (p >= 40 && p <= 47) {\n // bg color 8\n bg = p - 40;\n } else if (p >= 90 && p <= 97) {\n // fg color 16\n p += 8;\n fg = p - 90;\n } else if (p >= 100 && p <= 107) {\n // bg color 16\n p += 8;\n bg = p - 100;\n } else if (p === 0) {\n // default\n flags = this._terminal.defAttr >> 18;\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n // flags = 0;\n // fg = 0x1ff;\n // bg = 0x1ff;\n } else if (p === 1) {\n // bold text\n flags |= FLAGS.BOLD;\n } else if (p === 4) {\n // underlined text\n flags |= FLAGS.UNDERLINE;\n } else if (p === 5) {\n // blink\n flags |= FLAGS.BLINK;\n } else if (p === 7) {\n // inverse and positive\n // test with: echo -e '\\e[31m\\e[42mhello\\e[7mworld\\e[27mhi\\e[m'\n flags |= FLAGS.INVERSE;\n } else if (p === 8) {\n // invisible\n flags |= FLAGS.INVISIBLE;\n } else if (p === 2) {\n // dimmed text\n flags |= FLAGS.DIM;\n } else if (p === 22) {\n // not bold nor faint\n flags &= ~FLAGS.BOLD;\n flags &= ~FLAGS.DIM;\n } else if (p === 24) {\n // not underlined\n flags &= ~FLAGS.UNDERLINE;\n } else if (p === 25) {\n // not blink\n flags &= ~FLAGS.BLINK;\n } else if (p === 27) {\n // not inverse\n flags &= ~FLAGS.INVERSE;\n } else if (p === 28) {\n // not invisible\n flags &= ~FLAGS.INVISIBLE;\n } else if (p === 39) {\n // reset fg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n } else if (p === 49) {\n // reset bg\n bg = this._terminal.defAttr & 0x1ff;\n } else if (p === 38) {\n // fg color 256\n if (params[i + 1] === 2) {\n i += 2;\n fg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (fg === -1) fg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n fg = p;\n }\n } else if (p === 48) {\n // bg color 256\n if (params[i + 1] === 2) {\n i += 2;\n bg = this._terminal.matchColor(\n params[i] & 0xff,\n params[i + 1] & 0xff,\n params[i + 2] & 0xff);\n if (bg === -1) bg = 0x1ff;\n i += 2;\n } else if (params[i + 1] === 5) {\n i += 2;\n p = params[i] & 0xff;\n bg = p;\n }\n } else if (p === 100) {\n // reset fg/bg\n fg = (this._terminal.defAttr >> 9) & 0x1ff;\n bg = this._terminal.defAttr & 0x1ff;\n } else {\n this._terminal.error('Unknown SGR attribute: %d.', p);\n }\n }\n\n this._terminal.curAttr = (flags << 18) | (fg << 9) | bg;\n }\n\n /**\n * CSI Ps n Device Status Report (DSR).\n * Ps = 5 -> Status Report. Result (``OK'') is\n * CSI 0 n\n * Ps = 6 -> Report Cursor Position (CPR) [row;column].\n * Result is\n * CSI r ; c R\n * CSI ? Ps n\n * Device Status Report (DSR, DEC-specific).\n * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI\n * ? r ; c R (assumes page is zero).\n * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).\n * or CSI ? 1 1 n (not ready).\n * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)\n * or CSI ? 2 1 n (locked).\n * Ps = 2 6 -> Report Keyboard status as\n * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).\n * The last two parameters apply to VT400 & up, and denote key-\n * board ready and LK01 respectively.\n * Ps = 5 3 -> Report Locator status as\n * CSI ? 5 3 n Locator available, if compiled-in, or\n * CSI ? 5 0 n No Locator, if not.\n */\n public deviceStatus(params: number[]): void {\n if (!this._terminal.prefix) {\n switch (params[0]) {\n case 5:\n // status report\n this._terminal.send(C0.ESC + '[0n');\n break;\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '['\n + (this._terminal.buffer.y + 1)\n + ';'\n + (this._terminal.buffer.x + 1)\n + 'R');\n break;\n }\n } else if (this._terminal.prefix === '?') {\n // modern xterm doesnt seem to\n // respond to any of these except ?6, 6, and 5\n switch (params[0]) {\n case 6:\n // cursor position\n this._terminal.send(C0.ESC + '[?'\n + (this._terminal.buffer.y + 1)\n + ';'\n + (this._terminal.buffer.x + 1)\n + 'R');\n break;\n case 15:\n // no printer\n // this.send(C0.ESC + '[?11n');\n break;\n case 25:\n // dont support user defined keys\n // this.send(C0.ESC + '[?21n');\n break;\n case 26:\n // north american keyboard\n // this.send(C0.ESC + '[?27;1;0;0n');\n break;\n case 53:\n // no dec locator/mouse\n // this.send(C0.ESC + '[?50n');\n break;\n }\n }\n }\n\n /**\n * CSI ! p Soft terminal reset (DECSTR).\n * http://vt100.net/docs/vt220-rm/table4-10.html\n */\n public softReset(params: number[]): void {\n this._terminal.cursorHidden = false;\n this._terminal.insertMode = false;\n this._terminal.originMode = false;\n this._terminal.wraparoundMode = true; // defaults: xterm - true, vt100 - false\n this._terminal.applicationKeypad = false; // ?\n this._terminal.viewport.syncScrollArea();\n this._terminal.applicationCursor = false;\n this._terminal.buffer.scrollTop = 0;\n this._terminal.buffer.scrollBottom = this._terminal.rows - 1;\n this._terminal.curAttr = this._terminal.defAttr;\n this._terminal.buffer.x = this._terminal.buffer.y = 0; // ?\n this._terminal.charset = null;\n this._terminal.glevel = 0; // ??\n this._terminal.charsets = [null]; // ??\n }\n\n /**\n * CSI Ps SP q Set cursor style (DECSCUSR, VT520).\n * Ps = 0 -> blinking block.\n * Ps = 1 -> blinking block (default).\n * Ps = 2 -> steady block.\n * Ps = 3 -> blinking underline.\n * Ps = 4 -> steady underline.\n * Ps = 5 -> blinking bar (xterm).\n * Ps = 6 -> steady bar (xterm).\n */\n public setCursorStyle(params?: number[]): void {\n const param = params[0] < 1 ? 1 : params[0];\n switch (param) {\n case 1:\n case 2:\n this._terminal.setOption('cursorStyle', 'block');\n break;\n case 3:\n case 4:\n this._terminal.setOption('cursorStyle', 'underline');\n break;\n case 5:\n case 6:\n this._terminal.setOption('cursorStyle', 'bar');\n break;\n }\n const isBlinking = param % 2 === 1;\n this._terminal.setOption('cursorBlink', isBlinking);\n }\n\n /**\n * CSI Ps ; Ps r\n * Set Scrolling Region [top;bottom] (default = full size of win-\n * dow) (DECSTBM).\n * CSI ? Pm r\n */\n public setScrollRegion(params: number[]): void {\n if (this._terminal.prefix) return;\n this._terminal.buffer.scrollTop = (params[0] || 1) - 1;\n this._terminal.buffer.scrollBottom = (params[1] && params[1] <= this._terminal.rows ? params[1] : this._terminal.rows) - 1;\n this._terminal.buffer.x = 0;\n this._terminal.buffer.y = 0;\n }\n\n\n /**\n * CSI s\n * Save cursor (ANSI.SYS).\n */\n public saveCursor(params: number[]): void {\n this._terminal.buffer.savedX = this._terminal.buffer.x;\n this._terminal.buffer.savedY = this._terminal.buffer.y;\n }\n\n\n /**\n * CSI u\n * Restore cursor (ANSI.SYS).\n */\n public restoreCursor(params: number[]): void {\n this._terminal.buffer.x = this._terminal.buffer.savedX || 0;\n this._terminal.buffer.y = this._terminal.buffer.savedY || 0;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IEventEmitter, IListenerType } from './Interfaces';\n\nexport class EventEmitter implements IEventEmitter {\n private _events: {[type: string]: IListenerType[]};\n\n constructor() {\n // Restore the previous events if available, this will happen if the\n // constructor is called multiple times on the same object (terminal reset).\n this._events = this._events || {};\n }\n\n public on(type: string, listener: IListenerType): void {\n this._events[type] = this._events[type] || [];\n this._events[type].push(listener);\n }\n\n public off(type: string, listener: IListenerType): void {\n if (!this._events[type]) {\n return;\n }\n\n let obj = this._events[type];\n let i = obj.length;\n\n while (i--) {\n if (obj[i] === listener || obj[i].listener === listener) {\n obj.splice(i, 1);\n return;\n }\n }\n }\n\n public removeAllListeners(type: string): void {\n if (this._events[type]) {\n delete this._events[type];\n }\n }\n\n public once(type: string, listener: IListenerType): void {\n function on(): void {\n let args = Array.prototype.slice.call(arguments);\n this.off(type, on);\n listener.apply(this, args);\n }\n (<any>on).listener = listener;\n this.on(type, on);\n }\n\n public emit(type: string, ...args: any[]): void {\n if (!this._events[type]) {\n return;\n }\n let obj = this._events[type];\n for (let i = 0; i < obj.length; i++) {\n obj[i].apply(this, args);\n }\n }\n\n public listeners(type: string): IListenerType[] {\n return this._events[type] || [];\n }\n\n protected destroy(): void {\n this._events = {};\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * C0 control codes\n * See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes\n */\nexport namespace C0 {\n /** Null (Caret = ^@, C = \\0) */\n export const NUL = '\\x00';\n /** Start of Heading (Caret = ^A) */\n export const SOH = '\\x01';\n /** Start of Text (Caret = ^B) */\n export const STX = '\\x02';\n /** End of Text (Caret = ^C) */\n export const ETX = '\\x03';\n /** End of Transmission (Caret = ^D) */\n export const EOT = '\\x04';\n /** Enquiry (Caret = ^E) */\n export const ENQ = '\\x05';\n /** Acknowledge (Caret = ^F) */\n export const ACK = '\\x06';\n /** Bell (Caret = ^G, C = \\a) */\n export const BEL = '\\x07';\n /** Backspace (Caret = ^H, C = \\b) */\n export const BS = '\\x08';\n /** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \\t) */\n export const HT = '\\x09';\n /** Line Feed (Caret = ^J, C = \\n) */\n export const LF = '\\x0a';\n /** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \\v) */\n export const VT = '\\x0b';\n /** Form Feed (Caret = ^L, C = \\f) */\n export const FF = '\\x0c';\n /** Carriage Return (Caret = ^M, C = \\r) */\n export const CR = '\\x0d';\n /** Shift Out (Caret = ^N) */\n export const SO = '\\x0e';\n /** Shift In (Caret = ^O) */\n export const SI = '\\x0f';\n /** Data Link Escape (Caret = ^P) */\n export const DLE = '\\x10';\n /** Device Control One (XON) (Caret = ^Q) */\n export const DC1 = '\\x11';\n /** Device Control Two (Caret = ^R) */\n export const DC2 = '\\x12';\n /** Device Control Three (XOFF) (Caret = ^S) */\n export const DC3 = '\\x13';\n /** Device Control Four (Caret = ^T) */\n export const DC4 = '\\x14';\n /** Negative Acknowledge (Caret = ^U) */\n export const NAK = '\\x15';\n /** Synchronous Idle (Caret = ^V) */\n export const SYN = '\\x16';\n /** End of Transmission Block (Caret = ^W) */\n export const ETB = '\\x17';\n /** Cancel (Caret = ^X) */\n export const CAN = '\\x18';\n /** End of Medium (Caret = ^Y) */\n export const EM = '\\x19';\n /** Substitute (Caret = ^Z) */\n export const SUB = '\\x1a';\n /** Escape (Caret = ^[, C = \\e) */\n export const ESC = '\\x1b';\n /** File Separator (Caret = ^\\) */\n export const FS = '\\x1c';\n /** Group Separator (Caret = ^]) */\n export const GS = '\\x1d';\n /** Record Separator (Caret = ^^) */\n export const RS = '\\x1e';\n /** Unit Separator (Caret = ^_) */\n export const US = '\\x1f';\n /** Space */\n export const SP = '\\x20';\n /** Delete (Caret = ^?) */\n export const DEL = '\\x7f';\n};\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal } from './Interfaces';\n\ninterface IPosition {\n start: number;\n end: number;\n}\n\n/**\n * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend\n * events, displaying the in-progress composition to the UI and forwarding the final composition\n * to the handler.\n */\nexport class CompositionHelper {\n /**\n * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or\n * IME. This variable determines whether the compositionText should be displayed on the UI.\n */\n private isComposing: boolean;\n\n /**\n * The position within the input textarea's value of the current composition.\n */\n private compositionPosition: IPosition;\n\n /**\n * Whether a composition is in the process of being sent, setting this to false will cancel any\n * in-progress composition.\n */\n private isSendingComposition: boolean;\n\n /**\n * Creates a new CompositionHelper.\n * @param textarea The textarea that xterm uses for input.\n * @param compositionView The element to display the in-progress composition in.\n * @param terminal The Terminal to forward the finished composition to.\n */\n constructor(\n private textarea: HTMLTextAreaElement,\n private compositionView: HTMLElement,\n private terminal: ITerminal\n ) {\n this.isComposing = false;\n this.isSendingComposition = false;\n this.compositionPosition = { start: null, end: null };\n }\n\n /**\n * Handles the compositionstart event, activating the composition view.\n */\n public compositionstart(): void {\n this.isComposing = true;\n this.compositionPosition.start = this.textarea.value.length;\n this.compositionView.textContent = '';\n this.compositionView.classList.add('active');\n }\n\n /**\n * Handles the compositionupdate event, updating the composition view.\n * @param {CompositionEvent} ev The event.\n */\n public compositionupdate(ev: CompositionEvent): void {\n this.compositionView.textContent = ev.data;\n this.updateCompositionElements();\n setTimeout(() => {\n this.compositionPosition.end = this.textarea.value.length;\n }, 0);\n }\n\n /**\n * Handles the compositionend event, hiding the composition view and sending the composition to\n * the handler.\n */\n public compositionend(): void {\n this.finalizeComposition(true);\n }\n\n /**\n * Handles the keydown event, routing any necessary events to the CompositionHelper functions.\n * @param ev The keydown event.\n * @return Whether the Terminal should continue processing the keydown event.\n */\n public keydown(ev: KeyboardEvent): boolean {\n if (this.isComposing || this.isSendingComposition) {\n if (ev.keyCode === 229) {\n // Continue composing if the keyCode is the \"composition character\"\n return false;\n } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {\n // Continue composing if the keyCode is a modifier key\n return false;\n } else {\n // Finish composition immediately. This is mainly here for the case where enter is\n // pressed and the handler needs to be triggered before the command is executed.\n this.finalizeComposition(false);\n }\n }\n\n if (ev.keyCode === 229) {\n // If the \"composition character\" is used but gets to this point it means a non-composition\n // character (eg. numbers and punctuation) was pressed when the IME was active.\n this.handleAnyTextareaChanges();\n return false;\n }\n\n return true;\n }\n\n /**\n * Finalizes the composition, resuming regular input actions. This is called when a composition\n * is ending.\n * @param waitForPropogation Whether to wait for events to propogate before sending\n * the input. This should be false if a non-composition keystroke is entered before the\n * compositionend event is triggered, such as enter, so that the composition is send before\n * the command is executed.\n */\n private finalizeComposition(waitForPropogation: boolean): void {\n this.compositionView.classList.remove('active');\n this.isComposing = false;\n this.clearTextareaPosition();\n\n if (!waitForPropogation) {\n // Cancel any delayed composition send requests and send the input immediately.\n this.isSendingComposition = false;\n const input = this.textarea.value.substring(this.compositionPosition.start, this.compositionPosition.end);\n this.terminal.handler(input);\n } else {\n // Make a deep copy of the composition position here as a new compositionstart event may\n // fire before the setTimeout executes.\n const currentCompositionPosition = {\n start: this.compositionPosition.start,\n end: this.compositionPosition.end,\n };\n\n // Since composition* events happen before the changes take place in the textarea on most\n // browsers, use a setTimeout with 0ms time to allow the native compositionend event to\n // complete. This ensures the correct character is retrieved, this solution was used\n // because:\n // - The compositionend event's data property is unreliable, at least on Chromium\n // - The last compositionupdate event's data property does not always accurately describe\n // the character, a counter example being Korean where an ending consonsant can move to\n // the following character if the following input is a vowel.\n this.isSendingComposition = true;\n setTimeout(() => {\n // Ensure that the input has not already been sent\n if (this.isSendingComposition) {\n this.isSendingComposition = false;\n let input;\n if (this.isComposing) {\n // Use the end position to get the string if a new composition has started.\n input = this.textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);\n } else {\n // Don't use the end position here in order to pick up any characters after the\n // composition has finished, for example when typing a non-composition character\n // (eg. 2) after a composition character.\n input = this.textarea.value.substring(currentCompositionPosition.start);\n }\n this.terminal.handler(input);\n }\n }, 0);\n }\n }\n\n /**\n * Apply any changes made to the textarea after the current event chain is allowed to complete.\n * This should be called when not currently composing but a keydown event with the \"composition\n * character\" (229) is triggered, in order to allow non-composition text to be entered when an\n * IME is active.\n */\n private handleAnyTextareaChanges(): void {\n const oldValue = this.textarea.value;\n setTimeout(() => {\n // Ignore if a composition has started since the timeout\n if (!this.isComposing) {\n const newValue = this.textarea.value;\n const diff = newValue.replace(oldValue, '');\n if (diff.length > 0) {\n this.terminal.handler(diff);\n }\n }\n }, 0);\n }\n\n /**\n * Positions the composition view on top of the cursor and the textarea just below it (so the\n * IME helper dialog is positioned correctly).\n * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is\n * necessary as the IME events across browsers are not consistently triggered.\n */\n public updateCompositionElements(dontRecurse?: boolean): void {\n if (!this.isComposing) {\n return;\n }\n\n if (this.terminal.buffer.isCursorInViewport) {\n const cellHeight = Math.ceil(this.terminal.charMeasure.height * this.terminal.options.lineHeight);\n const cursorTop = this.terminal.buffer.y * cellHeight;\n const cursorLeft = this.terminal.buffer.x * this.terminal.charMeasure.width;\n\n this.compositionView.style.left = cursorLeft + 'px';\n this.compositionView.style.top = cursorTop + 'px';\n this.compositionView.style.height = cellHeight + 'px';\n this.compositionView.style.lineHeight = cellHeight + 'px';\n // Sync the textarea to the exact position of the composition view so the IME knows where the\n // text is.\n const compositionViewBounds = this.compositionView.getBoundingClientRect();\n this.textarea.style.left = cursorLeft + 'px';\n this.textarea.style.top = cursorTop + 'px';\n this.textarea.style.width = compositionViewBounds.width + 'px';\n this.textarea.style.height = compositionViewBounds.height + 'px';\n this.textarea.style.lineHeight = compositionViewBounds.height + 'px';\n }\n\n if (!dontRecurse) {\n setTimeout(() => this.updateCompositionElements(true), 0);\n }\n };\n\n /**\n * Clears the textarea's position so that the cursor does not blink on IE.\n * @private\n */\n private clearTextareaPosition(): void {\n this.textarea.style.left = '';\n this.textarea.style.top = '';\n };\n}\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { Charset } from './Types';\n\n/**\n * The character sets supported by the terminal. These enable several languages\n * to be represented within the terminal with only 8-bit encoding. See ISO 2022\n * for a discussion on character sets. Only VT100 character sets are supported.\n */\nexport const CHARSETS: { [key: string]: Charset } = {};\n\n/**\n * The default character set, US.\n */\nexport const DEFAULT_CHARSET: Charset = CHARSETS['B'];\n\n/**\n * DEC Special Character and Line Drawing Set.\n * Reference: http://vt100.net/docs/vt102-ug/table5-13.html\n * A lot of curses apps use this if they see TERM=xterm.\n * testing: echo -e '\\e(0a\\e(B'\n * The xterm output sometimes seems to conflict with the\n * reference above. xterm seems in line with the reference\n * when running vttest however.\n * The table below now uses xterm's output from vttest.\n */\nCHARSETS['0'] = {\n '`': '\\u25c6', // '◆'\n 'a': '\\u2592', // '▒'\n 'b': '\\u0009', // '\\t'\n 'c': '\\u000c', // '\\f'\n 'd': '\\u000d', // '\\r'\n 'e': '\\u000a', // '\\n'\n 'f': '\\u00b0', // '°'\n 'g': '\\u00b1', // '±'\n 'h': '\\u2424', // '\\u2424' (NL)\n 'i': '\\u000b', // '\\v'\n 'j': '\\u2518', // '┘'\n 'k': '\\u2510', // '┐'\n 'l': '\\u250c', // '┌'\n 'm': '\\u2514', // '└'\n 'n': '\\u253c', // '┼'\n 'o': '\\u23ba', // '⎺'\n 'p': '\\u23bb', // '⎻'\n 'q': '\\u2500', // '─'\n 'r': '\\u23bc', // '⎼'\n 's': '\\u23bd', // '⎽'\n 't': '\\u251c', // '├'\n 'u': '\\u2524', // '┤'\n 'v': '\\u2534', // '┴'\n 'w': '\\u252c', // '┬'\n 'x': '\\u2502', // '│'\n 'y': '\\u2264', // '≤'\n 'z': '\\u2265', // '≥'\n '{': '\\u03c0', // 'π'\n '|': '\\u2260', // '≠'\n '}': '\\u00a3', // '£'\n '~': '\\u00b7' // '·'\n};\n\n/**\n * British character set\n * ESC (A\n * Reference: http://vt100.net/docs/vt220-rm/table2-5.html\n */\nCHARSETS['A'] = {\n '#': '£'\n};\n\n/**\n * United States character set\n * ESC (B\n */\nCHARSETS['B'] = null;\n\n/**\n * Dutch character set\n * ESC (4\n * Reference: http://vt100.net/docs/vt220-rm/table2-6.html\n */\nCHARSETS['4'] = {\n '#': '£',\n '@': '¾',\n '[': 'ij',\n '\\\\': '½',\n ']': '|',\n '{': '¨',\n '|': 'f',\n '}': '¼',\n '~': '´'\n};\n\n/**\n * Finnish character set\n * ESC (C or ESC (5\n * Reference: http://vt100.net/docs/vt220-rm/table2-7.html\n */\nCHARSETS['C'] =\nCHARSETS['5'] = {\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * French character set\n * ESC (R\n * Reference: http://vt100.net/docs/vt220-rm/table2-8.html\n */\nCHARSETS['R'] = {\n '#': '£',\n '@': 'à',\n '[': '°',\n '\\\\': 'ç',\n ']': '§',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': '¨'\n};\n\n/**\n * French Canadian character set\n * ESC (Q\n * Reference: http://vt100.net/docs/vt220-rm/table2-9.html\n */\nCHARSETS['Q'] = {\n '@': 'à',\n '[': 'â',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '`': 'ô',\n '{': 'é',\n '|': 'ù',\n '}': 'è',\n '~': 'û'\n};\n\n/**\n * German character set\n * ESC (K\n * Reference: http://vt100.net/docs/vt220-rm/table2-10.html\n */\nCHARSETS['K'] = {\n '@': '§',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Ü',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'ß'\n};\n\n/**\n * Italian character set\n * ESC (Y\n * Reference: http://vt100.net/docs/vt220-rm/table2-11.html\n */\nCHARSETS['Y'] = {\n '#': '£',\n '@': '§',\n '[': '°',\n '\\\\': 'ç',\n ']': 'é',\n '`': 'ù',\n '{': 'à',\n '|': 'ò',\n '}': 'è',\n '~': 'ì'\n};\n\n/**\n * Norwegian/Danish character set\n * ESC (E or ESC (6\n * Reference: http://vt100.net/docs/vt220-rm/table2-12.html\n */\nCHARSETS['E'] =\nCHARSETS['6'] = {\n '@': 'Ä',\n '[': 'Æ',\n '\\\\': 'Ø',\n ']': 'Å',\n '^': 'Ü',\n '`': 'ä',\n '{': 'æ',\n '|': 'ø',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Spanish character set\n * ESC (Z\n * Reference: http://vt100.net/docs/vt220-rm/table2-13.html\n */\nCHARSETS['Z'] = {\n '#': '£',\n '@': '§',\n '[': '¡',\n '\\\\': 'Ñ',\n ']': '¿',\n '{': '°',\n '|': 'ñ',\n '}': 'ç'\n};\n\n/**\n * Swedish character set\n * ESC (H or ESC (7\n * Reference: http://vt100.net/docs/vt220-rm/table2-14.html\n */\nCHARSETS['H'] =\nCHARSETS['7'] = {\n '@': 'É',\n '[': 'Ä',\n '\\\\': 'Ö',\n ']': 'Å',\n '^': 'Ü',\n '`': 'é',\n '{': 'ä',\n '|': 'ö',\n '}': 'å',\n '~': 'ü'\n};\n\n/**\n * Swiss character set\n * ESC (=\n * Reference: http://vt100.net/docs/vt220-rm/table2-15.html\n */\nCHARSETS['='] = {\n '#': 'ù',\n '@': 'à',\n '[': 'é',\n '\\\\': 'ç',\n ']': 'ê',\n '^': 'î',\n '_': 'è',\n '`': 'ô',\n '{': 'ä',\n '|': 'ö',\n '}': 'ü',\n '~': 'û'\n};\n","/**\n * Copyright (c) 2016 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nexport const wcwidth = (function(opts: {nul: number, control: number}): (ucs: number) => number {\n // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c\n // combining characters\n const COMBINING_BMP = [\n [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489],\n [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2],\n [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603],\n [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670],\n [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED],\n [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A],\n [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902],\n [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D],\n [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981],\n [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD],\n [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C],\n [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D],\n [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC],\n [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD],\n [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C],\n [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D],\n [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0],\n [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48],\n [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC],\n [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD],\n [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D],\n [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6],\n [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E],\n [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC],\n [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35],\n [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E],\n [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97],\n [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030],\n [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039],\n [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F],\n [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753],\n [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD],\n [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD],\n [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922],\n [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B],\n [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34],\n [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42],\n [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF],\n [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063],\n [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F],\n [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B],\n [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F],\n [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB],\n ];\n const COMBINING_HIGH = [\n [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F],\n [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169],\n [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD],\n [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F],\n [0xE0100, 0xE01EF]\n ];\n // binary search\n function bisearch(ucs: number, data: number[][]): boolean {\n let min = 0;\n let max = data.length - 1;\n let mid;\n if (ucs < data[0][0] || ucs > data[max][1])\n return false;\n while (max >= min) {\n mid = (min + max) >> 1;\n if (ucs > data[mid][1])\n min = mid + 1;\n else if (ucs < data[mid][0])\n max = mid - 1;\n else\n return true;\n }\n return false;\n }\n function wcwidthBMP(ucs: number): number {\n // test for 8-bit control characters\n if (ucs === 0)\n return opts.nul;\n if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))\n return opts.control;\n // binary search in table of non-spacing characters\n if (bisearch(ucs, COMBINING_BMP))\n return 0;\n // if we arrive here, ucs is not a combining or C0/C1 control character\n if (isWideBMP(ucs)) {\n return 2;\n }\n return 1;\n }\n function isWideBMP(ucs: number): boolean {\n return (\n ucs >= 0x1100 && (\n ucs <= 0x115f || // Hangul Jamo init. consonants\n ucs === 0x2329 ||\n ucs === 0x232a ||\n (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs !== 0x303f) || // CJK..Yi\n (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables\n (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compat Ideographs\n (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms\n (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compat Forms\n (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms\n (ucs >= 0xffe0 && ucs <= 0xffe6)));\n }\n function wcwidthHigh(ucs: number): 0 | 1 | 2 {\n if (bisearch(ucs, COMBINING_HIGH))\n return 0;\n if ((ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd)) {\n return 2;\n }\n return 1;\n }\n const control = opts.control | 0;\n let table: number[] | Uint32Array = null;\n function init_table(): number[] | Uint32Array {\n // lookup table for BMP\n const CODEPOINTS = 65536; // BMP holds 65536 codepoints\n const BITWIDTH = 2; // a codepoint can have a width of 0, 1 or 2\n const ITEMSIZE = 32; // using uint32_t\n const CONTAINERSIZE = CODEPOINTS * BITWIDTH / ITEMSIZE;\n const CODEPOINTS_PER_ITEM = ITEMSIZE / BITWIDTH;\n table = (typeof Uint32Array === 'undefined')\n ? new Array(CONTAINERSIZE)\n : new Uint32Array(CONTAINERSIZE);\n for (let i = 0; i < CONTAINERSIZE; ++i) {\n let num = 0;\n let pos = CODEPOINTS_PER_ITEM;\n while (pos--)\n num = (num << 2) | wcwidthBMP(CODEPOINTS_PER_ITEM * i + pos);\n table[i] = num;\n }\n return table;\n }\n // get width from lookup table\n // position in container : num / CODEPOINTS_PER_ITEM\n // ==> n = table[Math.floor(num / 16)]\n // ==> n = table[num >> 4]\n // 16 codepoints per number: FFEEDDCCBBAA99887766554433221100\n // position in number : (num % CODEPOINTS_PER_ITEM) * BITWIDTH\n // ==> m = (n % 16) * 2\n // ==> m = (num & 15) << 1\n // right shift to position m\n // ==> n = n >> m e.g. m=12 000000000000FFEEDDCCBBAA99887766\n // we are only interested in 2 LSBs, cut off higher bits\n // ==> n = n & 3 e.g. 000000000000000000000000000000XX\n return function (num: number): number {\n num = num | 0; // get asm.js like optimization under V8\n if (num < 32)\n return control | 0;\n if (num < 127)\n return 1;\n let t = table || init_table();\n if (num < 65536)\n return t[num >> 4] >> ((num & 15) << 1) & 3;\n // do a full search for high codepoints\n return wcwidthHigh(num);\n };\n})({nul: 0, control: 0}); // configurable options\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, IBufferSet } from './Interfaces';\nimport { Buffer } from './Buffer';\nimport { EventEmitter } from './EventEmitter';\n\n/**\n * The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and\n * provides also utilities for working with them.\n */\nexport class BufferSet extends EventEmitter implements IBufferSet {\n private _normal: Buffer;\n private _alt: Buffer;\n private _activeBuffer: Buffer;\n\n /**\n * Create a new BufferSet for the given terminal.\n * @param {Terminal} terminal - The terminal the BufferSet will belong to\n */\n constructor(private _terminal: ITerminal) {\n super();\n this._normal = new Buffer(this._terminal, true);\n this._normal.fillViewportRows();\n\n // The alt buffer should never have scrollback.\n // See http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer\n this._alt = new Buffer(this._terminal, false);\n this._activeBuffer = this._normal;\n\n this.setupTabStops();\n }\n\n /**\n * Returns the alt Buffer of the BufferSet\n * @returns {Buffer}\n */\n public get alt(): Buffer {\n return this._alt;\n }\n\n /**\n * Returns the normal Buffer of the BufferSet\n * @returns {Buffer}\n */\n public get active(): Buffer {\n return this._activeBuffer;\n }\n\n /**\n * Returns the currently active Buffer of the BufferSet\n * @returns {Buffer}\n */\n public get normal(): Buffer {\n return this._normal;\n }\n\n /**\n * Sets the normal Buffer of the BufferSet as its currently active Buffer\n */\n public activateNormalBuffer(): void {\n // The alt buffer should always be cleared when we switch to the normal\n // buffer. This frees up memory since the alt buffer should always be new\n // when activated.\n this._alt.clear();\n\n this._activeBuffer = this._normal;\n this.emit('activate', this._normal);\n }\n\n /**\n * Sets the alt Buffer of the BufferSet as its currently active Buffer\n */\n public activateAltBuffer(): void {\n // Since the alt buffer is always cleared when the normal buffer is\n // activated, we want to fill it when switching to it.\n this._alt.fillViewportRows();\n this._activeBuffer = this._alt;\n this.emit('activate', this._alt);\n }\n\n /**\n * Resizes both normal and alt buffers, adjusting their data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n this._normal.resize(newCols, newRows);\n this._alt.resize(newCols, newRows);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n this._normal.setupTabStops(i);\n this._alt.setupTabStops(i);\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { ITerminal, IBuffer } from './Interfaces';\nimport { CircularList } from './utils/CircularList';\nimport { LineData, CharData } from './Types';\n\nexport const CHAR_DATA_ATTR_INDEX = 0;\nexport const CHAR_DATA_CHAR_INDEX = 1;\nexport const CHAR_DATA_WIDTH_INDEX = 2;\nexport const CHAR_DATA_CODE_INDEX = 3;\nexport const MAX_BUFFER_SIZE = 4294967295; // 2^32 - 1\n\n/**\n * This class represents a terminal buffer (an internal state of the terminal), where the\n * following information is stored (in high-level):\n * - text content of this particular buffer\n * - cursor position\n * - scroll position\n */\nexport class Buffer implements IBuffer {\n private _lines: CircularList<LineData>;\n\n public ydisp: number;\n public ybase: number;\n public y: number;\n public x: number;\n public scrollBottom: number;\n public scrollTop: number;\n public tabs: any;\n public savedY: number;\n public savedX: number;\n\n /**\n * Create a new Buffer.\n * @param _terminal The terminal the Buffer will belong to.\n * @param _hasScrollback Whether the buffer should respect the scrollback of\n * the terminal.\n */\n constructor(\n private _terminal: ITerminal,\n private _hasScrollback: boolean\n ) {\n this.clear();\n }\n\n public get lines(): CircularList<LineData> {\n return this._lines;\n }\n\n public get hasScrollback(): boolean {\n return this._hasScrollback && this.lines.maxLength > this._terminal.rows;\n }\n\n public get isCursorInViewport(): boolean {\n const absoluteY = this.ybase + this.y;\n const relativeY = absoluteY - this.ydisp;\n return (relativeY >= 0 && relativeY < this._terminal.rows);\n }\n\n /**\n * Gets the correct buffer length based on the rows provided, the terminal's\n * scrollback and whether this buffer is flagged to have scrollback or not.\n * @param rows The terminal rows to use in the calculation.\n */\n private _getCorrectBufferLength(rows: number): number {\n if (!this._hasScrollback) {\n return rows;\n }\n\n const correctBufferLength = rows + this._terminal.options.scrollback;\n\n return correctBufferLength > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : correctBufferLength;\n }\n\n /**\n * Fills the buffer's viewport with blank lines.\n */\n public fillViewportRows(): void {\n if (this._lines.length === 0) {\n let i = this._terminal.rows;\n while (i--) {\n this.lines.push(this._terminal.blankLine());\n }\n }\n }\n\n /**\n * Clears the buffer to it's initial state, discarding all previous data.\n */\n public clear(): void {\n this.ydisp = 0;\n this.ybase = 0;\n this.y = 0;\n this.x = 0;\n this._lines = new CircularList<LineData>(this._getCorrectBufferLength(this._terminal.rows));\n this.scrollTop = 0;\n this.scrollBottom = this._terminal.rows - 1;\n this.setupTabStops();\n }\n\n /**\n * Resizes the buffer, adjusting its data accordingly.\n * @param newCols The new number of columns.\n * @param newRows The new number of rows.\n */\n public resize(newCols: number, newRows: number): void {\n // Increase max length if needed before adjustments to allow space to fill\n // as required.\n const newMaxLength = this._getCorrectBufferLength(newRows);\n if (newMaxLength > this._lines.maxLength) {\n this._lines.maxLength = newMaxLength;\n }\n\n // The following adjustments should only happen if the buffer has been\n // initialized/filled.\n if (this._lines.length > 0) {\n // Deal with columns increasing (we don't do anything when columns reduce)\n if (this._terminal.cols < newCols) {\n const ch: CharData = [this._terminal.defAttr, ' ', 1, 32]; // does xterm use the default attr?\n for (let i = 0; i < this._lines.length; i++) {\n // TODO: This should be removed, with tests setup for the case that was\n // causing the underlying bug, see https://github.com/sourcelair/xterm.js/issues/824\n if (this._lines.get(i) === undefined) {\n this._lines.set(i, this._terminal.blankLine(undefined, undefined, newCols));\n }\n while (this._lines.get(i).length < newCols) {\n this._lines.get(i).push(ch);\n }\n }\n }\n\n // Resize rows in both directions as needed\n let addToY = 0;\n if (this._terminal.rows < newRows) {\n for (let y = this._terminal.rows; y < newRows; y++) {\n if (this._lines.length < newRows + this.ybase) {\n if (this.ybase > 0 && this._lines.length <= this.ybase + this.y + addToY + 1) {\n // There is room above the buffer and there are no empty elements below the line,\n // scroll up\n this.ybase--;\n addToY++;\n if (this.ydisp > 0) {\n // Viewport is at the top of the buffer, must increase downwards\n this.ydisp--;\n }\n } else {\n // Add a blank line if there is no buffer left at the top to scroll to, or if there\n // are blank lines after the cursor\n this._lines.push(this._terminal.blankLine(undefined, undefined, newCols));\n }\n }\n }\n } else { // (this._terminal.rows >= newRows)\n for (let y = this._terminal.rows; y > newRows; y--) {\n if (this._lines.length > newRows + this.ybase) {\n if (this._lines.length > this.ybase + this.y + 1) {\n // The line is a blank line below the cursor, remove it\n this._lines.pop();\n } else {\n // The line is the cursor, scroll down\n this.ybase++;\n this.ydisp++;\n }\n }\n }\n }\n\n // Reduce max length if needed after adjustments, this is done after as it\n // would otherwise cut data from the bottom of the buffer.\n if (newMaxLength < this._lines.maxLength) {\n // Trim from the top of the buffer and adjust ybase and ydisp.\n const amountToTrim = this._lines.length - newMaxLength;\n if (amountToTrim > 0) {\n this._lines.trimStart(amountToTrim);\n this.ybase = Math.max(this.ybase - amountToTrim, 0);\n this.ydisp = Math.max(this.ydisp - amountToTrim, 0);\n }\n this._lines.maxLength = newMaxLength;\n }\n\n // Make sure that the cursor stays on screen\n if (this.y >= newRows) {\n this.y = newRows - 1;\n }\n if (addToY) {\n this.y += addToY;\n }\n\n if (this.x >= newCols) {\n this.x = newCols - 1;\n }\n\n this.scrollTop = 0;\n }\n\n this.scrollBottom = newRows - 1;\n }\n\n /**\n * Translates a buffer line to a string, with optional start and end columns.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param line The line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n * @param startCol The column to start at.\n * @param endCol The column to end at.\n */\n public translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol: number = 0, endCol: number = null): string {\n // Get full line\n let lineString = '';\n const line = this.lines.get(lineIndex);\n if (!line) {\n return '';\n }\n\n // Initialize column and index values. Column values represent the actual\n // cell column, indexes represent the index in the string. Indexes are\n // needed here because some chars are 0 characters long (eg. after wide\n // chars) and some chars are longer than 1 characters long (eg. emojis).\n let startIndex = startCol;\n endCol = endCol || line.length;\n let endIndex = endCol;\n\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n lineString += char[CHAR_DATA_CHAR_INDEX];\n // Adjust start and end cols for wide characters if they affect their\n // column indexes\n if (char[CHAR_DATA_WIDTH_INDEX] === 0) {\n if (startCol >= i) {\n startIndex--;\n }\n if (endCol >= i) {\n endIndex--;\n }\n } else {\n // Adjust the columns to take glyphs that are represented by multiple\n // code points into account.\n if (char[CHAR_DATA_CHAR_INDEX].length > 1) {\n if (startCol > i) {\n startIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;\n }\n if (endCol > i) {\n endIndex += char[CHAR_DATA_CHAR_INDEX].length - 1;\n }\n }\n }\n }\n\n // Calculate the final end col by trimming whitespace on the right of the\n // line if needed.\n if (trimRight) {\n const rightWhitespaceIndex = lineString.search(/\\s+$/);\n if (rightWhitespaceIndex !== -1) {\n endIndex = Math.min(endIndex, rightWhitespaceIndex);\n }\n // Return the empty string if only trimmed whitespace is selected\n if (endIndex <= startIndex) {\n return '';\n }\n }\n\n return lineString.substring(startIndex, endIndex);\n }\n\n /**\n * Setup the tab stops.\n * @param i The index to start setting up tab stops from.\n */\n public setupTabStops(i?: number): void {\n if (i != null) {\n if (!this.tabs[i]) {\n i = this.prevStop(i);\n }\n } else {\n this.tabs = {};\n i = 0;\n }\n\n for (; i < this._terminal.cols; i += this._terminal.options.tabStopWidth) {\n this.tabs[i] = true;\n }\n }\n\n /**\n * Move the cursor to the previous tab stop from the given position (default is current).\n * @param x The position to move the cursor to the previous tab stop.\n */\n public prevStop(x?: number): number {\n if (x == null) {\n x = this.x;\n }\n while (!this.tabs[--x] && x > 0);\n return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x;\n }\n\n /**\n * Move the cursor one tab stop forward from the given position (default is current).\n * @param x The position to move the cursor one tab stop forward.\n */\n public nextStop(x?: number): number {\n if (x == null) {\n x = this.x;\n }\n while (!this.tabs[++x] && x < this._terminal.cols);\n return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x;\n }\n}\n",null],"names":[],"mappings":"AkCAA;;;ADMA;AAGa;AACA;AACA;AACA;AACA;AASb;AAmBA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;AACA;AACA;;;AAAA;AAOA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAGA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAYA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAjSa;;;;;;;;;;;;;;;;;ADhBb;AACA;AAMA;AAAA;AASA;AAAA;AAAA;AAEA;AACA;AAIA;AACA;AAEA;;AACA;AAMA;AAAA;AACA;AACA;;;AAAA;AAMA;AAAA;AACA;AACA;;;AAAA;AAMA;AAAA;AACA;AACA;;;AAAA;AAKA;AAIA;AAEA;AACA;AACA;AAKA;AAGA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AAxFa;;;;;;;ADRA;AAGb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;;;;;;;ADpJa;AAKA;AAYb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AD7OA;AAwBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AACA;AAUA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAUA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAMA;AACA;AACA;AACA;AAAA;AACA;AAAA;AApNa;;;;;;;ADRb;AAAA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AAEA;AACA;AAAC;;;;;;;ADvED;AAGA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AA/Da;;;;;;;ADAb;AACA;AAEA;AACA;AACA;AASA;AACA;AAAA;AAAA;AAEA;AACA;AAGA;AAEA;AACA;AACA;AAEA;AAIA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AAMA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAOA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAuCA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAAA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAwFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAoFA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAmEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAIA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAyBA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AAGA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAAA;AAz5Ca;;;;;;;;;;;;;;;;;ADfb;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAKA;AAAA;AAeA;AAAA;AACA;AARA;AAIA;AAOA;AACA;AACA;AACA;AACA;;AACA;AAMA;AACA;AACA;AAOA;AAAA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AAGA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAWA;AAAA;AAAA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AASA;AAAA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AA3PA;AA4PA;AAlQA;AAAa;;;;;;;ADhCb;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAKA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AAIA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAIA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AAIA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAMA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AAQA;AACA;AACA;AAQA;AACA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AASA;AAAA;AAjfa;;;;;;;;;;;;;;;;;ADnKb;AACA;AAGA;AAEA;AAEA;AAMA;AAKA;AAKA;AAMA;AAEA;AACA;AAaA;AAAA;AACA;AACA;AACA;AACA;AAUA;AAAA;AAiCA;AAAA;AACA;AACA;AACA;AARA;AAWA;AACA;AAEA;AACA;;AACA;AAKA;AAAA;AACA;AACA;AAMA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AAOA;AACA;AACA;AACA;AAEA;AAAA;;;AAAA;AACA;AAAA;;;AAAA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AACA;AAEA;AACA;;;AAAA;AAKA;AACA;AACA;AACA;AACA;AAOA;AAAA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AACA;AAMA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAKA;AAAA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAIA;AAIA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AAIA;AACA;AACA;AAAA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAEA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AAIA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAKA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAIA;AAEA;AACA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AAAA;AAjqBa;;;;;;;ADtDb;AAuBA;AACA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;;;AAAA;AAMA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AAxHa;;;;;;;;;;;;;;;;;ADYb;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AAIA;AAOA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAAA;AA6HA;AACA;AADA;AA1GA;AA8GA;AACA;;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAKA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAKA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAMA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAMA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AAGA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAOA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AAGA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAGA;AAGA;AAIA;AAEA;AAMA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAYA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AAGA;AAGA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AAIA;AACA;AACA;AACA;AAAA;AAIA;AAEA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AAOA;AAGA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AAEA;AACA;AAEA;AAIA;AACA;AAKA;AACA;AACA;AAGA;AAIA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAIA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAQA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AAEA;AAEA;AAGA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAIA;AACA;AACA;AAGA;AACA;AAQA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAMA;AAAA;AACA;AAKA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAOA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AAQA;AACA;AACA;AACA;AACA;AAEA;AACA;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AAMA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AASA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAIA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAMA;AAAA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAKA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAQA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAMA;AACA;AAAA;AACA;AAAA;AAOA;AAKA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AASA;AACA;AAEA;AACA;AAIA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAMA;AAEA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAMA;AAOA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAOA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AA3/Da;AAigEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAAC;AAGD;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;;;;;;;ADrrEA;AAAA;AACA;AACA;AACA;AACA;AAAC;;;;;;;ADrBD;AAcA;AAAA;AACA;AACA;AACA;AACA;AAjBA;AACA;AACA;AACA;AAgBA;AAGA;AACA;AAEA;AACA;AACA;AAMA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AAQA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAMA;AACA;AACA;AAAA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAAA;AAnIa;;;;;;;ADOb;AACA;AACA;AACA;AACA;AACA;AALA;AAWA;AACA;AACA;AACA;AACA;AACA;AALA;AAWA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AACA;AATA;AAgBA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAzBA;AAgCA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AApBA;AA4BA;AACA;AAGA;AACA;AACA;AANA;;;;;;;AD9GA;AAUA;AAWA;AAAA;AACA;AAXA;AAEA;AAIA;AACA;AACA;AAKA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAIA;AACA;AAGA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAAA;AArKa;AAuKb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AAXa;;;;;;;ADlLb;AAEA;AAEa;AACb;AAEA;AAYA;AAIA;AACA;AAdA;AACA;AACA;AACA;AACA;AACA;AAWA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAOA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAWA;AACA;AAKA;AAQA;AAAA;AACA;AAKA;AAQA;AACA;AAKA;AAQA;AACA;AACA;AAKA;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AASA;AACA;AACA;AAKA;AAAA;AACA;AACA;AAKA;AACA;AAYA;AACA;AACA;AACA;AACA;AAIA;AAgBA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAEA;AASA;AAAA;AACA;AACA;AAIA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AAEA;AAGA;AACA;AACA;AAEA;AAIA;AACA;AAOA;AACA;AACA;AAKA;AACA;AACA;AAAA;AAhUsB;;;;;;;ADPtB;AAEa;AAgBb;AAQA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAvCA;AAyCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAMA;AACA;AACA;AACA;AACA;AAJA;AAMA;AAIA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAGA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;;;;;;;ADrNA;AACA;AACA;AACA;AACA;AACa;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAMA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAKA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA1Da;;;;;;;;;;;;;;;;;AD5Db;AAGA;AAcA;AAEA;AAAA;AAMA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AApMa;AAsMb;AAcA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAAA;;;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAEA;AACA;AACA;AAMA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;;;;;;;AD5VA;AAGA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AA3Ba;;;;;;;;;;;;;;;;;ADKb;AACA;AAEA;AAAA;AAGA;AAAA;AAFA;AAIA;AACA;;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAnCa;;;;;;;;;;;;;;;;;ADNb;AACA;AACA;AACA;AAGA;AACA;AAEA;AAAA;AAWA;AAAA;AAAA;AATA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AAAA;AAEA;AAGA;AAGA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAQA;AACA;AACA;AACA;AACA;AACA;AAMA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AAKA;AAEA;AACA;AACA;AAMA;AAKA;AAMA;AAIA;AAGA;AAIA;AAIA;AACA;AAOA;AACA;AAQA;AACA;AAEA;AAEA;AAAA;AAzNa;;;;;;;;;;;;;;;;;ADNb;AAEA;AAAA;AAGA;AAAA;AAEA;AACA;AACA;AACA;;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AAGA;AAEA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AA5Ea;;;;;;;;;;;;;;;;;ADLb;AACA;AACA;AAEA;AAOA;AAEA;AAAA;AAMA;AAAA;AAFA;AAIA;;AACA;AAEA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAKA;AACA;AACA;AACA;AACA;AACA;AAIA;AAEA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAiBA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAIA;AAQA;AACA;AAMA;AACA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAGA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AAKA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AAKA;AAGA;AAGA;AACA;AACA;AAOA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAnOa;;;;;;;ADZb;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAC;;;;;;;ADVD;AAEA;AACA;AACA;AAEa;AACA;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ADhBb;AAQA;AAAA;AAOA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AAAA;AACA;AACA;;;AAAA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AA7Ca;;;;;;;;;;;;;;;;;ADRb;AAOA;AAAA;AAKA;AAAA;AACA;AAGA;AACA;AACA;;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAjBA;AAmBA;AAAA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AATA;AAWA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAAA;AAUA;AACA;AACA;AAUA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAMA;AACA;AACA;AAWA;AAAA;AAAA;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AACA;AAAA;AAxMa;;;;;;;ADFb;AACA;AACA;AAFA;AAEC;;;;;;;ADJD;AACA;AAAA;AAAA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAeA;AAEA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAKA;AACA;AAEA;AACA;AAYA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAtFa;;;;;;;ADCA;;;;;;;ADFb;AAEA;;;"}
@@ -0,0 +1,49 @@
1
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fit = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ function proposeGeometry(term) {
5
+ if (!term.element.parentElement) {
6
+ return null;
7
+ }
8
+ var parentElementStyle = window.getComputedStyle(term.element.parentElement);
9
+ var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
10
+ var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17);
11
+ var elementStyle = window.getComputedStyle(term.element);
12
+ var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom'));
13
+ var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left'));
14
+ var availableHeight = parentElementHeight - elementPaddingVer;
15
+ var availableWidth = parentElementWidth - elementPaddingHor;
16
+ var geometry = {
17
+ cols: Math.floor(availableWidth / term.renderer.dimensions.actualCellWidth),
18
+ rows: Math.floor(availableHeight / term.renderer.dimensions.actualCellHeight)
19
+ };
20
+ return geometry;
21
+ }
22
+ exports.proposeGeometry = proposeGeometry;
23
+ ;
24
+ function fit(term) {
25
+ var geometry = proposeGeometry(term);
26
+ if (geometry) {
27
+ if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
28
+ term.renderer.clear();
29
+ term.resize(geometry.cols, geometry.rows);
30
+ }
31
+ }
32
+ }
33
+ exports.fit = fit;
34
+ ;
35
+ function apply(terminalConstructor) {
36
+ terminalConstructor.prototype.proposeGeometry = function () {
37
+ return proposeGeometry(this);
38
+ };
39
+ terminalConstructor.prototype.fit = function () {
40
+ return fit(this);
41
+ };
42
+ }
43
+ exports.apply = apply;
44
+
45
+
46
+
47
+ },{}]},{},[1])(1)
48
+ });
49
+ //# sourceMappingURL=fit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fit.js","sources":["../../../src/addons/fit/fit.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Fit terminal columns and rows to the dimensions of its DOM element.\n *\n * ## Approach\n *\n * Rows: Truncate the division of the terminal parent element height by the\n * terminal row height.\n * Columns: Truncate the division of the terminal parent element width by the\n * terminal character width (apply display: inline at the terminal\n * row and truncate its width with the current number of columns).\n */\n\nexport function proposeGeometry(term) {\n if (!term.element.parentElement) {\n return null;\n }\n var parentElementStyle = window.getComputedStyle(term.element.parentElement);\n var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));\n var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17);\n var elementStyle = window.getComputedStyle(term.element);\n var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom'));\n var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left'));\n var availableHeight = parentElementHeight - elementPaddingVer;\n var availableWidth = parentElementWidth - elementPaddingHor;\n var geometry = {\n cols: Math.floor(availableWidth / term.renderer.dimensions.actualCellWidth),\n rows: Math.floor(availableHeight / term.renderer.dimensions.actualCellHeight)\n };\n\n return geometry;\n};\n\nexport function fit(term) {\n var geometry = proposeGeometry(term);\n if (geometry) {\n // Force a full render\n if (term.rows !== geometry.rows || term.cols !== geometry.cols) {\n term.renderer.clear();\n term.resize(geometry.cols, geometry.rows);\n }\n }\n};\n\nexport function apply(terminalConstructor) {\n terminalConstructor.prototype.proposeGeometry = function() {\n return proposeGeometry(this);\n }\n\n terminalConstructor.prototype.fit = function() {\n return fit(this);\n }\n}\n",null],"names":[],"mappings":"ACAA;;;ADeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAlBA;AAkBC;AAED;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AATA;AASC;AAED;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AARA;;;"}
@@ -0,0 +1,30 @@
1
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fullscreen = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ function toggleFullScreen(term, fullscreen) {
5
+ var fn;
6
+ if (typeof fullscreen == 'undefined') {
7
+ fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add';
8
+ }
9
+ else if (!fullscreen) {
10
+ fn = 'remove';
11
+ }
12
+ else {
13
+ fn = 'add';
14
+ }
15
+ term.element.classList[fn]('fullscreen');
16
+ }
17
+ exports.toggleFullScreen = toggleFullScreen;
18
+ ;
19
+ function apply(terminalConstructor) {
20
+ terminalConstructor.prototype.toggleFullScreen = function (fullscreen) {
21
+ return toggleFullScreen(this, fullscreen);
22
+ };
23
+ }
24
+ exports.apply = apply;
25
+
26
+
27
+
28
+ },{}]},{},[1])(1)
29
+ });
30
+ //# sourceMappingURL=fullscreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullscreen.js","sources":["../../../src/addons/fullscreen/fullscreen.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\n/**\n * Toggle the given terminal's fullscreen mode.\n * @param {Terminal} term - The terminal to toggle full screen mode\n * @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false)\n */\nexport function toggleFullScreen(term, fullscreen) {\n var fn;\n\n if (typeof fullscreen == 'undefined') {\n fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add';\n } else if (!fullscreen) {\n fn = 'remove';\n } else {\n fn = 'add';\n }\n\n term.element.classList[fn]('fullscreen');\n};\n\nexport function apply(terminalConstructor) {\n terminalConstructor.prototype.toggleFullScreen = function (fullscreen) {\n return toggleFullScreen(this, fullscreen);\n };\n}\n",null],"names":[],"mappings":"ACAA;;;ADUA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAEA;AACA;AAZA;AAYC;AAED;AACA;AACA;AACA;AACA;AAJA;;;"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Copyright (c) 2014 The xterm.js authors. All rights reserved.
3
+ * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
4
+ * https://github.com/chjj/term.js
5
+ * @license MIT
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ *
25
+ * Originally forked from (with the author's permission):
26
+ * Fabrice Bellard's javascript vt100 for jslinux:
27
+ * http://bellard.org/jslinux/
28
+ * Copyright (c) 2011 Fabrice Bellard
29
+ * The original design remains. The terminal itself
30
+ * has been extended to include xterm CSI codes, among
31
+ * other features.
32
+ */
33
+
34
+ /**
35
+ * Default styles for xterm.js
36
+ */
37
+
38
+ .xterm {
39
+ font-family: courier-new, courier, monospace;
40
+ font-feature-settings: "liga" 0;
41
+ position: relative;
42
+ user-select: none;
43
+ -ms-user-select: none;
44
+ -webkit-user-select: none;
45
+ }
46
+
47
+ .xterm.focus,
48
+ .xterm:focus {
49
+ outline: none;
50
+ }
51
+
52
+ .xterm .xterm-helpers {
53
+ position: absolute;
54
+ top: 0;
55
+ /**
56
+ * The z-index of the helpers must be higher than the canvases in order for
57
+ * IMEs to appear on top.
58
+ */
59
+ z-index: 10;
60
+ }
61
+
62
+ .xterm .xterm-helper-textarea {
63
+ /*
64
+ * HACK: to fix IE's blinking cursor
65
+ * Move textarea out of the screen to the far left, so that the cursor is not visible.
66
+ */
67
+ position: absolute;
68
+ opacity: 0;
69
+ left: -9999em;
70
+ top: 0;
71
+ width: 0;
72
+ height: 0;
73
+ z-index: -10;
74
+ /** Prevent wrapping so the IME appears against the textarea at the correct position */
75
+ white-space: nowrap;
76
+ overflow: hidden;
77
+ resize: none;
78
+ }
79
+
80
+ .xterm .composition-view {
81
+ /* TODO: Composition position got messed up somewhere */
82
+ background: #000;
83
+ color: #FFF;
84
+ display: none;
85
+ position: absolute;
86
+ white-space: nowrap;
87
+ z-index: 1;
88
+ }
89
+
90
+ .xterm .composition-view.active {
91
+ display: block;
92
+ }
93
+
94
+ .xterm .xterm-viewport {
95
+ /* On OS X this is required in order for the scroll bar to appear fully opaque */
96
+ background-color: #000;
97
+ overflow-y: scroll;
98
+ }
99
+
100
+ .xterm canvas {
101
+ position: absolute;
102
+ left: 0;
103
+ top: 0;
104
+ }
105
+
106
+ .xterm .xterm-scroll-area {
107
+ visibility: hidden;
108
+ }
109
+
110
+ .xterm .xterm-char-measure-element {
111
+ display: inline-block;
112
+ visibility: hidden;
113
+ position: absolute;
114
+ left: -9999em;
115
+ }
116
+
117
+ .xterm.enable-mouse-events {
118
+ /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
119
+ cursor: default;
120
+ }
121
+
122
+ .xterm:not(.enable-mouse-events) {
123
+ cursor: text;
124
+ }
@@ -0,0 +1,10 @@
1
+ .xterm.fullscreen {
2
+ position: fixed;
3
+ top: 0;
4
+ bottom: 0;
5
+ left: 0;
6
+ right: 0;
7
+ width: auto;
8
+ height: auto;
9
+ z-index: 255;
10
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rvt
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genadi Samokovarov
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-12-11 00:00:00.000000000 Z
12
+ date: 2019-04-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -88,17 +88,11 @@ files:
88
88
  - app/views/rvt/console_sessions/index.html.erb
89
89
  - config/routes.rb
90
90
  - lib/assets/javascripts/rvt.js
91
+ - lib/assets/stylesheets/rvt.css
91
92
  - lib/rvt.rb
92
- - lib/rvt/colors.rb
93
- - lib/rvt/colors/light.rb
94
- - lib/rvt/colors/monokai.rb
95
- - lib/rvt/colors/solarized.rb
96
- - lib/rvt/colors/tango.rb
97
- - lib/rvt/colors/xterm.rb
98
93
  - lib/rvt/engine.rb
99
94
  - lib/rvt/slave.rb
100
95
  - lib/rvt/version.rb
101
- - test/controllers/rvt/console_sessions_controller_test.rb
102
96
  - test/dummy/Rakefile
103
97
  - test/dummy/app/assets/javascripts/application.js
104
98
  - test/dummy/app/assets/stylesheets/application.css
@@ -123,11 +117,11 @@ files:
123
117
  - test/dummy/config/initializers/filter_parameter_logging.rb
124
118
  - test/dummy/config/initializers/inflections.rb
125
119
  - test/dummy/config/initializers/mime_types.rb
126
- - test/dummy/config/initializers/secret_token.rb
127
120
  - test/dummy/config/initializers/session_store.rb
128
121
  - test/dummy/config/initializers/wrap_parameters.rb
129
122
  - test/dummy/config/locales/en.yml
130
123
  - test/dummy/config/routes.rb
124
+ - test/dummy/config/secrets.yml
131
125
  - test/dummy/db/development.sqlite3
132
126
  - test/dummy/db/schema.rb
133
127
  - test/dummy/db/test.sqlite3
@@ -137,106 +131,325 @@ files:
137
131
  - test/dummy/public/422.html
138
132
  - test/dummy/public/500.html
139
133
  - test/dummy/public/favicon.ico
140
- - test/dummy/tmp/cache/assets/development/sprockets/0509a6e0e75d9ac5a88bba7291b04686
141
- - test/dummy/tmp/cache/assets/development/sprockets/2bd9d10dae311aa2dfb6dea9c1e0ad50
142
- - test/dummy/tmp/cache/assets/development/sprockets/2f41a6a41d0a16db31cabd2b8689ca00
143
- - test/dummy/tmp/cache/assets/development/sprockets/4de66e84a0d6f009fac50cd608fb8581
144
- - test/dummy/tmp/cache/assets/development/sprockets/56e8026311075410507152df2aea4307
145
- - test/dummy/tmp/cache/assets/development/sprockets/9542de15712d45f70221931bf78c00e5
146
- - test/dummy/tmp/cache/assets/development/sprockets/98cea396a602c53d876e79bf4b89de3b
147
- - test/dummy/tmp/cache/assets/development/sprockets/9df3968b0f171feec749766fffa50b2e
148
- - test/dummy/tmp/cache/assets/development/sprockets/aa5fc4cb46c5294192c9d3af8824f88b
149
- - test/dummy/tmp/cache/assets/development/sprockets/ac7197dc7dd9ab362d915d19e37a8e01
150
- - test/dummy/tmp/cache/assets/development/sprockets/b238befd6eff46b26d56322c1450ea45
151
- - test/dummy/tmp/cache/assets/development/sprockets/c69b8b79c21fd48ad84c3fad87945a5c
152
- - test/dummy/tmp/cache/assets/development/sprockets/da4318a4d8364d0616edd706508371bc
153
- - test/dummy/tmp/cache/assets/development/sprockets/dd71b14df42fd6dc95355cded9e4d0f9
154
- - test/dummy/tmp/cache/assets/development/sprockets/eb06cae1627276e46965809e766aff13
155
- - test/dummy/tmp/cache/assets/development/sprockets/edffb5017d27ddb65965203636286405
156
- - test/dummy/tmp/cache/assets/development/sprockets/f0ced5f3d4a75fce1c596d6c3f97a42d
157
- - test/dummy/tmp/cache/assets/development/sprockets/fb9e611526e612ba797f0c11b987826b
158
- - test/dummy/tmp/cache/assets/sprockets/v3.0/-K/-KiIicXUmKvS01lViUN0fVWjnk3WG8R7AU8KuOnsq8Q.cache
159
- - test/dummy/tmp/cache/assets/sprockets/v3.0/17/17pGZu57zKoZ94QZm4aKckh0sCZX8b7JQLSsbcOHHVk.cache
160
- - test/dummy/tmp/cache/assets/sprockets/v3.0/1H/1Hh7ihf7wCWWVBUS9Uoixm6HpfyOHzMv-2Tp36h5sAc.cache
161
- - test/dummy/tmp/cache/assets/sprockets/v3.0/1e/1esrtnLnKK8hR4ALg2UF3qhvLJB3u75jgYYlwr3BtiE.cache
162
- - test/dummy/tmp/cache/assets/sprockets/v3.0/2l/2lShAF_y3QIpyv7eGEC1oi2ks8II1yOglQYzZuI3GlU.cache
163
- - test/dummy/tmp/cache/assets/sprockets/v3.0/2p/2pfdtD4Unn94fgfTvW9IuHcslz_aC53bupzRnnBTjz8.cache
134
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/-k/-kWsWgMXl2ZAF8zZv4r8PS6rm6ffMtUd-Ma8pAT_OJ4.cache
135
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/08/08beTQHREIhjRtoBrxMZ6FHaxhlLwKQqnEPYIVND5ms.cache
136
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/0Y/0YioaTGG5pPIt_8ZprcTZY9grFYXnvHrWwAm0D-2DvM.cache
137
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/0p/0plJ6fG2bnSD-EltE32bpvmWlzM_EJ6rAbl_gfA6a_g.cache
138
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1-/1-iOGSnAfu5QzZ-CHEdTitP-5Af_kzPI-bDp0AB7w-w.cache
139
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/10/10VuBAk2tYbshM7nzg2PmLcyxqn79im6uV-fWNNHSnY.cache
140
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/13/13agLhf4vTx_mCWtPD-Osx7zQB3hATdVB99LwfZ2osQ.cache
141
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/15/15ok-KPHBDqe4Be1S1cMFedG2R7-SN0yX6yXr-_Wt1A.cache
142
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/19/19qxhXovOaykzRzWP6LTFWxznQKx2Vjw9v0cwFeRjko.cache
143
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1E/1Ei9hs8evGGBWvHfxqmbeAhzLwAwfctd96ReP9B3YHs.cache
144
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1a/1aYx8_5kppRwU4tKqFENf59WMr-P_9GPMBEhWSt5D-8.cache
145
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1i/1ihFGdkP4w8NQXWMtxQ5hyYR1oey0Repp8pnF-h3nPs.cache
146
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/28/28HQBuBhEKOo4yX8iIWFaWRdRqDOig7S9cSvvD4YLBs.cache
147
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/2A/2Aahz8qIBZ2aqPIl-oqU1cHu77fJCw0Ej5tRsgpQQPE.cache
148
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/30/30n33voi8xrNL1NGZker1EvTpGZ-cp1ZwGkF-fwX9ck.cache
164
149
  - test/dummy/tmp/cache/assets/sprockets/v3.0/3E/3Epa2d1ojZZbRfi_AL5pJqQOAeDXHvA6ne0Hl0vuO4A.cache
165
- - test/dummy/tmp/cache/assets/sprockets/v3.0/3V/3VuACKK5EZL0kFdIsulnRkj_H33Bhgt8rWXOQ3GtxK4.cache
166
- - test/dummy/tmp/cache/assets/sprockets/v3.0/4f/4fGELkMBNoXbrN_1xBFotqQ7TvvnD6wqNwzTIQxQoig.cache
167
- - test/dummy/tmp/cache/assets/sprockets/v3.0/5E/5ESZnaE5qh0iYvz9xmZmrU99psPmVEF9xbaOmhKjVd0.cache
168
- - test/dummy/tmp/cache/assets/sprockets/v3.0/5H/5HcK5g4Hf81q5eDV-D2FxWhFvU-FQC_0xXhORcReKFM.cache
169
- - test/dummy/tmp/cache/assets/sprockets/v3.0/5f/5f3EHjGVDFwHFPyQq5uKHDZpnzyuP21Bb2vs0abI_Uo.cache
170
- - test/dummy/tmp/cache/assets/sprockets/v3.0/6C/6CwrwCCdUsKoCchA9tI10DcEXTuTcCCvuaOWGBum96s.cache
171
- - test/dummy/tmp/cache/assets/sprockets/v3.0/74/74nSxlehXGJRbD0LU0Iba6VeJuNBCprOS7zalbnRXdQ.cache
172
- - test/dummy/tmp/cache/assets/sprockets/v3.0/80/80iuGcmJDTntKnnQNhnTc6BWK-fhydrU0ll3jrc-jxE.cache
173
- - test/dummy/tmp/cache/assets/sprockets/v3.0/8V/8VDZPz7iaeHUAFJM6c__4RL2qobs_HxEfh1cvN8X2tE.cache
174
- - test/dummy/tmp/cache/assets/sprockets/v3.0/8W/8WO5VcJOFOrSWseN2SKniU76vW4j6komRdMzmvQwHOQ.cache
175
- - test/dummy/tmp/cache/assets/sprockets/v3.0/AN/ANlzs9QWeQu6lYeBwGWFcK00sfOTLMsFsZaQzrzTEIA.cache
176
- - test/dummy/tmp/cache/assets/sprockets/v3.0/An/Ana-_KrSkUp0SHOpAG3yEY_792tMopenBFYRnrEemRQ.cache
177
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Bq/BqY9mFfdK9O4325lbO_-_QZCbEZuGiNguITrgGRIfNM.cache
150
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/3h/3hFbdb8PCPxwgaSG184S_f3_9YiLjPcz7acEsKvDfnc.cache
151
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/4g/4gWBKyXKrhIERJHmER7u3skVARiiO8CuDaobzsh5hrY.cache
152
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/4x/4x4SfJ8POcn_5GroGRCTXRl0R74-my-hSiWmw23gD_I.cache
153
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/52/52dj5_sQqYMdp-Jq__CRuim_UPaWd_SVUeoAUhXhk9o.cache
154
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/56/56SaNws-UaxyLsj8oMU8dfsUZtzJPqSuWcS6sRy7ZL8.cache
155
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/59/59Iv0zYsO0kAjBBmTxvYbLZVI927cQTdpxMz4SkxcsA.cache
156
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5D/5Dol0kRZNNycXHrUO8ZUfYseFukTciD88UYkntPvpcE.cache
157
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5Z/5ZXwjMKqJ-A2yXE3a0dbIrikKYZVnk3fui4DMmz48lk.cache
158
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5k/5kRJ4sH7y3qd1k6DTUoC0gbStd0OWKHN1BC44Vo_jMY.cache
159
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5s/5Sn1CbCVqNNz4NjoX4qkPHq_wtTq8UHU5UZiw8UOirk.cache
160
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5s/5sZ1gCXEFuPIOk-b4vWbEKq85JXMK8TffZzNKl8pNDA.cache
161
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/63/63lIk133HZt8Qk4bvvZop2l3fE82b0Dzg7v8rIJMA-E.cache
162
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6P/6Pvzfk4ZiEy6JwysTpNkcpGc6ZxqZmnhrOe341PJ7xE.cache
163
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6S/6SlQBk1nmBw_S2wU9RDxn4VC-QEPgkzrKDIcfWoWNQk.cache
164
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6V/6VZ7A4vtU3hzw90wVY8hbrWStQ_CVuKbMpTs9tyES5E.cache
165
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6r/6rhsKfTxfHYeMdDJC0WTG5MoSqYnTIm3cUbsSunotic.cache
166
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6u/6utay7VkqNIFbt3iHF-zcMOH74369hxhR3JYj3T6ADA.cache
167
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/70/700yl_vOvT8zWvOGRyEnKt8jbCoudw2winTEXq1kQWs.cache
168
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/77/77hNrjw_SVwPzr2bBM3hEeq9cBLn_60qU7LxnDeulwE.cache
169
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7S/7S66JDS9bYQrUkMmnDw14MqwN7tUDvBeITf23hXK_mU.cache
170
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7b/7bah6AfpQNLmcPzUhdVOjJwj-utQzT4Gp13yyUG1-os.cache
171
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7d/7dbFmSW4fCX2-qvOoLwhhfhJJTPdLWjeHizxdcBda3Q.cache
172
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7h/7h1SnthU_xgPEVAK3XafohnIRw5ztiyDMq4urK46TIQ.cache
173
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7i/7ilbgWjHSvpT2wOZYyaQ80wDLezPYjQZW5yHfpFyuyc.cache
174
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7w/7wB7Vul6Lch0qdkWDW8X8SzSi2-VR0PDKIStuas_jmk.cache
175
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/8V/8VuwNr6zDnVJWE58Xnep80kdc7WeKJSTOFjdn1hLwAY.cache
176
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9A/9ArW7CZi8OYRdOUyWUq2ghAXLAqesLT0zF66ys8xS9Q.cache
177
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9K/9KsWd_r6PFFDBiRGxGr_lCfV5sFTVN7MuaRRgoM9aBM.cache
178
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9M/9M8NdCdd4J5xZPOf5nbgcdAuWfqzH3Pi0m95Fi0cCX4.cache
179
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9c/9c58KfTtMtK_q0IRLv4Ohe6Ku9NR8cTvzNsUUwvFh3o.cache
180
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9c/9cLL-WwQAfVZYDPvfbpdtcnYqB0twxXZFAIYo_bIwDg.cache
181
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9f/9fjyLS5QJER_ouDjFs9r44-2NpIWEr_ARVS7Ejl5uVI.cache
182
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/A7/A7TBW10ylh4nLlUBMquQ9KQeYJXe7C7tJPNSXKpoBxc.cache
183
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AA/AAiRDGe6f3TnpziRJTw28NMq1gtnkZ5W3mbxowNTj1M.cache
184
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AR/ARKOmH6p6jVxoayq2bHzhdLGaYTd8KpX6Tu3QQQAPww.cache
185
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AS/ASWkkDKVcpfAiOu3B0KOejzVhAxxhYxqOQKBcZlm290.cache
186
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AT/ATEqECN4BijOQ993FAXv3MoryNacaylv073Jv9UeIOQ.cache
187
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AT/aT6_oAHJCuWhpkmdiQ70MxzEDA9i9fnO6kOUJuqLttY.cache
188
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ad/AdR0Qt_GcCj_0fxwl4lvjCAfJXJT8iwZb5RzeJt7X-g.cache
189
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ae/Aeswx4jbWYCQZlAPoZ6eOpckcVwEIQaCdyIEZ4yZ1vo.cache
190
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ae/Aez3Ln5GSo40ydxFzrQOFnySToV0-GnCIqhX3Z8PxjU.cache
191
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Az/Az-XOnvmnNddxIz4XLZ1I4DleC9n1REONV4xGg_QDA0.cache
192
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/BN/BNKTHM0qczl5J1srx4QT-at4EuqAA5SSEVeTmxjdUYc.cache
193
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/BW/BW1UGENNCOM3Axx_ShFZhHwm4_bcDP1QyQCk98WBayY.cache
194
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Be/Beyr-TRQYnkjEqSn8chN2Hhh3kVAbSR2_IhK9orJ9Xk.cache
195
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Bv/BvSr8HnNGZCLi7shOVomsQuAT5dX8IPGkepQ6tNxGUI.cache
196
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Bv/bVWlBMMWMQVoW83IV4Qf9L-ABRxEV6rmp6xhGgd2VNU.cache
197
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/C0/C005GHkGmz6P2P0YZaw73NcUTDviWT_hspo2V3zRqv8.cache
198
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/C0/c06NLyQZGWQsdwVXih7CfDBuHWmFSM2LspPVvPxrMIc.cache
199
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/CB/CB4g53dw2z-x-93N-W6AahS8wt4x7QwelZK2b61FUXA.cache
178
200
  - test/dummy/tmp/cache/assets/sprockets/v3.0/CJ/CJgfggUIbMu6MezYEC37omvMYp4wuEDiRmhTyfbTt54.cache
201
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ch/ChP_e519Fej_qZBClVpu8-bJm11J7UZJaN2wgaXNa94.cache
202
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/D7/D7AIWNFq0HwRCrpFDzdbYrc8vmqErySsARjPklXlAPg.cache
203
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/D7/D7s3i6wBxXKuXgmEi_xluk4ktUowNkkMSuUk72Qnd3c.cache
204
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/D8/D8A7QhUYhnXJ3LEEFw9NrHww1rN4Ky-LdBB0bOtK9Z0.cache
205
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/DW/DWIt1aCKlWxnd-4npDlqWMFBAjSrCinlmfA_TCZeslE.cache
206
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/DY/DY2J3UwXRTs-2Q6VBmon8K0OQJTPsamoZwijp7X-bm0.cache
207
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Da/Das9TcLHrt3FfmNKQgMbCTg8BsYF06X7x2gFXvoVsJg.cache
208
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/De/DermXth9dmU_XWCFEysWqQ3lL8KQhEi-GkHKs2iFWNU.cache
209
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dl/DlxaZWt1F6jcMlrBLNIamMP8LUsPdcGoCQBjQsqknlA.cache
210
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dn/Dna81lRfs6LHDdI5NVoLGXYJeCMPN4zfWXe-PwqMzAg.cache
211
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dn/dn8JjucKlRBMIvmKNSXxQ6j1zuvW_Wy8yyP_2_uNBt8.cache
212
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Do/DoZ1miHFIc0Zu4xRyikxRSM3bAXfrYlVbFNTB1qY9Os.cache
213
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dr/DrolWmSngZwPNXKJkGrfADLMhMbJdhfqbtihKKUM4cU.cache
214
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/E6/E6yy5KPw_faIzyJ98hK9jPM-3cRJjtqPJ_TUJENGcn8.cache
215
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EG/EGsDHaXyy-tzcZjX3wOgKkSTq_leXqT-PkOPUUdfWdM.cache
216
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EG/eGRA2iRfMMROTcuFKjGHZSN9YXMRnUBKC5KururoKEQ.cache
217
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EP/EPCJCAFRp5SWXenODKp7J3-LOEeQHXH3sPfaf1bHSSo.cache
218
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EP/ePBoUwOrluPhUdXqfhIpGf3zPddq1_3-Vg2oNLOewMA.cache
219
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ES/ES0i3T-gPmh0k4JHBm8e0636XUPegF0Y6PFm1KqrOpw.cache
220
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ES/EsVsWF0kxtr2d8p46pBHT_F438kHPSBPgW2Cn9cIEvo.cache
179
221
  - test/dummy/tmp/cache/assets/sprockets/v3.0/El/El6sDelFE4zi-yos85eKdhytxd04vayUxI1EvuqbEEU.cache
180
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Fx/FxJAcBo8p4ampqzXZFkXwX2Xx58e9sA2MznNT4tSb4k.cache
181
- - test/dummy/tmp/cache/assets/sprockets/v3.0/G1/G1bLOMv8ry4OZIOE6yamFeLyspUWFH7F5uHQsvx3L-Q.cache
182
- - test/dummy/tmp/cache/assets/sprockets/v3.0/GF/GFVuBv-xJC6l9uzpvIkeOzFpM_wrzgvn5gJpRJZJQYY.cache
183
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Gn/GnRhwIvx6FcsFco_Zaww1BSo7PCh-rHEJnmYByESMmk.cache
184
- - test/dummy/tmp/cache/assets/sprockets/v3.0/IR/IRkzGfhZ_j61PMxiMlMuiO5_8GJrPxVz_q1fUw8lELA.cache
185
- - test/dummy/tmp/cache/assets/sprockets/v3.0/MY/MYYdkkZJkduDmx4PCuuPiiFBaKv90qOpaPFoon-wg1Y.cache
186
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Mc/McQLAeERc8_h2GV4r_RSiTspx4ScOecJluPorLvWQv0.cache
187
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Ol/OlJLFMx2ecfQUa6QubAYEN6Nef_1Jk3rIggdhypnhKE.cache
188
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Or/OrmkzKYvYsup9pzrnDM4jqhxXtZ49RvP0eCaqe3chvA.cache
189
- - test/dummy/tmp/cache/assets/sprockets/v3.0/PV/PV-WmLYkFJdjKgVXpPxYl8nhQBu5frexNF5_DIbQKSM.cache
222
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ex/ExLUPQPUvttBUmDRlP6aWd7GP5yCWI1o8eKoCeCw3z4.cache
223
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/F0/F04RlQd4Wku__flRg9gkM00g8mfjuKzQKlvsrhcXqXc.cache
224
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/FA/FAA3VIY3nCH5gKoynhtYbxrahKETLcwURlXKa8K8jE4.cache
225
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Fz/FzQ7uGnfl3Suky99OCP5Y9_chV3zDJ_ls8pg_YpdeQY.cache
226
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GC/GCNnkrIFxTx1GDkpGHVfRDuq5Lmh91Hl_y1Cuuvydtw.cache
227
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GH/GHMro7l5elRwkZW6ocgvpEWdY-bCMla0J0BPd_6hqoE.cache
228
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GH/gHYDXMvegdiaMifmauTVm8Qy1gOSnoiKAnsCwAmMM6Y.cache
229
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GQ/GQGhdmNekxHTcK4z8c8_0XABvO_V3GU-ka52v-m1w7w.cache
230
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Gd/GdWzOBp-czgmy2Rby_RDhnKc9DuCOp6bu89sRvLKjgg.cache
231
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Gd/gDYut7mu03J1DXr8TuWSBtWUo6SCV8j21oKygbTMlqY.cache
232
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Gz/Gzbr2w7v4jG0Hk3mkrGRhUAVf074dfK-SbaCRp1BPqU.cache
233
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/H7/H7I9oc3DUcu1Fgug4P9wL2L5hFD6o_2GA1QN9Og7sEI.cache
234
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/HO/HOcl3-vJpAuPrL4hm8vHDlGplCavb3ddOz4TrmAZlXM.cache
235
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hk/HkwIX77oB82LdxxnXQtQR8zqpUlYQ9sTRNSAaRkvLtA.cache
236
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ht/HtmK3dFHJrhu5J-TC1JcX6mYcujL4FIJ06D3YD4XTbQ.cache
237
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hy/HyBjVqV93QJMiSmyiNNHd8W7bwg3gZl-hf5grEk-wgw.cache
238
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hy/hYomtUCsrKd36M73vuN6TqMogPeLrU6NIOu1wAKRxf8.cache
239
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hz/HzVr6Nm_b4eztKl1iNtoTbiUJg8YovXVVx309ooGcN8.cache
240
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/IK/IK_yJ4hlfIoYaLmA3gsgUHcRwQD8URO9Sk7Pi9qQWAA.cache
241
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ii/IiSw3rEjcPrbR7bHmv79rnIeihj6Ood5ZNVsxwKYqVk.cache
242
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Io/IoNdrAbIQw_WQQw1yvFl7FgAf-WGvZ2NM0r64hJolVQ.cache
243
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/JG/JGaR6S0bzqxKeawxt10Lzcm7TfUd3uQytf3jSxEWw48.cache
244
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/JQ/JQlWE0blDCjSPcJnQC7j_jIHh1pyP4EG3RewaazEdv0.cache
245
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Js/JsgdFJryO0r77umcztaF9gLlmMfEbMilAOjggdfgc60.cache
246
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Js/jsZpWqO6fd3TZYojdhzziiohSmF0ENGFCUg-aw4s-eQ.cache
247
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/KU/KU2gDD4G4XnXpghZBiXE1dWnF2RfbX-upKi-50zWTpY.cache
248
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/KU/Ku40yz8Vw0tWfXutEd9XACE8NupAyP9XqkCE0XAo4iA.cache
249
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Kl/KltQXiJL-E-5FOYGticndlKA3HlOHmK6bmXS2sSgpK8.cache
250
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/L0/L0iEiBEuw_cn9Kl1E14SeJqUHWhmwEkm4ALcv6-FUag.cache
251
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/LA/LAeWo8kRKzTAYnVcryAE38boNz6PwaGm0cLbYvEzeSA.cache
252
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Lk/LkyGhvZlAhiEAeLfI-S9BiXygetNMNsflyOPQuoruDo.cache
253
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Lm/Lm4AZ7UdsY463umaLuG6r9t_FwjjmXyOoLZe65t5Lgw.cache
254
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Lm/Lm4LVfF3ZLeTOosUYRZ02bLL9eJ_ufm65YSM57c_iLw.cache
255
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/M2/M2oif3DO_vNyYmPwq_4pSDMO2cr6C7aAnZ30QFarcqE.cache
256
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/MT/MTBWM31BtwMKG_GwIhNdso8ZCuY8XQJbsSdHL8K8B1w.cache
257
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NL/NL2zRwmr1IQtyc8yRugLhbMmFguaFd25SoYml1o0puI.cache
258
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NL/Nl7ScaktvaTV9fv6KnpRA5L4nhOYFIe602IcnZnRdn4.cache
259
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NO/NOSTEerYscJRYOB0fDhXWg8n2Ubns32JK_g_XeyZzEg.cache
260
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NQ/NQ5GwtrjHgrF979TJAJAIbyn_UBEAME1bZW0xMX5DnY.cache
261
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NW/NWyrH43hxzGBxfB9ZKdryDPlHeh2Djz9CvJqNJ9iLKk.cache
262
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ni/NiUFiKzq5amff2RZ37XuDkcPgTcuD49nRbZgDY_PhoY.cache
263
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/O9/O9n18FPyB5Aff7Ag87dJAlgAnvT9TWBnHCiiZms98SQ.cache
264
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Od/Odngw58z1w-IdGloSutkpEAhke6MVPpv7hpgz0-136Q.cache
265
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ou/OuWuLlXvGlYcE6paOZI8sh0cYX4aodsDz6GDY3TNqME.cache
266
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ov/OveMcuYy1aRyjiisX9H7lQzO7THrJnObrUmbln8Ih2k.cache
190
267
  - test/dummy/tmp/cache/assets/sprockets/v3.0/PX/PXDoBSysxwUQ75MPgOPOBIWnQAIxz2cwO9JxLqc4cXA.cache
191
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Po/PoeLkPEvD2iajH_gaRh-sIFdCZ-jEaac8_Kdt5EnBH0.cache
192
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Pq/Pq9EEQ_PUKpcnBH_AwZ_F30lvjSNXlN1hwaTn5zBllI.cache
193
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Qy/Qyi4pqtXinXLNBYkB-lXsfCpaw560tlqG997Omt9hjc.cache
194
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Rp/RphNp2ADQ6h0qpBMeRGccIFKL3cPNnEyRszHOHNcwV0.cache
268
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/PZ/PZyyxCG7Tl8VboaCD1eRsoY6cvDpHu19qJE0KWHl5Jk.cache
269
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pg/PgG_33ASxui8rv0pM1HsQPrp3QNZbddKMD9jwPdFYdc.cache
270
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pv/PvtPIvLHDp8JiNt2UJYleFfw-pkzgfMqtthHiroXjes.cache
271
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pv/pVsGEIR7lq-PoM18-0M-xxR1YI5AgKN2v4J_3R4gXI8.cache
272
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pw/Pwh4JIc1ad7UEbvoZEs9fa2MoW-Xp9NdDX4eN13EaHY.cache
273
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Q1/Q1UtBSZNuYVzeZLWkWpmm-o7HSOx5D2754JyC1LMGNg.cache
274
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHMR18NuNdQf-g0IxbBD2fEmhSLqd0y1IKyylyutK8k.cache
275
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qd/Qd5DKDJM6Qi-RUkfGBW1F5jyIbeblwo8SdKmJq5ZJeY.cache
276
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qd/QdpJoa9mkC5EWXpbhYB75TCPJMbNvI7L2eaJz3XhrkI.cache
277
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qi/Qi73ofNALTcqUT_EgM2MsJO4uof-GO4xf8TBnwUA92Y.cache
278
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qu/QuJlvJ4kcq52_cknXo5PEpKT8XVOm7dt2ceHpfbQ_iQ.cache
279
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/R4/R4hlf0uqIy39ANsEhv1XO510kFbe-F-60F7v_gPgq00.cache
280
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/R5/R5Qn7BZIE1RLU4p8Zd9obkcPZOFCxBGxihXR7ReB9GA.cache
281
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/R8/R86o4eyDkpLNiROsURzRj_ImLR1RVlX5noVgz7zNqDY.cache
282
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ro/RoSh3eZzzx7lBF28H0b_lMEE9O5XQEZJaeF7O9FhhRM.cache
283
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Rp/Rp0kuYqE5Oz_-FE2srLOTB6hrcIY0lkQxLVCAFw_pbA.cache
195
284
  - test/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwyuRMymf6iaEYfNIbHrWaQ4RnWQjgWxlgjHq5vnkiw.cache
196
- - test/dummy/tmp/cache/assets/sprockets/v3.0/UL/UL8LL9y5J1u3L9SdvG8_G_gHLE_rKFsUeAlq54HNNqE.cache
197
- - test/dummy/tmp/cache/assets/sprockets/v3.0/UX/UXDhiw_eV2_5-uhXuG5hggT62vcTU3mRXVHdd8hwNtI.cache
285
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/S6/S6VyQhnt514LFU9JWjGg_rT62-EJy4QH5n9Bl7REvPY.cache
286
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/SK/SKXDgh9EyOqMCaRQDvUFTq6OorSkeqj2XIJ4uZlEWQg.cache
287
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/SK/sK4Ow1R-Wh4ug8uCzmjHxk66Idr1-nrEEKCP352aD6I.cache
288
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/SV/SV1EOoJ3cic6j5f4MaYQUFeqzLuSBzJAklpvDlpj-Cg.cache
289
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Sj/SjIvNMfbTzxUiVzh1O6oIQopMViI1R-4kngOcPfzd1g.cache
290
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ss/Ss0Xu8tk_PS3RXr_TtbmhnhVeAyE7MCxrPTOTRDVFeI.cache
291
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/TP/TPlY8VwBzC6ccuQjmMY7h9G78_cm7Bu721rrL003R3o.cache
292
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/TR/TRfkq054uIjoKd2RkGPjJyr7y8NoRAjvgRhnqm50lSk.cache
293
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/TT/TTLu0ztO4_uQ-WjivJx1FZLkIfeRRPNTxX5PndJ8zLY.cache
294
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Tj/TjFaYwMvTy3DR--WZkLLwXGd_xGrfJQJ_ZlNodTFEx8.cache
295
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/To/ToVW_LwLfoMA7qkgomaV3ffF-SDvemmBPZkHTKzSnZw.cache
296
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Tu/TuSVUvSt5BY4-q598J6p2dHwl-uhQnb5mZDmzLpkL4g.cache
297
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/UC/UCqUT1Xbp58STjhhZ-sMkyqEJ8PvIn59WNJzUPwwt18.cache
298
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/UD/UD4gCZ4M7BhSfwd4hVOqHo_e_m72n8GA6jiSsR5fZWg.cache
299
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Uf/Uf9tPce43D393aktdyXRO5iSVQ0wUrFcZHWbxIFfVfY.cache
300
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/V_/V_BAjWq0DWEzo0Q9NxcSp1nTj7iAm1rSDgxuJtOeuxM.cache
301
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vk/VkDp8B06fjIECtYuMeMBZhK07emntw6eGBH9l-CrJPk.cache
302
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vm/VMD-a78buNTA9zY_iHxPIquL81oFoiZRyUUUTLLifI0.cache
303
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vm/Vm7RBeQL13acXlvnlmzQAOR2-3n4sMzD81wvnDi7WjI.cache
304
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vw/Vw8hPD2-WLFPWQrRrL0zhoQOWWBnulRJLh_yqph6VIA.cache
198
305
  - test/dummy/tmp/cache/assets/sprockets/v3.0/W-/W-l_iL21hjDik06px3y0cNxwRax-wcyMHqCYU44IbCs.cache
199
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Wr/WriPF39G9moRbujaXvonAiEHjjgypR1iqYJrCkxmCpw.cache
200
- - test/dummy/tmp/cache/assets/sprockets/v3.0/X5/X5A2BcGLOrFB27HxUPfMTY1R9Pc_V4dlB49BKzEkbI4.cache
201
- - test/dummy/tmp/cache/assets/sprockets/v3.0/XW/XWSxy-Iv-mixLzAfY2etVgorBgWnKcDzPvc5JYtv8ZQ.cache
306
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/WL/WLeGA295T4fKL__kob_oUqylByYlyIXbyZXVXQ7fEBI.cache
307
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Wr/WrdmWGzSUAyKEx67shH_XK7LI7OeC2GipDGzU3zfMiQ.cache
308
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/XM/XMHn7vqwVvLWj2RwNhVLEylzbG_PeBLHroQfJEWajBI.cache
309
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/XW/XWzxn70WfV6gI0dBMktR9kVbjBCvLXn2Ft3ZM_AdMuI.cache
310
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Y0/Y0p_hBGflJWS11onCiUbkg3YGi2hbQOLA7Xy4sZ5h-g.cache
202
311
  - test/dummy/tmp/cache/assets/sprockets/v3.0/YA/YAiXkO3U70SeVjjP9Z2vDilLSy0F2KRSPYTtPHMfZ_8.cache
203
- - test/dummy/tmp/cache/assets/sprockets/v3.0/YU/YUnPOcXA7tScQSqfkzbf-VVnrkDph0mOtFRWXdA41CQ.cache
204
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Yg/YgzFmnUV-Bc8yd1PJan3HIFu4EI8kc4q220Ea3F-lnM.cache
205
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Yk/YkC1ANqSFWUmQhl7MGjSK_iCs_lP8mVO5QaIjn-Mdy4.cache
206
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Z5/Z5LXG7HQ6dbcPnio52VUtebna6NdsQmvuJCMq01Vths.cache
207
- - test/dummy/tmp/cache/assets/sprockets/v3.0/ZJ/ZJjFVQk_XGGXlz4fvvlEWY-4Wy0ZaJ6WrBHSzpiBIm8.cache
208
- - test/dummy/tmp/cache/assets/sprockets/v3.0/ZT/ZTsUUbGZ_rkYZ41o_lsp46dSuiGxGeOt4Q5BO3tRQHo.cache
209
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Zy/ZyyIY2PVVJpW_kZNCpOdjl2WEzSM8NsQMisOdGTIO54.cache
210
- - test/dummy/tmp/cache/assets/sprockets/v3.0/cJ/cJPDe92SSVjhN0aWjrgKTT4kS0Fok6FVUS6Ucf3CQ4k.cache
211
- - test/dummy/tmp/cache/assets/sprockets/v3.0/cW/cWtFGImKhUS7JYaEIBNPmFmtxIokpNEtprbrIu-KYLk.cache
212
- - test/dummy/tmp/cache/assets/sprockets/v3.0/dd/ddQSSbSqtYqXeXJfq9MgkETEBISNXYRzE-wIPkcv9s4.cache
213
- - test/dummy/tmp/cache/assets/sprockets/v3.0/eR/eRFxgeqg4P6SKIaqiHeDezODcKT_sMwFyGfqtPmu7vY.cache
214
- - test/dummy/tmp/cache/assets/sprockets/v3.0/g2/g2c3cRllZCQaG2kipoX1Cr40y7Lmne7Xp0JWV2rFVnk.cache
215
- - test/dummy/tmp/cache/assets/sprockets/v3.0/hO/hOh9hLhXju7HOOyQ22B04x2-tCSXXkAhbyXVbTWGwQM.cache
216
- - test/dummy/tmp/cache/assets/sprockets/v3.0/hg/hgu4xAfu5uOcafMf7-jA-qLNDcM7XgWFdwAfHjN4mQE.cache
217
- - test/dummy/tmp/cache/assets/sprockets/v3.0/k0/k0Sfk3cETJbZWYz1xsnnpgAn8xbzpBM8rJT9ffkdqnk.cache
218
- - test/dummy/tmp/cache/assets/sprockets/v3.0/le/lelLtTsvG67CE4gtCdbS_eRsDTCgrhSWFTg_t7gBbWI.cache
219
- - test/dummy/tmp/cache/assets/sprockets/v3.0/mJ/mJ_7-eeiChJdsNIN2gU0C9i_AaqnBmj6SaqV3I7nCe0.cache
312
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/YA/yA__0V_x7k0yKI212qKiZJYVV1SlqnAUjo8xA9lETYM.cache
313
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/YD/YDoprxxinr4AALGFMWIqUKHOsP1uajTUXYifinKaPfo.cache
314
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/YI/YIJ8wGXFsbFBBiPImfLMXYUm0TdGG2INe036faITzDk.cache
315
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Yv/YvXQz5sZHtXCVO0wvmHeQxJHheo5GeID88vKbtpn1vQ.cache
316
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Yv/yVbylE1uhnqOlfStbQfwubjvWQMoFD1q3oNBG_fjefs.cache
317
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZA/ZA3vRhJyNOLHkdrjGGdAxQn56Q6yOTPlQ_uDuzmynag.cache
318
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZB/ZBXrd5AdUsWldhFyk1EVuVGU2yXlFGyhVMjxiEiqMD0.cache
319
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZD/ZDKXHhzn4B_u92sZ8xLetjlnyNFvYzKaNkLm1BSPmVw.cache
320
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZD/ZDvHyfCXyEa5qWOXwktQRcABbe8waPNPw4fY5Z_D5Ak.cache
321
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZT/ZTU_yG8w31YT8Ba71RrGOcDwlSx9oClaYgveZp4ZBVA.cache
322
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Zl/ZlzLk4d2MKNw7UD22N9MXbsv30UXQxKBdZV1Bf7ngvc.cache
323
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_I/_I3O1hBJhyYQ1ZgFT81XRhXgoG4pqNxgfAGaWklXzTM.cache
324
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_K/_KcWiE5nAEDQpqJfZFqMtPhaeMhihp4UCN4vR5I1S0c.cache
325
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_W/_WVL6zcvlXgbkhRMslHtA0rvqTwr9xLq28GF6DoMd0Q.cache
326
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_n/_N2fgzGU5Oqu3S-Vn-Msc_0cpHMP_nshxJ9WFOviKbs.cache
327
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_n/_nWbvBOATVfCe68YFH9Smg9ownps3aoUyyN-9NQRtQo.cache
328
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_o/_ohnYmY_vC_G7Vqan8sUzJmaquB6QhcLYGc77DKtc4s.cache
329
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_y/_y9FD6kDSeAa5zzj1LFiz-PF8FV_0jr-gK6iDsKWvXk.cache
330
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_z/_zs_atfF7ypRzG5AvIBCfqZdYM0PBLuvYjNWpDI6BV8.cache
331
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/a3/a3Cwa31etUxox1CqQ6uxNrEpbGHLDJYFfG7Nm3fhHlg.cache
332
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/a4/a4bEtdZMtr3Rt6Y0CVkFV0sIWWx3Bv86mWyfkbaeFfo.cache
333
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aF/aFcBC07vbjBdmiW0TmtwWRMQ5Vn3vZTZiCGp4BylQkg.cache
334
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aP/aP_Mu42a9d_0j4KTczl266PjVyHmZEqgvJYTFCB3JUo.cache
335
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/a_/a__X31_jf2sHL-xJYEpoKWWhiXSNkWrTNJYhc7l9Gt8.cache
336
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aj/ajcmeCxc24RkfJfq10l_S42XKGIwjKLG_fS5qG-xhHM.cache
337
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/av/avZJH3ARnrLfgPgYHP8HVxOLiVh4EzcrKakkNXmsahw.cache
338
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aw/awYTeITVFdmTsuRvIYv9CdXF__4X7EsFq0F-dq8geFQ.cache
339
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ay/ay-1nEAOxGhFWl_HkBancemF5i0_jTIDS288Lob9ro4.cache
340
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/b6/b6a9B8W2cWgchjK3aSNjvwbf0xfEYWeTMa5CJCj2Un8.cache
341
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bB/bBHfqPuo9gcrr8VUkavCPSBGbUF-q7vj4cc_p-fiylw.cache
342
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bB/bBj0Q2GCK3NR7kP5sTE38luc6soBv7DS5tcWB-4etfI.cache
343
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bJ/bJkQ_dSwbtkZYujIu24wH5tu8HiLFig-qHDp8Wt-Zps.cache
344
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bk/bkim99ppC3FdpJTtMaGS8CllO5Jsbuf8GWYZeaarv5Q.cache
345
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cF/CfSIn6eMEXDtmjrr7oPouTR1KePajS2uqioW2_gQELI.cache
346
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cF/cF1_z7co1UqOeJh2s_aVQlB05tBGdaNDNi346EGWMbU.cache
347
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cN/cNI6iuD_nmI1oyibhmC2qXY4pWeTn9IfdkLkQSoPg5g.cache
348
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cc/cceVLx5AGYnLErPT_zXq8wCafz02ViM5B7e0J_hfCsA.cache
349
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ci/cicVHpT-BWeQrpUOhGl0awCCV-kddJZ06zia5IPuMas.cache
350
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cw/cwgwqvm0fDhWNsca03U1OyT-vzClEMfANDlKKjNcxXc.cache
351
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dD/dDo8M_nyU7maBGfXwZRMKF_00JeV4QaiKCDXUdtj5yY.cache
352
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dD/ddQSSbSqtYqXeXJfq9MgkETEBISNXYRzE-wIPkcv9s4.cache
353
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dm/dm__3FYto_fFH4IwEG4qAjhgAQGZuh0zPCzqgZ3bsP8.cache
354
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dx/DxnCtGUnAQmWQ7Tfzy2kc-YcYwMvz4PrgvrQBgaIQSw.cache
355
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dx/dxlUHAaODLiwtgh6MYuhmrJF13BAshewUD8k9_5k2a0.cache
356
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eE/eE0TmXZi5NoBQ6Li02OT-EMu_GU4EvIhiMa-0Nqls3U.cache
357
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eU/eUtPUlUJHVQxMuD4vIem9_N2HUkAPO4aVxjNdFVxACc.cache
358
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eV/eVcQYhEcDW8oispYNiL-Po01tfC2bqPxFHua7qDB3vQ.cache
359
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eZ/eZ8o0ZRPhdXLYUbFI1GdB4FQBDnlWM43nHgpH5_47QY.cache
360
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/f4/f43dOSIXprZE-wii_NU6nSxA9LvTdEe8MPpQ7jvBk38.cache
361
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/fB/fBcyS9tNmJu_9foxN5eenuH18Jumnw0uTMwPQHORUTU.cache
362
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/fS/fScKQfCZDnNi0jKvowBp0jP5dnLP5hiJjAEryoc4dn8.cache
363
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/fX/fX_OzRutFSBkeYwpekI2H5cO-eS9CcXIXE6dyFj3E5U.cache
364
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/g0/g0APGuGiB1phtXXtTsLBLkQ-k8h0GLn13mEMVmsWoik.cache
365
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/gL/gLSHSgXhdqJvlFY1r2EipTUTXI6Z2QBb_pgQ4A4FBhk.cache
366
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/hX/hX_1Br_XYMH3o5EDrBCM7jD4AR9iJhUNHzhUUMAksV8.cache
367
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/jN/jNaneI4p8mnSH0z3QpTwlCdeWbFSUWV_C_mRAg5hDXw.cache
368
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/jo/JobbYwsoKbjQxVXQz7IQbMX23HEyDbSA_zrRPPKhiUc.cache
369
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/jo/jo96mxml_RK1qUCEXd0yVf5dnSLoPqp00LEbETIIb2s.cache
370
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/k1/k1-Vu1bnBwnOu3y_QFBFyAtSGlUdvb4uhgM8xsB-_Tg.cache
371
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/k1/k1NKoz-AMR9xzRByivuGFkyp0MWQ3heaVviggtIrdK8.cache
372
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/kg/kgn1MwDe-7_T00earCMuIoRMLaeOt7S4r7769Pp8M-c.cache
373
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/l4/l4uI_1HekPy0WPa8gOz8XmbUxJCl334KSYSlpFEdSfM.cache
374
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/l6/l6KEh8r-KKee9rVKcxqIEeF5TqUwW2VqYb7paP0gCQ0.cache
375
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/lB/lBegfVYn4A81In0Ld3bvxg31hzp6sjlOr7dmdJXGjSU.cache
376
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ld/ldfozoSusCzw0GM19A6-LvzzAfrx_RQrGmDDLogloFs.cache
377
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/m4/m4-SSFfa1SYGt723CkTWQYbtaT7MBp8szC3rPFbOPuU.cache
378
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mG/mGHo3qDusQEKkkocFHTDR0J5EMIlrzROC_2ghaZYAgk.cache
379
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mO/mOP3Sm9m1M6TmWps33skF4hvd092don0dHlobn9ems0.cache
380
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mf/mfK3V0cWrlgG3paJRNUczrUppBoIWAam-b6p-J_WlQk.cache
381
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mz/mzKBIxymZpXit4v2iRnRXIK5uUIS6uUZjI0W9LZ2Bh0.cache
382
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/n2/n20Gp--0D3PUtpFMitv38Kp8LlMft5UOkTRoNHO2Tsk.cache
383
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/nB/nBH2-bAlepNFvXTSF-tmll0Rc5qvcVumktcl1KYydgI.cache
384
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/np/np0_MPHZcS-cPB69C1GzPDnipzfTk84FOeH9QXioyUw.cache
385
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/nr/nr4V60agkWIjRWDV23Auh41K0GRcXp5ctSoOyfQ1ANM.cache
386
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/oF/oF1leWgLg8_fDwI2qhBAo-V4f9ZODIH5mHd0PugDsNs.cache
387
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/oR/oRE5A6xr4tZ7gQD2Rwr9V_Z0l5vagZKNRe23f-TL7b4.cache
388
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/oh/ohJ4Vsjgs6q6LfnHd8vG2TI65-F-l8BYiRWwjcsFso8.cache
389
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pI/pIvfsBJlCo1lQR93RpavkgL1N4G3Kikd1Qs4Pl-zjNU.cache
390
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pP/pPyIvuoG5HNslNZnl6WuQyv0GTL50R4LB6MkifeioTU.cache
391
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pe/peB66vL_jJOczpV2_nGLjkEysGH1NhHdDGl_ZS_v7hk.cache
392
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pf/pFmcB3iWgwr2YrgnAyzYh8THxlAVyR2mFfvTYHH-YyM.cache
393
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pf/pfMqjshoLtd1XSMyglJefgksJD4UXBHcZQNawdXm1VY.cache
394
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pm/pmgvDDjavDz10BkFzD-EJtoEinfdu3nJQbbRhXwUNaE.cache
395
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pq/pqpMzQ1IGWV58QESaBli5VpFIdwysPKJJcvDwSjJTYA.cache
396
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ps/psQe2VtxoTgu7PHDADBGZ1cVzeCrGQIdXf7_0DEK4Dk.cache
397
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/py/pyoxXth3hjzgIEciAO90l0vIVCTJgEXsT4OZCMgq2Sk.cache
220
398
  - test/dummy/tmp/cache/assets/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache
221
- - test/dummy/tmp/cache/assets/sprockets/v3.0/ql/ql0YZqZCZb93mAbIX-l1Ut97H7xFR7iqs2cLenFIMDY.cache
222
- - test/dummy/tmp/cache/assets/sprockets/v3.0/rp/rpULJhACB9dPnbqAlVkrmJY1TtBillfIpwXuHEJW90w.cache
223
- - test/dummy/tmp/cache/assets/sprockets/v3.0/so/soQJaougFDETlHZ4JMK_lVbAnKBYVa5Bz-HT5zJRHu0.cache
224
- - test/dummy/tmp/cache/assets/sprockets/v3.0/tC/tCEBLgzem7g5HdQk880uJ0dZ_VP4LjyVByw6MszTkjk.cache
225
- - test/dummy/tmp/cache/assets/sprockets/v3.0/td/tdnEBVuuDY8qxEUccGN9gIoQ4UgdMlDCBFjSlTtOh68.cache
226
- - test/dummy/tmp/cache/assets/sprockets/v3.0/u-/u-8MlgYJTKG5XosY4wBeyytbkS581QUBp6M3jwob82c.cache
227
- - test/dummy/tmp/cache/assets/sprockets/v3.0/vk/vkZdW5MBiFdQHWCaACKYNgJd9pD_heV3KjZs5pY4aIs.cache
399
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/q8/q8fTGiTy76lCLNbNwWWd9l7vwZj-7UQAOILzuNpyPYE.cache
400
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/qC/qC9rgHGmZKwnZ8QdZB2jEU3T7-_a-ZwdCP-cse12hcQ.cache
401
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/qG/qGAmOmX47-Od1oIVpNpRm0QtluFKIG_YDrBxg92f_Qk.cache
402
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/qa/qa3eRLDemADWcqVjtdOy1Rn3QtrRcIxpEm-GJQK8VIw.cache
403
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9BXtR-nk0bHNNjdnm89FiY3vzg326WQ0cozcR7MAVs.cache
404
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rX/RX0qkXXVT2XvXlxf2UC2FX1cNADKfsTUaoqdW0XdgvU.cache
405
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rX/rXOJ0KA20NEA1hDNnr9Vhh7tAjsRU6oFuC9b2xSX7Wg.cache
406
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rm/rmSkgYSgACYLjfteWUTVHgLRF015ih5Ghn5hPGzr6l4.cache
407
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rt/rtmN66UYiZRgWN-5O6RltSKgB5FfJjrpo6WGuITzsak.cache
408
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/sA/sAJQRjCY3ZHLydFrYlHqT7wIPCHWKxekLe1n7pFZXSc.cache
409
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/sm/smClQJEaXbOXsJz0VnFW9TkFrmIyIXf_iC6PVz61bzo.cache
410
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/sy/syQjP7AEbQA9Rtv5DQwdHhgxOttKIr0bTu-fkgastLc.cache
411
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ti/tiXJRasL-8irn9-ucULKRcizf-T5j6chc9o9TiGbLg4.cache
412
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/tm/TMgw-aQC9dgBPc1BXBy62shB9NoqoN9W_ExXyTJ2lmg.cache
413
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/tm/tmQCbe3HULQeoxiX25lw9r9G-l0x3N0GUBd3Q3E_Gg4.cache
414
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/u4/u4yRYa-sHfUpWhua-XHN5xqt-JDg27-7PCqWYOZ224s.cache
415
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/uR/uRsMGxtpdSbYT4BnABXQz1hmlUPS0ni3GZRhNilmVTw.cache
416
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/uk/ukyUQTHe6_q46nFt1pNk8lHJ7yMXClSkvMKEITn8fXw.cache
417
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/uq/uqqkZXvLr_0jkDyOG0Y7A6eKYk4NMV5wkIjfV_Bjluk.cache
418
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/vA/vANYosMYbDyO0OInbCnKkq5uvcQxvkOvhEyRDu7wa0Y.cache
419
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/vL/vLGD24TdjMqkMC9OulNocvIxraeSSi9ZkIyBImgABnw.cache
228
420
  - test/dummy/tmp/cache/assets/sprockets/v3.0/vy/vyYy1Bc7NhRijtwmLDahiYL4cbniLDW8FDb15jHT62I.cache
229
- - test/dummy/tmp/cache/assets/sprockets/v3.0/w1/w17AnoGy2EExgSUDbqpQ9wTF6Gsyo45geeQhF2wllRU.cache
421
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/w0/w0eQItpBpGPhWcCLqMgaLY0JLZXutLWFcsUTn1qR5pk.cache
422
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/wF/wFlOPYS4FNz7cD-_U_rwg8F8PUn13yaWFooOxfJo4P0.cache
423
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/wc/wc8UYUZjewZhupzm83IS5YSBKTIWJ_JNEqnHY7YxFMc.cache
230
424
  - test/dummy/tmp/cache/assets/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache
231
- - test/dummy/tmp/cache/assets/sprockets/v3.0/yn/ynr5ukJ9QD4J7P9Of9s-s-NY_o659ZDZ_fOOr-M1G_w.cache
425
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xF/xFZYxCrU064E66OKGh51d8_W4JWUwaoWLBq1AFAZPIU.cache
426
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xL/xLXcC1BEJrDSHD7y1h23lTfN3Ipjl84ZykUSTAkjR9U.cache
427
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xN/xNdFjDVsGZY_vt30-9CATW_bnmspkJv5B2qWzbO8u9U.cache
428
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xT/xTFokDlBnhGaP-69TnsrL746Sv_W8kX1v-ddbQK4P6U.cache
429
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xd/xd635CIGQo56JO8fL5i8Dy1msteAYQjpiFthBFWAUIY.cache
430
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xh/xhJCi-D9afo14RwqSYDWL1i747D8B6k9_jmRfJSoYGg.cache
431
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xi/xiNNGLgEegeUG_f4ZTKGOh6ba_XNjRdnOcvboWindM4.cache
432
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/yJ/yJsY6xrDWnxzzJt93h8k-4GjMeSMrgoKkrTrV7xl17Y.cache
433
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/yL/yL0bdmM8VCSMv3PrRzxQuK97ryFH5AwWy-S1S6SPCV4.cache
434
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/y_/y_DWqm2YPyqW8nf9NKBld9BoSili1-763FurOXM--XM.cache
435
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/yo/yoAO2cAGL23s9uCXo3NeFZcXWdsm2is6LNPR9BTaz9E.cache
232
436
  - test/dummy/tmp/cache/assets/sprockets/v3.0/z5/z5xi0xizT_upzhmbLHIO97TA6HzJ4MmDwg5RKHDAuRQ.cache
233
437
  - test/dummy/tmp/cache/assets/sprockets/v3.0/zJ/zJqqUJchm4LP7TqM8CZ8ZjGkDrxe_k2_Yum4WUCIxjc.cache
438
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zO/zOeLSHXDQa1VugXjg2x1RO19C5bav-CJ5e6el6syIcE.cache
439
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zc/zCK3gD6LO48YyjRHsmCq52KaC6MfOcn-2PLhvdGgNpA.cache
440
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zc/zcV1wOXds_ytFpSvePYmuQoXrSwPHLM8TuSfnyhmYuM.cache
441
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zu/zuyy-EWaEKL5Sx0PP_173Hx62_I-53Q-yJrXsIYvZhc.cache
234
442
  - test/models/console_session_test.rb
235
- - test/rvt/colors_test.rb
236
- - test/rvt/engine_test.rb
237
443
  - test/rvt/slave_test.rb
238
444
  - test/test_helper.rb
239
- - vendor/assets/javascripts/term.js
445
+ - vendor/assets/javascripts/xterm.js
446
+ - vendor/assets/javascripts/xterm.js.map
447
+ - vendor/assets/javascripts/xterm/addons/fit/fit.js
448
+ - vendor/assets/javascripts/xterm/addons/fit/fit.js.map
449
+ - vendor/assets/javascripts/xterm/addons/fullscreen/fullscreen.js
450
+ - vendor/assets/javascripts/xterm/addons/fullscreen/fullscreen.js.map
451
+ - vendor/assets/stylesheets/xterm.css
452
+ - vendor/assets/stylesheets/xterm/addons/fullscreen/fullscreen.css
240
453
  homepage: https://github.com/gsamokovarov/rvt
241
454
  licenses:
242
455
  - MIT
@@ -256,147 +469,357 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
469
  - !ruby/object:Gem::Version
257
470
  version: '0'
258
471
  requirements: []
259
- rubyforge_project:
260
- rubygems_version: 2.5.1
472
+ rubygems_version: 3.0.3
261
473
  signing_key:
262
474
  specification_version: 4
263
475
  summary: A VT100 compatible terminal, running on Rails.
264
476
  test_files:
265
- - test/controllers/rvt/console_sessions_controller_test.rb
266
- - test/dummy/Rakefile
267
- - test/dummy/app/assets/javascripts/application.js
268
- - test/dummy/app/assets/stylesheets/application.css
269
477
  - test/dummy/app/controllers/application_controller.rb
270
- - test/dummy/app/helpers/application_helper.rb
271
- - test/dummy/app/views/controller_helper_test/index.html.erb
272
478
  - test/dummy/app/views/exception_test/xhr.html.erb
273
479
  - test/dummy/app/views/helper_test/index.html.erb
480
+ - test/dummy/app/views/controller_helper_test/index.html.erb
274
481
  - test/dummy/app/views/layouts/application.html.erb
482
+ - test/dummy/app/assets/javascripts/application.js
483
+ - test/dummy/app/assets/stylesheets/application.css
484
+ - test/dummy/app/helpers/application_helper.rb
485
+ - test/dummy/bin/rake
275
486
  - test/dummy/bin/bundle
276
487
  - test/dummy/bin/rails
277
- - test/dummy/bin/rake
278
- - test/dummy/config/application.rb
279
- - test/dummy/config/boot.rb
280
- - test/dummy/config/database.yml
281
- - test/dummy/config/environment.rb
282
- - test/dummy/config/environments/development.rb
488
+ - test/dummy/config/secrets.yml
489
+ - test/dummy/config/routes.rb
490
+ - test/dummy/config/locales/en.yml
283
491
  - test/dummy/config/environments/production.rb
492
+ - test/dummy/config/environments/development.rb
284
493
  - test/dummy/config/environments/test.rb
494
+ - test/dummy/config/environment.rb
495
+ - test/dummy/config/application.rb
496
+ - test/dummy/config/database.yml
497
+ - test/dummy/config/boot.rb
285
498
  - test/dummy/config/initializers/backtrace_silencers.rb
286
- - test/dummy/config/initializers/filter_parameter_logging.rb
287
- - test/dummy/config/initializers/inflections.rb
288
499
  - test/dummy/config/initializers/mime_types.rb
289
- - test/dummy/config/initializers/secret_token.rb
500
+ - test/dummy/config/initializers/filter_parameter_logging.rb
290
501
  - test/dummy/config/initializers/session_store.rb
291
502
  - test/dummy/config/initializers/wrap_parameters.rb
292
- - test/dummy/config/locales/en.yml
293
- - test/dummy/config/routes.rb
503
+ - test/dummy/config/initializers/inflections.rb
294
504
  - test/dummy/config.ru
295
- - test/dummy/db/development.sqlite3
505
+ - test/dummy/Rakefile
506
+ - test/dummy/public/favicon.ico
507
+ - test/dummy/public/422.html
508
+ - test/dummy/public/500.html
509
+ - test/dummy/public/404.html
296
510
  - test/dummy/db/schema.rb
297
511
  - test/dummy/db/test.sqlite3
298
- - test/dummy/log/development.log
512
+ - test/dummy/db/development.sqlite3
299
513
  - test/dummy/log/test.log
300
- - test/dummy/public/404.html
301
- - test/dummy/public/422.html
302
- - test/dummy/public/500.html
303
- - test/dummy/public/favicon.ico
304
- - test/dummy/tmp/cache/assets/development/sprockets/0509a6e0e75d9ac5a88bba7291b04686
305
- - test/dummy/tmp/cache/assets/development/sprockets/2bd9d10dae311aa2dfb6dea9c1e0ad50
306
- - test/dummy/tmp/cache/assets/development/sprockets/2f41a6a41d0a16db31cabd2b8689ca00
307
- - test/dummy/tmp/cache/assets/development/sprockets/4de66e84a0d6f009fac50cd608fb8581
308
- - test/dummy/tmp/cache/assets/development/sprockets/56e8026311075410507152df2aea4307
309
- - test/dummy/tmp/cache/assets/development/sprockets/9542de15712d45f70221931bf78c00e5
310
- - test/dummy/tmp/cache/assets/development/sprockets/98cea396a602c53d876e79bf4b89de3b
311
- - test/dummy/tmp/cache/assets/development/sprockets/9df3968b0f171feec749766fffa50b2e
312
- - test/dummy/tmp/cache/assets/development/sprockets/aa5fc4cb46c5294192c9d3af8824f88b
313
- - test/dummy/tmp/cache/assets/development/sprockets/ac7197dc7dd9ab362d915d19e37a8e01
314
- - test/dummy/tmp/cache/assets/development/sprockets/b238befd6eff46b26d56322c1450ea45
315
- - test/dummy/tmp/cache/assets/development/sprockets/c69b8b79c21fd48ad84c3fad87945a5c
316
- - test/dummy/tmp/cache/assets/development/sprockets/da4318a4d8364d0616edd706508371bc
317
- - test/dummy/tmp/cache/assets/development/sprockets/dd71b14df42fd6dc95355cded9e4d0f9
318
- - test/dummy/tmp/cache/assets/development/sprockets/eb06cae1627276e46965809e766aff13
319
- - test/dummy/tmp/cache/assets/development/sprockets/edffb5017d27ddb65965203636286405
320
- - test/dummy/tmp/cache/assets/development/sprockets/f0ced5f3d4a75fce1c596d6c3f97a42d
321
- - test/dummy/tmp/cache/assets/development/sprockets/fb9e611526e612ba797f0c11b987826b
322
- - test/dummy/tmp/cache/assets/sprockets/v3.0/-K/-KiIicXUmKvS01lViUN0fVWjnk3WG8R7AU8KuOnsq8Q.cache
323
- - test/dummy/tmp/cache/assets/sprockets/v3.0/17/17pGZu57zKoZ94QZm4aKckh0sCZX8b7JQLSsbcOHHVk.cache
324
- - test/dummy/tmp/cache/assets/sprockets/v3.0/1H/1Hh7ihf7wCWWVBUS9Uoixm6HpfyOHzMv-2Tp36h5sAc.cache
325
- - test/dummy/tmp/cache/assets/sprockets/v3.0/1e/1esrtnLnKK8hR4ALg2UF3qhvLJB3u75jgYYlwr3BtiE.cache
326
- - test/dummy/tmp/cache/assets/sprockets/v3.0/2l/2lShAF_y3QIpyv7eGEC1oi2ks8II1yOglQYzZuI3GlU.cache
327
- - test/dummy/tmp/cache/assets/sprockets/v3.0/2p/2pfdtD4Unn94fgfTvW9IuHcslz_aC53bupzRnnBTjz8.cache
514
+ - test/dummy/log/development.log
515
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/59/59Iv0zYsO0kAjBBmTxvYbLZVI927cQTdpxMz4SkxcsA.cache
516
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/SK/sK4Ow1R-Wh4ug8uCzmjHxk66Idr1-nrEEKCP352aD6I.cache
517
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/SK/SKXDgh9EyOqMCaRQDvUFTq6OorSkeqj2XIJ4uZlEWQg.cache
518
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/uR/uRsMGxtpdSbYT4BnABXQz1hmlUPS0ni3GZRhNilmVTw.cache
519
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_I/_I3O1hBJhyYQ1ZgFT81XRhXgoG4pqNxgfAGaWklXzTM.cache
520
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6S/6SlQBk1nmBw_S2wU9RDxn4VC-QEPgkzrKDIcfWoWNQk.cache
521
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pm/pmgvDDjavDz10BkFzD-EJtoEinfdu3nJQbbRhXwUNaE.cache
328
522
  - test/dummy/tmp/cache/assets/sprockets/v3.0/3E/3Epa2d1ojZZbRfi_AL5pJqQOAeDXHvA6ne0Hl0vuO4A.cache
329
- - test/dummy/tmp/cache/assets/sprockets/v3.0/3V/3VuACKK5EZL0kFdIsulnRkj_H33Bhgt8rWXOQ3GtxK4.cache
330
- - test/dummy/tmp/cache/assets/sprockets/v3.0/4f/4fGELkMBNoXbrN_1xBFotqQ7TvvnD6wqNwzTIQxQoig.cache
331
- - test/dummy/tmp/cache/assets/sprockets/v3.0/5E/5ESZnaE5qh0iYvz9xmZmrU99psPmVEF9xbaOmhKjVd0.cache
332
- - test/dummy/tmp/cache/assets/sprockets/v3.0/5H/5HcK5g4Hf81q5eDV-D2FxWhFvU-FQC_0xXhORcReKFM.cache
333
- - test/dummy/tmp/cache/assets/sprockets/v3.0/5f/5f3EHjGVDFwHFPyQq5uKHDZpnzyuP21Bb2vs0abI_Uo.cache
334
- - test/dummy/tmp/cache/assets/sprockets/v3.0/6C/6CwrwCCdUsKoCchA9tI10DcEXTuTcCCvuaOWGBum96s.cache
335
- - test/dummy/tmp/cache/assets/sprockets/v3.0/74/74nSxlehXGJRbD0LU0Iba6VeJuNBCprOS7zalbnRXdQ.cache
336
- - test/dummy/tmp/cache/assets/sprockets/v3.0/80/80iuGcmJDTntKnnQNhnTc6BWK-fhydrU0ll3jrc-jxE.cache
337
- - test/dummy/tmp/cache/assets/sprockets/v3.0/8V/8VDZPz7iaeHUAFJM6c__4RL2qobs_HxEfh1cvN8X2tE.cache
338
- - test/dummy/tmp/cache/assets/sprockets/v3.0/8W/8WO5VcJOFOrSWseN2SKniU76vW4j6komRdMzmvQwHOQ.cache
339
- - test/dummy/tmp/cache/assets/sprockets/v3.0/AN/ANlzs9QWeQu6lYeBwGWFcK00sfOTLMsFsZaQzrzTEIA.cache
340
- - test/dummy/tmp/cache/assets/sprockets/v3.0/An/Ana-_KrSkUp0SHOpAG3yEY_792tMopenBFYRnrEemRQ.cache
341
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Bq/BqY9mFfdK9O4325lbO_-_QZCbEZuGiNguITrgGRIfNM.cache
342
- - test/dummy/tmp/cache/assets/sprockets/v3.0/CJ/CJgfggUIbMu6MezYEC37omvMYp4wuEDiRmhTyfbTt54.cache
343
- - test/dummy/tmp/cache/assets/sprockets/v3.0/El/El6sDelFE4zi-yos85eKdhytxd04vayUxI1EvuqbEEU.cache
344
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Fx/FxJAcBo8p4ampqzXZFkXwX2Xx58e9sA2MznNT4tSb4k.cache
345
- - test/dummy/tmp/cache/assets/sprockets/v3.0/G1/G1bLOMv8ry4OZIOE6yamFeLyspUWFH7F5uHQsvx3L-Q.cache
346
- - test/dummy/tmp/cache/assets/sprockets/v3.0/GF/GFVuBv-xJC6l9uzpvIkeOzFpM_wrzgvn5gJpRJZJQYY.cache
347
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Gn/GnRhwIvx6FcsFco_Zaww1BSo7PCh-rHEJnmYByESMmk.cache
348
- - test/dummy/tmp/cache/assets/sprockets/v3.0/IR/IRkzGfhZ_j61PMxiMlMuiO5_8GJrPxVz_q1fUw8lELA.cache
349
- - test/dummy/tmp/cache/assets/sprockets/v3.0/MY/MYYdkkZJkduDmx4PCuuPiiFBaKv90qOpaPFoon-wg1Y.cache
350
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Mc/McQLAeERc8_h2GV4r_RSiTspx4ScOecJluPorLvWQv0.cache
351
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Ol/OlJLFMx2ecfQUa6QubAYEN6Nef_1Jk3rIggdhypnhKE.cache
352
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Or/OrmkzKYvYsup9pzrnDM4jqhxXtZ49RvP0eCaqe3chvA.cache
353
- - test/dummy/tmp/cache/assets/sprockets/v3.0/PV/PV-WmLYkFJdjKgVXpPxYl8nhQBu5frexNF5_DIbQKSM.cache
523
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_n/_nWbvBOATVfCe68YFH9Smg9ownps3aoUyyN-9NQRtQo.cache
524
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_n/_N2fgzGU5Oqu3S-Vn-Msc_0cpHMP_nshxJ9WFOviKbs.cache
525
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zJ/zJqqUJchm4LP7TqM8CZ8ZjGkDrxe_k2_Yum4WUCIxjc.cache
526
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/vA/vANYosMYbDyO0OInbCnKkq5uvcQxvkOvhEyRDu7wa0Y.cache
354
527
  - test/dummy/tmp/cache/assets/sprockets/v3.0/PX/PXDoBSysxwUQ75MPgOPOBIWnQAIxz2cwO9JxLqc4cXA.cache
355
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Po/PoeLkPEvD2iajH_gaRh-sIFdCZ-jEaac8_Kdt5EnBH0.cache
356
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Pq/Pq9EEQ_PUKpcnBH_AwZ_F30lvjSNXlN1hwaTn5zBllI.cache
357
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Qy/Qyi4pqtXinXLNBYkB-lXsfCpaw560tlqG997Omt9hjc.cache
358
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Rp/RphNp2ADQ6h0qpBMeRGccIFKL3cPNnEyRszHOHNcwV0.cache
359
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwyuRMymf6iaEYfNIbHrWaQ4RnWQjgWxlgjHq5vnkiw.cache
360
- - test/dummy/tmp/cache/assets/sprockets/v3.0/UL/UL8LL9y5J1u3L9SdvG8_G_gHLE_rKFsUeAlq54HNNqE.cache
361
- - test/dummy/tmp/cache/assets/sprockets/v3.0/UX/UXDhiw_eV2_5-uhXuG5hggT62vcTU3mRXVHdd8hwNtI.cache
362
- - test/dummy/tmp/cache/assets/sprockets/v3.0/W-/W-l_iL21hjDik06px3y0cNxwRax-wcyMHqCYU44IbCs.cache
363
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Wr/WriPF39G9moRbujaXvonAiEHjjgypR1iqYJrCkxmCpw.cache
364
- - test/dummy/tmp/cache/assets/sprockets/v3.0/X5/X5A2BcGLOrFB27HxUPfMTY1R9Pc_V4dlB49BKzEkbI4.cache
365
- - test/dummy/tmp/cache/assets/sprockets/v3.0/XW/XWSxy-Iv-mixLzAfY2etVgorBgWnKcDzPvc5JYtv8ZQ.cache
366
- - test/dummy/tmp/cache/assets/sprockets/v3.0/YA/YAiXkO3U70SeVjjP9Z2vDilLSy0F2KRSPYTtPHMfZ_8.cache
367
- - test/dummy/tmp/cache/assets/sprockets/v3.0/YU/YUnPOcXA7tScQSqfkzbf-VVnrkDph0mOtFRWXdA41CQ.cache
368
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Yg/YgzFmnUV-Bc8yd1PJan3HIFu4EI8kc4q220Ea3F-lnM.cache
369
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Yk/YkC1ANqSFWUmQhl7MGjSK_iCs_lP8mVO5QaIjn-Mdy4.cache
370
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Z5/Z5LXG7HQ6dbcPnio52VUtebna6NdsQmvuJCMq01Vths.cache
371
- - test/dummy/tmp/cache/assets/sprockets/v3.0/ZJ/ZJjFVQk_XGGXlz4fvvlEWY-4Wy0ZaJ6WrBHSzpiBIm8.cache
372
- - test/dummy/tmp/cache/assets/sprockets/v3.0/ZT/ZTsUUbGZ_rkYZ41o_lsp46dSuiGxGeOt4Q5BO3tRQHo.cache
373
- - test/dummy/tmp/cache/assets/sprockets/v3.0/Zy/ZyyIY2PVVJpW_kZNCpOdjl2WEzSM8NsQMisOdGTIO54.cache
374
- - test/dummy/tmp/cache/assets/sprockets/v3.0/cJ/cJPDe92SSVjhN0aWjrgKTT4kS0Fok6FVUS6Ucf3CQ4k.cache
375
- - test/dummy/tmp/cache/assets/sprockets/v3.0/cW/cWtFGImKhUS7JYaEIBNPmFmtxIokpNEtprbrIu-KYLk.cache
376
- - test/dummy/tmp/cache/assets/sprockets/v3.0/dd/ddQSSbSqtYqXeXJfq9MgkETEBISNXYRzE-wIPkcv9s4.cache
377
- - test/dummy/tmp/cache/assets/sprockets/v3.0/eR/eRFxgeqg4P6SKIaqiHeDezODcKT_sMwFyGfqtPmu7vY.cache
378
- - test/dummy/tmp/cache/assets/sprockets/v3.0/g2/g2c3cRllZCQaG2kipoX1Cr40y7Lmne7Xp0JWV2rFVnk.cache
379
- - test/dummy/tmp/cache/assets/sprockets/v3.0/hO/hOh9hLhXju7HOOyQ22B04x2-tCSXXkAhbyXVbTWGwQM.cache
380
- - test/dummy/tmp/cache/assets/sprockets/v3.0/hg/hgu4xAfu5uOcafMf7-jA-qLNDcM7XgWFdwAfHjN4mQE.cache
381
- - test/dummy/tmp/cache/assets/sprockets/v3.0/k0/k0Sfk3cETJbZWYz1xsnnpgAn8xbzpBM8rJT9ffkdqnk.cache
382
- - test/dummy/tmp/cache/assets/sprockets/v3.0/le/lelLtTsvG67CE4gtCdbS_eRsDTCgrhSWFTg_t7gBbWI.cache
383
- - test/dummy/tmp/cache/assets/sprockets/v3.0/mJ/mJ_7-eeiChJdsNIN2gU0C9i_AaqnBmj6SaqV3I7nCe0.cache
528
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/V_/V_BAjWq0DWEzo0Q9NxcSp1nTj7iAm1rSDgxuJtOeuxM.cache
529
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pv/pVsGEIR7lq-PoM18-0M-xxR1YI5AgKN2v4J_3R4gXI8.cache
530
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pv/PvtPIvLHDp8JiNt2UJYleFfw-pkzgfMqtthHiroXjes.cache
531
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/sy/syQjP7AEbQA9Rtv5DQwdHhgxOttKIr0bTu-fkgastLc.cache
532
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZD/ZDvHyfCXyEa5qWOXwktQRcABbe8waPNPw4fY5Z_D5Ak.cache
533
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZD/ZDKXHhzn4B_u92sZ8xLetjlnyNFvYzKaNkLm1BSPmVw.cache
534
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/yL/yL0bdmM8VCSMv3PrRzxQuK97ryFH5AwWy-S1S6SPCV4.cache
535
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pq/pqpMzQ1IGWV58QESaBli5VpFIdwysPKJJcvDwSjJTYA.cache
536
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zc/zcV1wOXds_ytFpSvePYmuQoXrSwPHLM8TuSfnyhmYuM.cache
537
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zc/zCK3gD6LO48YyjRHsmCq52KaC6MfOcn-2PLhvdGgNpA.cache
538
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9K/9KsWd_r6PFFDBiRGxGr_lCfV5sFTVN7MuaRRgoM9aBM.cache
539
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_o/_ohnYmY_vC_G7Vqan8sUzJmaquB6QhcLYGc77DKtc4s.cache
540
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/z5/z5xi0xizT_upzhmbLHIO97TA6HzJ4MmDwg5RKHDAuRQ.cache
541
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6u/6utay7VkqNIFbt3iHF-zcMOH74369hxhR3JYj3T6ADA.cache
542
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5Z/5ZXwjMKqJ-A2yXE3a0dbIrikKYZVnk3fui4DMmz48lk.cache
543
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/56/56SaNws-UaxyLsj8oMU8dfsUZtzJPqSuWcS6sRy7ZL8.cache
544
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Yv/yVbylE1uhnqOlfStbQfwubjvWQMoFD1q3oNBG_fjefs.cache
545
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Yv/YvXQz5sZHtXCVO0wvmHeQxJHheo5GeID88vKbtpn1vQ.cache
546
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6r/6rhsKfTxfHYeMdDJC0WTG5MoSqYnTIm3cUbsSunotic.cache
547
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pe/peB66vL_jJOczpV2_nGLjkEysGH1NhHdDGl_ZS_v7hk.cache
548
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Sj/SjIvNMfbTzxUiVzh1O6oIQopMViI1R-4kngOcPfzd1g.cache
549
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5s/5Sn1CbCVqNNz4NjoX4qkPHq_wtTq8UHU5UZiw8UOirk.cache
550
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5s/5sZ1gCXEFuPIOk-b4vWbEKq85JXMK8TffZzNKl8pNDA.cache
551
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/sm/smClQJEaXbOXsJz0VnFW9TkFrmIyIXf_iC6PVz61bzo.cache
552
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pP/pPyIvuoG5HNslNZnl6WuQyv0GTL50R4LB6MkifeioTU.cache
553
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Uf/Uf9tPce43D393aktdyXRO5iSVQ0wUrFcZHWbxIFfVfY.cache
554
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZB/ZBXrd5AdUsWldhFyk1EVuVGU2yXlFGyhVMjxiEiqMD0.cache
555
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/yJ/yJsY6xrDWnxzzJt93h8k-4GjMeSMrgoKkrTrV7xl17Y.cache
556
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pw/Pwh4JIc1ad7UEbvoZEs9fa2MoW-Xp9NdDX4eN13EaHY.cache
557
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/0p/0plJ6fG2bnSD-EltE32bpvmWlzM_EJ6rAbl_gfA6a_g.cache
558
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9M/9M8NdCdd4J5xZPOf5nbgcdAuWfqzH3Pi0m95Fi0cCX4.cache
559
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Zl/ZlzLk4d2MKNw7UD22N9MXbsv30UXQxKBdZV1Bf7ngvc.cache
560
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/0Y/0YioaTGG5pPIt_8ZprcTZY9grFYXnvHrWwAm0D-2DvM.cache
561
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_z/_zs_atfF7ypRzG5AvIBCfqZdYM0PBLuvYjNWpDI6BV8.cache
562
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/SV/SV1EOoJ3cic6j5f4MaYQUFeqzLuSBzJAklpvDlpj-Cg.cache
563
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9c/9cLL-WwQAfVZYDPvfbpdtcnYqB0twxXZFAIYo_bIwDg.cache
564
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9c/9c58KfTtMtK_q0IRLv4Ohe6Ku9NR8cTvzNsUUwvFh3o.cache
565
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/py/pyoxXth3hjzgIEciAO90l0vIVCTJgEXsT4OZCMgq2Sk.cache
566
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/YD/YDoprxxinr4AALGFMWIqUKHOsP1uajTUXYifinKaPfo.cache
567
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/a4/a4bEtdZMtr3Rt6Y0CVkFV0sIWWx3Bv86mWyfkbaeFfo.cache
568
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/BW/BW1UGENNCOM3Axx_ShFZhHwm4_bcDP1QyQCk98WBayY.cache
569
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dn/Dna81lRfs6LHDdI5NVoLGXYJeCMPN4zfWXe-PwqMzAg.cache
570
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dn/dn8JjucKlRBMIvmKNSXxQ6j1zuvW_Wy8yyP_2_uNBt8.cache
571
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/a3/a3Cwa31etUxox1CqQ6uxNrEpbGHLDJYFfG7Nm3fhHlg.cache
572
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/MT/MTBWM31BtwMKG_GwIhNdso8ZCuY8XQJbsSdHL8K8B1w.cache
573
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hk/HkwIX77oB82LdxxnXQtQR8zqpUlYQ9sTRNSAaRkvLtA.cache
574
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/nr/nr4V60agkWIjRWDV23Auh41K0GRcXp5ctSoOyfQ1ANM.cache
575
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/av/avZJH3ARnrLfgPgYHP8HVxOLiVh4EzcrKakkNXmsahw.cache
576
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mz/mzKBIxymZpXit4v2iRnRXIK5uUIS6uUZjI0W9LZ2Bh0.cache
577
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GH/gHYDXMvegdiaMifmauTVm8Qy1gOSnoiKAnsCwAmMM6Y.cache
578
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GH/GHMro7l5elRwkZW6ocgvpEWdY-bCMla0J0BPd_6hqoE.cache
579
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Gz/Gzbr2w7v4jG0Hk3mkrGRhUAVf074dfK-SbaCRp1BPqU.cache
580
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mO/mOP3Sm9m1M6TmWps33skF4hvd092don0dHlobn9ems0.cache
581
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bk/bkim99ppC3FdpJTtMaGS8CllO5Jsbuf8GWYZeaarv5Q.cache
582
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dr/DrolWmSngZwPNXKJkGrfADLMhMbJdhfqbtihKKUM4cU.cache
583
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hy/hYomtUCsrKd36M73vuN6TqMogPeLrU6NIOu1wAKRxf8.cache
584
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hy/HyBjVqV93QJMiSmyiNNHd8W7bwg3gZl-hf5grEk-wgw.cache
585
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ad/AdR0Qt_GcCj_0fxwl4lvjCAfJXJT8iwZb5RzeJt7X-g.cache
586
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ni/NiUFiKzq5amff2RZ37XuDkcPgTcuD49nRbZgDY_PhoY.cache
587
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mf/mfK3V0cWrlgG3paJRNUczrUppBoIWAam-b6p-J_WlQk.cache
588
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bB/bBHfqPuo9gcrr8VUkavCPSBGbUF-q7vj4cc_p-fiylw.cache
589
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bB/bBj0Q2GCK3NR7kP5sTE38luc6soBv7DS5tcWB-4etfI.cache
590
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/D7/D7AIWNFq0HwRCrpFDzdbYrc8vmqErySsARjPklXlAPg.cache
591
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/D7/D7s3i6wBxXKuXgmEi_xluk4ktUowNkkMSuUk72Qnd3c.cache
592
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aj/ajcmeCxc24RkfJfq10l_S42XKGIwjKLG_fS5qG-xhHM.cache
593
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Be/Beyr-TRQYnkjEqSn8chN2Hhh3kVAbSR2_IhK9orJ9Xk.cache
594
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aP/aP_Mu42a9d_0j4KTczl266PjVyHmZEqgvJYTFCB3JUo.cache
595
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Da/Das9TcLHrt3FfmNKQgMbCTg8BsYF06X7x2gFXvoVsJg.cache
596
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aw/awYTeITVFdmTsuRvIYv9CdXF__4X7EsFq0F-dq8geFQ.cache
597
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Kl/KltQXiJL-E-5FOYGticndlKA3HlOHmK6bmXS2sSgpK8.cache
598
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ay/ay-1nEAOxGhFWl_HkBancemF5i0_jTIDS288Lob9ro4.cache
599
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Bv/bVWlBMMWMQVoW83IV4Qf9L-ABRxEV6rmp6xhGgd2VNU.cache
600
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Bv/BvSr8HnNGZCLi7shOVomsQuAT5dX8IPGkepQ6tNxGUI.cache
601
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Do/DoZ1miHFIc0Zu4xRyikxRSM3bAXfrYlVbFNTB1qY9Os.cache
602
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NO/NOSTEerYscJRYOB0fDhXWg8n2Ubns32JK_g_XeyZzEg.cache
603
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/mG/mGHo3qDusQEKkkocFHTDR0J5EMIlrzROC_2ghaZYAgk.cache
604
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/bJ/bJkQ_dSwbtkZYujIu24wH5tu8HiLFig-qHDp8Wt-Zps.cache
605
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/g0/g0APGuGiB1phtXXtTsLBLkQ-k8h0GLn13mEMVmsWoik.cache
606
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ae/Aez3Ln5GSo40ydxFzrQOFnySToV0-GnCIqhX3Z8PxjU.cache
607
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ae/Aeswx4jbWYCQZlAPoZ6eOpckcVwEIQaCdyIEZ4yZ1vo.cache
608
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/hX/hX_1Br_XYMH3o5EDrBCM7jD4AR9iJhUNHzhUUMAksV8.cache
609
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/D8/D8A7QhUYhnXJ3LEEFw9NrHww1rN4Ky-LdBB0bOtK9Z0.cache
610
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ld/ldfozoSusCzw0GM19A6-LvzzAfrx_RQrGmDDLogloFs.cache
611
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/fX/fX_OzRutFSBkeYwpekI2H5cO-eS9CcXIXE6dyFj3E5U.cache
612
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/f4/f43dOSIXprZE-wii_NU6nSxA9LvTdEe8MPpQ7jvBk38.cache
613
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cN/cNI6iuD_nmI1oyibhmC2qXY4pWeTn9IfdkLkQSoPg5g.cache
614
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Js/jsZpWqO6fd3TZYojdhzziiohSmF0ENGFCUg-aw4s-eQ.cache
615
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Js/JsgdFJryO0r77umcztaF9gLlmMfEbMilAOjggdfgc60.cache
616
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Lm/Lm4AZ7UdsY463umaLuG6r9t_FwjjmXyOoLZe65t5Lgw.cache
617
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Lm/Lm4LVfF3ZLeTOosUYRZ02bLL9eJ_ufm65YSM57c_iLw.cache
618
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ci/cicVHpT-BWeQrpUOhGl0awCCV-kddJZ06zia5IPuMas.cache
619
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EP/EPCJCAFRp5SWXenODKp7J3-LOEeQHXH3sPfaf1bHSSo.cache
620
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EP/ePBoUwOrluPhUdXqfhIpGf3zPddq1_3-Vg2oNLOewMA.cache
621
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ii/IiSw3rEjcPrbR7bHmv79rnIeihj6Ood5ZNVsxwKYqVk.cache
622
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/C0/C005GHkGmz6P2P0YZaw73NcUTDviWT_hspo2V3zRqv8.cache
623
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/C0/c06NLyQZGWQsdwVXih7CfDBuHWmFSM2LspPVvPxrMIc.cache
624
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eE/eE0TmXZi5NoBQ6Li02OT-EMu_GU4EvIhiMa-0Nqls3U.cache
625
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/l4/l4uI_1HekPy0WPa8gOz8XmbUxJCl334KSYSlpFEdSfM.cache
626
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/El/El6sDelFE4zi-yos85eKdhytxd04vayUxI1EvuqbEEU.cache
627
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/jo/jo96mxml_RK1qUCEXd0yVf5dnSLoPqp00LEbETIIb2s.cache
628
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/jo/JobbYwsoKbjQxVXQz7IQbMX23HEyDbSA_zrRPPKhiUc.cache
629
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ch/ChP_e519Fej_qZBClVpu8-bJm11J7UZJaN2wgaXNa94.cache
630
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Od/Odngw58z1w-IdGloSutkpEAhke6MVPpv7hpgz0-136Q.cache
631
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Lk/LkyGhvZlAhiEAeLfI-S9BiXygetNMNsflyOPQuoruDo.cache
632
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eV/eVcQYhEcDW8oispYNiL-Po01tfC2bqPxFHua7qDB3vQ.cache
633
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/lB/lBegfVYn4A81In0Ld3bvxg31hzp6sjlOr7dmdJXGjSU.cache
634
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cF/CfSIn6eMEXDtmjrr7oPouTR1KePajS2uqioW2_gQELI.cache
635
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cF/cF1_z7co1UqOeJh2s_aVQlB05tBGdaNDNi346EGWMbU.cache
636
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ex/ExLUPQPUvttBUmDRlP6aWd7GP5yCWI1o8eKoCeCw3z4.cache
637
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/jN/jNaneI4p8mnSH0z3QpTwlCdeWbFSUWV_C_mRAg5hDXw.cache
638
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/fB/fBcyS9tNmJu_9foxN5eenuH18Jumnw0uTMwPQHORUTU.cache
639
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ov/OveMcuYy1aRyjiisX9H7lQzO7THrJnObrUmbln8Ih2k.cache
640
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Io/IoNdrAbIQw_WQQw1yvFl7FgAf-WGvZ2NM0r64hJolVQ.cache
641
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/JG/JGaR6S0bzqxKeawxt10Lzcm7TfUd3uQytf3jSxEWw48.cache
642
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/q8/q8fTGiTy76lCLNbNwWWd9l7vwZj-7UQAOILzuNpyPYE.cache
643
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xi/xiNNGLgEegeUG_f4ZTKGOh6ba_XNjRdnOcvboWindM4.cache
644
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xN/xNdFjDVsGZY_vt30-9CATW_bnmspkJv5B2qWzbO8u9U.cache
384
645
  - test/dummy/tmp/cache/assets/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache
385
- - test/dummy/tmp/cache/assets/sprockets/v3.0/ql/ql0YZqZCZb93mAbIX-l1Ut97H7xFR7iqs2cLenFIMDY.cache
386
- - test/dummy/tmp/cache/assets/sprockets/v3.0/rp/rpULJhACB9dPnbqAlVkrmJY1TtBillfIpwXuHEJW90w.cache
387
- - test/dummy/tmp/cache/assets/sprockets/v3.0/so/soQJaougFDETlHZ4JMK_lVbAnKBYVa5Bz-HT5zJRHu0.cache
388
- - test/dummy/tmp/cache/assets/sprockets/v3.0/tC/tCEBLgzem7g5HdQk880uJ0dZ_VP4LjyVByw6MszTkjk.cache
389
- - test/dummy/tmp/cache/assets/sprockets/v3.0/td/tdnEBVuuDY8qxEUccGN9gIoQ4UgdMlDCBFjSlTtOh68.cache
390
- - test/dummy/tmp/cache/assets/sprockets/v3.0/u-/u-8MlgYJTKG5XosY4wBeyytbkS581QUBp6M3jwob82c.cache
391
- - test/dummy/tmp/cache/assets/sprockets/v3.0/vk/vkZdW5MBiFdQHWCaACKYNgJd9pD_heV3KjZs5pY4aIs.cache
392
- - test/dummy/tmp/cache/assets/sprockets/v3.0/vy/vyYy1Bc7NhRijtwmLDahiYL4cbniLDW8FDb15jHT62I.cache
393
- - test/dummy/tmp/cache/assets/sprockets/v3.0/w1/w17AnoGy2EExgSUDbqpQ9wTF6Gsyo45geeQhF2wllRU.cache
646
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/wc/wc8UYUZjewZhupzm83IS5YSBKTIWJ_JNEqnHY7YxFMc.cache
647
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7d/7dbFmSW4fCX2-qvOoLwhhfhJJTPdLWjeHizxdcBda3Q.cache
648
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9BXtR-nk0bHNNjdnm89FiY3vzg326WQ0cozcR7MAVs.cache
649
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Q1/Q1UtBSZNuYVzeZLWkWpmm-o7HSOx5D2754JyC1LMGNg.cache
650
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHMR18NuNdQf-g0IxbBD2fEmhSLqd0y1IKyylyutK8k.cache
651
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/qa/qa3eRLDemADWcqVjtdOy1Rn3QtrRcIxpEm-GJQK8VIw.cache
652
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/TP/TPlY8VwBzC6ccuQjmMY7h9G78_cm7Bu721rrL003R3o.cache
653
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1-/1-iOGSnAfu5QzZ-CHEdTitP-5Af_kzPI-bDp0AB7w-w.cache
654
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1a/1aYx8_5kppRwU4tKqFENf59WMr-P_9GPMBEhWSt5D-8.cache
394
655
  - test/dummy/tmp/cache/assets/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache
395
- - test/dummy/tmp/cache/assets/sprockets/v3.0/yn/ynr5ukJ9QD4J7P9Of9s-s-NY_o659ZDZ_fOOr-M1G_w.cache
396
- - test/dummy/tmp/cache/assets/sprockets/v3.0/z5/z5xi0xizT_upzhmbLHIO97TA6HzJ4MmDwg5RKHDAuRQ.cache
397
- - test/dummy/tmp/cache/assets/sprockets/v3.0/zJ/zJqqUJchm4LP7TqM8CZ8ZjGkDrxe_k2_Yum4WUCIxjc.cache
656
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/28/28HQBuBhEKOo4yX8iIWFaWRdRqDOig7S9cSvvD4YLBs.cache
657
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7b/7bah6AfpQNLmcPzUhdVOjJwj-utQzT4Gp13yyUG1-os.cache
658
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Tj/TjFaYwMvTy3DR--WZkLLwXGd_xGrfJQJ_ZlNodTFEx8.cache
659
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xF/xFZYxCrU064E66OKGh51d8_W4JWUwaoWLBq1AFAZPIU.cache
660
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/R8/R86o4eyDkpLNiROsURzRj_ImLR1RVlX5noVgz7zNqDY.cache
661
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rt/rtmN66UYiZRgWN-5O6RltSKgB5FfJjrpo6WGuITzsak.cache
662
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/tm/tmQCbe3HULQeoxiX25lw9r9G-l0x3N0GUBd3Q3E_Gg4.cache
663
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/tm/TMgw-aQC9dgBPc1BXBy62shB9NoqoN9W_ExXyTJ2lmg.cache
664
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/10/10VuBAk2tYbshM7nzg2PmLcyxqn79im6uV-fWNNHSnY.cache
665
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/19/19qxhXovOaykzRzWP6LTFWxznQKx2Vjw9v0cwFeRjko.cache
666
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xh/xhJCi-D9afo14RwqSYDWL1i747D8B6k9_jmRfJSoYGg.cache
667
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/WL/WLeGA295T4fKL__kob_oUqylByYlyIXbyZXVXQ7fEBI.cache
668
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qu/QuJlvJ4kcq52_cknXo5PEpKT8XVOm7dt2ceHpfbQ_iQ.cache
669
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/qG/qGAmOmX47-Od1oIVpNpRm0QtluFKIG_YDrBxg92f_Qk.cache
670
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ro/RoSh3eZzzx7lBF28H0b_lMEE9O5XQEZJaeF7O9FhhRM.cache
671
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qi/Qi73ofNALTcqUT_EgM2MsJO4uof-GO4xf8TBnwUA92Y.cache
672
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xT/xTFokDlBnhGaP-69TnsrL746Sv_W8kX1v-ddbQK4P6U.cache
673
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/4x/4x4SfJ8POcn_5GroGRCTXRl0R74-my-hSiWmw23gD_I.cache
674
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/2A/2Aahz8qIBZ2aqPIl-oqU1cHu77fJCw0Ej5tRsgpQQPE.cache
675
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7w/7wB7Vul6Lch0qdkWDW8X8SzSi2-VR0PDKIStuas_jmk.cache
676
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1i/1ihFGdkP4w8NQXWMtxQ5hyYR1oey0Repp8pnF-h3nPs.cache
677
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9f/9fjyLS5QJER_ouDjFs9r44-2NpIWEr_ARVS7Ejl5uVI.cache
678
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ss/Ss0Xu8tk_PS3RXr_TtbmhnhVeAyE7MCxrPTOTRDVFeI.cache
679
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/YA/yA__0V_x7k0yKI212qKiZJYVV1SlqnAUjo8xA9lETYM.cache
680
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/YA/YAiXkO3U70SeVjjP9Z2vDilLSy0F2KRSPYTtPHMfZ_8.cache
681
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/y_/y_DWqm2YPyqW8nf9NKBld9BoSili1-763FurOXM--XM.cache
682
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/9A/9ArW7CZi8OYRdOUyWUq2ghAXLAqesLT0zF66ys8xS9Q.cache
683
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/yo/yoAO2cAGL23s9uCXo3NeFZcXWdsm2is6LNPR9BTaz9E.cache
684
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vk/VkDp8B06fjIECtYuMeMBZhK07emntw6eGBH9l-CrJPk.cache
685
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/UD/UD4gCZ4M7BhSfwd4hVOqHo_e_m72n8GA6jiSsR5fZWg.cache
686
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/vL/vLGD24TdjMqkMC9OulNocvIxraeSSi9ZkIyBImgABnw.cache
687
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5D/5Dol0kRZNNycXHrUO8ZUfYseFukTciD88UYkntPvpcE.cache
688
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/UC/UCqUT1Xbp58STjhhZ-sMkyqEJ8PvIn59WNJzUPwwt18.cache
689
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/S6/S6VyQhnt514LFU9JWjGg_rT62-EJy4QH5n9Bl7REvPY.cache
690
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Pg/PgG_33ASxui8rv0pM1HsQPrp3QNZbddKMD9jwPdFYdc.cache
691
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/uq/uqqkZXvLr_0jkDyOG0Y7A6eKYk4NMV5wkIjfV_Bjluk.cache
692
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zu/zuyy-EWaEKL5Sx0PP_173Hx62_I-53Q-yJrXsIYvZhc.cache
693
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/3h/3hFbdb8PCPxwgaSG184S_f3_9YiLjPcz7acEsKvDfnc.cache
694
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/vy/vyYy1Bc7NhRijtwmLDahiYL4cbniLDW8FDb15jHT62I.cache
695
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pI/pIvfsBJlCo1lQR93RpavkgL1N4G3Kikd1Qs4Pl-zjNU.cache
696
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/u4/u4yRYa-sHfUpWhua-XHN5xqt-JDg27-7PCqWYOZ224s.cache
697
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/sA/sAJQRjCY3ZHLydFrYlHqT7wIPCHWKxekLe1n7pFZXSc.cache
698
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6P/6Pvzfk4ZiEy6JwysTpNkcpGc6ZxqZmnhrOe341PJ7xE.cache
699
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vw/Vw8hPD2-WLFPWQrRrL0zhoQOWWBnulRJLh_yqph6VIA.cache
700
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/30/30n33voi8xrNL1NGZker1EvTpGZ-cp1ZwGkF-fwX9ck.cache
701
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/YI/YIJ8wGXFsbFBBiPImfLMXYUm0TdGG2INe036faITzDk.cache
702
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vm/Vm7RBeQL13acXlvnlmzQAOR2-3n4sMzD81wvnDi7WjI.cache
703
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Vm/VMD-a78buNTA9zY_iHxPIquL81oFoiZRyUUUTLLifI0.cache
704
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ps/psQe2VtxoTgu7PHDADBGZ1cVzeCrGQIdXf7_0DEK4Dk.cache
705
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_W/_WVL6zcvlXgbkhRMslHtA0rvqTwr9xLq28GF6DoMd0Q.cache
706
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/08/08beTQHREIhjRtoBrxMZ6FHaxhlLwKQqnEPYIVND5ms.cache
707
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZA/ZA3vRhJyNOLHkdrjGGdAxQn56Q6yOTPlQ_uDuzmynag.cache
708
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/PZ/PZyyxCG7Tl8VboaCD1eRsoY6cvDpHu19qJE0KWHl5Jk.cache
709
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/5k/5kRJ4sH7y3qd1k6DTUoC0gbStd0OWKHN1BC44Vo_jMY.cache
710
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/zO/zOeLSHXDQa1VugXjg2x1RO19C5bav-CJ5e6el6syIcE.cache
711
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/uk/ukyUQTHe6_q46nFt1pNk8lHJ7yMXClSkvMKEITn8fXw.cache
712
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_y/_y9FD6kDSeAa5zzj1LFiz-PF8FV_0jr-gK6iDsKWvXk.cache
713
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/_K/_KcWiE5nAEDQpqJfZFqMtPhaeMhihp4UCN4vR5I1S0c.cache
714
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/52/52dj5_sQqYMdp-Jq__CRuim_UPaWd_SVUeoAUhXhk9o.cache
715
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/6V/6VZ7A4vtU3hzw90wVY8hbrWStQ_CVuKbMpTs9tyES5E.cache
716
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Y0/Y0p_hBGflJWS11onCiUbkg3YGi2hbQOLA7Xy4sZ5h-g.cache
717
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/63/63lIk133HZt8Qk4bvvZop2l3fE82b0Dzg7v8rIJMA-E.cache
718
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pf/pfMqjshoLtd1XSMyglJefgksJD4UXBHcZQNawdXm1VY.cache
719
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/pf/pFmcB3iWgwr2YrgnAyzYh8THxlAVyR2mFfvTYHH-YyM.cache
720
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ZT/ZTU_yG8w31YT8Ba71RrGOcDwlSx9oClaYgveZp4ZBVA.cache
721
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/KU/Ku40yz8Vw0tWfXutEd9XACE8NupAyP9XqkCE0XAo4iA.cache
722
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/KU/KU2gDD4G4XnXpghZBiXE1dWnF2RfbX-upKi-50zWTpY.cache
723
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Hz/HzVr6Nm_b4eztKl1iNtoTbiUJg8YovXVVx309ooGcN8.cache
724
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/-k/-kWsWgMXl2ZAF8zZv4r8PS6rm6ffMtUd-Ma8pAT_OJ4.cache
725
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ht/HtmK3dFHJrhu5J-TC1JcX6mYcujL4FIJ06D3YD4XTbQ.cache
726
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dx/DxnCtGUnAQmWQ7Tfzy2kc-YcYwMvz4PrgvrQBgaIQSw.cache
727
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dx/dxlUHAaODLiwtgh6MYuhmrJF13BAshewUD8k9_5k2a0.cache
728
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/A7/A7TBW10ylh4nLlUBMquQ9KQeYJXe7C7tJPNSXKpoBxc.cache
729
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dm/dm__3FYto_fFH4IwEG4qAjhgAQGZuh0zPCzqgZ3bsP8.cache
730
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dD/ddQSSbSqtYqXeXJfq9MgkETEBISNXYRzE-wIPkcv9s4.cache
731
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/dD/dDo8M_nyU7maBGfXwZRMKF_00JeV4QaiKCDXUdtj5yY.cache
732
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AR/ARKOmH6p6jVxoayq2bHzhdLGaYTd8KpX6Tu3QQQAPww.cache
733
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/HO/HOcl3-vJpAuPrL4hm8vHDlGplCavb3ddOz4TrmAZlXM.cache
734
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/kg/kgn1MwDe-7_T00earCMuIoRMLaeOt7S4r7769Pp8M-c.cache
735
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/M2/M2oif3DO_vNyYmPwq_4pSDMO2cr6C7aAnZ30QFarcqE.cache
736
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/b6/b6a9B8W2cWgchjK3aSNjvwbf0xfEYWeTMa5CJCj2Un8.cache
737
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NQ/NQ5GwtrjHgrF979TJAJAIbyn_UBEAME1bZW0xMX5DnY.cache
738
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/gL/gLSHSgXhdqJvlFY1r2EipTUTXI6Z2QBb_pgQ4A4FBhk.cache
739
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/DY/DY2J3UwXRTs-2Q6VBmon8K0OQJTPsamoZwijp7X-bm0.cache
740
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/k1/k1NKoz-AMR9xzRByivuGFkyp0MWQ3heaVviggtIrdK8.cache
741
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/k1/k1-Vu1bnBwnOu3y_QFBFyAtSGlUdvb4uhgM8xsB-_Tg.cache
742
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NL/NL2zRwmr1IQtyc8yRugLhbMmFguaFd25SoYml1o0puI.cache
743
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NL/Nl7ScaktvaTV9fv6KnpRA5L4nhOYFIe602IcnZnRdn4.cache
744
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GQ/GQGhdmNekxHTcK4z8c8_0XABvO_V3GU-ka52v-m1w7w.cache
745
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/DW/DWIt1aCKlWxnd-4npDlqWMFBAjSrCinlmfA_TCZeslE.cache
746
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/BN/BNKTHM0qczl5J1srx4QT-at4EuqAA5SSEVeTmxjdUYc.cache
747
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AA/AAiRDGe6f3TnpziRJTw28NMq1gtnkZ5W3mbxowNTj1M.cache
748
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/a_/a__X31_jf2sHL-xJYEpoKWWhiXSNkWrTNJYhc7l9Gt8.cache
749
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/aF/aFcBC07vbjBdmiW0TmtwWRMQ5Vn3vZTZiCGp4BylQkg.cache
750
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/nB/nBH2-bAlepNFvXTSF-tmll0Rc5qvcVumktcl1KYydgI.cache
751
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/H7/H7I9oc3DUcu1Fgug4P9wL2L5hFD6o_2GA1QN9Og7sEI.cache
752
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AT/ATEqECN4BijOQ993FAXv3MoryNacaylv073Jv9UeIOQ.cache
753
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AT/aT6_oAHJCuWhpkmdiQ70MxzEDA9i9fnO6kOUJuqLttY.cache
754
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/np/np0_MPHZcS-cPB69C1GzPDnipzfTk84FOeH9QXioyUw.cache
755
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/m4/m4-SSFfa1SYGt723CkTWQYbtaT7MBp8szC3rPFbOPuU.cache
756
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/De/DermXth9dmU_XWCFEysWqQ3lL8KQhEi-GkHKs2iFWNU.cache
757
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/NW/NWyrH43hxzGBxfB9ZKdryDPlHeh2Djz9CvJqNJ9iLKk.cache
758
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/AS/ASWkkDKVcpfAiOu3B0KOejzVhAxxhYxqOQKBcZlm290.cache
759
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/n2/n20Gp--0D3PUtpFMitv38Kp8LlMft5UOkTRoNHO2Tsk.cache
760
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/GC/GCNnkrIFxTx1GDkpGHVfRDuq5Lmh91Hl_y1Cuuvydtw.cache
761
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Az/Az-XOnvmnNddxIz4XLZ1I4DleC9n1REONV4xGg_QDA0.cache
762
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Dl/DlxaZWt1F6jcMlrBLNIamMP8LUsPdcGoCQBjQsqknlA.cache
763
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Gd/GdWzOBp-czgmy2Rby_RDhnKc9DuCOp6bu89sRvLKjgg.cache
764
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Gd/gDYut7mu03J1DXr8TuWSBtWUo6SCV8j21oKygbTMlqY.cache
765
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/L0/L0iEiBEuw_cn9Kl1E14SeJqUHWhmwEkm4ALcv6-FUag.cache
766
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eZ/eZ8o0ZRPhdXLYUbFI1GdB4FQBDnlWM43nHgpH5_47QY.cache
767
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cc/cceVLx5AGYnLErPT_zXq8wCafz02ViM5B7e0J_hfCsA.cache
768
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/E6/E6yy5KPw_faIzyJ98hK9jPM-3cRJjtqPJ_TUJENGcn8.cache
769
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/oh/ohJ4Vsjgs6q6LfnHd8vG2TI65-F-l8BYiRWwjcsFso8.cache
770
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/F0/F04RlQd4Wku__flRg9gkM00g8mfjuKzQKlvsrhcXqXc.cache
771
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/CJ/CJgfggUIbMu6MezYEC37omvMYp4wuEDiRmhTyfbTt54.cache
772
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ES/EsVsWF0kxtr2d8p46pBHT_F438kHPSBPgW2Cn9cIEvo.cache
773
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ES/ES0i3T-gPmh0k4JHBm8e0636XUPegF0Y6PFm1KqrOpw.cache
774
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/oF/oF1leWgLg8_fDwI2qhBAo-V4f9ZODIH5mHd0PugDsNs.cache
775
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/cw/cwgwqvm0fDhWNsca03U1OyT-vzClEMfANDlKKjNcxXc.cache
776
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/FA/FAA3VIY3nCH5gKoynhtYbxrahKETLcwURlXKa8K8jE4.cache
777
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/IK/IK_yJ4hlfIoYaLmA3gsgUHcRwQD8URO9Sk7Pi9qQWAA.cache
778
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/oR/oRE5A6xr4tZ7gQD2Rwr9V_Z0l5vagZKNRe23f-TL7b4.cache
779
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Ou/OuWuLlXvGlYcE6paOZI8sh0cYX4aodsDz6GDY3TNqME.cache
780
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/O9/O9n18FPyB5Aff7Ag87dJAlgAnvT9TWBnHCiiZms98SQ.cache
781
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/l6/l6KEh8r-KKee9rVKcxqIEeF5TqUwW2VqYb7paP0gCQ0.cache
782
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EG/eGRA2iRfMMROTcuFKjGHZSN9YXMRnUBKC5KururoKEQ.cache
783
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/EG/EGsDHaXyy-tzcZjX3wOgKkSTq_leXqT-PkOPUUdfWdM.cache
784
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Fz/FzQ7uGnfl3Suky99OCP5Y9_chV3zDJ_ls8pg_YpdeQY.cache
785
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/JQ/JQlWE0blDCjSPcJnQC7j_jIHh1pyP4EG3RewaazEdv0.cache
786
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/eU/eUtPUlUJHVQxMuD4vIem9_N2HUkAPO4aVxjNdFVxACc.cache
787
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/CB/CB4g53dw2z-x-93N-W6AahS8wt4x7QwelZK2b61FUXA.cache
788
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/LA/LAeWo8kRKzTAYnVcryAE38boNz6PwaGm0cLbYvEzeSA.cache
789
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/fS/fScKQfCZDnNi0jKvowBp0jP5dnLP5hiJjAEryoc4dn8.cache
790
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Wr/WrdmWGzSUAyKEx67shH_XK7LI7OeC2GipDGzU3zfMiQ.cache
791
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/8V/8VuwNr6zDnVJWE58Xnep80kdc7WeKJSTOFjdn1hLwAY.cache
792
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/77/77hNrjw_SVwPzr2bBM3hEeq9cBLn_60qU7LxnDeulwE.cache
793
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/w0/w0eQItpBpGPhWcCLqMgaLY0JLZXutLWFcsUTn1qR5pk.cache
794
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/70/700yl_vOvT8zWvOGRyEnKt8jbCoudw2winTEXq1kQWs.cache
795
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/1E/1Ei9hs8evGGBWvHfxqmbeAhzLwAwfctd96ReP9B3YHs.cache
796
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/TT/TTLu0ztO4_uQ-WjivJx1FZLkIfeRRPNTxX5PndJ8zLY.cache
797
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rm/rmSkgYSgACYLjfteWUTVHgLRF015ih5Ghn5hPGzr6l4.cache
798
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/XM/XMHn7vqwVvLWj2RwNhVLEylzbG_PeBLHroQfJEWajBI.cache
799
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/R4/R4hlf0uqIy39ANsEhv1XO510kFbe-F-60F7v_gPgq00.cache
800
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rX/rXOJ0KA20NEA1hDNnr9Vhh7tAjsRU6oFuC9b2xSX7Wg.cache
801
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/rX/RX0qkXXVT2XvXlxf2UC2FX1cNADKfsTUaoqdW0XdgvU.cache
802
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7i/7ilbgWjHSvpT2wOZYyaQ80wDLezPYjQZW5yHfpFyuyc.cache
803
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/15/15ok-KPHBDqe4Be1S1cMFedG2R7-SN0yX6yXr-_Wt1A.cache
804
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xd/xd635CIGQo56JO8fL5i8Dy1msteAYQjpiFthBFWAUIY.cache
805
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/To/ToVW_LwLfoMA7qkgomaV3ffF-SDvemmBPZkHTKzSnZw.cache
806
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Tu/TuSVUvSt5BY4-q598J6p2dHwl-uhQnb5mZDmzLpkL4g.cache
807
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/qC/qC9rgHGmZKwnZ8QdZB2jEU3T7-_a-ZwdCP-cse12hcQ.cache
808
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/TR/TRfkq054uIjoKd2RkGPjJyr7y8NoRAjvgRhnqm50lSk.cache
809
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qd/QdpJoa9mkC5EWXpbhYB75TCPJMbNvI7L2eaJz3XhrkI.cache
810
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Qd/Qd5DKDJM6Qi-RUkfGBW1F5jyIbeblwo8SdKmJq5ZJeY.cache
811
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7S/7S66JDS9bYQrUkMmnDw14MqwN7tUDvBeITf23hXK_mU.cache
812
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/XW/XWzxn70WfV6gI0dBMktR9kVbjBCvLXn2Ft3ZM_AdMuI.cache
813
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/W-/W-l_iL21hjDik06px3y0cNxwRax-wcyMHqCYU44IbCs.cache
814
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwyuRMymf6iaEYfNIbHrWaQ4RnWQjgWxlgjHq5vnkiw.cache
815
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/13/13agLhf4vTx_mCWtPD-Osx7zQB3hATdVB99LwfZ2osQ.cache
816
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/wF/wFlOPYS4FNz7cD-_U_rwg8F8PUn13yaWFooOxfJo4P0.cache
817
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/ti/tiXJRasL-8irn9-ucULKRcizf-T5j6chc9o9TiGbLg4.cache
818
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/Rp/Rp0kuYqE5Oz_-FE2srLOTB6hrcIY0lkQxLVCAFw_pbA.cache
819
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/7h/7h1SnthU_xgPEVAK3XafohnIRw5ztiyDMq4urK46TIQ.cache
820
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/R5/R5Qn7BZIE1RLU4p8Zd9obkcPZOFCxBGxihXR7ReB9GA.cache
821
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/4g/4gWBKyXKrhIERJHmER7u3skVARiiO8CuDaobzsh5hrY.cache
822
+ - test/dummy/tmp/cache/assets/sprockets/v3.0/xL/xLXcC1BEJrDSHD7y1h23lTfN3Ipjl84ZykUSTAkjR9U.cache
398
823
  - test/models/console_session_test.rb
399
- - test/rvt/colors_test.rb
400
- - test/rvt/engine_test.rb
401
- - test/rvt/slave_test.rb
402
824
  - test/test_helper.rb
825
+ - test/rvt/slave_test.rb