Compare commits

...

92 Commits

Author SHA1 Message Date
Eugene Pankov
17bac5a904 build fix 2018-12-10 17:18:23 +01:00
Eugene Pankov
c34123ffe3 build fix 2018-12-10 16:31:45 +01:00
Eugene Pankov
c755885bbb build fix 2018-12-10 15:06:15 +01:00
Eugene Pankov
f49e3f0664 Revert "bumped webpack"
This reverts commit c58c629d0e.
2018-12-10 14:54:46 +01:00
Eugene Pankov
7852ac2071 potential fix for xterm double-paste (#468) 2018-12-10 14:23:08 +01:00
Eugene Pankov
60358e7ac4 xterm copy-on-select (fixes #400) 2018-12-10 13:08:57 +01:00
Eugene Pankov
f32bdbdeac make scroll-on-input behaviour configurable (fixes #543) 2018-12-10 11:57:13 +01:00
Eugene Pankov
c58c629d0e bumped webpack 2018-12-10 11:56:07 +01:00
Eugene Pankov
a091f46100 fixed settings sidebar offset (fixes #549) 2018-12-10 11:27:32 +01:00
Eugene Pankov
76e8652492 hotkey fixes 2018-12-07 15:12:37 +01:00
Eugene Pankov
2606b910f1 nicer scrollbars (fixes #440) 2018-12-07 14:54:56 +01:00
Eugene Pankov
9440d687d3 don't crash if no global spawn hotkey is assigned (#540) 2018-12-07 14:50:26 +01:00
Eugene Pankov
216f5c2213 . 2018-12-07 14:50:16 +01:00
Eugene
dbadef1c4e Merge pull request #541 from scott-kirk/patch-1
Typo in README
2018-12-06 23:55:30 +01:00
Scott Kirkpatrick
1baf80cfe6 Typo in README 2018-12-06 15:16:01 -05:00
Eugene Pankov
2e50bfccf4 Merge branch 'master' of github.com:Eugeny/terminus 2018-12-05 13:57:02 +01:00
Eugene Pankov
07a3d88397 updated icon 2018-12-05 01:34:11 +01:00
Eugene
6e5ce8e0b1 Merge pull request #536 from Drachenkaetzchen/wsl-color-warning
Inform users about 16 color limit with WSL
2018-12-05 01:33:36 +01:00
Eugene Pankov
c1d1ddd3b7 Merge branch 'master' of github.com:Eugeny/terminus 2018-12-05 01:31:03 +01:00
Eugene
bd5f274cf3 Merge pull request #537 from Drachenkaetzchen/bugfix-wheelevent-ts32
Fix for MouseWheelEvent deprecation in TypeScript 3.2
2018-12-05 01:30:19 +01:00
Eugene Pankov
38045165d4 avoid double squirrel check 2018-12-05 01:28:51 +01:00
Eugene
9e7721d2a9 Merge pull request #535 from Drachenkaetzchen/bugfix-534
Bugfix for issue #534: Catch any errors occurring during checkForUpda…
2018-12-05 01:27:29 +01:00
Felicia Hummel
1d593e0495 Inform users about 16 color limit with WSL
This patch adds a warning that when using WSL we're limited to 16 colors. It took me about 4 hours debugging why it didn't work, and this patch hopefully prevents others from wasting 4 hours.
2018-12-05 00:38:19 +01:00
Felicia Hummel
9b263c7237 Fix for MouseWheelEvent deprecation in TypeScript 3.2
MouseWheelEvent is deprecated and was removed with TypeScript 3.2, however, MouseWheelEvent is still aliased to WheelEvent. For more info see https://github.com/Microsoft/TSJS-lib-generator/pull/579

This PR fixes the build with TypeScript 3.2 by checking the object properties.
2018-12-05 00:33:10 +01:00
Felicia Hummel
ca05c1b819 Merge 2018-12-05 00:27:42 +01:00
Eugene Pankov
2107ed7ab7 force focus on new terminal tabs (fixes #533) 2018-12-05 00:06:01 +01:00
Felicia Hummel
9fd69f668a Bugfix for issue #534: Catch any errors occurring during checkForUpdates() to allow App to start up even if Squirrel is not available 2018-12-04 23:58:18 +01:00
Eugene Pankov
8800614bff tab colors 2018-12-02 16:41:17 +01:00
Eugene Pankov
867ddb4809 bumped electron 2018-12-02 15:28:25 +01:00
Eugene Pankov
5cf31d3351 fall back to github updates if squirrel is unavailable 2018-12-02 15:28:18 +01:00
Eugene Pankov
dff55558dd bump 2018-11-28 22:56:51 +01:00
Eugene Pankov
991294e61a auto-updater (fixes #348) 2018-11-28 21:26:15 +01:00
Eugene Pankov
462232a2fb xterm scrollbar styles 2018-11-28 16:45:58 +01:00
Eugene Pankov
8857ca9714 fixed #484 2018-11-28 15:44:29 +01:00
Eugene Pankov
eb81b9fd01 check tabs before closing the window (fixes #520) 2018-11-22 17:51:12 +01:00
Eugene Pankov
12d1fb9334 Merge branch 'master' of github.com:Eugeny/terminus 2018-11-15 12:39:59 +01:00
Eugene Pankov
ab6d5e851b don't crash if no cwd 2018-11-15 12:39:51 +01:00
Eugene Pankov
952e8461e6 an option to clear last ssh quick connection (fixes #435, fixes #493) 2018-11-11 13:45:47 +01:00
Eugene Pankov
702d29b5b4 added --hidden startup option (fixes #488) 2018-11-11 13:24:27 +01:00
Eugene Pankov
64fc36df51 cleanup 2018-11-11 12:38:51 +01:00
Eugene Pankov
8cfaf9082b bumped electron 2018-11-10 21:26:43 +01:00
Eugene Pankov
8269a8e01b perf: faster hotkey matching 2018-11-10 21:11:22 +01:00
Eugene Pankov
7fcf632378 perf: don't re-set tab progress every time 2018-11-10 21:11:15 +01:00
Eugene Pankov
2e6acd2fa1 perf: reduced pty bufferization window 2018-11-10 21:10:47 +01:00
Eugene Pankov
50ab4fc37e added a settings hotkey (fixes #487) 2018-10-31 17:45:42 +01:00
Eugene Pankov
4426d4827f bring window to front when called from CLI (fixes #489) 2018-10-31 17:37:34 +01:00
Eugene Pankov
215ddf0eec yarn integrity 2018-10-31 17:33:17 +01:00
Eugene Pankov
146de1a2c0 fixed #490 2018-10-31 17:33:03 +01:00
Eugene Pankov
a39eb31379 word 2018-10-31 17:30:08 +01:00
Eugene Pankov
5831e87f68 build fix 2018-10-29 17:25:02 +01:00
Eugene Pankov
f250756254 force autofocus in rename-tab modal (fixes #484) 2018-10-29 16:45:51 +01:00
Eugene Pankov
6a821fa6cf Merge branch 'master' of github.com:Eugeny/terminus 2018-10-29 16:45:50 +01:00
Eugene Pankov
9f204eddb4 fixed #485 2018-10-29 16:39:12 +01:00
Eugene Pankov
4bfea11ae3 build fix 2018-10-27 17:01:55 +02:00
Eugene Pankov
c8686e47dc ppk passphrase support (fixes #281) 2018-10-27 15:46:37 +02:00
Eugene Pankov
b68f601fbb remove whitespace from selection's end (fixes #327) 2018-10-27 13:37:29 +02:00
Eugene Pankov
c2a40b2c5e getChildProcesses() support for win32 2018-10-27 13:25:51 +02:00
Eugene Pankov
d9b28f4c0b build fix 2018-10-26 17:57:31 +02:00
Eugene Pankov
a03d01d9ce ligatures support in xterm (fixes #417) 2018-10-26 16:33:32 +02:00
Eugene Pankov
2b4d3e99b6 multi-window fixes 2018-10-26 16:17:20 +02:00
Eugene Pankov
394587301c build fix 2018-10-26 15:19:02 +02:00
Eugene Pankov
b3f15e27c6 process completion notifications 2018-10-26 14:03:46 +02:00
Eugene Pankov
822e068bb5 analytics user UUID 2018-10-25 17:32:51 +02:00
Eugene Pankov
9f35ab1a66 nicer plugins ui 2018-10-25 16:38:42 +02:00
Eugene Pankov
2ebb107bed ui fix 2018-10-25 16:23:32 +02:00
Eugene Pankov
bb017f5b1b readme update 2018-10-25 16:19:08 +02:00
Eugene Pankov
31a7f9a2f8 readme updates 2018-10-25 16:18:16 +02:00
Eugene Pankov
7566bcaaac custom environment vars (fixes #346) 2018-10-25 15:51:46 +02:00
Eugene Pankov
4682ef72a1 build fix 2018-10-23 13:55:22 +02:00
Eugene Pankov
1c0a002952 added missing deps 2018-10-23 12:04:32 +02:00
Eugene Pankov
2fd28f2bf3 avoid double paste on macOS 2018-10-23 11:56:55 +02:00
Eugene Pankov
5cb3cef6ce much faster tab closing on macOS 2018-10-23 11:56:44 +02:00
Eugene Pankov
a4ccbfa857 bumped electron 2018-10-23 11:45:16 +02:00
Eugene Pankov
c8e1c17514 bumped Angular to 7 2018-10-22 16:02:20 +02:00
Eugene Pankov
8b6779b064 cleanup 2018-10-22 15:49:40 +02:00
Eugene Pankov
258665aaac UI tweaks 2018-10-22 15:44:12 +02:00
Eugene Pankov
efee11efe2 added the ko-fi link 2018-10-16 15:50:34 +02:00
Eugene Pankov
2208c4ed72 added appveyor artifacts link 2018-10-16 13:03:03 +02:00
Eugene Pankov
573484ae38 do not create start menu folder (fixes #466) 2018-10-16 13:01:22 +02:00
Eugene Pankov
8881b835b4 suggest WSL root path as working directory (#454) 2018-10-13 19:09:50 +02:00
Eugene Pankov
144798a336 lint 2018-10-13 18:56:09 +02:00
Eugene Pankov
8110fef3c0 reversed cursor blink cycle (fixes #422) 2018-10-13 18:54:21 +02:00
Eugene Pankov
a0e3b0b033 tell the user how to mute the WSL bell (fixes #413) 2018-10-13 14:14:39 +02:00
Eugene Pankov
d7db132c76 prevent ctrl-click events (#465) 2018-10-13 13:35:16 +02:00
Eugene Pankov
8f0f1b19df allow selecting windows vibrancy type (fixes #460) 2018-10-13 04:30:12 -07:00
Eugene Pankov
7b33d89032 build fix 2018-10-12 20:40:31 +02:00
Eugene Pankov
9b6a09129c hotkeys for specific shells 2018-10-12 17:59:22 +02:00
Eugene Pankov
cc610e158e bumped webpack 2018-10-12 16:55:55 +02:00
Eugene Pankov
0fa94d8397 split terminal settings into separate tabs 2018-10-12 16:55:42 +02:00
Eugene Pankov
c13159f7e2 nicer config editor font 2018-10-12 13:49:59 +02:00
Eugene Pankov
fd6ee5c8ec Update docs/readme.png 2018-10-12 13:20:11 +02:00
Eugene Pankov
bfcc5b4cb9 removed child_process redirection 2018-10-12 12:25:46 +02:00
96 changed files with 4058 additions and 3719 deletions

View File

@@ -1,55 +0,0 @@
parser: babel-eslint
extends: standard
env:
node: true
commonjs: true
rules:
no-duplicate-imports: error
import/no-duplicates: 0
array-bracket-spacing:
- error
- never
block-scoped-var: error
brace-style:
- error
- 1tbs
computed-property-spacing:
- error
- never
comma-dangle:
- error
- always-multiline
curly: error
eol-last: error
eqeqeq:
- error
- smart
max-depth:
- 1
- 5
max-statements:
- 1
- 80
no-multiple-empty-lines: error
no-mixed-spaces-and-tabs: error
no-trailing-spaces: error
no-unused-vars:
- error
- vars: all
args: after-used
argsIgnorePattern: ^_
no-undef: error
no-use-before-define:
- error
- nofunc
no-var: error
object-curly-spacing:
- error
- always
quote-props:
- warn
- as-needed
- keywords: true
numbers: true
strict:
- error

View File

@@ -1,8 +1,13 @@
![](https://github.com/Eugeny/terminus/raw/master/docs/readme.png)
<p align="center">
<a href="https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg"/></a> <a href="https://travis-ci.org/Eugeny/terminus"><img src="https://travis-ci.org/Eugeny/terminus.svg?branch=master"/></a>
<a href="https://ci.appveyor.com/project/Eugeny/terminus"><img src="https://ci.appveyor.com/api/projects/status/wnnq4hm5mbd9rgoy?svg=true"/></a>
</p>
[![Build Status](https://travis-ci.org/Eugeny/terminus.svg?branch=master)](https://travis-ci.org/Eugeny/terminus) [![Build status](https://ci.appveyor.com/api/projects/status/wnnq4hm5mbd9rgoy?svg=true)](https://ci.appveyor.com/project/Eugeny/terminus) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE) [![Downloads](https://img.shields.io/badge/downloads-latest_release-brightgreen.svg)](https://github.com/Eugeny/terminus/releases/latest)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus?ref=badge_shield)
<p align="center">
<a href="https://github.com/Eugeny/terminus/releases/latest">Downloads</a> | <a href="https://t.me/joinchat/AAAAAEZuCv2WKKYcfyQ3QA">Community</a> | <a href="https://ci.appveyor.com/project/Eugeny/terminus/build/artifacts">Latest Windows nightly</a>
</p>
----
@@ -17,6 +22,10 @@
* PowerShell Core, WSL (Bash on Windows), PowerShell, Git-Bash, Cygwin, Cmder and CMD support
* Tab persistence on macOS and Linux
[![Buy me a coffee](https://github.com/Eugeny/terminus/raw/master/docs/kofi.png)](https://ko-fi.com/eugeny)
---
# Plugins
@@ -28,15 +37,15 @@ Plugins can be installed directly from the Settings view inside Terminus.
* [shell-selector](https://github.com/Eugeny/terminus-shell-selector) - a quick shell selector pane
* [title-control](https://github.com/kbjr/terminus-title-control) - allows modifying the title of the terminal tabs by providing a prefix, suffix, and/or strings to be removed
* [scrollbar](https://github.com/kbjr/terminus-scrollbar) - adds a scrollbar to terminal tabs
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - quicklky send commands to one or all terminal tabs
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - quickly send commands to one or all terminal tabs
---
# Contributing
Pull requests and plugins are welcome!
Pull requests and plugins are welcome!
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) for information of how the project is laid out, and a very brief plugin development tutorial.
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) for information of how the project is laid out, and a very brief plugin development tutorial.
## License

View File

@@ -1,91 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="150mm"
height="150mm"
viewBox="0 0 150 150"
version="1.1"
id="svg8"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="logo.svg"
inkscape:export-filename="/home/eugene/Work/term/build/icons/512x512.png"
inkscape:export-xdpi="86.699997"
inkscape:export-ydpi="86.699997">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="85.897128"
inkscape:cy="375.72042"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:window-width="1366"
inkscape:window-height="692"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-intersection-paths="true"
inkscape:object-paths="true" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-10.356544,-82.309525)">
<path
inkscape:connector-curvature="0"
id="path138"
style="opacity:0.9;fill:#bfd9f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12037313px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="M 33.048081,103.66303 101.30357,143.02426 80.80219,154.86063 33.048089,125.73315 Z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path116"
style="opacity:0.9;fill:#6666af;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12037313px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 141.59934,143.95811 0.051,23.16109 -87.420905,49.42651 -0.0034,-22.16232 z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path118"
style="opacity:0.9;fill:#bfd9f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12037313px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 33.233182,182.28294 20.992812,12.1202 0.0034,22.16208 -20.996251,-12.19239 z"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:0.9;fill:#9dbef0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.12649226px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 52.236336,92.196079 -19.484508,11.249681 68.551742,39.5785 -68.366041,39.4708 21.107487,12.18633 68.366044,-39.4708 19.48451,-11.24968 z"
id="path134"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</g>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#SVGID_1_);}
.st1{opacity:0.16;fill:url(#SVGID_2_);}
.st2{fill:url(#SVGID_3_);}
.st3{opacity:0.16;fill:url(#SVGID_4_);}
.st4{fill:url(#SVGID_5_);}
.st5{opacity:0.15;fill:url(#SVGID_6_);}
.st6{fill:url(#SVGID_7_);}
</style>
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="260.9675" y1="871.1813" x2="919.1845" y2="491.1596">
<stop offset="0" style="stop-color:#669ABD"/>
<stop offset="1" style="stop-color:#77DBDB"/>
</linearGradient>
<polygon class="st0" points="297.54,934.52 882.6,596.72 882.61,427.82 297.54,765.65 "/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="553.5051" y1="617.8278" x2="626.647" y2="744.5132">
<stop offset="0.5588" style="stop-color:#000000;stop-opacity:0"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<polygon class="st1" points="297.54,934.52 882.6,596.72 882.61,427.82 297.54,765.65 "/>
</g>
<g>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="114.6631" y1="744.5275" x2="334.0905" y2="871.2141">
<stop offset="0" style="stop-color:#6A8FAD"/>
<stop offset="1" style="stop-color:#669ABD"/>
</linearGradient>
<polygon class="st2" points="151.23,681.18 151.22,850.09 297.54,934.52 297.54,765.65 "/>
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="260.9478" y1="744.5281" x2="187.8059" y2="871.2135">
<stop offset="0.5588" style="stop-color:#000000;stop-opacity:0"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<polygon class="st3" points="151.23,681.18 151.22,850.09 297.54,934.52 297.54,765.65 "/>
</g>
<g>
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="114.663" y1="237.793" x2="553.5026" y2="491.1571">
<stop offset="0" style="stop-color:#6A8FAD"/>
<stop offset="1" style="stop-color:#669ABD"/>
</linearGradient>
<polygon class="st4" points="151.23,174.45 151.21,343.36 443.79,512.27 590.08,427.81 "/>
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="370.6562" y1="301.1281" x2="297.5094" y2="427.8221">
<stop offset="0.5588" style="stop-color:#000000;stop-opacity:0"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<polygon class="st5" points="151.23,174.45 151.21,343.36 443.79,512.27 590.08,427.81 "/>
</g>
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="78.0912" y1="554.4979" x2="736.3375" y2="174.4593">
<stop offset="0" style="stop-color:#CCECFF"/>
<stop offset="1" style="stop-color:#9FECED"/>
</linearGradient>
<polygon class="st6" points="297.51,765.64 151.23,681.18 590.08,427.81 151.23,174.45 297.5,90 882.61,427.82 "/>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,6 +1,6 @@
import { app, ipcMain, Menu, Tray, shell } from 'electron'
import { loadConfig } from './config'
import { Window } from './window'
import { Window, WindowOptions } from './window'
export class Application {
private tray: Tray
@@ -20,8 +20,8 @@ export class Application {
app.commandLine.appendSwitch('disable-http-cache')
}
async newWindow (): Promise<Window> {
let window = new Window()
async newWindow (options?: WindowOptions): Promise<Window> {
let window = new Window(options)
this.windows.push(window)
window.visible$.subscribe(visible => {
if (visible) {

View File

@@ -28,6 +28,10 @@ export function parseArgs (argv, cwd) {
describe: 'Show DevTools on start',
type: 'boolean'
})
.option('hidden', {
describe: 'Start minimized',
type: 'boolean'
})
.option('version', {
alias: 'v',
describe: 'Show version and exit',

View File

@@ -59,5 +59,5 @@ app.on('ready', () => {
}
]))
}
application.newWindow()
application.newWindow({ hidden: argv.hidden })
})

View File

@@ -14,23 +14,30 @@ if (process.platform === 'win32') {
DwmEnableBlurBehindWindow = require('windows-blurbehind').DwmEnableBlurBehindWindow
}
export interface WindowOptions {
hidden?: boolean
}
export class Window {
ready: Promise<void>
private visible = new Subject<boolean>()
private window: BrowserWindow
private windowConfig: ElectronConfig
private windowBounds: Rectangle
private closing = false
get visible$ (): Observable<boolean> { return this.visible }
constructor () {
constructor (options?: WindowOptions) {
let configData = loadConfig()
options = options || {}
this.windowConfig = new ElectronConfig({ name: 'window' })
this.windowBounds = this.windowConfig.get('windowBoundaries')
let maximized = this.windowConfig.get('maximized')
let options: Electron.BrowserWindowConstructorOptions = {
let bwOptions: Electron.BrowserWindowConstructorOptions = {
width: 800,
height: 600,
title: 'Terminus',
@@ -41,33 +48,36 @@ export class Window {
show: false,
backgroundColor: '#00000000'
}
Object.assign(options, this.windowBounds)
Object.assign(bwOptions, this.windowBounds)
if ((configData.appearance || {}).frame === 'native') {
options.frame = true
bwOptions.frame = true
} else {
if (process.platform === 'darwin') {
options.titleBarStyle = 'hiddenInset'
bwOptions.titleBarStyle = 'hiddenInset'
}
}
if (process.platform === 'linux') {
options.backgroundColor = '#131d27'
bwOptions.backgroundColor = '#131d27'
}
this.window = new BrowserWindow(options)
this.window = new BrowserWindow(bwOptions)
this.window.once('ready-to-show', () => {
if (process.platform === 'darwin') {
this.window.setVibrancy('dark')
} else if (process.platform === 'win32' && (configData.appearance || {}).vibrancy) {
this.setVibrancy(true)
}
if (maximized) {
this.window.maximize()
} else {
this.window.show()
if (!options.hidden) {
if (maximized) {
this.window.maximize()
} else {
this.window.show()
}
this.window.focus()
}
this.window.focus()
})
this.window.loadURL(`file://${app.getAppPath()}/dist/index.html?${this.window.id}`, { extraHeaders: 'pragma: no-cache\n' })
@@ -88,13 +98,13 @@ export class Window {
})
}
setVibrancy (enabled: boolean) {
setVibrancy (enabled: boolean, type?: string) {
if (process.platform === 'win32') {
if (parseFloat(os.release()) >= 10) {
let attribValue = AccentState.ACCENT_DISABLED
let color = 0x00000000
if (enabled) {
if (parseInt(os.release().split('.')[2]) >= 17063) {
if (parseInt(os.release().split('.')[2]) >= 17063 && type === 'fluent') {
attribValue = AccentState.ACCENT_ENABLE_FLUENT
color = 0x01000000 // using a small alpha because acrylic bugs out at full transparency.
} else {
@@ -117,6 +127,9 @@ export class Window {
}
send (event, ...args) {
if (!this.window) {
return
}
this.window.webContents.send(event, ...args)
}
@@ -133,7 +146,12 @@ export class Window {
this.window.on('enter-full-screen', () => this.window.webContents.send('host:window-enter-full-screen'))
this.window.on('leave-full-screen', () => this.window.webContents.send('host:window-leave-full-screen'))
this.window.on('close', () => {
this.window.on('close', event => {
if (!this.closing) {
event.preventDefault()
this.window.webContents.send('host:window-close-request')
return
}
this.windowConfig.set('windowBoundaries', this.windowBounds)
this.windowConfig.set('maximized', this.window.isMaximized())
})
@@ -154,19 +172,31 @@ export class Window {
}
})
ipcMain.on('window-focus', () => {
ipcMain.on('window-focus', event => {
if (event.sender !== this.window.webContents) {
return
}
this.window.focus()
})
ipcMain.on('window-maximize', () => {
ipcMain.on('window-maximize', event => {
if (event.sender !== this.window.webContents) {
return
}
this.window.maximize()
})
ipcMain.on('window-unmaximize', () => {
ipcMain.on('window-unmaximize', event => {
if (event.sender !== this.window.webContents) {
return
}
this.window.unmaximize()
})
ipcMain.on('window-toggle-maximize', () => {
ipcMain.on('window-toggle-maximize', event => {
if (event.sender !== this.window.webContents) {
return
}
if (this.window.isMaximized()) {
this.window.unmaximize()
} else {
@@ -174,25 +204,58 @@ export class Window {
}
})
ipcMain.on('window-minimize', () => {
ipcMain.on('window-minimize', event => {
if (event.sender !== this.window.webContents) {
return
}
this.window.minimize()
})
ipcMain.on('window-set-bounds', (_event, bounds) => {
ipcMain.on('window-set-bounds', (event, bounds) => {
if (event.sender !== this.window.webContents) {
return
}
this.window.setBounds(bounds)
})
ipcMain.on('window-set-always-on-top', (_event, flag) => {
ipcMain.on('window-set-always-on-top', (event, flag) => {
if (event.sender !== this.window.webContents) {
return
}
this.window.setAlwaysOnTop(flag)
})
ipcMain.on('window-set-vibrancy', (_event, enabled) => {
this.setVibrancy(enabled)
ipcMain.on('window-set-vibrancy', (event, enabled, type) => {
if (event.sender !== this.window.webContents) {
return
}
this.setVibrancy(enabled, type)
})
ipcMain.on('window-set-title', (_event, title) => {
ipcMain.on('window-set-title', (event, title) => {
if (event.sender !== this.window.webContents) {
return
}
this.window.setTitle(title)
})
ipcMain.on('window-bring-to-front', event => {
if (event.sender !== this.window.webContents) {
return
}
if (this.window.isMinimized()) {
this.window.restore()
}
this.window.show()
this.window.moveTop()
})
ipcMain.on('window-close', () => {
this.closing = true
this.window.close()
})
this.window.webContents.on('new-window', event => event.preventDefault())
}
private destroy () {

View File

@@ -1,6 +1,7 @@
{
"name": "terminus",
"description": "A terminal for a modern age",
"repository": "https://github.com/eugeny/terminus",
"author": {
"name": "Eugene Pankov",
"email": "e@ajenti.org"
@@ -12,14 +13,14 @@
"watch": "webpack --progress --color --watch"
},
"dependencies": {
"@angular/animations": "6.0.2",
"@angular/common": "6.0.2",
"@angular/compiler": "6.0.2",
"@angular/core": "6.0.2",
"@angular/forms": "6.0.2",
"@angular/platform-browser": "6.0.2",
"@angular/platform-browser-dynamic": "6.0.2",
"@ng-bootstrap/ng-bootstrap": "^2.0.0",
"@angular/animations": "7.0.0",
"@angular/common": "7.0.0",
"@angular/compiler": "7.0.0",
"@angular/core": "7.0.0",
"@angular/forms": "7.0.0",
"@angular/platform-browser": "7.0.0",
"@angular/platform-browser-dynamic": "7.0.0",
"@ng-bootstrap/ng-bootstrap": "^3.3.1",
"devtron": "1.4.0",
"electron-config": "0.2.1",
"electron-debug": "^2.0.0",
@@ -27,11 +28,11 @@
"electron-squirrel-startup": "^1.0.0",
"js-yaml": "3.8.2",
"mz": "^2.6.0",
"ngx-toastr": "^8.7.3",
"ngx-toastr": "^9.1.1",
"path": "0.12.7",
"rxjs": "^6.3.3",
"yargs": "^12.0.1",
"zone.js": "~0.8.26"
"zone.js": "^0.8.26"
},
"optionalDependencies": {
"windows-blurbehind": "^1.0.0",

View File

@@ -1,5 +1,6 @@
import '../lib/lru'
import 'source-sans-pro'
import 'source-code-pro/source-code-pro.css'
import 'font-awesome/css/font-awesome.css'
import 'ngx-toastr/toastr.css'
import './preload.scss'
@@ -33,7 +34,3 @@ process.on('uncaughtException' as any, (err) => {
Raven.captureException(err as any)
console.error(err)
})
const childProcess = require('child_process')
childProcess.spawn = require('electron').remote.require('child_process').spawn
childProcess.exec = require('electron').remote.require('child_process').exec

View File

@@ -2,91 +2,110 @@
# yarn lockfile v1
"@angular/animations@6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-6.0.2.tgz#92063f612c3b33d962eddc9ad538cadd231fbe47"
"@angular/animations@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-7.0.0.tgz#5c9e1683063c29df10253b7dc5bb9b13694ee396"
integrity sha512-IYdryQXdYfPvhJpExLSAr0o9rlUeyVS++a6h/sjqN1dkUt/yJBHLRreuHx8Udvlj2nH70raHJgevk8FwhAkTdA==
dependencies:
tslib "^1.9.0"
"@angular/common@6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@angular/common/-/common-6.0.2.tgz#e4cbb7d45d8d2f35e918d62f0cbfd8c87e9168f7"
"@angular/common@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@angular/common/-/common-7.0.0.tgz#29206614d2b8dc79e5207b7dc6f9fc559e9a24f2"
integrity sha512-jp6MA6EOq/a1m+F0c1aZC345pAYYYFpN1m7GMM91JlqkjzJMhyYVk+Bod9xQOEWadcpY+RFudG+jRsPCMO8bvQ==
dependencies:
tslib "^1.9.0"
"@angular/compiler@6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-6.0.2.tgz#b9d29b7e032c767179967540f1ed7f8777a615a1"
"@angular/compiler@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-7.0.0.tgz#f953a213a01e4736e94fe1a370b07e13e2393b71"
integrity sha512-4fkohfGyG1BEpeYenOartuJmduyZ/R3XQx46hDDiR/9A8/Go4qLGkgr9Bd/JL/gPIR1XAHH9D5ii2sh+28ZEmA==
dependencies:
tslib "^1.9.0"
"@angular/core@6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@angular/core/-/core-6.0.2.tgz#d183730d73182a4590a5d71083db45655f210e69"
"@angular/core@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@angular/core/-/core-7.0.0.tgz#01e9db9074a1db1c47a32f745b787d1c86f5d61a"
integrity sha512-DjVyWNGBWKEeBvxeXy8FGBNlnr/W/tNygOZEd6/uCktcXTG4DNyNQrWuNZUKEpr7RuIT3YVMj+UNwgTq0jB/9g==
dependencies:
tslib "^1.9.0"
"@angular/forms@6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-6.0.2.tgz#a0647930e8b6e7fbd48f55eb69b399a41bcd091a"
"@angular/forms@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-7.0.0.tgz#672c306b13e94a20b72c096214642a326c43699a"
integrity sha512-rTg1UHq9gHR6zY3Kkip1KCm/YTck/rlR8CvVFIMwF0bdQxUCT51SXVn58nXts9yDaieABcGaQHNkQn1mARslgw==
dependencies:
tslib "^1.9.0"
"@angular/platform-browser-dynamic@6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-6.0.2.tgz#755689df9f02bbcb270c7872a75a2ffe7e0b0c33"
"@angular/platform-browser-dynamic@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.0.0.tgz#2b2a50b5a8176bee257f90ee47b1d873502f7182"
integrity sha512-lH2KuH+Em1y/mTOE6yTJmsOxYkMbYKzKLP9gYzc9vZu3er1df6Jx6jxefeBmAr9v+kNCLnpnHWHz2y4GzAesJA==
dependencies:
tslib "^1.9.0"
"@angular/platform-browser@6.0.2":
version "6.0.2"
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-6.0.2.tgz#19f56f6efbd0e7af5f35fe2f8cde3557dc8ba689"
"@angular/platform-browser@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-7.0.0.tgz#8c13a6380cf465b3628e5b576a1313e9b4976093"
integrity sha512-XyvL30d6meJ+SXlOmdR+sxoLdSvkQdmVNvpdvUzAHC/EqwA/byg4V3bTe5lpZmypclgFCjkGoTsz6uOnnwlQhw==
dependencies:
tslib "^1.9.0"
"@ng-bootstrap/ng-bootstrap@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-2.0.0.tgz#65f78c7dd5a8ac424f44bb2050a9eab247cdeb0c"
"@ng-bootstrap/ng-bootstrap@^3.3.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-3.3.1.tgz#435eebc57dd4a371d02f342f1e919d1c4bb522a2"
integrity sha512-awty+5Kil0i/xIV7SSmKa5YozU83EdIx2EenF2AUDTczSKhHNhRByo82rjtwIhshN25/ZEss4aSDhgILLI88fw==
dependencies:
tslib "^1.9.0"
"@types/mz@0.0.31":
version "0.0.31"
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-0.0.31.tgz#a4d80c082fefe71e40a7c0f07d1e6555bbbc7b52"
integrity sha1-pNgMCC/v5x5Ap8DwfR5lVbu8e1I=
dependencies:
"@types/node" "*"
"@types/node@*":
version "8.0.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.13.tgz#530f0f9254209b0335bf5cc6387822594ef47093"
integrity sha512-Y3EAG7VA7NVNbZek/fjJtILnmTk/ZfpJuWZGDBqDZ1dVIxgJJJ82fXPW7pKnqyV9CD/9bcPOCi7eErUqGMHOrA==
accessibility-developer-tools@^2.11.0:
version "2.12.0"
resolved "https://registry.yarnpkg.com/accessibility-developer-tools/-/accessibility-developer-tools-2.12.0.tgz#3da0cce9d6ec6373964b84f35db7cfc3df7ab514"
integrity sha1-PaDM6dbsY3OWS4TzXbfPw996tRQ=
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
integrity sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=
dependencies:
sprintf-js "~1.0.2"
camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
cliui@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
dependencies:
string-width "^2.1.1"
strip-ansi "^4.0.0"
@@ -95,10 +114,12 @@ cliui@^4.0.0:
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
conf@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/conf/-/conf-0.11.2.tgz#879f479267600483e502583462ca4063fc9779b2"
integrity sha1-h59HkmdgBIPlAlg0YspAY/yXebI=
dependencies:
dot-prop "^3.0.0"
env-paths "^0.3.0"
@@ -108,6 +129,7 @@ conf@^0.11.1:
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
dependencies:
lru-cache "^4.0.1"
shebang-command "^1.2.0"
@@ -116,18 +138,21 @@ cross-spawn@^5.0.1:
debug@^2.2.0, debug@^2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=
dependencies:
ms "2.0.0"
decamelize@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7"
integrity sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==
dependencies:
xregexp "4.0.0"
devtron@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/devtron/-/devtron-1.4.0.tgz#b5e748bd6e95bbe70bfcc68aae6fe696119441e1"
integrity sha1-tedIvW6Vu+cL/MaKrm/mlhGUQeE=
dependencies:
accessibility-developer-tools "^2.11.0"
highlight.js "^9.3.0"
@@ -136,18 +161,21 @@ devtron@1.4.0:
dot-prop@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc=
dependencies:
is-obj "^1.0.0"
electron-config@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/electron-config/-/electron-config-0.2.1.tgz#7e12c26412d06bf3ed3896d0479df162986b95ba"
integrity sha1-fhLCZBLQa/PtOJbQR53xYphrlbo=
dependencies:
conf "^0.11.1"
electron-debug@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/electron-debug/-/electron-debug-2.0.0.tgz#3059a6557acbfb091f138d83875f57bac80cea6d"
integrity sha512-orGlw9uErUztdD7cgdKz78txq3czpOnKG/zvvsINkUsugqL+dn77UFrbwRGVgPwuLJ7Ejbjjk9EcxIcgTivMbA==
dependencies:
electron-is-dev "^0.3.0"
electron-localshortcut "^3.0.0"
@@ -155,18 +183,22 @@ electron-debug@^2.0.0:
electron-is-accelerator@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b"
integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
electron-is-dev@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.1.2.tgz#8a1043e32b3a1da1c3f553dce28ce764246167e3"
integrity sha1-ihBD4ys6HaHD9VPc4oznZCRhZ+M=
electron-is-dev@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.3.0.tgz#14e6fda5c68e9e4ecbeff9ccf037cbd7c05c5afe"
integrity sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=
electron-localshortcut@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz#10c1ffd537b8d39170aaf6e1551341f7780dd2ce"
integrity sha512-MgL/j5jdjW7iA0R6cI7S045B0GlKXWM1FjjujVPjlrmyXRa6yH0bGSaIAfxXAF9tpJm3pLEiQzerYHkRh9JG/A==
dependencies:
debug "^2.6.8"
electron-is-accelerator "^0.1.0"
@@ -176,20 +208,24 @@ electron-localshortcut@^3.0.0:
electron-squirrel-startup@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/electron-squirrel-startup/-/electron-squirrel-startup-1.0.0.tgz#19b4e55933fa0ef8f556784b9c660f772546a0b8"
integrity sha1-GbTlWTP6Dvj1VnhLnGYPdyVGoLg=
dependencies:
debug "^2.2.0"
env-paths@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-0.3.1.tgz#c30ccfcbc30c890943dc08a85582517ef00da463"
integrity sha1-wwzPy8MMiQlD3AioVYJRfvANpGM=
esprima@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
execa@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
dependencies:
cross-spawn "^5.0.1"
get-stream "^3.0.0"
@@ -202,6 +238,7 @@ execa@^0.7.0:
find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=
dependencies:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
@@ -209,58 +246,71 @@ find-up@^1.0.0:
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
dependencies:
locate-path "^3.0.0"
get-caller-file@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
get-stream@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
highlight.js@^9.3.0:
version "9.12.0"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
integrity sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=
humanize-plus@^1.8.1:
version "1.8.2"
resolved "https://registry.yarnpkg.com/humanize-plus/-/humanize-plus-1.8.2.tgz#a65b34459ad6367adbb3707a82a3c9f916167030"
integrity sha1-pls0RZrWNnrbs3B6gqPJ+RYWcDA=
inherits@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
dependencies:
number-is-nan "^1.0.0"
is-fullwidth-code-point@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
is-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
js-yaml@3.8.2:
version "3.8.2"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721"
integrity sha1-AtPiwPa+qyAkjUEsNSIDgn14ZyE=
dependencies:
argparse "^1.0.7"
esprima "^3.1.1"
@@ -268,20 +318,24 @@ js-yaml@3.8.2:
keyboardevent-from-electron-accelerator@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-1.1.0.tgz#324614f6e33490c37ffc5be5876b3e85fe223c84"
integrity sha512-VDC4vKWGrR3VgIKCE4CsXnvObGgP8C2idnTKEMUkuEuvDGE1GEBX9FtNdJzrD00iQlhI3xFxRaeItsUmlERVng==
keyboardevents-areequal@^0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz#88191ec738ce9f7591c25e9056de928b40277194"
integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
lcid@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
dependencies:
invert-kv "^1.0.0"
locate-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
dependencies:
p-locate "^3.0.0"
path-exists "^3.0.0"
@@ -289,6 +343,7 @@ locate-path@^3.0.0:
lru-cache@^4.0.1:
version "4.1.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c"
integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==
dependencies:
pseudomap "^1.0.2"
yallist "^2.1.2"
@@ -296,58 +351,69 @@ lru-cache@^4.0.1:
mem@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=
dependencies:
mimic-fn "^1.0.0"
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
mz@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.6.0.tgz#c8b8521d958df0a4f2768025db69c719ee4ef1ce"
integrity sha1-yLhSHZWN8KTydoAl22nHGe5O8c4=
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
ngx-toastr@^8.7.3:
version "8.7.3"
resolved "https://registry.yarnpkg.com/ngx-toastr/-/ngx-toastr-8.7.3.tgz#d3b7a8077ba1c860dd8a44779ccad38c5ea15c92"
ngx-toastr@^9.1.1:
version "9.1.1"
resolved "https://registry.yarnpkg.com/ngx-toastr/-/ngx-toastr-9.1.1.tgz#c7ec0284d13951422ccf47439a387372ddccc768"
integrity sha512-v43BmIXPmwMRx9Uv0ru2UaPQLA14gTsqWgXrO1DKC8RXnBGGoQEE48cVCaDX1GhaGM5GSzVO2s0o+nb688zsFw==
dependencies:
tslib "^1.9.0"
npm-run-path@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
dependencies:
path-key "^2.0.0"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
os-locale@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==
dependencies:
execa "^0.7.0"
lcid "^1.0.0"
@@ -356,40 +422,48 @@ os-locale@^2.0.0:
p-finally@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
p-limit@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec"
integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==
dependencies:
p-try "^2.0.0"
p-locate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
dependencies:
p-limit "^2.0.0"
p-try@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1"
integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==
path-exists@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=
dependencies:
pinkie-promise "^2.0.0"
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
path-key@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
path@0.12.7:
version "0.12.7"
resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f"
integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=
dependencies:
process "^0.11.1"
util "^0.10.3"
@@ -397,66 +471,80 @@ path@0.12.7:
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
dependencies:
pinkie "^2.0.0"
pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
pkg-up@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26"
integrity sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=
dependencies:
find-up "^1.0.0"
process@^0.11.1:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
rxjs@^6.3.3:
version "6.3.3"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"
integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==
dependencies:
tslib "^1.9.0"
set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
dependencies:
shebang-regex "^1.0.0"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
signal-exit@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
dependencies:
code-point-at "^1.0.0"
is-fullwidth-code-point "^1.0.0"
@@ -465,6 +553,7 @@ string-width@^1.0.1:
string-width@^2.0.0, string-width@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
dependencies:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
@@ -472,62 +561,74 @@ string-width@^2.0.0, string-width@^2.1.1:
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
dependencies:
ansi-regex "^2.0.0"
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
dependencies:
ansi-regex "^3.0.0"
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
dependencies:
any-promise "^1.0.0"
tslib@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.1.tgz#a5d1f0532a49221c87755cfcc89ca37197242ba7"
integrity sha512-avfPS28HmGLLc2o4elcc2EIq2FcH++Yo5YxpBZi9Yw93BCTGFthI4HPE4Rpep6vSYQaK8e69PelM44tPj+RaQg==
util@^0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
dependencies:
inherits "2.0.1"
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
which@^1.2.9:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
dependencies:
isexe "^2.0.0"
windows-blurbehind@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/windows-blurbehind/-/windows-blurbehind-1.0.0.tgz#050efb988704c44335bdc3efefd757f6e463b8ac"
integrity sha512-lO+A7fhTHO7oy9zJM3o1AdzfSQrmtPkdwvleeuww840ghijjEA1f1Zp8bKA3mJu2DFNtVT40fwmqtgsCGat4UA==
windows-swca@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/windows-swca/-/windows-swca-1.1.1.tgz#0b3530278c67d408baac71c3a6aeb16d55318bf8"
integrity sha512-hKmHrNYJD72Kg0u35fjkiFIuMKuC+Tztmf3Obnf4aTkNjstEpbSEspEeSo3ZNixaVCETA1dLbDkVUQVF1QxtWA==
wrap-ansi@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
dependencies:
string-width "^1.0.1"
strip-ansi "^3.0.1"
@@ -535,24 +636,29 @@ wrap-ansi@^2.0.0:
xregexp@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-4.0.0.tgz#e698189de49dd2a18cc5687b05e17c8e43943020"
integrity sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==
"y18n@^3.2.1 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
yargs-parser@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"
integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==
dependencies:
camelcase "^4.1.0"
yargs@^12.0.1:
version "12.0.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.1.tgz#6432e56123bb4e7c3562115401e98374060261c2"
integrity sha512-B0vRAp1hRX4jgIOWFtjfNjd9OA9RWYZ6tqGA9/I/IrTMsxmKvtWy+ersM+jzpQqbC3YfLzeABPdeTgcJ9eu1qQ==
dependencies:
cliui "^4.0.0"
decamelize "^2.0.0"
@@ -567,6 +673,7 @@ yargs@^12.0.1:
y18n "^3.2.1 || ^4.0.0"
yargs-parser "^10.1.0"
zone.js@~0.8.26:
zone.js@^0.8.26:
version "0.8.26"
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.8.26.tgz#7bdd72f7668c5a7ad6b118148b4ea39c59d08d2d"
integrity sha512-W9Nj+UmBJG251wkCacIkETgra4QgBo/vgoEkb4a2uoLzpQG7qF9nzwoLXWU5xj3Fg2mxGvEDh47mg24vXccYjA==

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 644 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -1,124 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="150mm"
height="150mm"
viewBox="0 0 150 150"
version="1.1"
id="svg8"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/eugene/Work/term/build/icons/512x512.png"
inkscape:export-xdpi="86.699997"
inkscape:export-ydpi="86.699997">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4649">
<stop
style="stop-color:#000316;stop-opacity:1"
offset="0"
id="stop4645" />
<stop
style="stop-color:#190065;stop-opacity:1"
offset="1"
id="stop4647" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4649"
id="linearGradient4651"
x1="89.26284"
y1="85.146751"
x2="89.26284"
y2="229.47229"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.82182032,0,0,0.82182032,15.208802,28.029361)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.49497475"
inkscape:cx="85.897128"
inkscape:cy="375.72042"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-bbox="true"
inkscape:window-width="1366"
inkscape:window-height="692"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-intersection-paths="true"
inkscape:object-paths="true" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-10.356544,-82.309525)">
<rect
id="rect168"
width="123.27305"
height="123.27305"
x="23.72002"
y="95.673004"
style="fill:url(#linearGradient4651);fill-opacity:1;stroke-width:0.21743995"
rx="8.2182035"
ry="8.2182035" />
<path
inkscape:connector-curvature="0"
id="path138"
style="opacity:0.9;fill:#bfd9f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.82182032px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
d="m 47.511243,117.17807 50.067023,28.8724 -15.038249,8.68226 -35.028768,-21.3657 z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path116"
style="opacity:0.9;fill:#6666af;fill-rule:evenodd;stroke:none;stroke-width:0.82182032px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
d="m 127.13617,146.73547 0.0374,16.98921 -64.125308,36.25552 -0.0025,-16.25659 z"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
id="path118"
style="opacity:0.9;fill:#bfd9f1;fill-rule:evenodd;stroke:none;stroke-width:0.82182032px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
d="m 47.647019,174.84764 15.398727,8.89046 0.0025,16.25641 -15.401249,-8.94341 z"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:0.9;fill:#9dbef0;fill-rule:evenodd;stroke:none;stroke-width:0.82630885px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
d="m 61.586284,108.76679 -14.292349,8.25191 50.284331,29.03177 -50.148115,28.95277 15.482843,8.93896 50.148116,-28.95277 14.29235,-8.25191 z"
id="path134"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</g>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.8;fill:#00232E;}
.st1{fill:url(#SVGID_1_);}
.st2{opacity:0.16;fill:url(#SVGID_2_);}
.st3{fill:url(#SVGID_3_);}
.st4{opacity:0.16;fill:url(#SVGID_4_);}
.st5{fill:url(#SVGID_5_);}
.st6{opacity:0.15;fill:url(#SVGID_6_);}
.st7{fill:url(#SVGID_7_);}
</style>
<polygon class="st0" points="449.5,645.47 407.51,621.23 533.47,548.5 407.51,475.77 449.5,451.53 617.45,548.5 "/>
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="439.0065" y1="603.0394" x2="627.9464" y2="493.9549">
<stop offset="0" style="stop-color:#669ABD"/>
<stop offset="1" style="stop-color:#77DBDB"/>
</linearGradient>
<polygon class="st1" points="449.5,621.22 617.45,524.25 617.45,475.77 449.5,572.75 "/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="522.9788" y1="530.3148" x2="543.9741" y2="566.6795">
<stop offset="0.5588" style="stop-color:#000000;stop-opacity:0"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<polygon class="st2" points="449.5,621.22 617.45,524.25 617.45,475.77 449.5,572.75 "/>
</g>
<g>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="397.0101" y1="566.6837" x2="459.9963" y2="603.0487">
<stop offset="0" style="stop-color:#6A8FAD"/>
<stop offset="1" style="stop-color:#669ABD"/>
</linearGradient>
<polygon class="st3" points="407.51,548.5 407.5,596.99 449.5,621.22 449.5,572.75 "/>
<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="439.0009" y1="566.6838" x2="418.0056" y2="603.0486">
<stop offset="0.5588" style="stop-color:#000000;stop-opacity:0"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<polygon class="st4" points="407.51,548.5 407.5,596.99 449.5,621.22 449.5,572.75 "/>
</g>
<g>
<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="397.0101" y1="421.2265" x2="522.9781" y2="493.9542">
<stop offset="0" style="stop-color:#6A8FAD"/>
<stop offset="1" style="stop-color:#669ABD"/>
</linearGradient>
<polygon class="st5" points="407.51,403.04 407.5,451.53 491.49,500.01 533.48,475.77 "/>
<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="470.4924" y1="439.4067" x2="449.4958" y2="475.774">
<stop offset="0.5588" style="stop-color:#000000;stop-opacity:0"/>
<stop offset="1" style="stop-color:#000000"/>
</linearGradient>
<polygon class="st6" points="407.51,403.04 407.5,451.53 491.49,500.01 533.48,475.77 "/>
</g>
<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="386.5123" y1="512.136" x2="575.4605" y2="403.0467">
<stop offset="0" style="stop-color:#CCECFF"/>
<stop offset="1" style="stop-color:#9FECED"/>
</linearGradient>
<polygon class="st7" points="449.5,572.74 407.51,548.5 533.48,475.77 407.51,403.04 449.49,378.8 617.45,475.77 "/>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 426 426" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<g id="Layer-1" serif:id="Layer 1" transform="matrix(1,0,0,1,-29.3571,-233.318)">
<g>
<path id="path138" d="M93.68,293.848L287.16,405.423L229.046,438.975L93.68,356.409L93.68,293.848Z" style="fill:url(#_Linear1);"/>
<path id="path118" d="M94.204,516.708L153.711,551.064L153.721,613.886L94.204,579.325L94.204,516.708Z" style="fill:url(#_Linear2);"/>
</g>
<path id="path116" d="M401.384,408.07L401.529,473.724L153.721,613.83L153.712,551.008L401.384,408.07Z" style="fill:rgb(0,94,167);fill-opacity:0.9;"/>
<path id="path134" d="M148.072,261.343L92.84,293.232L287.16,405.423L93.366,517.309L153.198,551.853L346.992,439.967L402.224,408.078L148.072,261.343Z" style="fill:rgb(7,147,255);fill-opacity:0.9;"/>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(193.48,0,0,320.038,93.6796,453.867)"><stop offset="0" style="stop-color:rgb(0,121,215);stop-opacity:0.9"/><stop offset="1" style="stop-color:rgb(40,97,156);stop-opacity:0.9"/></linearGradient>
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(193.48,0,0,320.038,93.6796,453.867)"><stop offset="0" style="stop-color:rgb(0,121,215);stop-opacity:0.9"/><stop offset="1" style="stop-color:rgb(40,97,156);stop-opacity:0.9"/></linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,4 +1,6 @@
<!DOCTYPE html><html><head><base href="dist/"><meta name="viewport" content="initial-scale=1, minimal-ui, shrink-to-fit=no"><link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400" rel="stylesheet"><script src="bundle.js"></script><title>Terminus</title></head><body><div class="mt-5 mb-5" id="header"><div class="text-center"><h1>Terminus</h1><div class="subtitle mb-3">A terminal for a more modern age</div><a class="btn btn-lg btn-outline-dark mt-4" href="https://github.com/Eugeny/terminus/releases/latest" target="_blank"><strong>DOWNLOAD</strong></a><a class="btn btn-lg btn-outline-secondary mt-4 ml-3" href="https://github.com/Eugeny/terminus" target="_blank"><strong>GITHUB</strong></a></div></div><div class="background-stripe"><div class="overlay overlay1"></div><div class="overlay overlay2"></div><div class="terminal"></div></div><div class="container mt-5 mb-5"><div class="d-flex flex-wrap flex-md-nowrap"><div class="w-100"><div class="feature">windows</div><div class="feature">linux</div><div class="feature">macos</div><br><div class="feature">powershell</div><div class="feature">wsl</div><div class="feature">cygwin</div><div class="feature">git-bash</div><div class="feature">cmder</div><div class="feature">clink</div></div><div class="w-100"><div class="feature">full unicode</div><div class="feature">global hotkey</div><div class="feature">plugins</div><div class="feature">tab recovery</div><div class="feature">custom css</div><div class="feature">themes</div><div class="feature">font ligatures</div><div class="feature">clickable paths</div><div class="feature">tabs on top/bottom</div><div class="feature">vibrancy</div><div class="feature">bracketed paste</div></div></div></div><div class="container mt-5 mb-5"><div class="text-center"><a class="btn btn-lg btn-outline-secondary mt-5" href="/terminus/#header"><strong>BEAM ME UP</strong></a></div></div><div class="background-stripe2"><div class="overlay overlay1"></div></div><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
<!DOCTYPE html><html><head><base href="dist/"><meta name="viewport" content="initial-scale=1, minimal-ui, shrink-to-fit=no"><link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400" rel="stylesheet"><script src="bundle.js"></script><title>Terminus</title></head><body><div class="mt-5 mb-5" id="header"><div class="text-center"><h1>Terminus</h1><div class="subtitle mb-3">A terminal for a more modern age</div><a class="btn btn-lg btn-outline-dark mt-4" href="https://github.com/Eugeny/terminus/releases/latest" target="_blank"><strong>DOWNLOAD</strong></a><a class="btn btn-lg btn-outline-secondary mt-4 ml-3" href="https://github.com/Eugeny/terminus" target="_blank"><strong>GITHUB</strong></a></div></div><div class="background-stripe"><div class="overlay overlay1"></div><div class="overlay overlay2"></div><div class="terminal"></div></div><div class="container mt-5 mb-5"><div class="d-flex flex-wrap flex-md-nowrap"><div class="w-100"><div class="feature">windows</div><div class="feature">linux</div><div class="feature">macos</div><br><div class="feature">powershell</div><div class="feature">wsl</div><div class="feature">cygwin</div><div class="feature">git-bash</div><div class="feature">cmder</div><div class="feature">clink</div></div><div class="w-100"><div class="feature">full unicode</div><div class="feature">global hotkey</div><div class="feature">plugins</div><div class="feature">tab recovery</div><div class="feature">custom css</div><div class="feature">themes</div><div class="feature">font ligatures</div><div class="feature">clickable paths</div><div class="feature">tabs on top/bottom</div><div class="feature">vibrancy</div><div class="feature">bracketed paste</div></div></div></div><div class="container mt-5 mb-5"><div class="text-center mt-5"><div class="mb-4 mt-5"><script type="text/javascript" src="https://ko-fi.com/widgets/widget_2.js"></script><script type="text/javascript">kofiwidget2.init('Buy me a coffee', '#46b798', 'J3J8KWTF')
kofiwidget2.draw()
</script></div><a class="btn btn-lg btn-outline-secondary mt-3" href="/terminus/#header"><strong>BEAM ME UP</strong></a></div></div><div class="background-stripe2"><div class="overlay overlay1"></div></div><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

View File

@@ -52,8 +52,14 @@ html
.feature bracketed paste
.container.mt-5.mb-5
.text-center
a.btn.btn-lg.btn-outline-secondary.mt-5(href='/terminus/#header')
.text-center.mt-5
.mb-4.mt-5
script(type='text/javascript', src='https://ko-fi.com/widgets/widget_2.js')
script(type='text/javascript').
kofiwidget2.init('Buy me a coffee', '#46b798', 'J3J8KWTF')
kofiwidget2.draw()
a.btn.btn-lg.btn-outline-secondary.mt-3(href='/terminus/#header')
strong BEAM ME UP
.background-stripe2

BIN
docs/kofi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

@@ -7,26 +7,17 @@
"@types/js-yaml": "^3.11.2",
"@types/node": "^10.11.5",
"@types/webpack-env": "1.13.0",
"app-builder-lib": "^20.28.4",
"apply-loader": "0.1.0",
"awesome-typescript-loader": "^5.0.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.6",
"babel-loader": "^7.1.5",
"babel-preset-es2015": "^6.24.1",
"core-js": "2.4.1",
"cross-env": "4.0.0",
"css-loader": "0.28.0",
"electron": "3.0.0",
"electron-builder": "^20.27.1",
"electron": "4.0.0-beta.8",
"electron-builder": "^20.38.2",
"electron-builder-squirrel-windows": "^20.28.3",
"electron-installer-snap": "^3.0.0",
"electron-rebuild": "^1.8.2",
"eslint": "^5.4.0",
"eslint-config-standard": "^11.0.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-node": "^7.0.1",
"eslint-plugin-promise": "^4.0.0",
"eslint-plugin-standard": "^3.1.0",
"file-loader": "^1.1.11",
"font-awesome": "4.7.0",
"graceful-fs": "^4.1.11",
@@ -48,6 +39,7 @@
"raw-loader": "0.5.1",
"sass-loader": "^7.0.1",
"shelljs": "0.7.7",
"source-code-pro": "^2.30.1",
"source-sans-pro": "2.0.10",
"style-loader": "0.13.1",
"svg-inline-loader": "^0.8.0",
@@ -55,13 +47,13 @@
"tslint": "5.1.0",
"tslint-config-standard": "5.0.2",
"tslint-eslint-rules": "4.0.0",
"typescript": "^2.8.3",
"typescript": "^3.1.3",
"url-loader": "^1.1.1",
"val-loader": "0.5.0",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3",
"webpack": "^4.22.0",
"webpack-cli": "^3.1.2",
"yaml-loader": "0.4.0",
"yarn": "^1.3.2"
"yarn": "^1.10.1"
},
"build": {
"appId": "org.terminus",

View File

@@ -4,7 +4,7 @@ const vars = require('./vars')
builder({
dir: true,
mac: ['dmg'],
mac: ['dmg', 'zip'],
config: {
extraMetadata: {
version: vars.version,

View File

@@ -20,5 +20,4 @@ exports.bundledModules = [
'@angular',
'@ng-bootstrap',
]
exports.nativeModules = ['node-pty-tmp', 'font-manager', 'xkeychain', 'electron-vibrancy']
exports.electronVersion = pkgInfo.devDependencies.electron

View File

@@ -5,7 +5,9 @@
"@types/node@7.0.12":
version "7.0.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.12.tgz#ae5f67a19c15f752148004db07cbbb372e69efc9"
integrity sha1-rl9noZwV91IUgATbB8u7Ny5p78k=
"@types/webpack-env@^1.13.0":
version "1.13.1"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.1.tgz#b45c222e24301bd006e3edfc762cc6b51bda236a"
integrity sha512-oHyg0NssP2RCpCvE35hhbSqMJRsc5lSW+GFe+Vc65JL+kHII1VMYM+0KeV/z4utFuUqPoQRmq8KMMp7ba0dj6Q==

View File

@@ -8,8 +8,8 @@
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"build": "rm -rf dist && webpack --progress --color --display-modules",
"watch": "rm -rf dist && webpack --progress --color --watch"
"build": "webpack --progress --color --display-modules",
"watch": "webpack --progress --color --watch"
},
"files": [
"dist"
@@ -21,7 +21,7 @@
"@types/node": "^7.0.37",
"@types/webpack-env": "^1.13.0",
"@types/winston": "^2.3.6",
"axios": "0.16.2",
"axios": "^0.18.0",
"bootstrap": "^4.1.3",
"core-js": "^2.4.1",
"electron-updater": "^2.8.9",
@@ -45,6 +45,5 @@
"deepmerge": "^1.5.0",
"js-yaml": "^3.9.0",
"winston": "^2.4.0"
},
"false": {}
}
}

View File

@@ -5,4 +5,6 @@ export interface IHotkeyDescription {
export abstract class HotkeyProvider {
hotkeys: IHotkeyDescription[] = []
abstract provide (): Promise<IHotkeyDescription[]>
}

View File

@@ -1,4 +1,4 @@
export { BaseTabComponent } from '../components/baseTab.component'
export { BaseTabComponent, BaseTabProcess } from '../components/baseTab.component'
export { TabRecoveryProvider, RecoveredTab } from './tabRecovery'
export { ToolbarButtonProvider, IToolbarButton } from './toolbarButtonProvider'
export { ConfigProvider } from './configProvider'

View File

@@ -50,7 +50,7 @@ title-bar(
)
button.btn.btn-secondary.btn-tab-bar.btn-update(
*ngIf='appUpdate',
*ngIf='updatesAvailable',
title='Update available',
(click)='updateApp()',
[innerHTML]='updateIcon'

View File

@@ -10,9 +10,10 @@
will-change: transform;
cursor: default;
animation: 0.5s ease-out fadeIn;
transition: 0.25s background;
}
$tabs-height: 36px;
$tabs-height: 38px;
$tab-border-radius: 4px;

View File

@@ -11,7 +11,7 @@ import { ConfigService } from '../services/config.service'
import { DockingService } from '../services/docking.service'
import { TabRecoveryService } from '../services/tabRecovery.service'
import { ThemesService } from '../services/themes.service'
import { UpdaterService, Update } from '../services/updater.service'
import { UpdaterService } from '../services/updater.service'
import { TouchbarService } from '../services/touchbar.service'
import { BaseTabComponent } from './baseTab.component'
@@ -56,12 +56,15 @@ export class AppRootComponent {
@Input() ready = false
@Input() leftToolbarButtons: IToolbarButton[]
@Input() rightToolbarButtons: IToolbarButton[]
@HostBinding('class') hostClass = `platform-${process.platform}`
@HostBinding('class.platform-win32') platformClassWindows = process.platform === 'win32'
@HostBinding('class.platform-darwin') platformClassMacOS = process.platform === 'darwin'
@HostBinding('class.platform-linux') platformClassLinux = process.platform === 'linux'
@HostBinding('class.no-tabs') noTabs = true
tabsDragging = false
unsortedTabs: BaseTabComponent[] = []
updateIcon: SafeHtml
updatesAvailable = false
private logger: Logger
private appUpdate: Update
constructor (
private docking: DockingService,
@@ -119,7 +122,7 @@ export class AppRootComponent {
})
this.hostApp.secondInstance$.subscribe(() => {
this.onGlobalHotkey()
this.presentWindow()
})
this.hotkeys.globalHotkey.subscribe(() => {
this.onGlobalHotkey()
@@ -129,8 +132,8 @@ export class AppRootComponent {
ngbModal.open(SafeModeModalComponent)
}
this.updater.check().then(update => {
this.appUpdate = update
this.updater.check().then(available => {
this.updatesAvailable = available
})
this.touchbar.update()
@@ -138,45 +141,60 @@ export class AppRootComponent {
config.changed$.subscribe(() => this.updateVibrancy())
this.updateVibrancy()
let lastProgress = null
this.app.tabOpened$.subscribe(tab => {
this.unsortedTabs.push(tab)
tab.progress$.subscribe(progress => {
if (lastProgress === progress) {
return
}
if (progress !== null) {
this.hostApp.getWindow().setProgressBar(progress / 100.0, { mode: 'normal' })
} else {
this.hostApp.getWindow().setProgressBar(-1, { mode: 'none' })
}
lastProgress = progress
})
this.noTabs = false
})
this.app.tabClosed$.subscribe(tab => {
this.unsortedTabs = this.unsortedTabs.filter(x => x !== tab)
this.noTabs = app.tabs.length === 0
})
}
onGlobalHotkey () {
if (this.hostApp.getWindow().isFocused()) {
// focused
this.electron.loseFocus()
this.hostApp.getWindow().blur()
if (this.hostApp.platform !== Platform.macOS) {
this.hideWindow()
} else {
this.presentWindow()
}
}
presentWindow () {
if (!this.hostApp.getWindow().isVisible()) {
// unfocused, invisible
this.hostApp.getWindow().show()
this.hostApp.getWindow().focus()
} else {
if (this.config.store.appearance.dock === 'off') {
// not docked, visible
setTimeout(() => {
this.hostApp.getWindow().focus()
})
} else {
// docked, visible
this.hostApp.getWindow().hide()
}
} else {
if (!this.hostApp.getWindow().isVisible()) {
// unfocused, invisible
this.hostApp.getWindow().show()
this.hostApp.getWindow().focus()
} else {
if (this.config.store.appearance.dock === 'off') {
// not docked, visible
setTimeout(() => {
this.hostApp.getWindow().focus()
})
} else {
// docked, visible
this.hostApp.getWindow().hide()
}
}
}
}
hideWindow () {
this.electron.loseFocus()
this.hostApp.getWindow().blur()
if (this.hostApp.platform !== Platform.macOS) {
this.hostApp.getWindow().hide()
}
}
@@ -199,7 +217,7 @@ export class AppRootComponent {
}
updateApp () {
this.electron.shell.openExternal(this.appUpdate.url)
this.updater.update()
}
onTabDragStart () {
@@ -224,7 +242,7 @@ export class AppRootComponent {
}
private updateVibrancy () {
this.hostApp.setVibrancy(this.config.store.appearance.vibrancy)
this.hostApp.setVibrancy(this.config.store.appearance.vibrancy, this.config.store.appearance.vibrancyType)
this.hostApp.getWindow().setOpacity(this.config.store.appearance.opacity)
}
}

View File

@@ -1,6 +1,10 @@
import { Observable, Subject } from 'rxjs'
import { ViewRef } from '@angular/core'
export interface BaseTabProcess {
name: string
}
export abstract class BaseTabComponent {
private static lastTabID = 0
id: number
@@ -9,11 +13,13 @@ export abstract class BaseTabComponent {
hasFocus = false
hasActivity = false
hostView: ViewRef
color: string = null
protected titleChange = new Subject<string>()
protected focused = new Subject<void>()
protected blurred = new Subject<void>()
protected progress = new Subject<number>()
protected activity = new Subject<boolean>()
protected destroyed = new Subject<void>()
private progressClearTimeout: number
@@ -22,6 +28,7 @@ export abstract class BaseTabComponent {
get titleChange$ (): Observable<string> { return this.titleChange }
get progress$ (): Observable<number> { return this.progress }
get activity$ (): Observable<boolean> { return this.activity }
get destroyed$ (): Observable<void> { return this.destroyed }
constructor () {
this.id = BaseTabComponent.lastTabID++
@@ -66,6 +73,10 @@ export abstract class BaseTabComponent {
return null
}
async getCurrentProcess (): Promise<BaseTabProcess> {
return null
}
async canClose (): Promise<boolean> {
return true
}
@@ -83,5 +94,7 @@ export abstract class BaseTabComponent {
this.blurred.complete()
this.titleChange.complete()
this.progress.complete()
this.destroyed.next()
this.destroyed.complete()
}
}

View File

@@ -1,5 +1,5 @@
.modal-body
input.form-control(type='text', [(ngModel)]='value', (keyup.enter)='save()', autofocus)
input.form-control(type='text', #input, [(ngModel)]='value', (keyup.enter)='save()', autofocus)
.modal-footer
button.btn.btn-outline-primary((click)='save()') Save

View File

@@ -1,4 +1,4 @@
import { Component, Input } from '@angular/core'
import { Component, Input, ElementRef, ViewChild } from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
@Component({
@@ -7,11 +7,18 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
})
export class RenameTabModalComponent {
@Input() value: string
@ViewChild('input') input: ElementRef
constructor (
private modalInstance: NgbActiveModal
) { }
ngOnInit () {
setTimeout(() => {
this.input.nativeElement.focus()
}, 250)
}
save () {
this.modalInstance.close(this.value)
}

View File

@@ -1,4 +1,7 @@
.progressbar([style.width]='progress + "%"', *ngIf='progress != null')
.index(#handle) {{index + 1}}
.index(
#handle,
[style.background-color]='tab.color',
) {{index + 1}}
.name([title]='tab.customTitle || tab.title') {{tab.customTitle || tab.title}}
button((click)='app.closeTab(tab, true)') &times;

View File

@@ -1,4 +1,4 @@
$tabs-height: 36px;
$tabs-height: 38px;
:host {
position: relative;

View File

@@ -7,6 +7,16 @@ import { ElectronService } from '../services/electron.service'
import { AppService } from '../services/app.service'
import { HostAppService, Platform } from '../services/hostApp.service'
const COLORS = [
{ name: 'No color', value: null },
{ name: 'Blue', value: '#0275d8' },
{ name: 'Green', value: '#5cb85c' },
{ name: 'Orange', value: '#f0ad4e' },
{ name: 'Purple', value: '#613d7c' },
{ name: 'Red', value: '#d9534f' },
{ name: 'Yellow', value: '#ffd500' },
]
@Component({
selector: 'tab-header',
template: require('./tabHeader.component.pug'),
@@ -20,57 +30,16 @@ export class TabHeaderComponent {
@Input() progress: number
@ViewChild('handle') handle: ElementRef
private contextMenu: any
private completionNotificationEnabled = false
constructor (
zone: NgZone,
electron: ElectronService,
public app: AppService,
private electron: ElectronService,
private zone: NgZone,
private hostApp: HostAppService,
private ngbModal: NgbModal,
private parentDraggable: SortableComponent,
) {
this.contextMenu = electron.remote.Menu.buildFromTemplate([
{
label: 'Close',
click: () => {
zone.run(() => {
app.closeTab(this.tab, true)
})
}
},
{
label: 'Close other tabs',
click: () => {
zone.run(() => {
for (let tab of app.tabs.filter(x => x !== this.tab)) {
app.closeTab(tab, true)
}
})
}
},
{
label: 'Close tabs to the right',
click: () => {
zone.run(() => {
for (let tab of app.tabs.slice(app.tabs.indexOf(this.tab) + 1)) {
app.closeTab(tab, true)
}
})
}
},
{
label: 'Close tabs to the left',
click: () => {
zone.run(() => {
for (let tab of app.tabs.slice(0, app.tabs.indexOf(this.tab))) {
app.closeTab(tab, true)
}
})
}
},
])
}
) { }
ngOnInit () {
if (this.hostApp.platform === Platform.macOS) {
@@ -90,17 +59,98 @@ export class TabHeaderComponent {
}).catch(() => null)
}
@HostListener('auxclick', ['$event']) onAuxClick ($event: MouseEvent): void {
@HostListener('auxclick', ['$event']) async onAuxClick ($event: MouseEvent) {
if ($event.which === 2) {
this.app.closeTab(this.tab, true)
}
if ($event.which === 3) {
this.contextMenu.popup({
event.preventDefault()
let contextMenu = this.electron.remote.Menu.buildFromTemplate([
{
label: 'Close',
click: () => this.zone.run(() => {
this.app.closeTab(this.tab, true)
})
},
{
label: 'Close other tabs',
click: () => this.zone.run(() => {
for (let tab of this.app.tabs.filter(x => x !== this.tab)) {
this.app.closeTab(tab, true)
}
})
},
{
label: 'Close tabs to the right',
click: () => this.zone.run(() => {
for (let tab of this.app.tabs.slice(this.app.tabs.indexOf(this.tab) + 1)) {
this.app.closeTab(tab, true)
}
})
},
{
label: 'Close tabs to the left',
click: () => this.zone.run(() => {
for (let tab of this.app.tabs.slice(0, this.app.tabs.indexOf(this.tab))) {
this.app.closeTab(tab, true)
}
})
},
{
label: 'Color',
sublabel: COLORS.find(x => x.value === this.tab.color).name,
submenu: COLORS.map(color => ({
label: color.name,
type: 'radio',
checked: this.tab.color === color.value,
click: () => this.zone.run(() => {
this.tab.color = color.value
}),
})),
}
])
let process = await this.tab.getCurrentProcess()
if (process) {
contextMenu.append(new this.electron.MenuItem({
id: 'sep',
type: 'separator',
}))
contextMenu.append(new this.electron.MenuItem({
id: 'process-name',
enabled: false,
label: 'Current process: ' + process.name,
}))
contextMenu.append(new this.electron.MenuItem({
id: 'completion',
label: 'Notify when done',
type: 'checkbox',
checked: this.completionNotificationEnabled,
click: () => this.zone.run(() => {
this.completionNotificationEnabled = !this.completionNotificationEnabled
if (this.completionNotificationEnabled) {
this.app.observeTabCompletion(this.tab).subscribe(() => {
new Notification('Process completed', {
body: process.name,
}).addEventListener('click', () => {
this.app.selectTab(this.tab)
})
this.completionNotificationEnabled = false
})
} else {
this.app.stopObservingTabCompletion(this.tab)
}
})
}))
}
contextMenu.popup({
x: $event.pageX,
y: $event.pageY,
async: true,
})
event.preventDefault()
}
}
}

View File

@@ -9,7 +9,7 @@ button.btn.btn-secondary.btn-maximize(
svg(version='1.1', width='10', height='10')
path(d='M 0,0 0,10 10,10 10,0 Z M 1,1 9,1 9,9 1,9 Z')
button.btn.btn-secondary.btn-close(
(click)='hostApp.getWindow().close()',
(click)='app.closeWindow()'
)
svg(version='1.1', width='10', height='10')
path(d='M 0,0 0,0.7 4.3,5 0,9.3 0,10 0.7,10 5,5.7 9.3,10 10,10 10,9.3 5.7,5 10,0.7 10,0 9.3,0 5,4.3 0.7,0 Z')

View File

@@ -1,5 +1,6 @@
import { Component } from '@angular/core'
import { HostAppService } from '../services/hostApp.service'
import { AppService } from '../services/app.service'
@Component({
selector: 'window-controls',
@@ -7,5 +8,5 @@ import { HostAppService } from '../services/hostApp.service'
styles: [require('./windowControls.component.scss')],
})
export class WindowControlsComponent {
constructor (public hostApp: HostAppService) { }
constructor (public hostApp: HostAppService, public app: AppService) { }
}

View File

@@ -9,4 +9,5 @@ appearance:
css: '/* * { color: blue !important; } */'
opacity: 1.0
vibrancy: false
vibrancyType: 'blur'
enableAnalytics: true

View File

@@ -1,4 +1,5 @@
import { Observable, Subject, AsyncSubject } from 'rxjs'
import { takeUntil } from 'rxjs/operators'
import { Injectable, ComponentFactoryResolver, Injector } from '@angular/core'
import { BaseTabComponent } from '../components/baseTab.component'
import { Logger, LogService } from './log.service'
@@ -7,6 +8,33 @@ import { HostAppService } from './hostApp.service'
export declare type TabComponentType = new (...args: any[]) => BaseTabComponent
class CompletionObserver {
get done$ (): Observable<void> { return this.done }
get destroyed$ (): Observable<void> { return this.destroyed }
private done = new AsyncSubject<void>()
private destroyed = new AsyncSubject<void>()
private interval: number
constructor (private tab: BaseTabComponent) {
this.interval = setInterval(() => this.tick(), 1000)
this.tab.destroyed$.pipe(takeUntil(this.destroyed$)).subscribe(() => this.stop())
}
async tick () {
if (!(await this.tab.getCurrentProcess())) {
this.done.next(null)
this.stop()
}
}
stop () {
clearInterval(this.interval)
this.destroyed.next(null)
this.destroyed.complete()
this.done.complete()
}
}
@Injectable()
export class AppService {
tabs: BaseTabComponent[] = []
@@ -20,6 +48,8 @@ export class AppService {
private tabClosed = new Subject<BaseTabComponent>()
private ready = new AsyncSubject<void>()
private completionObservers = new Map<BaseTabComponent, CompletionObserver>()
get activeTabChange$ (): Observable<BaseTabComponent> { return this.activeTabChange }
get tabOpened$ (): Observable<BaseTabComponent> { return this.tabOpened }
get tabsChanged$ (): Observable<void> { return this.tabsChanged }
@@ -34,6 +64,8 @@ export class AppService {
log: LogService,
) {
this.logger = log.create('app')
this.hostApp.windowCloseRequest$.subscribe(() => this.closeWindow())
}
openNewTab (type: TabComponentType, inputs?: any): BaseTabComponent {
@@ -128,9 +160,36 @@ export class AppService {
this.tabClosed.next(tab)
}
async closeWindow () {
for (let tab of this.tabs) {
if (!await tab.canClose()) {
return
}
}
for (let tab of this.tabs) {
tab.destroy()
}
this.hostApp.closeWindow()
}
emitReady () {
this.ready.next(null)
this.ready.complete()
this.hostApp.emitReady()
}
observeTabCompletion (tab: BaseTabComponent): Observable<void> {
if (!this.completionObservers.has(tab)) {
let observer = new CompletionObserver(tab)
observer.destroyed$.subscribe(() => {
this.stopObservingTabCompletion(tab)
})
this.completionObservers.set(tab, observer)
}
return this.completionObservers.get(tab).done$
}
stopObservingTabCompletion (tab: BaseTabComponent) {
this.completionObservers.delete(tab)
}
}

View File

@@ -9,15 +9,19 @@ import { HostAppService } from './hostApp.service'
const configMerge = (a, b) => require('deepmerge')(a, b, { arrayMerge: (_d, s) => s })
function isStructuralMember (v) {
return v instanceof Object && !(v instanceof Array) &&
Object.keys(v).length > 0 && !v.__nonStructural
}
function isNonStructuralObjectMember (v) {
return v instanceof Object && !(v instanceof Array) && v.__nonStructural
}
export class ConfigProxy {
constructor (real: any, defaults: any) {
for (let key in defaults) {
if (
defaults[key] instanceof Object &&
!(defaults[key] instanceof Array) &&
Object.keys(defaults[key]).length > 0 &&
!defaults[key].__nonStructural
) {
if (isStructuralMember(defaults[key])) {
if (!real[key]) {
real[key] = {}
}
@@ -38,15 +42,36 @@ export class ConfigProxy {
{
enumerable: true,
configurable: false,
get: () => (real[key] !== undefined) ? real[key] : defaults[key],
get: () => this.getValue(key),
set: (value) => {
real[key] = value
this.setValue(key, value)
}
}
)
}
}
this.getValue = (key: string) => {
if (real[key] !== undefined) {
return real[key]
} else {
if (isNonStructuralObjectMember(defaults[key])) {
real[key] = {...defaults[key]}
delete real[key].__nonStructural
return real[key]
} else {
return defaults[key]
}
}
}
this.setValue = (key: string, value: any) => {
real[key] = value
}
}
getValue (key: string): any { } // tslint:disable-line
setValue (key: string, value: any) { } // tslint:disable-line
}
@Injectable()

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { TouchBar, BrowserWindow, Menu } from 'electron'
import { TouchBar, BrowserWindow, Menu, MenuItem } from 'electron'
@Injectable()
export class ElectronService {
@@ -12,9 +12,11 @@ export class ElectronService {
nativeImage: any
screen: any
remote: any
autoUpdater: any
TouchBar: typeof TouchBar
BrowserWindow: typeof BrowserWindow
Menu: typeof Menu
MenuItem: typeof MenuItem
private electron: any
constructor () {
@@ -28,9 +30,11 @@ export class ElectronService {
this.ipcRenderer = this.electron.ipcRenderer
this.globalShortcut = this.remote.globalShortcut
this.nativeImage = this.remote.nativeImage
this.autoUpdater = this.remote.autoUpdater
this.TouchBar = this.remote.TouchBar
this.BrowserWindow = this.remote.BrowserWindow
this.Menu = this.remote.Menu
this.MenuItem = this.remote.MenuItem
}
remoteRequire (name: string): any {

View File

@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service'
import { ConfigService } from './config.service'
import ua = require('universal-analytics')
import uuidv4 = require('uuid/v4')
@Injectable()
export class HomeBaseService {
@@ -32,12 +33,15 @@ export class HomeBaseService {
linux: 'OS: Linux',
}[os.platform()]
let plugins = (window as any).installedPlugins.filter(x => !x.isBuiltin).map(x => x.name)
body += `Plugins: ${plugins.join(', ')}\n\n`
body += `Plugins: ${plugins.join(', ') || 'none'}\n\n`
this.electron.shell.openExternal(`https://github.com/eugeny/terminus/issues/new?body=${encodeURIComponent(body)}&labels=${label}`)
}
enableAnalytics () {
const session = ua('UA-3278102-20')
if (!window.localStorage.analyticsUserID) {
window.localStorage.analyticsUserID = uuidv4()
}
const session = ua('UA-3278102-20', window.localStorage.analyticsUserID)
session.set('cd1', this.appVersion)
session.set('cd2', process.platform)
session.pageview('/').send()

View File

@@ -28,6 +28,7 @@ export class HostAppService {
private cliRunCommand = new Subject<string[]>()
private cliPaste = new Subject<string>()
private configChangeBroadcast = new Subject<void>()
private windowCloseRequest = new Subject<void>()
private logger: Logger
private windowId: number
@@ -37,6 +38,7 @@ export class HostAppService {
get cliRunCommand$ (): Observable<string[]> { return this.cliRunCommand }
get cliPaste$ (): Observable<string> { return this.cliPaste }
get configChangeBroadcast$ (): Observable<void> { return this.configChangeBroadcast }
get windowCloseRequest$ (): Observable<void> { return this.windowCloseRequest }
constructor (
private zone: NgZone,
@@ -72,6 +74,10 @@ export class HostAppService {
this.zone.run(() => this.shown.emit())
})
electron.ipcRenderer.on('host:window-close-request', () => {
this.zone.run(() => this.windowCloseRequest.next())
})
electron.ipcRenderer.on('host:second-instance', (_$event, argv: any, cwd: string) => this.zone.run(() => {
this.logger.info('Second instance', argv)
const op = argv._[0]
@@ -85,6 +91,8 @@ export class HostAppService {
text = shellEscape([text])
}
this.cliPaste.next(text)
} else {
this.secondInstance.next()
}
}))
@@ -150,13 +158,13 @@ export class HostAppService {
this.electron.ipcRenderer.send('window-set-always-on-top', flag)
}
setVibrancy (enable: boolean) {
setVibrancy (enable: boolean, type: string) {
document.body.classList.toggle('vibrant', enable)
if (this.platform === Platform.macOS) {
this.getWindow().setVibrancy(enable ? 'dark' : null)
}
if (this.platform === Platform.Windows) {
this.electron.ipcRenderer.send('window-set-vibrancy', enable)
this.electron.ipcRenderer.send('window-set-vibrancy', enable, type)
}
}
@@ -180,6 +188,14 @@ export class HostAppService {
this.electron.ipcRenderer.send('app:ready')
}
bringToFront () {
this.electron.ipcRenderer.send('window-bring-to-front')
}
closeWindow () {
this.electron.ipcRenderer.send('window-close')
}
quit () {
this.logger.info('Quitting')
this.electron.app.quit()

View File

@@ -24,13 +24,13 @@ export class HotkeysService {
globalHotkey = new EventEmitter()
private currentKeystrokes: EventBufferEntry[] = []
private disabledLevel = 0
private hotkeyDescriptions: IHotkeyDescription[]
private hotkeyDescriptions: IHotkeyDescription[] = []
constructor (
private zone: NgZone,
private electron: ElectronService,
private config: ConfigService,
@Inject(HotkeyProvider) hotkeyProviders: HotkeyProvider[],
@Inject(HotkeyProvider) private hotkeyProviders: HotkeyProvider[],
) {
let events = ['keydown', 'keyup']
events.forEach((event) => {
@@ -42,11 +42,13 @@ export class HotkeysService {
}
})
})
this.hotkeyDescriptions = this.config.enabledServices(hotkeyProviders).map(x => x.hotkeys).reduce((a, b) => a.concat(b))
this.config.changed$.subscribe(() => {
this.registerGlobalHotkey()
})
this.registerGlobalHotkey()
this.getHotkeyDescriptions().then(hotkeys => {
this.hotkeyDescriptions = hotkeys
})
}
pushKeystroke (name, nativeEvent) {
@@ -84,7 +86,7 @@ export class HotkeysService {
registerGlobalHotkey () {
this.electron.globalShortcut.unregisterAll()
let value = this.config.store.hotkeys['toggle-window']
let value = this.config.store.hotkeys['toggle-window'] || []
if (typeof value === 'string') {
value = [value]
}
@@ -102,28 +104,44 @@ export class HotkeysService {
}
getHotkeysConfig () {
return this.getHotkeysConfigRecursive(this.config.store.hotkeys)
}
getHotkeysConfigRecursive (branch) {
let keys = {}
for (let key in this.config.store.hotkeys) {
let value = this.config.store.hotkeys[key]
if (typeof value === 'string') {
value = [value]
for (let key in branch) {
let value = branch[key]
if (value instanceof Object && !(value instanceof Array)) {
let subkeys = this.getHotkeysConfigRecursive(value)
for (let subkey in subkeys) {
keys[key + '.' + subkey] = subkeys[subkey]
}
} else {
if (typeof value === 'string') {
value = [value]
}
if (value) {
value = value.map((item) => (typeof item === 'string') ? [item] : item)
keys[key] = value
}
}
value = value.map((item) => (typeof item === 'string') ? [item] : item)
keys[key] = value
}
return keys
}
getCurrentFullyMatchedHotkey (): string {
for (let id in this.getHotkeysConfig()) {
for (let sequence of this.getHotkeysConfig()[id]) {
let currentStrokes = this.getCurrentKeystrokes()
let currentStrokes = this.getCurrentKeystrokes()
let config = this.getHotkeysConfig()
for (let id in config) {
for (let sequence of config[id]) {
if (currentStrokes.length < sequence.length) {
continue
}
if (sequence.every((x, index) => {
return x.toLowerCase() === currentStrokes[currentStrokes.length - sequence.length + index].toLowerCase()
})) {
if (sequence.every(
(x, index) =>
x.toLowerCase() ===
currentStrokes[currentStrokes.length - sequence.length + index].toLowerCase()
)) {
return id
}
}
@@ -132,15 +150,17 @@ export class HotkeysService {
}
getCurrentPartiallyMatchedHotkeys (): PartialHotkeyMatch[] {
let currentStrokes = this.getCurrentKeystrokes()
let config = this.getHotkeysConfig()
let result = []
for (let id in this.getHotkeysConfig()) {
for (let sequence of this.getHotkeysConfig()[id]) {
let currentStrokes = this.getCurrentKeystrokes()
for (let id in config) {
for (let sequence of config[id]) {
for (let matchLength = Math.min(currentStrokes.length, sequence.length); matchLength > 0; matchLength--) {
if (sequence.slice(0, matchLength).every((x, index) => {
return x.toLowerCase() === currentStrokes[currentStrokes.length - matchLength + index].toLowerCase()
})) {
if (sequence.slice(0, matchLength).every(
(x, index) =>
x.toLowerCase() ===
currentStrokes[currentStrokes.length - matchLength + index].toLowerCase()
)) {
result.push({
matchedLength: matchLength,
id,
@@ -169,6 +189,15 @@ export class HotkeysService {
isEnabled () {
return this.disabledLevel === 0
}
async getHotkeyDescriptions (): Promise<IHotkeyDescription[]> {
return (
await Promise.all(
this.config.enabledServices(this.hotkeyProviders)
.map(async x => x.provide ? x.provide() : x.hotkeys)
)
).reduce((a, b) => a.concat(b))
}
}
@Injectable()
@@ -243,4 +272,8 @@ export class AppHotkeyProvider extends HotkeyProvider {
name: 'Tab 10',
},
]
async provide (): Promise<IHotkeyDescription[]> {
return this.hotkeys
}
}

View File

@@ -1,36 +1,77 @@
import axios from 'axios'
import * as os from 'os'
import { Injectable } from '@angular/core'
import { Logger, LogService } from './log.service'
import { ElectronService } from './electron.service'
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
export interface Update {
version: string
url: string
}
@Injectable()
export class UpdaterService {
private logger: Logger
private downloaded: Promise<boolean>
private isSquirrel = true
private updateURL: string
constructor (
log: LogService,
private electron: ElectronService,
) {
this.logger = log.create('updater')
try {
electron.autoUpdater.setFeedURL(`https://terminus-updates.herokuapp.com/update/${os.platform()}/${electron.app.getVersion()}`)
} catch (e) {
this.isSquirrel = false
this.logger.info('Squirrel updater unavailable, falling back')
}
this.electron.autoUpdater.on('update-available', () => {
this.logger.info('Update available')
})
this.electron.autoUpdater.once('update-not-available', () => {
this.logger.info('No updates')
})
this.downloaded = new Promise<boolean>(resolve => {
this.electron.autoUpdater.once('update-downloaded', () => resolve(true))
})
this.logger.debug('Checking for updates')
if (this.isSquirrel) {
try {
this.electron.autoUpdater.checkForUpdates()
} catch (e) {
this.isSquirrel = false
this.logger.info('Squirrel updater unavailable, falling back')
}
}
}
async check (): Promise<Update> {
this.logger.debug('Checking for updates')
let response = await axios.get(UPDATES_URL)
let data = response.data
let version = data.tag_name.substring(1)
if (this.electron.app.getVersion() !== version) {
this.logger.info('Update available:', version)
return { version, url: data.html_url }
async check (): Promise<boolean> {
if (!this.isSquirrel) {
this.logger.debug('Checking for updates')
let response = await axios.get(UPDATES_URL)
let data = response.data
let version = data.tag_name.substring(1)
if (this.electron.app.getVersion() !== version) {
this.logger.info('Update available')
this.updateURL = data.html_url
return true
}
this.logger.info('No updates')
return false
}
return this.downloaded
}
async update () {
if (!this.isSquirrel) {
this.electron.shell.openExternal(this.updateURL)
} else {
await this.downloaded
this.electron.autoUpdater.quitAndInstall()
}
this.logger.info('No updates')
return null
}
}

View File

@@ -26,6 +26,7 @@ $body-bg2: #20333e;
$body-color: #ccc;
$font-family-sans-serif: "Source Sans Pro";
$font-family-monospace: "Source Code Pro";
$font-size-base: 14rem / 16;
$btn-border-radius: 0;
@@ -124,6 +125,10 @@ body {
}
app-root {
&.no-tabs {
background: rgba(0,0,0,.5);
}
&> .content {
.tab-bar {
.btn-tab-bar {
@@ -361,3 +366,18 @@ toggle.active .body .toggle {
fill: white;
fill-opacity: 0.75;
}
*::-webkit-scrollbar {
background: rgba(0, 0, 0, .125);
width: 10px;
margin: 5px;
}
*::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, .25);
}
*::-webkit-scrollbar-corner,
*::-webkit-resizer {
opacity: 0;
}

View File

@@ -5,24 +5,29 @@
"@types/js-yaml@^3.9.0":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.9.1.tgz#2f3c142771bb345829ce690c5838760b6b9ba553"
integrity sha512-6ejot8/A47YhEGg8K/Gi+/Nu4vohMgxEG383aBaHKjrGjJUQE7umk+vg5I7TaPe4C99nUZrCDw+weK3M7gg/oA==
"@types/node@*", "@types/node@^7.0.37":
version "7.0.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
integrity sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==
"@types/webpack-env@^1.13.0":
version "1.13.1"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.1.tgz#b45c222e24301bd006e3edfc762cc6b51bda236a"
integrity sha512-oHyg0NssP2RCpCvE35hhbSqMJRsc5lSW+GFe+Vc65JL+kHII1VMYM+0KeV/z4utFuUqPoQRmq8KMMp7ba0dj6Q==
"@types/winston@^2.3.6":
version "2.3.6"
resolved "https://registry.yarnpkg.com/@types/winston/-/winston-2.3.6.tgz#0f0954b9e16abd40598dc6e9cc2ea43044237997"
integrity sha512-gZsUc53u4JHqt5nvfgTnjNP1SkzDmDtY7eZz/8WUFL43Pp8KMR+g8LiHjslwLLheIS/hfGH55QW4tJVjNwYh/Q==
dependencies:
"@types/node" "*"
ajv@^5.1.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
@@ -32,145 +37,167 @@ ajv@^5.1.0:
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
integrity sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=
dependencies:
sprintf-js "~1.0.2"
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
async@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9"
integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
aws4@^1.6.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axios@0.16.2:
version "0.16.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d"
axios@^0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=
dependencies:
follow-redirects "^1.2.3"
follow-redirects "^1.3.0"
is-buffer "^1.1.5"
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
dependencies:
tweetnacl "^0.14.3"
bluebird-lst@^1.0.2, bluebird-lst@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.3.tgz#cc56c18660eff0a0b86e2c33d1659618f7005158"
integrity sha512-NKk/GQk5fXcLKt4USI1htGuMwXHhKLa2a32FCNBFAOcpL0k8U5yFpusr3+NKc6RjytL8umW5pSQmtJCWWhiLrQ==
dependencies:
bluebird "^3.5.0"
bluebird@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
integrity sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=
boom@4.x.x:
version "4.3.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
integrity sha1-T4owBctKfjiJ90kDD9JbluAdLjE=
dependencies:
hoek "4.x.x"
boom@5.x.x:
version "5.2.0"
resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
integrity sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==
dependencies:
hoek "4.x.x"
bootstrap@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.1.3.tgz#0eb371af2c8448e8c210411d0cb824a6409a12be"
integrity sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w==
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
colors@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
combined-stream@1.0.6, combined-stream@~1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
integrity sha1-cj599ugBrFYTETp+RFqbactjKBg=
dependencies:
delayed-stream "~1.0.0"
core-js@^2.4.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
integrity sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
cryptiles@3.x.x:
version "3.1.2"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
integrity sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=
dependencies:
boom "5.x.x"
cycle@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
dependencies:
assert-plus "^1.0.0"
debug@^2.4.5:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies:
ms "2.0.0"
debug@^3.0.0:
debug@=3.1.0, debug@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.0.1.tgz#0564c612b521dc92d9f2988f0549e34f9c98db64"
integrity sha512-6nVc6S36qbt/mutyt+UGMnawAMrPDZUPQjRZI3FS9tCtDRhvxJbK79unYBLPi+z5SLXQ3ftoVBFCblQtNSls8w==
dependencies:
ms "2.0.0"
deepmerge@^1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-1.5.1.tgz#c053bf06fd7276f1994f70c09a0760cb61a56237"
integrity sha512-Ndl8eeOHB9dQkmT1HWCgY3t0odl4bmWKFzjQZBYAxVTNs2B3nn5b6orimRYHKZ4FI8psvZkA1INRCW6l7vc9lQ==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
@@ -178,6 +205,7 @@ ecc-jsbn@~0.1.1:
electron-builder-http@~19.27.5:
version "19.27.5"
resolved "https://registry.yarnpkg.com/electron-builder-http/-/electron-builder-http-19.27.5.tgz#800865df2e618ffab9e5b3b895c15b4ce7fd7f17"
integrity sha512-irxaEueAp+5GP8n2dLCh6scR4aE9+7IzEwAQ/R++U1rg1ADgsmhTOAx+Glt/u3tMzz7X8cM60P+tMtXyz1VfiQ==
dependencies:
bluebird-lst "^1.0.3"
debug "^3.0.1"
@@ -186,10 +214,12 @@ electron-builder-http@~19.27.5:
electron-is-dev@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.3.0.tgz#14e6fda5c68e9e4ecbeff9ccf037cbd7c05c5afe"
integrity sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=
electron-updater@^2.8.9:
version "2.8.9"
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-2.8.9.tgz#e2525dcbd7c27ff173bdfd2e87056d67310e2555"
integrity sha512-ZlNBaznkhGO/fxPPEK3r+rzCch6ULrgecTRJsYu2cFkX4oS5AFfL5dndw1EpZzKIOHYYIEUSjZ5FpI3FCHit2Q==
dependencies:
bluebird-lst "^1.0.3"
debug "^3.0.1"
@@ -207,44 +237,54 @@ electron-updater@^2.8.9:
esprima@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
integrity sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==
extend@~3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
eyes@0.1.x:
version "0.1.8"
resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"
integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=
fast-deep-equal@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
follow-redirects@^1.2.3:
version "1.2.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.4.tgz#355e8f4d16876b43f577b0d5ce2668b9723214ea"
follow-redirects@^1.3.0:
version "1.5.10"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
dependencies:
debug "^2.4.5"
debug "=3.1.0"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
integrity sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=
dependencies:
asynckit "^0.4.0"
combined-stream "1.0.6"
@@ -253,6 +293,7 @@ form-data@~2.3.1:
fs-extra-p@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-4.4.0.tgz#729c601c4f4c701328921adc7cfe9b236f100660"
integrity sha512-SDAF7Ma08/ERKmbNHBvoaxxox33/xiomZGhJlxoSaGYGn7jHCwLTFRnJ82wxrylZa+h0TtkBrrtXzRO79p3AHQ==
dependencies:
bluebird-lst "^1.0.2"
fs-extra "^4.0.0"
@@ -260,6 +301,7 @@ fs-extra-p@^4.4.0:
fs-extra@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.1.tgz#7fc0c6c8957f983f57f306a24e5b9ddd8d0dd880"
integrity sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=
dependencies:
graceful-fs "^4.1.2"
jsonfile "^3.0.0"
@@ -268,20 +310,24 @@ fs-extra@^4.0.0:
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
dependencies:
assert-plus "^1.0.0"
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=
dependencies:
ajv "^5.1.0"
har-schema "^2.0.0"
@@ -289,6 +335,7 @@ har-validator@~5.0.3:
hawk@~6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
integrity sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==
dependencies:
boom "4.x.x"
cryptiles "3.x.x"
@@ -298,30 +345,36 @@ hawk@~6.0.2:
hoek@4.x.x:
version "4.2.1"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb"
integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
is-buffer@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
isstream@0.1.x, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
js-yaml@^3.9.0, js-yaml@^3.9.1:
version "3.9.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0"
integrity sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
@@ -329,28 +382,34 @@ js-yaml@^3.9.0, js-yaml@^3.9.1:
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
jsonfile@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66"
integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=
optionalDependencies:
graceful-fs "^4.1.6"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
@@ -360,36 +419,44 @@ jsprim@^1.2.2:
lazy-val@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.2.tgz#d9b07fb1fce54cbc99b3c611de431b83249369b6"
integrity sha512-2BaSu6qVnicKdWQPysrffZVFAKcPcZQ/q2YyeSjAxWaJlvCvKSrkcvsSHlleeIfA//fW2goTcYDTy2cBLN7+PQ==
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
macaddress@^0.2.7:
version "0.2.8"
resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
integrity sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=
mime-db@~1.35.0:
version "1.35.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47"
integrity sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==
mime-types@^2.1.12, mime-types@~2.1.17:
version "2.1.19"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0"
integrity sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==
dependencies:
mime-db "~1.35.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ng2-dnd@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/ng2-dnd/-/ng2-dnd-5.0.2.tgz#862278ac7dedfa14f5783bbf34014d5d73dfefb4"
integrity sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ==
ngx-perfect-scrollbar@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-6.0.0.tgz#92b51957c04ed6a6d416beca2707bab005667b68"
integrity sha512-x4bzfI7AmeZubUN+tJJ99GYniSgHLJbTAg3ecbWd8dG6z59efgx4yxUjN1sDh7UYgimtg3w857qXEZJW/USAhA==
dependencies:
perfect-scrollbar "^1.3.0"
resize-observer-polyfill "^1.4.0"
@@ -397,30 +464,37 @@ ngx-perfect-scrollbar@^6.0.0:
oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=
perfect-scrollbar@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.3.0.tgz#61da56f94b58870d8e0a617bce649cee17d1e3b2"
integrity sha512-7Ub8YOvZB5k+pTy0K3LYUDnH9Xl3qvHcclJyIX+AV5UxHxll146iVGq4rtc+848nTDBQq89J7QxKKMA++cTXzQ==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
qs@~6.5.1:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
rage-edit-tmp@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/rage-edit-tmp/-/rage-edit-tmp-1.1.0.tgz#fc5d76716d2fe2cf97dcafbf3e26753e3a08e3b2"
integrity sha512-lR97QHY5WSf9orInMJhPqUbenkdiy7QbXUoRMI+wBZGyAPkxNwgo7h6ojq634QrBf/kQo3mVXYjuD3ZYraNaZQ==
request@2.86.0:
version "2.86.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.86.0.tgz#2b9497f449b0a32654c081a5cf426bbfb5bf5b69"
integrity sha512-BQZih67o9r+Ys94tcIW4S7Uu8pthjrQVxhsZ/weOwHbDfACxvIyvnAbzFQxjy1jMtvFSzv5zf4my6cZsJBbVzw==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.6.0"
@@ -447,50 +521,61 @@ request@2.86.0:
resize-observer-polyfill@^1.4.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz#660ff1d9712a2382baa2cad450a4716209f9ca69"
integrity sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==
safe-buffer@^5.0.1, safe-buffer@^5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sax@^1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
semver@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==
shell-escape@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/shell-escape/-/shell-escape-0.2.0.tgz#68fd025eb0490b4f567a027f0bf22480b5f84133"
integrity sha1-aP0CXrBJC09WegJ/C/IkgLX4QTM=
sntp@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
integrity sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==
dependencies:
hoek "4.x.x"
source-map-support@^0.4.16:
version "0.4.17"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.17.tgz#6f2150553e6375375d0ccb3180502b78c18ba430"
integrity sha512-30c1Ch8FSjV0FwC253iftbbj0dU/OXoSg1LAEGZJUlGgjTNj6cu+DVqJWWIZJY5RXLWV4eFtR+4ouo0VIOYOTg==
dependencies:
source-map "^0.5.6"
source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sshpk@^1.7.0:
version "1.14.2"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
integrity sha1-xvxhZIo9nE52T9P8306hBeSSupg=
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
@@ -506,26 +591,31 @@ sshpk@^1.7.0:
stack-trace@0.0.x:
version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
tough-cookie@~2.3.3:
version "2.3.4"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655"
integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==
dependencies:
punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
universal-analytics@^0.4.17:
version "0.4.17"
resolved "https://registry.yarnpkg.com/universal-analytics/-/universal-analytics-0.4.17.tgz#b57a07e37446ebe4f32872b2152a44cbc5cc4b73"
integrity sha512-N2JFymxv4q2N5Wmftc5JCcM5t1tp+sc1kqeDRhDL4XLY5X6PBZ0kav2wvVUZJJMvmSq3WXrmzDu062p+cSFYfQ==
dependencies:
debug "^3.0.0"
request "2.86.0"
@@ -534,20 +624,24 @@ universal-analytics@^0.4.17:
universalify@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
integrity sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=
uuid-1345@^0.99.6:
version "0.99.6"
resolved "https://registry.yarnpkg.com/uuid-1345/-/uuid-1345-0.99.6.tgz#b1270ae015a7721c7adec6c46ec169c6098aed40"
integrity sha1-sScK4BWnchx63sbEbsFpxgmK7UA=
dependencies:
macaddress "^0.2.7"
uuid@^3.0.0, uuid@^3.1.0:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
@@ -556,6 +650,7 @@ verror@1.10.0:
winston@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.0.tgz#808050b93d52661ed9fb6c26b3f0c826708b0aee"
integrity sha1-gIBQuT1SZh7Z+2wms/DIJnCLCu4=
dependencies:
async "~1.0.0"
colors "1.0.x"
@@ -567,5 +662,6 @@ winston@^2.4.0:
xelement@^1.0.16:
version "1.0.16"
resolved "https://registry.yarnpkg.com/xelement/-/xelement-1.0.16.tgz#900bb46c20fc2dffadff778a9d2dc36699d0ff7e"
integrity sha1-kAu0bCD8Lf+t/3eKnS3DZpnQ/34=
dependencies:
sax "^1.2.1"

View File

@@ -6,44 +6,43 @@ button.btn.btn-outline-info.btn-sm.pull-right((click)='openPluginsFolder()')
i.fa.fa-folder
span Plugins folder
h3 Installed
h3.mb-1 Installed
.list-group
ng-container(*ngFor='let plugin of pluginManager.installedPlugins|orderBy:"name"')
.list-group-item.flex-column.align-items-start
.d-flex.w-100
.mr-auto.d-flex.flex-column
strong {{plugin.name}}
a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}}
.d-flex.flex-column.align-items-end.mr-3
div {{plugin.version}}
small.text-muted {{plugin.author}}
button.btn.btn-secondary.ml-2(
*ngIf='npmInstalled && knownUpgrades[plugin.name]',
(click)='upgradePlugin(plugin)',
[disabled]='busy[plugin.name] != undefined'
)
i.fa.fa-fw.fa-arrow-up(*ngIf='busy[plugin.name] != BusyState.Installing')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
span Upgrade ({{knownUpgrades[plugin.name].version}})
button.btn.btn-secondary.ml-2(
(click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin && npmInstalled',
[disabled]='busy[plugin.name] != undefined'
)
i.fa.fa-fw.fa-trash-o(*ngIf='busy[plugin.name] != BusyState.Uninstalling')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Uninstalling')
button.btn.btn-secondary.ml-2(
*ngIf='config.store.pluginBlacklist.includes(plugin.name)',
(click)='enablePlugin(plugin)'
)
i.fa.fa-fw.fa-play
button.btn.btn-secondary.ml-2(
*ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
(click)='disablePlugin(plugin)'
)
i.fa.fa-fw.fa-pause
.mb-3.d-flex.w-100.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins|orderBy:"name"')
button.btn.btn-outline-danger.active.mr-2(
*ngIf='config.store.pluginBlacklist.includes(plugin.name)',
(click)='enablePlugin(plugin)'
)
i.fa.fa-fw.fa-pause
button.btn.btn-outline-secondary.mr-2(
*ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
(click)='disablePlugin(plugin)'
)
i.fa.fa-fw.fa-check
.mr-auto.d-flex.flex-column
div
strong {{plugin.name}}
small.text-muted.ml-1 {{plugin.version}} / {{plugin.author}}
a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}}
button.btn.btn-primary.ml-2(
*ngIf='npmInstalled && knownUpgrades[plugin.name]',
(click)='upgradePlugin(plugin)',
[disabled]='busy[plugin.name] != undefined'
)
i.fa.fa-fw.fa-arrow-up(*ngIf='busy[plugin.name] != BusyState.Installing')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
span Upgrade ({{knownUpgrades[plugin.name].version}})
button.btn.btn-outline-danger.ml-2(
(click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin && npmInstalled',
[disabled]='busy[plugin.name] != undefined'
)
i.fa.fa-fw.fa-trash-o(*ngIf='busy[plugin.name] != BusyState.Uninstalling')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Uninstalling')
.text-center.mt-5(*ngIf='npmMissing')
h4 npm not installed
@@ -59,7 +58,7 @@ h3 Installed
div(*ngIf='npmInstalled')
h3.mt-4 Available
.input-group.mb-4
.input-group.mb-3
.input-group-prepend
.input-group-text
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='!availablePluginsReady')
@@ -72,21 +71,19 @@ div(*ngIf='npmInstalled')
)
.list-group.mb-4(*ngIf='availablePlugins$')
.mb-4(*ngIf='availablePlugins$')
ng-container(*ngFor='let plugin of (availablePlugins$|async|orderBy:"name")')
.list-group-item.flex-column.align-items-start(*ngIf='!isAlreadyInstalled(plugin)')
.d-flex.w-100
.mr-auto.d-flex.flex-column
.d-flex.w-100.align-items-center.mb-3(*ngIf='!isAlreadyInstalled(plugin)')
button.btn.btn-primary.mr-2(
(click)='installPlugin(plugin)',
[disabled]='busy[plugin.name] != undefined'
)
i.fa.fa-fw.fa-download(*ngIf='busy[plugin.name] != BusyState.Installing')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
div((click)='showPluginInfo(plugin)')
div
strong {{plugin.name}}
a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}}
.d-flex.flex-column.align-items-end.mr-3
div {{plugin.version}}
small.text-muted {{plugin.author}}
i.fa.fa-check.text-success.ml-1(*ngIf='plugin.isOfficial', title='Official')
button.btn.btn-primary(
(click)='installPlugin(plugin)',
[disabled]='busy[plugin.name] != undefined'
)
i.fa.fa-fw.fa-download(*ngIf='busy[plugin.name] != BusyState.Installing')
i.fa.fa-fw.fa-circle-o-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
small.text-muted.ml-1 {{plugin.version}} / {{plugin.author}}
i.fa.fa-check.text-success.ml-1(*ngIf='plugin.isOfficial', title='Official')
small.text-muted {{plugin.description}}

View File

@@ -5,52 +5,63 @@
"@types/mz@0.0.31":
version "0.0.31"
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-0.0.31.tgz#a4d80c082fefe71e40a7c0f07d1e6555bbbc7b52"
integrity sha1-pNgMCC/v5x5Ap8DwfR5lVbu8e1I=
dependencies:
"@types/node" "*"
"@types/node@*", "@types/node@7.0.12":
version "7.0.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.12.tgz#ae5f67a19c15f752148004db07cbbb372e69efc9"
integrity sha1-rl9noZwV91IUgATbB8u7Ny5p78k=
"@types/semver@^5.3.32":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.4.0.tgz#f3658535af7f1f502acd6da7daf405ffeb1f7ee4"
integrity sha512-PBHCvO98hNec9A491vBbh0ZNDOVxccwKL1u2pm6fs9oDgm7SEnw0lEHqHfjsYryDxnE3zaf7LvERWEXjOp1hig==
"@types/webpack-env@1.13.0":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.0.tgz#3044381647e11ee973c5af2e925323930f691d80"
integrity sha1-MEQ4FkfhHulzxa8uklMjkw9pHYA=
alphanum-sort@^1.0.1, alphanum-sort@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
ansi-styles@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
integrity sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==
dependencies:
color-convert "^1.9.0"
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
integrity sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=
dependencies:
sprintf-js "~1.0.2"
autoprefixer@^6.3.1:
version "6.7.7"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014"
integrity sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=
dependencies:
browserslist "^1.7.6"
caniuse-db "^1.0.30000634"
@@ -62,6 +73,7 @@ autoprefixer@^6.3.1:
axios@^0.16.2:
version "0.16.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d"
integrity sha1-uk+S8XFn37q0CYN4VFS5rBScPG0=
dependencies:
follow-redirects "^1.2.3"
is-buffer "^1.1.5"
@@ -69,6 +81,7 @@ axios@^0.16.2:
babel-code-frame@^6.11.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=
dependencies:
chalk "^1.1.3"
esutils "^2.0.2"
@@ -77,14 +90,17 @@ babel-code-frame@^6.11.0:
balanced-match@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=
big.js@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
integrity sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=
browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
version "1.7.7"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9"
integrity sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=
dependencies:
caniuse-db "^1.0.30000639"
electron-to-chromium "^1.2.7"
@@ -92,6 +108,7 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
caniuse-api@^1.5.2:
version "1.6.1"
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c"
integrity sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=
dependencies:
browserslist "^1.3.6"
caniuse-db "^1.0.30000529"
@@ -101,10 +118,12 @@ caniuse-api@^1.5.2:
caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639:
version "1.0.30000726"
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000726.tgz#9bb742f8d026a62df873bc03c06843d2255b60d7"
integrity sha1-m7dC+NAmpi34c7wDwGhD0iVbYNc=
chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
@@ -115,6 +134,7 @@ chalk@^1.1.3:
chalk@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
integrity sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==
dependencies:
ansi-styles "^3.1.0"
escape-string-regexp "^1.0.5"
@@ -123,38 +143,45 @@ chalk@^2.1.0:
clap@^1.0.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.0.tgz#59c90fe3e137104746ff19469a27a634ff68c857"
integrity sha1-WckP4+E3EEdG/xlGmiemNP9oyFc=
dependencies:
chalk "^1.1.3"
clone@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
integrity sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=
coa@~1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd"
integrity sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=
dependencies:
q "^1.1.2"
color-convert@^1.3.0, color-convert@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
integrity sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=
dependencies:
color-name "^1.1.1"
color-name@^1.0.0, color-name@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
color-string@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991"
integrity sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=
dependencies:
color-name "^1.0.0"
color@^0.11.0:
version "0.11.4"
resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764"
integrity sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=
dependencies:
clone "^1.0.2"
color-convert "^1.3.0"
@@ -163,6 +190,7 @@ color@^0.11.0:
colormin@^1.0.5:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133"
integrity sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=
dependencies:
color "^0.11.0"
css-color-names "0.0.4"
@@ -171,14 +199,17 @@ colormin@^1.0.5:
colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM=
css-color-names@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
css-loader@^0.28.0:
version "0.28.7"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.7.tgz#5f2ee989dd32edd907717f953317656160999c1b"
integrity sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==
dependencies:
babel-code-frame "^6.11.0"
css-selector-tokenizer "^0.7.0"
@@ -198,6 +229,7 @@ css-loader@^0.28.0:
css-selector-tokenizer@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86"
integrity sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=
dependencies:
cssesc "^0.1.0"
fastparse "^1.1.1"
@@ -206,10 +238,12 @@ css-selector-tokenizer@^0.7.0:
cssesc@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=
"cssnano@>=2.6.1 <4":
version "3.10.0"
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38"
integrity sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=
dependencies:
autoprefixer "^6.3.1"
decamelize "^1.1.2"
@@ -247,6 +281,7 @@ cssesc@^0.1.0:
csso@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85"
integrity sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=
dependencies:
clap "^1.0.9"
source-map "^0.5.3"
@@ -254,122 +289,149 @@ csso@~2.3.1:
debug@^2.4.5:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=
dependencies:
ms "2.0.0"
decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
defined@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
electron-to-chromium@^1.2.7:
version "1.3.21"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.21.tgz#a967ebdcfe8ed0083fc244d1894022a8e8113ea2"
integrity sha1-qWfr3P6O0Ag/wkTRiUAiqOgRPqI=
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
esprima@^2.6.0:
version "2.7.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=
esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
fastparse@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8"
integrity sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=
flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
integrity sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=
follow-redirects@^1.2.3:
version "1.2.4"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.4.tgz#355e8f4d16876b43f577b0d5ce2668b9723214ea"
integrity sha512-Suw6KewLV2hReSyEOeql+UUkBVyiBm3ok1VPrVFRZnQInWpdoZbbiG5i8aJVSjTr0yQ4Ava0Sh6/joCg1Brdqw==
dependencies:
debug "^2.4.5"
function-bind@^1.0.2:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
dependencies:
ansi-regex "^2.0.0"
has-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=
has@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
integrity sha1-hGFzP1OLCDfJNh45qauelwTcLyg=
dependencies:
function-bind "^1.0.2"
html-comment-regex@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
integrity sha1-ZouTd26q5V696POtRkswekljYl4=
icss-replace-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=
icss-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-2.1.0.tgz#83f0a0ec378bf3246178b6c2ad9136f135b1c962"
integrity sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=
dependencies:
postcss "^6.0.1"
indexes-of@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607"
integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc=
is-absolute-url@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6"
integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=
is-buffer@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
integrity sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=
is-plain-obj@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
is-svg@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9"
integrity sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=
dependencies:
html-comment-regex "^1.1.0"
js-base64@^2.1.9:
version "2.1.9"
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce"
integrity sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=
js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
js-yaml@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
integrity sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=
dependencies:
argparse "^1.0.7"
esprima "^2.6.0"
@@ -377,14 +439,17 @@ js-yaml@~3.7.0:
jsesc@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
json5@^0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
loader-utils@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=
dependencies:
big.js "^3.1.3"
emojis-list "^2.0.0"
@@ -393,40 +458,49 @@ loader-utils@^1.0.2:
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY=
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
macaddress@^0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
integrity sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=
math-expression-evaluator@^1.2.14:
version "1.2.17"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
integrity sha1-3oGf282E3M2PrlnGrreWFbnSZqw=
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
mz@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.6.0.tgz#c8b8521d958df0a4f2768025db69c719ee4ef1ce"
integrity sha1-yLhSHZWN8KTydoAl22nHGe5O8c4=
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
@@ -435,14 +509,17 @@ mz@^2.6.0:
ngx-pipes@^1.6.1:
version "1.6.5"
resolved "https://registry.yarnpkg.com/ngx-pipes/-/ngx-pipes-1.6.5.tgz#7dfe7bf1425b2e661ecde0e8a419e82be575dfa1"
integrity sha512-CtiDGlQITKUszBrHo6JoBOiS8iAuqoEm7ptHMEfD3iJvzRK9tNK4ZEmmBxqUPwzAPyjeGW8ALlul1QdqFrOoSg==
normalize-range@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=
normalize-url@^1.4.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c"
integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=
dependencies:
object-assign "^4.0.1"
prepend-http "^1.0.0"
@@ -452,14 +529,17 @@ normalize-url@^1.4.0:
num2fraction@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
postcss-calc@^5.2.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e"
integrity sha1-d7rnypKK2FcW4v2kLyYb98HWW14=
dependencies:
postcss "^5.0.2"
postcss-message-helpers "^2.0.0"
@@ -468,6 +548,7 @@ postcss-calc@^5.2.0:
postcss-colormin@^2.1.8:
version "2.2.2"
resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b"
integrity sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=
dependencies:
colormin "^1.0.5"
postcss "^5.0.13"
@@ -476,6 +557,7 @@ postcss-colormin@^2.1.8:
postcss-convert-values@^2.3.4:
version "2.6.1"
resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d"
integrity sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=
dependencies:
postcss "^5.0.11"
postcss-value-parser "^3.1.2"
@@ -483,30 +565,35 @@ postcss-convert-values@^2.3.4:
postcss-discard-comments@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d"
integrity sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=
dependencies:
postcss "^5.0.14"
postcss-discard-duplicates@^2.0.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932"
integrity sha1-uavye4isGIFYpesSq8riAmO5GTI=
dependencies:
postcss "^5.0.4"
postcss-discard-empty@^2.0.1:
version "2.1.0"
resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5"
integrity sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=
dependencies:
postcss "^5.0.14"
postcss-discard-overridden@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58"
integrity sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=
dependencies:
postcss "^5.0.16"
postcss-discard-unused@^2.2.1:
version "2.2.3"
resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433"
integrity sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=
dependencies:
postcss "^5.0.14"
uniqs "^2.0.0"
@@ -514,6 +601,7 @@ postcss-discard-unused@^2.2.1:
postcss-filter-plugins@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz#6d85862534d735ac420e4a85806e1f5d4286d84c"
integrity sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=
dependencies:
postcss "^5.0.4"
uniqid "^4.0.0"
@@ -521,6 +609,7 @@ postcss-filter-plugins@^2.0.0:
postcss-merge-idents@^2.1.5:
version "2.1.7"
resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270"
integrity sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=
dependencies:
has "^1.0.1"
postcss "^5.0.10"
@@ -529,12 +618,14 @@ postcss-merge-idents@^2.1.5:
postcss-merge-longhand@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658"
integrity sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=
dependencies:
postcss "^5.0.4"
postcss-merge-rules@^2.0.3:
version "2.1.2"
resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721"
integrity sha1-0d9d+qexrMO+VT8OnhDofGG19yE=
dependencies:
browserslist "^1.5.2"
caniuse-api "^1.5.2"
@@ -545,10 +636,12 @@ postcss-merge-rules@^2.0.3:
postcss-message-helpers@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e"
integrity sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=
postcss-minify-font-values@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69"
integrity sha1-S1jttWZB66fIR0qzUmyv17vey2k=
dependencies:
object-assign "^4.0.1"
postcss "^5.0.4"
@@ -557,6 +650,7 @@ postcss-minify-font-values@^1.0.2:
postcss-minify-gradients@^1.0.1:
version "1.0.5"
resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1"
integrity sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=
dependencies:
postcss "^5.0.12"
postcss-value-parser "^3.3.0"
@@ -564,6 +658,7 @@ postcss-minify-gradients@^1.0.1:
postcss-minify-params@^1.0.4:
version "1.2.2"
resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3"
integrity sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=
dependencies:
alphanum-sort "^1.0.1"
postcss "^5.0.2"
@@ -573,6 +668,7 @@ postcss-minify-params@^1.0.4:
postcss-minify-selectors@^2.0.4:
version "2.1.1"
resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf"
integrity sha1-ssapjAByz5G5MtGkllCBFDEXNb8=
dependencies:
alphanum-sort "^1.0.2"
has "^1.0.1"
@@ -582,12 +678,14 @@ postcss-minify-selectors@^2.0.4:
postcss-modules-extract-imports@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85"
integrity sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=
dependencies:
postcss "^6.0.1"
postcss-modules-local-by-default@^1.0.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069"
integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=
dependencies:
css-selector-tokenizer "^0.7.0"
postcss "^6.0.1"
@@ -595,6 +693,7 @@ postcss-modules-local-by-default@^1.0.1:
postcss-modules-scope@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90"
integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A=
dependencies:
css-selector-tokenizer "^0.7.0"
postcss "^6.0.1"
@@ -602,6 +701,7 @@ postcss-modules-scope@^1.0.0:
postcss-modules-values@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20"
integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=
dependencies:
icss-replace-symbols "^1.1.0"
postcss "^6.0.1"
@@ -609,12 +709,14 @@ postcss-modules-values@^1.1.0:
postcss-normalize-charset@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1"
integrity sha1-757nEhLX/nWceO0WL2HtYrXLk/E=
dependencies:
postcss "^5.0.5"
postcss-normalize-url@^3.0.7:
version "3.0.8"
resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222"
integrity sha1-EI90s/L82viRov+j6kWSJ5/HgiI=
dependencies:
is-absolute-url "^2.0.0"
normalize-url "^1.4.0"
@@ -624,6 +726,7 @@ postcss-normalize-url@^3.0.7:
postcss-ordered-values@^2.1.0:
version "2.2.3"
resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d"
integrity sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=
dependencies:
postcss "^5.0.4"
postcss-value-parser "^3.0.1"
@@ -631,6 +734,7 @@ postcss-ordered-values@^2.1.0:
postcss-reduce-idents@^2.2.2:
version "2.4.0"
resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3"
integrity sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=
dependencies:
postcss "^5.0.4"
postcss-value-parser "^3.0.2"
@@ -638,12 +742,14 @@ postcss-reduce-idents@^2.2.2:
postcss-reduce-initial@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea"
integrity sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=
dependencies:
postcss "^5.0.4"
postcss-reduce-transforms@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1"
integrity sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=
dependencies:
has "^1.0.1"
postcss "^5.0.8"
@@ -652,6 +758,7 @@ postcss-reduce-transforms@^1.0.3:
postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2:
version "2.2.3"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90"
integrity sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=
dependencies:
flatten "^1.0.2"
indexes-of "^1.0.1"
@@ -660,6 +767,7 @@ postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2:
postcss-svgo@^2.1.1:
version "2.1.6"
resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d"
integrity sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=
dependencies:
is-svg "^2.0.0"
postcss "^5.0.14"
@@ -669,6 +777,7 @@ postcss-svgo@^2.1.1:
postcss-unique-selectors@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d"
integrity sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=
dependencies:
alphanum-sort "^1.0.1"
postcss "^5.0.4"
@@ -677,10 +786,12 @@ postcss-unique-selectors@^2.0.2:
postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15"
integrity sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=
postcss-zindex@^2.0.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22"
integrity sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=
dependencies:
has "^1.0.1"
postcss "^5.0.4"
@@ -689,6 +800,7 @@ postcss-zindex@^2.0.1:
postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16:
version "5.2.17"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b"
integrity sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=
dependencies:
chalk "^1.1.3"
js-base64 "^2.1.9"
@@ -698,6 +810,7 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0
postcss@^6.0.1:
version "6.0.11"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.11.tgz#f48db210b1d37a7f7ab6499b7a54982997ab6f72"
integrity sha512-DsnIzznNRQprsGTALpkC0xjDygo+QcOd+qVjP9+RjyzrPiyYOXBGOwoJ4rAiiE4lu6JggQ/jW4niY24WLxuncg==
dependencies:
chalk "^2.1.0"
source-map "^0.5.7"
@@ -706,14 +819,17 @@ postcss@^6.0.1:
prepend-http@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
q@^1.1.2:
version "1.5.0"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1"
integrity sha1-3QG6ydBtMObyGa7LglPunr3DCPE=
query-string@^4.1.0:
version "4.3.4"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb"
integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s=
dependencies:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
@@ -721,6 +837,7 @@ query-string@^4.1.0:
reduce-css-calc@^1.2.6:
version "1.3.0"
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=
dependencies:
balanced-match "^0.4.2"
math-expression-evaluator "^1.2.14"
@@ -729,16 +846,19 @@ reduce-css-calc@^1.2.6:
reduce-function-call@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.2.tgz#5a200bf92e0e37751752fe45b0ab330fd4b6be99"
integrity sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=
dependencies:
balanced-match "^0.4.2"
regenerate@^1.2.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
integrity sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=
regexpu-core@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b"
integrity sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=
dependencies:
regenerate "^1.2.1"
regjsgen "^0.2.0"
@@ -747,68 +867,82 @@ regexpu-core@^1.0.0:
regjsgen@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=
regjsparser@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=
dependencies:
jsesc "~0.5.0"
sax@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
semver@^5.3.0:
version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==
sort-keys@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0=
dependencies:
is-plain-obj "^1.0.0"
source-list-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
integrity sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==
source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
dependencies:
ansi-regex "^2.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
supports-color@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=
dependencies:
has-flag "^1.0.0"
supports-color@^4.0.0, supports-color@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e"
integrity sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==
dependencies:
has-flag "^2.0.0"
svgo@^0.7.0:
version "0.7.2"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5"
integrity sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=
dependencies:
coa "~1.0.1"
colors "~1.1.2"
@@ -821,33 +955,40 @@ svgo@^0.7.0:
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
dependencies:
any-promise "^1.0.0"
uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=
uniqid@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-4.1.1.tgz#89220ddf6b751ae52b5f72484863528596bb84c1"
integrity sha1-iSIN32t1GuUrX3JISGNShZa7hME=
dependencies:
macaddress "^0.2.8"
uniqs@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02"
integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI=
vendors@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22"
integrity sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=
whet.extend@~0.9.9:
version "0.9.9"
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"
integrity sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=

View File

@@ -6,7 +6,7 @@
"terminus-builtin-plugin"
],
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"typings": "dist/src/index.d.ts",
"scripts": {
"build": "webpack --progress --color --display-modules",
"watch": "webpack --progress --color --watch"
@@ -30,6 +30,5 @@
"@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.22",
"terminus-core": "*",
"rxjs": "5.3.0"
},
"false": {}
}
}

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { DomSanitizer } from '@angular/platform-browser'
import { ToolbarButtonProvider, IToolbarButton, AppService, HostAppService } from 'terminus-core'
import { ToolbarButtonProvider, IToolbarButton, AppService, HostAppService, HotkeysService } from 'terminus-core'
import { SettingsTabComponent } from './components/settingsTab.component'
@@ -8,11 +8,18 @@ import { SettingsTabComponent } from './components/settingsTab.component'
export class ButtonProvider extends ToolbarButtonProvider {
constructor (
hostApp: HostAppService,
hotkeys: HotkeysService,
private app: AppService,
private domSanitizer: DomSanitizer,
) {
super()
hostApp.preferencesMenu$.subscribe(() => this.open())
hotkeys.matchedHotkey.subscribe(async (hotkey) => {
if (hotkey === 'settings') {
this.open()
}
})
}
provide (): IToolbarButton[] {

View File

@@ -61,7 +61,8 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.form-line(*ngIf='hostApp.platform !== Platform.Linux')
.header
.title Vibrancy
.title(*ngIf='hostApp.platform === Platform.Windows') Acrylic background
.title(*ngIf='hostApp.platform === Platform.macOS') Vibrancy
.description Gives the window a blurred transparent background
toggle(
@@ -69,14 +70,37 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
(ngModelChange)='config.save()'
)
.form-line(*ngIf='config.store.appearance.vibrancy && isFluentVibrancySupported')
.header
.title Background type
.btn-group(
[(ngModel)]='config.store.appearance.vibrancyType',
(ngModelChange)='config.save()',
ngbRadioGroup
)
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"blur"'
)
| Blur
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"fluent"'
)
| Fluent
.form-line
.header
.title Window opacity
.title Transparency
input(
type='range',
[(ngModel)]='config.store.appearance.opacity',
(ngModelChange)='config.save(); (hostApp.platform === Platform.Linux && config.requestRestart())',
min='0.05',
min='0.4',
max='1',
step='0.01'
)
@@ -242,10 +266,10 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
tr(*ngFor='let hotkey of hotkeyDescriptions|filterBy:["name"]:hotkeyFilter')
td {{hotkey.name}}
td {{hotkey.id}}
td
td.pr-5
multi-hotkey-input(
[(model)]='config.store.hotkeys[hotkey.id]',
(modelChange)='config.save(); docking.dock()'
[model]='getHotkey(hotkey.id)',
(modelChange)='setHotkey(hotkey.id, $event); config.save(); docking.dock()'
)
ngb-tab(*ngFor='let provider of settingsProviders', [id]='provider.id')

View File

@@ -19,6 +19,6 @@
}
textarea {
font-family: 'Source Sans Mono', monospace;
font-family: 'Source Code Pro', monospace;
min-height: 120px;
}

View File

@@ -1,12 +1,13 @@
import * as yaml from 'js-yaml'
import * as os from 'os'
import { Subscription } from 'rxjs'
import { Component, Inject, Input } from '@angular/core'
import { Component, Inject, Input, HostBinding } from '@angular/core'
import { HotkeysService } from 'terminus-core'
import {
ElectronService,
DockingService,
ConfigService,
IHotkeyDescription,
HotkeyProvider,
BaseTabComponent,
Theme,
HostAppService,
@@ -34,6 +35,8 @@ export class SettingsTabComponent extends BaseTabComponent {
configDefaults: any
configFile: string
isShellIntegrationInstalled = false
isFluentVibrancySupported = false
@HostBinding('class.pad-window-controls') padWindowControls = false
private configSubscription: Subscription
constructor (
@@ -43,22 +46,34 @@ export class SettingsTabComponent extends BaseTabComponent {
public hostApp: HostAppService,
public homeBase: HomeBaseService,
public shellIntegration: ShellIntegrationService,
@Inject(HotkeyProvider) hotkeyProviders: HotkeyProvider[],
hotkeys: HotkeysService,
@Inject(SettingsTabProvider) public settingsProviders: SettingsTabProvider[],
@Inject(Theme) public themes: Theme[],
) {
super()
this.hotkeyDescriptions = config.enabledServices(hotkeyProviders).map(x => x.hotkeys).reduce((a, b) => a.concat(b))
this.setTitle('Settings')
this.screens = this.docking.getScreens()
this.settingsProviders = config.enabledServices(this.settingsProviders)
this.themes = config.enabledServices(this.themes)
this.configDefaults = yaml.safeDump(config.getDefaults())
this.configFile = config.readRaw()
this.configSubscription = config.changed$.subscribe(() => {
const onConfigChange = () => {
this.configFile = config.readRaw()
this.padWindowControls = hostApp.platform === Platform.macOS
&& config.store.appearance.tabsLocation === 'bottom'
}
this.configSubscription = config.changed$.subscribe(onConfigChange)
onConfigChange()
hotkeys.getHotkeyDescriptions().then(descriptions => {
this.hotkeyDescriptions = descriptions
})
this.isFluentVibrancySupported = hostApp.platform === Platform.Windows
&& parseFloat(os.release()) >= 10
&& parseInt(os.release().split('.')[2]) >= 17063
}
async ngOnInit () {
@@ -98,4 +113,22 @@ export class SettingsTabComponent extends BaseTabComponent {
await this.shellIntegration.install()
this.isShellIntegrationInstalled = true
}
getHotkey (id: string) {
let ptr = this.config.store.hotkeys
for (let token of id.split(/\./g)) {
ptr = ptr[token]
}
return ptr
}
setHotkey (id: string, value) {
let ptr = this.config.store
let prop = 'hotkeys'
for (let token of id.split(/\./g)) {
ptr = ptr[prop]
prop = token
}
ptr[prop] = value
}
}

View File

@@ -21,3 +21,7 @@
:host /deep/ ngb-tabset > .tab-content > .tab-pane {
width: 100%;
}
:host.pad-window-controls /deep/ ngb-tabset > .nav {
padding-top: 40px;
}

View File

@@ -0,0 +1,22 @@
import { ConfigProvider, Platform } from 'terminus-core'
export class SettingsConfigProvider extends ConfigProvider {
defaults = { }
platformDefaults = {
[Platform.macOS]: {
hotkeys: {
settings: ['⌘-,'],
}
},
[Platform.Windows]: {
hotkeys: {
settings: ['Ctrl-,']
}
},
[Platform.Linux]: {
hotkeys: {
settings: ['Ctrl-,']
}
},
}
}

View File

@@ -0,0 +1,16 @@
import { Injectable } from '@angular/core'
import { IHotkeyDescription, HotkeyProvider } from 'terminus-core'
@Injectable()
export class SettingsHotkeyProvider extends HotkeyProvider {
hotkeys: IHotkeyDescription[] = [
{
id: 'settings',
name: 'Open Settings',
},
]
async provide (): Promise<IHotkeyDescription[]> {
return this.hotkeys
}
}

View File

@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import { NgPipesModule } from 'ngx-pipes'
import { ToolbarButtonProvider, TabRecoveryProvider } from 'terminus-core'
import { ToolbarButtonProvider, TabRecoveryProvider, HotkeyProvider, ConfigProvider } from 'terminus-core'
import TerminusCorePlugin from 'terminus-core'
import { HotkeyInputModalComponent } from './components/hotkeyInputModal.component'
@@ -14,6 +14,8 @@ import { SettingsTabBodyComponent } from './components/settingsTabBody.component
import { ButtonProvider } from './buttonProvider'
import { RecoveryProvider } from './recoveryProvider'
import { SettingsHotkeyProvider } from './hotkeys'
import { SettingsConfigProvider } from './config'
@NgModule({
imports: [
@@ -25,7 +27,9 @@ import { RecoveryProvider } from './recoveryProvider'
],
providers: [
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true }
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true },
{ provide: ConfigProvider, useClass: SettingsConfigProvider, multi: true },
{ provide: HotkeyProvider, useClass: SettingsHotkeyProvider, multi: true },
],
entryComponents: [
HotkeyInputModalComponent,
@@ -38,8 +42,7 @@ import { RecoveryProvider } from './recoveryProvider'
SettingsTabBodyComponent,
],
})
export default class SettingsModule {
}
export default class SettingsModule { }
export * from './api'
export { SettingsTabComponent }

View File

@@ -6,6 +6,7 @@ module.exports = {
entry: 'src/index.ts',
devtool: 'source-map',
context: __dirname,
mode: 'development',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
@@ -46,6 +47,7 @@ module.exports = {
externals: [
'fs',
'path',
'os',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,

View File

@@ -5,15 +5,19 @@
"@types/deep-equal@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.0.tgz#9ebeaa73d1fc4791f038a5f1440e0449ea968495"
integrity sha1-nr6qc9H8R5HwOKXxRA4ESeqWhJU=
"@types/node@7.0.12":
version "7.0.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.12.tgz#ae5f67a19c15f752148004db07cbbb372e69efc9"
integrity sha1-rl9noZwV91IUgATbB8u7Ny5p78k=
"@types/webpack-env@1.13.0":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.0.tgz#3044381647e11ee973c5af2e925323930f691d80"
integrity sha1-MEQ4FkfhHulzxa8uklMjkw9pHYA=
ngx-pipes@^1.6.1:
version "1.6.5"
resolved "https://registry.yarnpkg.com/ngx-pipes/-/ngx-pipes-1.6.5.tgz#7dfe7bf1425b2e661ecde0e8a419e82be575dfa1"
integrity sha512-CtiDGlQITKUszBrHo6JoBOiS8iAuqoEm7ptHMEfD3iJvzRK9tNK4ZEmmBxqUPwzAPyjeGW8ALlul1QdqFrOoSg==

View File

@@ -14,7 +14,9 @@ export class PromptModalComponent {
) { }
ngOnInit () {
this.input.nativeElement.focus()
setTimeout(() => {
this.input.nativeElement.focus()
})
}
ok () {

View File

@@ -9,11 +9,13 @@
)
.list-group.mt-3(*ngIf='lastConnection')
a.list-group-item.list-group-item-action((click)='connect(lastConnection)')
a.list-group-item.list-group-item-action.d-flex.align-items-center((click)='connect(lastConnection)')
i.fa.fa-fw.fa-history
span {{lastConnection.name}}
.mr-auto {{lastConnection.name}}
button.btn.btn-outline-danger.btn-sm((click)='clearLastConnection(); $event.stopPropagation()')
i.fa.fa-trash-o
.list-group.mt-3.connections-list
.list-group.mt-3.connections-list(*ngIf='childGroups.length')
ng-container(*ngFor='let group of childGroups')
.list-group-item.list-group-item-action.d-flex.align-items-center(
(click)='groupCollapsed[group.name] = !groupCollapsed[group.name]'

View File

@@ -54,6 +54,11 @@ export class SSHModalComponent {
this.connect(connection)
}
clearLastConnection () {
window.localStorage.lastConnection = null
this.lastConnection = null
}
connect (connection: SSHConnection) {
this.close()
this.ssh.connect(connection).catch(error => {

View File

@@ -49,7 +49,11 @@ export class SSHService {
if (privateKey) {
this.logger.info('Loaded private key from', privateKeyPath)
if (privateKey.includes('ENCRYPTED')) {
let encrypted = privateKey.includes('ENCRYPTED')
if (privateKeyPath.toLowerCase().endsWith('.ppk')) {
encrypted = encrypted || privateKey.includes('Encryption:') && !privateKey.includes('Encryption: none')
}
if (encrypted) {
let modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = 'Private key passphrase'
modal.componentInstance.password = true

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
"terminus-builtin-plugin"
],
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"typings": "dist/src/index.d.ts",
"scripts": {
"build": "webpack --progress --color --display-modules",
"watch": "webpack --progress --color --watch"
@@ -17,6 +17,7 @@
"author": "Eugene Pankov",
"license": "MIT",
"devDependencies": {
"@terminus-term/xterm": "3.8.4",
"@types/deep-equal": "^1.0.0",
"@types/mz": "0.0.31",
"@types/node": "7.0.12",
@@ -25,7 +26,8 @@
"deep-equal": "1.0.1",
"file-loader": "^0.11.2",
"rage-edit-tmp": "^1.1.0",
"xterm": "^3.6.0"
"uuid": "^3.3.2",
"xterm-addon-ligatures-tmp": "^0.1.0-beta-1"
},
"peerDependencies": {
"@angular/common": "4.0.1",
@@ -47,5 +49,9 @@
"ps-node": "^0.1.6",
"runes": "^0.4.2"
},
"optionalDependencies": {
"macos-native-processlist": "^1.0.0",
"windows-process-tree": "^0.2.3"
},
"false": {}
}

View File

@@ -1,7 +1,5 @@
import { Observable } from 'rxjs'
import { TerminalTabComponent } from './components/terminalTab.component'
export { TerminalTabComponent }
export { IChildProcess } from './services/sessions.service'
export abstract class TerminalDecorator {
// tslint:disable-next-line no-empty

View File

@@ -11,8 +11,11 @@ module.exports = function patchPTYModule (mod) {
let lastFlush = 0
let nextTimeout = 0
const maxWindow = 250
const minWindow = 50
// Minimum prebuffering window (ms) if the input is non-stop flowing
const minWindow = 10
// Maximum buffering time (ms) until output must be flushed unconditionally
const maxWindow = 100
function flush () {
if (buffer) {
@@ -36,9 +39,11 @@ module.exports = function patchPTYModule (mod) {
terminal.on('data', data => {
buffer += data
if (Date.now() - lastFlush > maxWindow) {
// Taking too much time buffering, flush to keep things interactive
flush()
} else {
if (Date.now() > nextTimeout - (minWindow / 10)) {
if (Date.now() > nextTimeout - (maxWindow / 10)) {
// Extend the window if it's expiring
reschedule()
}
}

View File

@@ -0,0 +1,243 @@
h3.mb-3 Appearance
.row
.col-md-6
.form-line
.header
.title Frontend
.description Switches terminal frontend implementation (experimental)
select.form-control(
[(ngModel)]='config.store.terminal.frontend',
(ngModelChange)='config.save()',
)
option(value='hterm') hterm
option(value='xterm') xterm
.form-line
.header
.title Font
.d-flex.w-75
input.form-control.w-75(
type='text',
[ngbTypeahead]='fontAutocomplete',
[(ngModel)]='config.store.terminal.font',
(ngModelChange)='config.save()',
)
input.form-control.w-25(
type='number',
[(ngModel)]='config.store.terminal.fontSize',
(ngModelChange)='config.save()',
)
.form-line
.header
.title Enable font ligatures
toggle(
[(ngModel)]='config.store.terminal.ligatures',
(ngModelChange)='config.save()',
)
.form-line(*ngIf='!editingColorScheme')
.header
.title Color scheme
.input-group.w-50
select.form-control(
[compareWith]='equalComparator',
[(ngModel)]='config.store.terminal.colorScheme',
(ngModelChange)='config.save()',
)
option(*ngFor='let scheme of config.store.terminal.customColorSchemes', [ngValue]='scheme') Custom: {{scheme.name}}
option(*ngFor='let scheme of colorSchemes', [ngValue]='scheme') {{scheme.name}}
.input-group-btn
button.btn.btn-secondary((click)='editScheme(config.store.terminal.colorScheme)') Edit
.input-group-btn
button.btn.btn-outline-danger(
(click)='deleteScheme(config.store.terminal.colorScheme)',
*ngIf='isCustomScheme(config.store.terminal.colorScheme)'
)
i.fa.fa-trash-o
.form-group(*ngIf='editingColorScheme')
label Editing
.input-group
input.form-control(type='text', [(ngModel)]='editingColorScheme.name')
.input-group-btn
button.btn.btn-secondary((click)='saveScheme()') Save
.input-group-btn
button.btn.btn-secondary((click)='cancelEditing()') Cancel
.form-group(*ngIf='editingColorScheme')
color-picker(
[(model)]='editingColorScheme.foreground',
(modelChange)='config.save(); schemeChanged = true',
title='FG',
)
color-picker(
[(model)]='editingColorScheme.background',
(modelChange)='config.save(); schemeChanged = true',
title='BG',
)
color-picker(
[(model)]='editingColorScheme.cursor',
(modelChange)='config.save(); schemeChanged = true',
title='CU',
)
color-picker(
*ngFor='let _ of editingColorScheme.colors; let idx = index; trackBy: colorsTrackBy',
[(model)]='editingColorScheme.colors[idx]',
(modelChange)='config.save(); schemeChanged = true',
[title]='idx',
)
.col-md-6
.form-group
.appearance-preview(
[style.font-family]='config.store.terminal.font',
[style.font-size]='config.store.terminal.fontSize + "px"',
[style.background-color]='(config.store.terminal.background == "theme") ? null : config.store.terminal.colorScheme.background',
[style.color]='config.store.terminal.colorScheme.foreground',
[style.font-feature-settings]='\'"liga" \' + config.store.terminal.ligatures ? 1 : 0',
[style.font-variant-ligatures]='config.store.terminal.ligatures ? "initial" : "none"',
)
div
span([style.background-color]='config.store.terminal.colorScheme.colors[0]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[1]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[2]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[3]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[4]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[5]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[6]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[7]') &nbsp;
span &nbsp;&nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[0]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[1]') R
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[2]') G
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[3]') Y
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[4]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[5]') M
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[6]') T
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[7]') W
div
span([style.background-color]='config.store.terminal.colorScheme.colors[8]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[9]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[10]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[11]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[12]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[13]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[14]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[15]') &nbsp;
span &nbsp;&nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[8]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[9]') R
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[10]') G
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[11]') Y
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[12]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[13]') M
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[14]') T
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[15]') W
div
span &nbsp;
div
span john@doe-pc
span([style.color]='config.store.terminal.colorScheme.colors[1]') $
span ls -l
div
span drwxr-xr-x 1 root
span([style.color]='config.store.terminal.colorScheme.colors[4]') directory
div
span -rw-r--r-- 1 root file
div
span -rwxr-xr-x 1 root
span([style.color]='config.store.terminal.colorScheme.colors[2]') executable
div
span -rwxr-xr-x 1 root
span([style.color]='config.store.terminal.colorScheme.colors[6]') sym
span ->
span([style.color]='config.store.terminal.colorScheme.colors[1]') link
div
span &nbsp;
div
span john@doe-pc
span([style.color]='config.store.terminal.colorScheme.colors[1]') $
span rm -rf /
span([style.background-color]='config.store.terminal.colorScheme.cursor') &nbsp;
.form-line
.header
.title Terminal background
.btn-group(
[(ngModel)]='config.store.terminal.background',
(ngModelChange)='config.save()',
ngbRadioGroup
)
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"theme"'
)
| From theme
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"colorScheme"'
)
| From color scheme
.form-line
.header
.title Cursor shape
.btn-group(
[(ngModel)]='config.store.terminal.cursor',
(ngModelChange)='config.save()',
ngbRadioGroup
)
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"block"'
)
| █
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"beam"'
)
| |
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"underline"'
)
| ▁
.form-line
.header
.title Blink cursor
toggle(
[(ngModel)]='config.store.terminal.cursorBlink',
(ngModelChange)='config.save()',
)

View File

@@ -1,7 +1,7 @@
.appearance-preview {
padding: 10px 0;
margin-left: 30px;
margin: 0 0 10px;
margin-left: 20px;
padding: 10px;
overflow: hidden;
span {
white-space: pre;

View File

@@ -0,0 +1,90 @@
import { Observable } from 'rxjs'
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
import { exec } from 'mz/child_process'
import deepEqual = require('deep-equal')
const fontManager = require('font-manager')
import { Component, Inject } from '@angular/core'
import { ConfigService, HostAppService, Platform } from 'terminus-core'
import { TerminalColorSchemeProvider, ITerminalColorScheme } from '../api'
@Component({
template: require('./appearanceSettingsTab.component.pug'),
styles: [require('./appearanceSettingsTab.component.scss')],
})
export class AppearanceSettingsTabComponent {
fonts: string[] = []
colorSchemes: ITerminalColorScheme[] = []
equalComparator = deepEqual
editingColorScheme: ITerminalColorScheme
schemeChanged = false
constructor (
@Inject(TerminalColorSchemeProvider) private colorSchemeProviders: TerminalColorSchemeProvider[],
private hostApp: HostAppService,
public config: ConfigService,
) { }
async ngOnInit () {
if (this.hostApp.platform === Platform.Windows || this.hostApp.platform === Platform.macOS) {
let fonts = await new Promise<any[]>((resolve) => fontManager.findFonts({ monospace: true }, resolve))
this.fonts = fonts.map(x => x.family)
this.fonts.sort()
}
if (this.hostApp.platform === Platform.Linux) {
exec('fc-list :spacing=mono').then(([stdout, _]) => {
this.fonts = stdout.toString()
.split('\n')
.filter(x => !!x)
.map(x => x.split(':')[1].trim())
.map(x => x.split(',')[0].trim())
this.fonts.sort()
})
}
this.colorSchemes = (await Promise.all(this.config.enabledServices(this.colorSchemeProviders).map(x => x.getSchemes()))).reduce((a, b) => a.concat(b))
}
fontAutocomplete = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
map(query => this.fonts.filter(v => new RegExp(query, 'gi').test(v))),
map(list => Array.from(new Set(list))),
)
}
editScheme (scheme: ITerminalColorScheme) {
this.editingColorScheme = scheme
this.schemeChanged = false
}
saveScheme () {
let schemes = this.config.store.terminal.customColorSchemes
schemes = schemes.filter(x => x !== this.editingColorScheme && x.name !== this.editingColorScheme.name)
schemes.push(this.editingColorScheme)
this.config.store.terminal.customColorSchemes = schemes
this.config.save()
this.cancelEditing()
}
cancelEditing () {
this.editingColorScheme = null
}
deleteScheme (scheme: ITerminalColorScheme) {
if (confirm(`Delete "${scheme.name}"?`)) {
let schemes = this.config.store.terminal.customColorSchemes
schemes = schemes.filter(x => x !== scheme)
this.config.store.terminal.customColorSchemes = schemes
this.config.save()
}
}
isCustomScheme (scheme: ITerminalColorScheme) {
return this.config.store.terminal.customColorSchemes.some(x => deepEqual(x, scheme))
}
colorsTrackBy (index) {
return index
}
}

View File

@@ -0,0 +1,73 @@
h3.mb-3 Shell
.form-line
.header
.title Shell
.description Default shell for new tabs
select.form-control(
[(ngModel)]='config.store.terminal.shell',
(ngModelChange)='config.save()',
)
option(
*ngFor='let shell of shells',
[ngValue]='shell.id'
) {{shell.name}}
.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.shell.startsWith("wsl")')
.mr-auto WSL terminal only supports 16 colors until ConPTY is implemented in node-pty
button.btn.btn-secondary((click)='openConPtyInfo()') More Information
.form-line(*ngIf='config.store.terminal.shell == "custom"')
.header
.title Custom shell
input.form-control(
type='text',
[(ngModel)]='config.store.terminal.customShell',
(ngModelChange)='config.save()',
)
.form-line(*ngIf='persistenceProviders.length > 0')
.header
.title Session persistence
.description Restores tabs when Terminus is restarted
select.form-control(
[(ngModel)]='config.store.terminal.persistence',
(ngModelChange)='config.save()',
)
option([ngValue]='null') Off
option(
*ngFor='let provider of persistenceProviders',
[ngValue]='provider.id'
) {{provider.displayName}}
.form-line
.header
.title Working directory
.input-group
input.form-control(
type='text',
placeholder='Home directory',
[(ngModel)]='config.store.terminal.workingDirectory',
(ngModelChange)='config.save()',
)
.input-group-btn
button.btn.btn-secondary((click)='pickWorkingDirectory()')
i.fa.fa-folder-open
.form-line
.header
.title Environment
.description Inject additional environment variables
div
.mb-2.d-flex.align-items-center(*ngFor='let pair of environmentVars')
input.form-control.w-50([(ngModel)]='pair.key', (blur)='saveEnvironment()', placeholder='Variable name')
input.form-control.w-50.mr-1([(ngModel)]='pair.value', (blur)='saveEnvironment()', placeholder='Value')
button.btn.btn-secondary((click)='removeEnvironmentVar(pair.key)')
i.fa.fa-trash-o
button.btn.btn-secondary((click)='addEnvironmentVar()')
i.fa.fa-plus.mr-2
span Add

View File

@@ -0,0 +1,72 @@
import { Component, Inject } from '@angular/core'
import { Subscription } from 'rxjs'
import { ConfigService, ElectronService } from 'terminus-core'
import { IShell, ShellProvider, SessionPersistenceProvider } from '../api'
@Component({
template: require('./shellSettingsTab.component.pug'),
})
export class ShellSettingsTabComponent {
shells: IShell[] = []
persistenceProviders: SessionPersistenceProvider[]
environmentVars: {key: string, value: string}[] = []
private configSubscription: Subscription
constructor (
public config: ConfigService,
private electron: ElectronService,
@Inject(ShellProvider) private shellProviders: ShellProvider[],
@Inject(SessionPersistenceProvider) persistenceProviders: SessionPersistenceProvider[],
) {
this.persistenceProviders = this.config.enabledServices(persistenceProviders).filter(x => x.isAvailable())
config.store.terminal.environment = config.store.terminal.environment || {}
this.reloadEnvironment()
this.configSubscription = config.changed$.subscribe(() => this.reloadEnvironment())
}
async ngOnInit () {
this.shells = (await Promise.all(this.config.enabledServices(this.shellProviders).map(x => x.provide()))).reduce((a, b) => a.concat(b))
}
openConPtyInfo() {
this.electron.shell.openExternal('https://github.com/Microsoft/node-pty/issues/216')
}
ngOnDestroy () {
this.configSubscription.unsubscribe()
}
pickWorkingDirectory () {
let shell = this.shells.find(x => x.id === this.config.store.terminal.shell)
console.log(shell)
let paths = this.electron.dialog.showOpenDialog({
defaultPath: shell.fsBase,
properties: ['openDirectory', 'showHiddenFiles'],
})
if (paths) {
this.config.store.terminal.workingDirectory = paths[0]
}
}
reloadEnvironment () {
this.environmentVars = Object.entries(this.config.store.terminal.environment).map(([k, v]) => ({ key: k, value: v as string }))
}
saveEnvironment () {
this.config.store.terminal.environment = {}
for (let pair of this.environmentVars) {
this.config.store.terminal.environment[pair.key] = pair.value
}
}
addEnvironmentVar () {
this.environmentVars.push({ key: '', value: '' })
}
removeEnvironmentVar (key: string) {
this.environmentVars = this.environmentVars.filter(x => x.key !== key)
this.saveEnvironment()
}
}

View File

@@ -1,298 +1,4 @@
h3.mb-3 Appearance
.row
.col-md-6
.form-line
.header
.title Frontend
.description Switches terminal frontend implementation (experimental)
select.form-control(
[(ngModel)]='config.store.terminal.frontend',
(ngModelChange)='config.save()',
)
option(value='hterm') hterm
option(value='xterm') xterm
.form-line
.header
.title Font
.d-flex.w-75
input.form-control.w-75(
type='text',
[ngbTypeahead]='fontAutocomplete',
[(ngModel)]='config.store.terminal.font',
(ngModelChange)='config.save()',
)
input.form-control.w-25(
type='number',
[(ngModel)]='config.store.terminal.fontSize',
(ngModelChange)='config.save()',
)
.form-line
.header
.title Enable font ligatures
toggle(
[(ngModel)]='config.store.terminal.ligatures',
(ngModelChange)='config.save()',
)
.form-line(*ngIf='!editingColorScheme')
.header
.title Color scheme
.input-group.w-50
select.form-control(
[compareWith]='equalComparator',
[(ngModel)]='config.store.terminal.colorScheme',
(ngModelChange)='config.save()',
)
option(*ngFor='let scheme of config.store.terminal.customColorSchemes', [ngValue]='scheme') Custom: {{scheme.name}}
option(*ngFor='let scheme of colorSchemes', [ngValue]='scheme') {{scheme.name}}
.input-group-btn
button.btn.btn-secondary((click)='editScheme(config.store.terminal.colorScheme)') Edit
.input-group-btn
button.btn.btn-outline-danger(
(click)='deleteScheme(config.store.terminal.colorScheme)',
*ngIf='isCustomScheme(config.store.terminal.colorScheme)'
)
i.fa.fa-trash-o
.form-group(*ngIf='editingColorScheme')
label Editing
.input-group
input.form-control(type='text', [(ngModel)]='editingColorScheme.name')
.input-group-btn
button.btn.btn-secondary((click)='saveScheme()') Save
.input-group-btn
button.btn.btn-secondary((click)='cancelEditing()') Cancel
.form-group(*ngIf='editingColorScheme')
color-picker(
[(model)]='editingColorScheme.foreground',
(modelChange)='config.save(); schemeChanged = true',
title='FG',
)
color-picker(
[(model)]='editingColorScheme.background',
(modelChange)='config.save(); schemeChanged = true',
title='BG',
)
color-picker(
[(model)]='editingColorScheme.cursor',
(modelChange)='config.save(); schemeChanged = true',
title='CU',
)
color-picker(
*ngFor='let _ of editingColorScheme.colors; let idx = index; trackBy: colorsTrackBy',
[(model)]='editingColorScheme.colors[idx]',
(modelChange)='config.save(); schemeChanged = true',
[title]='idx',
)
.form-line
.header
.title Terminal background
.btn-group(
[(ngModel)]='config.store.terminal.background',
(ngModelChange)='config.save()',
ngbRadioGroup
)
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"theme"'
)
| From theme
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"colorScheme"'
)
| From colors
.col-md-6
.form-group
.appearance-preview(
[style.font-family]='config.store.terminal.font',
[style.font-size]='config.store.terminal.fontSize + "px"',
[style.background-color]='(config.store.terminal.background == "theme") ? null : config.store.terminal.colorScheme.background',
[style.color]='config.store.terminal.colorScheme.foreground',
[style.font-feature-settings]='\'"liga" \' + config.store.terminal.ligatures ? 1 : 0',
[style.font-variant-ligatures]='config.store.terminal.ligatures ? "initial" : "none"',
)
div
span([style.background-color]='config.store.terminal.colorScheme.colors[0]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[1]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[2]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[3]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[4]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[5]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[6]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[7]') &nbsp;
span &nbsp;&nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[0]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[1]') R
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[2]') G
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[3]') Y
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[4]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[5]') M
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[6]') T
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[7]') W
div
span([style.background-color]='config.store.terminal.colorScheme.colors[8]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[9]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[10]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[11]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[12]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[13]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[14]') &nbsp;
span([style.background-color]='config.store.terminal.colorScheme.colors[15]') &nbsp;
span &nbsp;&nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[8]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[9]') R
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[10]') G
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[11]') Y
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[12]') B
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[13]') M
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[14]') T
span &nbsp;
span([style.color]='config.store.terminal.colorScheme.colors[15]') W
div
span &nbsp;
div
span john@doe-pc
span([style.color]='config.store.terminal.colorScheme.colors[1]') $
span ls -l
div
span drwxr-xr-x 1 root
span([style.color]='config.store.terminal.colorScheme.colors[4]') directory
div
span -rw-r--r-- 1 root file
div
span -rwxr-xr-x 1 root
span([style.color]='config.store.terminal.colorScheme.colors[2]') executable
div
span -rwxr-xr-x 1 root
span([style.color]='config.store.terminal.colorScheme.colors[6]') sym
span ->
span([style.color]='config.store.terminal.colorScheme.colors[1]') link
div
span &nbsp;
div
span john@doe-pc
span([style.color]='config.store.terminal.colorScheme.colors[1]') $
span rm -rf /
span([style.background-color]='config.store.terminal.colorScheme.cursor') &nbsp;
.form-line
.header
.title Cursor shape
.btn-group(
[(ngModel)]='config.store.terminal.cursor',
(ngModelChange)='config.save()',
ngbRadioGroup
)
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"block"'
)
| █
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"beam"'
)
| |
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"underline"'
)
| ▁
.form-line
.header
.title Blink cursor
toggle(
[(ngModel)]='config.store.terminal.cursorBlink',
(ngModelChange)='config.save()',
)
h3.mt-3.mb-3 Shell
.form-line
.header
.title Shell
.description Default shell for new tabs
select.form-control(
[(ngModel)]='config.store.terminal.shell',
(ngModelChange)='config.save()',
)
option(
*ngFor='let shell of shells',
[ngValue]='shell.id'
) {{shell.name}}
.form-line(*ngIf='config.store.terminal.shell == "custom"')
.header
.title Custom shell
input.form-control(
type='text',
[(ngModel)]='config.store.terminal.customShell',
(ngModelChange)='config.save()',
)
.form-line(*ngIf='persistenceProviders.length > 0')
.header
.title Session persistence
.description Restores tabs when Terminus is restarted
select.form-control(
[(ngModel)]='config.store.terminal.persistence',
(ngModelChange)='config.save()',
)
option([ngValue]='null') Off
option(
*ngFor='let provider of persistenceProviders',
[ngValue]='provider.id'
) {{provider.displayName}}
.form-line
.header
.title Working directory
input.form-control(
type='text',
placeholder='Home directory',
[(ngModel)]='config.store.terminal.workingDirectory',
(ngModelChange)='config.save()',
)
h3.mt-3.mb-3 Behaviour
h3.mb-3 Terminal
.form-line
.header
@@ -323,7 +29,11 @@ h3.mt-3.mb-3 Behaviour
[value]='"audible"'
)
| Audible
.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.bell != "audible" && config.store.terminal.shell.startsWith("wsl")')
.mr-auto WSL terminal bell can only be muted via Volume Mixer
button.btn.btn-secondary((click)='openWSLVolumeMixer()') Show Mixer
.form-line
.header
.title Right click
@@ -372,6 +82,15 @@ h3.mt-3.mb-3 Behaviour
[(ngModel)]='config.store.terminal.copyOnSelect',
(ngModelChange)='config.save()',
)
.form-line
.header
.title Scroll on input
.description Scrolls the terminal to the bottom on user input
toggle(
[(ngModel)]='config.store.terminal.scrollOnInput',
(ngModelChange)='config.save()',
)
.form-line
.header

View File

@@ -1,97 +1,23 @@
import { Observable } from 'rxjs'
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'
import { exec } from 'mz/child_process'
import deepEqual = require('deep-equal')
const fontManager = require('font-manager')
import { Component, Inject } from '@angular/core'
import { ConfigService, HostAppService, Platform } from 'terminus-core'
import { TerminalColorSchemeProvider, ITerminalColorScheme, IShell, ShellProvider, SessionPersistenceProvider } from '../api'
import { Component } from '@angular/core'
import { ConfigService, ElectronService } from 'terminus-core'
import { TerminalService } from '../services/terminal.service'
@Component({
template: require('./terminalSettingsTab.component.pug'),
styles: [require('./terminalSettingsTab.component.scss')],
})
export class TerminalSettingsTabComponent {
fonts: string[] = []
shells: IShell[] = []
persistenceProviders: SessionPersistenceProvider[]
colorSchemes: ITerminalColorScheme[] = []
equalComparator = deepEqual
editingColorScheme: ITerminalColorScheme
schemeChanged = false
constructor (
public config: ConfigService,
private hostApp: HostAppService,
@Inject(ShellProvider) private shellProviders: ShellProvider[],
@Inject(TerminalColorSchemeProvider) private colorSchemeProviders: TerminalColorSchemeProvider[],
@Inject(SessionPersistenceProvider) persistenceProviders: SessionPersistenceProvider[],
) {
this.persistenceProviders = this.config.enabledServices(persistenceProviders).filter(x => x.isAvailable())
}
private electron: ElectronService,
private terminal: TerminalService,
) { }
async ngOnInit () {
if (this.hostApp.platform === Platform.Windows || this.hostApp.platform === Platform.macOS) {
let fonts = await new Promise<any[]>((resolve) => fontManager.findFonts({ monospace: true }, resolve))
this.fonts = fonts.map(x => x.family)
this.fonts.sort()
}
if (this.hostApp.platform === Platform.Linux) {
exec('fc-list :spacing=mono').then(([stdout, _]) => {
this.fonts = stdout.toString()
.split('\n')
.filter(x => !!x)
.map(x => x.split(':')[1].trim())
.map(x => x.split(',')[0].trim())
this.fonts.sort()
})
}
this.colorSchemes = (await Promise.all(this.config.enabledServices(this.colorSchemeProviders).map(x => x.getSchemes()))).reduce((a, b) => a.concat(b))
this.shells = (await Promise.all(this.config.enabledServices(this.shellProviders).map(x => x.provide()))).reduce((a, b) => a.concat(b))
}
fontAutocomplete = (text$: Observable<string>) => {
return text$.pipe(
debounceTime(200),
distinctUntilChanged(),
map(query => this.fonts.filter(v => new RegExp(query, 'gi').test(v))),
map(list => Array.from(new Set(list))),
)
}
editScheme (scheme: ITerminalColorScheme) {
this.editingColorScheme = scheme
this.schemeChanged = false
}
saveScheme () {
let schemes = this.config.store.terminal.customColorSchemes
schemes = schemes.filter(x => x !== this.editingColorScheme && x.name !== this.editingColorScheme.name)
schemes.push(this.editingColorScheme)
this.config.store.terminal.customColorSchemes = schemes
this.config.save()
this.cancelEditing()
}
cancelEditing () {
this.editingColorScheme = null
}
deleteScheme (scheme: ITerminalColorScheme) {
if (confirm(`Delete "${scheme.name}"?`)) {
let schemes = this.config.store.terminal.customColorSchemes
schemes = schemes.filter(x => x !== scheme)
this.config.store.terminal.customColorSchemes = schemes
this.config.save()
}
}
isCustomScheme (scheme: ITerminalColorScheme) {
return this.config.store.terminal.customColorSchemes.some(x => deepEqual(x, scheme))
}
colorsTrackBy (index) {
return index
openWSLVolumeMixer () {
this.electron.shell.openItem('sndvol.exe')
this.terminal.openTab({
id: '',
command: 'wsl.exe',
args: ['tput', 'bel'],
}, null, true)
}
}

View File

@@ -2,7 +2,7 @@ import { Observable, Subject, Subscription } from 'rxjs'
import { first } from 'rxjs/operators'
import { ToastrService } from 'ngx-toastr'
import { Component, NgZone, Inject, Optional, ViewChild, HostBinding, Input } from '@angular/core'
import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, Platform } from 'terminus-core'
import { AppService, ConfigService, BaseTabComponent, BaseTabProcess, ElectronService, HostAppService, HotkeysService, Platform } from 'terminus-core'
import { IShell } from '../api'
import { Session, SessionsService } from '../services/sessions.service'
@@ -228,6 +228,8 @@ export class TerminalTabComponent extends BaseTabComponent {
}
},
]
this.frontend.focus()
}
detachTermContainerHandlers () {
@@ -259,15 +261,23 @@ export class TerminalTabComponent extends BaseTabComponent {
}
}
if (event.type === 'mousewheel') {
let wheelDeltaY = 0
if ('wheelDeltaY' in event) {
wheelDeltaY = (event as MouseWheelEvent).wheelDeltaY
} else {
wheelDeltaY = (event as MouseWheelEvent).deltaY
}
if (event.ctrlKey || event.metaKey) {
if ((event as MouseWheelEvent).wheelDeltaY > 0) {
if (wheelDeltaY > 0) {
this.zoomIn()
} else {
this.zoomOut()
}
} else if (event.altKey) {
event.preventDefault()
let delta = Math.round((event as MouseWheelEvent).wheelDeltaY / 50)
let delta = Math.round(wheelDeltaY / 50)
this.sendInput(((delta > 0) ? '\u001bOA' : '\u001bOB').repeat(Math.abs(delta)))
}
}
@@ -290,7 +300,9 @@ export class TerminalTabComponent extends BaseTabComponent {
sendInput (data: string) {
this.session.write(data)
this.frontend.scrollToBottom()
if (this.config.store.terminal.scrollOnInput) {
this.frontend.scrollToBottom()
}
}
write (data: string) {
@@ -347,6 +359,16 @@ export class TerminalTabComponent extends BaseTabComponent {
this.frontend.setZoom(this.zoom)
}
async getCurrentProcess (): Promise<BaseTabProcess> {
let children = await this.session.getChildProcesses()
if (!children.length) {
return null
}
return {
name: children[0].command
}
}
ngOnDestroy () {
this.frontend.detach(this.content.nativeElement)
this.detachTermContainerHandlers()
@@ -368,9 +390,6 @@ export class TerminalTabComponent extends BaseTabComponent {
}
async canClose (): Promise<boolean> {
if (this.hostApp.platform === Platform.Windows) {
return true
}
let children = await this.session.getChildProcesses()
if (children.length === 0) {
return true

View File

@@ -2,6 +2,11 @@ import { ConfigProvider, Platform } from 'terminus-core'
export class TerminalConfigProvider extends ConfigProvider {
defaults = {
hotkeys: {
shell: {
__nonStructural: true,
},
},
terminal: {
frontend: 'hterm',
autoOpen: false,
@@ -16,6 +21,7 @@ export class TerminalConfigProvider extends ConfigProvider {
customShell: '',
rightClick: 'menu',
copyOnSelect: false,
scrollOnInput: true,
workingDirectory: '',
altIsMeta: false,
colorScheme: {
@@ -43,7 +49,8 @@ export class TerminalConfigProvider extends ConfigProvider {
'#ffffff',
]
},
customColorSchemes: []
customColorSchemes: [],
environment: {},
},
}
@@ -60,7 +67,6 @@ export class TerminalConfigProvider extends ConfigProvider {
'⌘-C',
],
'paste': [
'⌘-V',
],
'clear': [
'⌘-K',

View File

@@ -15,6 +15,7 @@ export class HTermFrontend extends Frontend {
if (!this.initialized) {
this.init()
this.initialized = true
preferenceManager.set('background-color', 'transparent')
this.term.decorate(host)
this.htermIframe = this.term.scrollPort_.iframe_
} else {
@@ -51,9 +52,6 @@ export class HTermFrontend extends Frontend {
}
configure (config: any): void {
if (!this.term) {
return
}
this.configuredFontSize = config.terminal.fontSize
this.configuredLinePadding = config.terminal.linePadding
this.setFontSize()
@@ -74,6 +72,8 @@ export class HTermFrontend extends Frontend {
preferenceManager.set('pass-alt-number', true)
preferenceManager.set('cursor-blink', config.terminal.cursorBlink)
preferenceManager.set('clear-selection-after-copy', true)
preferenceManager.set('scroll-on-output', false)
preferenceManager.set('scroll-on-keystroke', config.terminal.scrollOnInput)
if (config.terminal.colorScheme.foreground) {
preferenceManager.set('foreground-color', config.terminal.colorScheme.foreground)
@@ -90,14 +90,8 @@ export class HTermFrontend extends Frontend {
this.configuredBackgroundColor = preferenceManager.get('background-color')
if (config.terminal.colorScheme.colors) {
preferenceManager.set(
'color-palette-overrides',
Object.assign([], config.terminal.colorScheme.colors, this.term.colorPaletteOverrides)
)
}
if (config.terminal.colorScheme.cursor) {
preferenceManager.set('cursor-color', config.terminal.colorScheme.cursor)
if (!this.term) {
return
}
let css = require('../hterm.userCSS.scss')
@@ -118,6 +112,17 @@ export class HTermFrontend extends Frontend {
}
css += config.appearance.css
this.term.setCSS(css)
if (config.terminal.colorScheme.colors) {
preferenceManager.set(
'color-palette-overrides',
Object.assign([], config.terminal.colorScheme.colors, this.term.colorPaletteOverrides)
)
}
if (config.terminal.colorScheme.cursor) {
preferenceManager.set('cursor-color', config.terminal.colorScheme.cursor)
}
this.term.setBracketedPaste(config.terminal.bracketedPaste)
this.term.defaultCursorShape = {
block: hterm.hterm.Terminal.cursorShape.BLOCK,
@@ -227,6 +232,18 @@ export class HTermFrontend extends Frontend {
this.contentUpdated.next()
return ret
}
const _expandSelection = screen.expandSelection.bind(screen)
screen.expandSelection = (selection) => {
// Drop whitespace at the end of selection
let range = selection.getRangeAt(0)
if (range.endOffset > 0 && range.endContainer.nodeType === 3 && range.endContainer.textContent !== '') {
while (/[\s\S]+\s$/.test(range.endContainer.textContent.substr(0,range.endOffset))) {
range.setEnd(range.endContainer, range.endOffset - 1)
}
}
_expandSelection(selection)
}
}
const _measureCharacterSize = this.term.scrollPort_.measureCharacterSize.bind(this.term.scrollPort_)
@@ -235,5 +252,11 @@ export class HTermFrontend extends Frontend {
size.height += this.configuredLinePadding
return size
}
const _onCursorBlink = this.term.onCursorBlink_.bind(this.term)
this.term.onCursorBlink_ = () => {
this.term.cursorNode_.style.opacity = '0'
_onCursorBlink()
}
}
}

View File

@@ -0,0 +1,7 @@
.xterm-viewport::-webkit-scrollbar {
background: rgba(0, 0, 0, .125);
}
.xterm-viewport::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, .25);
}

View File

@@ -1,10 +1,13 @@
import { Frontend } from './frontend'
import { Terminal, ITheme } from 'xterm'
import * as fit from 'xterm/lib/addons/fit/fit'
import 'xterm/dist/xterm.css'
import { Terminal, ITheme } from '@terminus-term/xterm'
import * as fit from '@terminus-term/xterm/src/addons/fit/fit'
import * as ligatures from 'xterm-addon-ligatures-tmp'
import '@terminus-term/xterm/lib/xterm.css'
import './xterm.css'
import deepEqual = require('deep-equal')
Terminal.applyAddon(fit)
Terminal.applyAddon(ligatures)
export class XTermFrontend extends Frontend {
enableResizing = true
@@ -13,6 +16,7 @@ export class XTermFrontend extends Frontend {
private zoom = 0
private resizeHandler: any
private configuredTheme: ITheme = {}
private copyOnSelect = false
constructor () {
super()
@@ -20,6 +24,7 @@ export class XTermFrontend extends Frontend {
allowTransparency: true,
enableBold: true,
})
this.xterm.on('data', data => {
this.input.next(data)
})
@@ -29,6 +34,11 @@ export class XTermFrontend extends Frontend {
this.xterm.on('title', title => {
this.title.next(title)
})
this.xterm.on('selection', () => {
if (this.copyOnSelect) {
this.copySelection()
}
})
}
attach (host: HTMLElement): void {
@@ -44,9 +54,9 @@ export class XTermFrontend extends Frontend {
host.addEventListener('dragOver', (event: any) => this.dragOver.next(event))
host.addEventListener('drop', event => this.drop.next(event))
host.addEventListener('mousedown', event => this.mouseEvent.next(event))
host.addEventListener('mouseup', event => this.mouseEvent.next(event))
host.addEventListener('mousewheel', event => this.mouseEvent.next(event))
host.addEventListener('mousedown', event => this.mouseEvent.next(event as MouseEvent))
host.addEventListener('mouseup', event => this.mouseEvent.next(event as MouseEvent))
host.addEventListener('mousewheel', event => this.mouseEvent.next(event as MouseEvent))
}
detach (host: HTMLElement): void {
@@ -97,6 +107,8 @@ export class XTermFrontend extends Frontend {
this.configuredFontSize = config.terminal.fontSize
this.setFontSize()
this.copyOnSelect = config.terminal.copyOnSelect
let theme: ITheme = {
foreground: config.terminal.colorScheme.foreground,
background: (config.terminal.background === 'colorScheme') ? config.terminal.colorScheme.background : 'transparent',
@@ -116,6 +128,10 @@ export class XTermFrontend extends Frontend {
this.xterm.setOption('theme', theme)
this.configuredTheme = theme
}
if (config.terminal.ligatures && this.xterm.element) {
(this.xterm as any).enableLigatures()
}
}
setZoom (zoom: number): void {

View File

@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core'
import { IHotkeyDescription, HotkeyProvider } from 'terminus-core'
import { TerminalService } from './services/terminal.service'
@Injectable()
export class TerminalHotkeyProvider extends HotkeyProvider {
@@ -61,4 +62,16 @@ export class TerminalHotkeyProvider extends HotkeyProvider {
name: 'Intelligent Ctrl-C (copy/abort)',
},
]
constructor (
private terminal: TerminalService,
) { super() }
async provide (): Promise<IHotkeyDescription[]> {
let shells = await this.terminal.shells$.toPromise()
return this.hotkeys.concat(shells.map(shell => ({
id: `shell.${shell.id}`,
name: `New tab: ${shell.name}`
})))
}
}

View File

@@ -8,6 +8,7 @@ a:hover {
x-screen {
transition: 0.125s ease background;
background: transparent;
&::-webkit-scrollbar {
width: 3px;

View File

@@ -11,6 +11,8 @@ import { HostAppService } from 'terminus-core'
import { ToolbarButtonProvider, TabRecoveryProvider, ConfigProvider, HotkeysService, HotkeyProvider, AppService, ConfigService } from 'terminus-core'
import { SettingsTabProvider } from 'terminus-settings'
import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component'
import { ShellSettingsTabComponent } from './components/shellSettingsTab.component'
import { TerminalTabComponent } from './components/terminalTab.component'
import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.component'
import { ColorPickerComponent } from './components/colorPicker.component'
@@ -24,7 +26,7 @@ import { TMuxPersistenceProvider } from './persistence/tmux'
import { ButtonProvider } from './buttonProvider'
import { RecoveryProvider } from './recoveryProvider'
import { SessionPersistenceProvider, TerminalColorSchemeProvider, TerminalDecorator, ShellProvider } from './api'
import { TerminalSettingsTabProvider } from './settings'
import { TerminalSettingsTabProvider, AppearanceSettingsTabProvider, ShellSettingsTabProvider } from './settings'
import { PathDropDecorator } from './pathDrop'
import { TerminalConfigProvider } from './config'
import { TerminalHotkeyProvider } from './hotkeys'
@@ -58,9 +60,12 @@ import { hterm } from './hterm'
TerminalFrontendService,
TerminalService,
{ provide: SettingsTabProvider, useClass: AppearanceSettingsTabProvider, multi: true },
{ provide: SettingsTabProvider, useClass: ShellSettingsTabProvider, multi: true },
{ provide: SettingsTabProvider, useClass: TerminalSettingsTabProvider, multi: true },
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
{ provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true },
{ provide: SettingsTabProvider, useClass: TerminalSettingsTabProvider, multi: true },
{ provide: ConfigProvider, useClass: TerminalConfigProvider, multi: true },
{ provide: HotkeyProvider, useClass: TerminalHotkeyProvider, multi: true },
{ provide: TerminalColorSchemeProvider, useClass: HyperColorSchemes, multi: true },
@@ -89,11 +94,15 @@ import { hterm } from './hterm'
],
entryComponents: [
TerminalTabComponent,
AppearanceSettingsTabComponent,
ShellSettingsTabComponent,
TerminalSettingsTabComponent,
],
declarations: [
ColorPickerComponent,
TerminalTabComponent,
AppearanceSettingsTabComponent,
ShellSettingsTabComponent,
TerminalSettingsTabComponent,
],
})
@@ -139,16 +148,22 @@ export default class TerminalModule {
if (hotkey === 'new-tab') {
terminal.openTab()
}
})
hotkeys.matchedHotkey.subscribe(async (hotkey) => {
if (hotkey === 'new-window') {
hostApp.newWindow()
}
if (hotkey.startsWith('shell.')) {
let shells = await terminal.shells$.toPromise()
let shell = shells.find(x => x.id === hotkey.split('.')[1])
if (shell) {
terminal.openTab(shell)
}
}
})
hostApp.cliOpenDirectory$.subscribe(async directory => {
if (await fs.exists(directory)) {
if ((await fs.stat(directory)).isDirectory()) {
terminal.openTab(null, directory)
hostApp.bringToFront()
}
}
})
@@ -158,14 +173,16 @@ export default class TerminalModule {
command: command[0],
args: command.slice(1),
}, null, true)
hostApp.bringToFront()
})
hostApp.cliPaste$.subscribe(text => {
if (app.activeTab instanceof TerminalTabComponent && app.activeTab.session) {
(app.activeTab as TerminalTabComponent).sendInput(text)
hostApp.bringToFront()
}
})
}
}
export * from './api'
export { TerminalService, BaseSession, TerminalTabComponent, TerminalFrontendService }
export * from './api'

View File

@@ -9,6 +9,17 @@ import { exec } from 'mz/child_process'
import { SessionOptions, SessionPersistenceProvider } from '../api'
let macOSNativeProcessList
try {
macOSNativeProcessList = require('macos-native-processlist')
} catch (e) { } // tslint:disable-line
let windowsProcessTree
try {
windowsProcessTree = require('windows-process-tree')
} catch (e) {
} // tslint:disable-line
export interface IChildProcess {
pid: number
ppid: number
@@ -104,6 +115,15 @@ export class Session extends BaseSession {
this.truePID = (this.pty as any).pid
}
setTimeout(async () => {
// Retrieve any possible single children now that shell has fully started
let processes = await this.getChildProcesses()
while (processes.length === 1) {
this.truePID = processes[0].pid
processes = await this.getChildProcesses()
}
}, 2000)
this.open = true
this.pty.on('data-buffered', data => {
@@ -155,6 +175,25 @@ export class Session extends BaseSession {
if (!this.truePID) {
return []
}
if (process.platform === 'darwin') {
let processes = await macOSNativeProcessList.getProcessList()
return processes.filter(x => x.ppid === this.truePID).map(p => ({
pid: p.pid,
ppid: p.ppid,
command: p.name,
}))
}
if (process.platform === 'win32') {
return await new Promise<IChildProcess[]>(resolve => {
windowsProcessTree.getProcessTree(this.truePID, tree => {
resolve(tree ? tree.children.map(child => ({
pid: child.pid,
ppid: tree.pid,
command: child.name,
})) : [])
})
})
}
return new Promise<IChildProcess[]>((resolve, reject) => {
psNode.lookup({ ppid: this.truePID }, (err, processes) => {
if (err) {
@@ -192,7 +231,12 @@ export class Session extends BaseSession {
return null
}
if (process.platform === 'darwin') {
let lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n')
let lines: string[]
try {
lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n')
} catch (e) {
return null
}
if (lines[1] === 'fcwd') {
return lines[2].substring(1)
} else {

View File

@@ -27,10 +27,16 @@ export class TerminalService {
})
}
async getShells (): Promise<IShell[]> {
let shellLists = await Promise.all(this.config.enabledServices(this.shellProviders).map(x => x.provide()))
return shellLists.reduce((a, b) => a.concat(b), [])
}
async reloadShells () {
this.shells = new AsyncSubject<IShell[]>()
let shellLists = await Promise.all(this.config.enabledServices(this.shellProviders).map(x => x.provide()))
this.shells.next(shellLists.reduce((a, b) => a.concat(b)))
let shells = await this.getShells()
this.logger.debug('Shells list:', shells)
this.shells.next(shells)
this.shells.complete()
}
@@ -46,7 +52,7 @@ export class TerminalService {
let shells = await this.shells$.toPromise()
shell = shells.find(x => x.id === this.config.store.terminal.shell) || shells[0]
}
let env: any = Object.assign({}, process.env, shell.env || {})
let env: any = Object.assign({}, process.env, shell.env || {}, this.config.store.terminal.environment || {})
this.logger.log(`Starting shell ${shell.name}`, shell)
let sessionOptions = await this.sessions.prepareNewSession({

View File

@@ -1,8 +1,30 @@
import { Injectable } from '@angular/core'
import { SettingsTabProvider } from 'terminus-settings'
import { AppearanceSettingsTabComponent } from './components/appearanceSettingsTab.component'
import { ShellSettingsTabComponent } from './components/shellSettingsTab.component'
import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.component'
@Injectable()
export class AppearanceSettingsTabProvider extends SettingsTabProvider {
id = 'terminal-appearance'
title = 'Appearance'
getComponentType (): any {
return AppearanceSettingsTabComponent
}
}
@Injectable()
export class ShellSettingsTabProvider extends SettingsTabProvider {
id = 'terminal-shell'
title = 'Shell'
getComponentType (): any {
return ShellSettingsTabComponent
}
}
@Injectable()
export class TerminalSettingsTabProvider extends SettingsTabProvider {
id = 'terminal'

View File

@@ -15,7 +15,7 @@ export class CustomShellProvider extends ShellProvider {
let args = this.config.store.terminal.customShell.split(' ')
return [{
id: 'custom',
name: 'Custom',
name: 'Custom shell',
command: args[0],
args: args.slice(1),
}]

View File

@@ -57,7 +57,7 @@ export class WSLShellProvider extends ShellProvider {
name: `WSL / ${name}`,
command: wslPath,
args: ['-d', name],
fsBase: (child as any).$values.basepath,
fsBase: (child as any).$values.basepath + '\\rootfs',
env: {
TERM: 'xterm-color',
COLORTERM: 'truecolor',

View File

@@ -14,8 +14,8 @@ module.exports = {
devtoolModuleFilenameTemplate: 'webpack-terminus-terminal:///[resource-path]',
},
mode: process.env.DEV ? 'development' : 'production',
optimization:{
minimize: false,
optimization: {
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
@@ -58,6 +58,8 @@ module.exports = {
'font-manager',
'path',
'node-pty-tmp',
'macos-native-processlist',
'windows-process-tree',
'mz/fs',
'mz/child_process',
/^rxjs/,

View File

@@ -2,138 +2,255 @@
# yarn lockfile v1
"@terminus-term/xterm@3.8.4":
version "3.8.4"
resolved "https://registry.yarnpkg.com/@terminus-term/xterm/-/xterm-3.8.4.tgz#c9a9d9e0d46dbd8a94e06384e2d7268d36f5b0c6"
integrity sha512-DrxCjnJh9n3ivpldwI098PnuVYwg9e5lFlU8/1qfh/J/wFHbG3dX/bEtB4ynfTi3IXVJozFO2psD96+W2h3yeQ==
"@types/async-lock@0.0.19":
version "0.0.19"
resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-0.0.19.tgz#4bdb7f8d9ac2826588b98068903aedbd9d95dce8"
integrity sha1-S9t/jZrCgmWIuYBokDrtvZ2V3Og=
"@types/deep-equal@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.0.tgz#9ebeaa73d1fc4791f038a5f1440e0449ea968495"
version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03"
integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg==
"@types/mz@0.0.31":
version "0.0.31"
resolved "https://registry.yarnpkg.com/@types/mz/-/mz-0.0.31.tgz#a4d80c082fefe71e40a7c0f07d1e6555bbbc7b52"
integrity sha1-pNgMCC/v5x5Ap8DwfR5lVbu8e1I=
dependencies:
"@types/node" "*"
"@types/node@*", "@types/node@7.0.12":
"@types/node@*":
version "10.12.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.0.tgz#ea6dcbddbc5b584c83f06c60e82736d8fbb0c235"
integrity sha512-3TUHC3jsBAB7qVRGxT6lWyYo2v96BMmD2PTcl47H25Lu7UXtFH/2qqmKiVrnel6Ne//0TFYf6uvNX+HW2FRkLQ==
"@types/node@7.0.12":
version "7.0.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.12.tgz#ae5f67a19c15f752148004db07cbbb372e69efc9"
integrity sha1-rl9noZwV91IUgATbB8u7Ny5p78k=
"@types/webpack-env@1.13.0":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.0.tgz#3044381647e11ee973c5af2e925323930f691d80"
integrity sha1-MEQ4FkfhHulzxa8uklMjkw9pHYA=
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
async-lock@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.0.0.tgz#b81abbdbd2a6e516773a044b7e6917ae2001f370"
version "1.1.3"
resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.1.3.tgz#e47f1cbb6bec765b73e27ed8961d58006457ec08"
integrity sha512-nxlfFLGfCJ1r7p9zhR5OuL6jYkDd9P7FqSitfLji+C1NdyhCz4+rWW3kiPiyPASHhN7VlsKEvRWWbnME9lYngw==
big.js@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
version "3.2.0"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==
connected-domain@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/connected-domain/-/connected-domain-1.0.0.tgz#bfe77238c74be453a79f0cb6058deeb4f2358e93"
integrity sha1-v+dyOMdL5FOnnwy2BY3utPI1jpM=
dataurl@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dataurl/-/dataurl-0.1.0.tgz#1f4734feddec05ffe445747978d86759c4b33199"
integrity sha1-H0c0/t3sBf/kRXR5eNhnWcSzMZk=
deep-equal@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
file-loader@^0.11.2:
version "0.11.2"
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.2.tgz#4ff1df28af38719a6098093b88c82c71d1794a34"
integrity sha512-N+uhF3mswIFeziHQjGScJ/yHXYt3DiLBeC+9vWW+WjUBiClMSOlV1YrXQi+7KM2aA3Rn4Bybgv+uXFQbfkzpvg==
dependencies:
loader-utils "^1.0.2"
font-finder@^1.0.2, font-finder@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/font-finder/-/font-finder-1.0.4.tgz#2ca944954dd8d0e1b5bdc4c596cc08607761d89b"
integrity sha512-naF16RpjWUTFLqzhmdivYpBCrqySN6PI+a4GPtoEsCdvOpbKYTGeTjO7mxh3Wwjz4xKU+Oqx9kwOcteLDeMFQA==
dependencies:
get-system-fonts "^2.0.0"
promise-stream-reader "^1.0.1"
font-ligatures@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/font-ligatures/-/font-ligatures-1.3.2.tgz#227eb5fc38fef34b5373aa19b555320b82842a71"
integrity sha512-h9t+gvKVr/c2GnQs4GhXHY39/qyLlXNaIxupU1cxj7YOXEFT8+sJfcchIrZ9UETZUUT7dNcI7RDOXN7gFtuw2g==
dependencies:
font-finder "^1.0.3"
lru-cache "^4.1.3"
opentype.js "^0.8.0"
font-manager@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/font-manager/-/font-manager-0.3.0.tgz#9efdc13e521a3d8752e7ab56c3938818043a311f"
integrity sha512-6N3pzO+9kxE3yD9c4VN7reg5fqgFvjcUdxZmwauRzsExaeKRu0APfEi3DOISFakokybgKlZcLFQHawwc2TMpQQ==
dependencies:
nan ">=2.10.0"
get-system-fonts@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/get-system-fonts/-/get-system-fonts-2.0.0.tgz#a43b9a33f05c0715a60176d2aad5ce6e98f0a3c6"
integrity sha512-iiM/DavyF2nnLdELzPBSHojzQJVai9WiwrRzn5gp2dutJuerC8qHyBoh4lxfVdKGbnb9eZ4p8Oefbuc3yExB7Q==
hterm-umdjs@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/hterm-umdjs/-/hterm-umdjs-1.4.1.tgz#0cd5352eaf927c70b83c36146cf2c2a281dba957"
integrity sha512-r5JOmdDK1bZCmp3cKcuGRLVeum33H+pzD119ZxmQou+QUVe6SAVSz03HvKWVhM2Ao1Biv+fkhFDmnsaRPq0tFg==
json5@^0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
loader-utils@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=
dependencies:
big.js "^3.1.3"
emojis-list "^2.0.0"
json5 "^0.5.0"
lru-cache@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c"
integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==
dependencies:
pseudomap "^1.0.2"
yallist "^2.1.2"
macos-native-processlist@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/macos-native-processlist/-/macos-native-processlist-1.0.0.tgz#1dcf1fac554e057f90c6451c39420e065d186a68"
integrity sha512-FYA5DzCBvt+1wcCR8iFoCW2zZ8GZXtR6Ee/kpC9gVlqvEcM2ooma71KV8EIP2VaM+v2HOQAVvNoKSmFBd4z8dQ==
dependencies:
nan "^2.10.0"
mz@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.6.0.tgz#c8b8521d958df0a4f2768025db69c719ee4ef1ce"
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
nan@>=2.10.0, nan@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
version "2.11.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766"
integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==
node-pty-tmp@0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/node-pty-tmp/-/node-pty-tmp-0.7.2.tgz#d1528245a46ab193c54e34792ee0b89d0f557417"
integrity sha512-/I0BluFKSy7SOnlR5TALVx+pQEJZQStsfkwCpmsxHymSUVc3dJeOLrbaaVtNsU0VchXF3KOZJmHk7EUdBmWbfQ==
dependencies:
nan "^2.10.0"
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
opentype.js@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/opentype.js/-/opentype.js-0.8.0.tgz#acabcfa1642fbe894a3e4d759e43ba694e02bd35"
integrity sha1-rKvPoWQvvolKPk11nkO6aU4CvTU=
dependencies:
tiny-inflate "^1.0.2"
promise-stream-reader@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/promise-stream-reader/-/promise-stream-reader-1.0.1.tgz#4e793a79c9d49a73ccd947c6da9c127f12923649"
integrity sha512-Tnxit5trUjBAqqZCGWwjyxhmgMN4hGrtpW3Oc/tRI4bpm/O2+ej72BB08l6JBnGQgVDGCLvHFGjGgQS6vzhwXg==
ps-node@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/ps-node/-/ps-node-0.1.6.tgz#9af67a99d7b1d0132e51a503099d38a8d2ace2c3"
integrity sha1-mvZ6mdex0BMuUaUDCZ04qNKs4sM=
dependencies:
table-parser "^0.1.3"
pseudomap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
rage-edit-tmp@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/rage-edit-tmp/-/rage-edit-tmp-1.1.0.tgz#fc5d76716d2fe2cf97dcafbf3e26753e3a08e3b2"
integrity sha512-lR97QHY5WSf9orInMJhPqUbenkdiy7QbXUoRMI+wBZGyAPkxNwgo7h6ojq634QrBf/kQo3mVXYjuD3ZYraNaZQ==
runes@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/runes/-/runes-0.4.2.tgz#1ddc1ea41de769cb32fc068a64fbbc45cd21052e"
version "0.4.3"
resolved "https://registry.yarnpkg.com/runes/-/runes-0.4.3.tgz#32f7738844bc767b65cc68171528e3373c7bb355"
integrity sha512-K6p9y4ZyL9wPzA+PMDloNQPfoDGTiFYDvdlXznyGKgD10BJpcAosvATKrExRKOrNLgD8E7Um7WGW0lxsnOuNLg==
table-parser@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/table-parser/-/table-parser-0.1.3.tgz#0441cfce16a59481684c27d1b5a67ff15a43c7b0"
integrity sha1-BEHPzhallIFoTCfRtaZ/8VpDx7A=
dependencies:
connected-domain "^1.0.0"
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
dependencies:
any-promise "^1.0.0"
xterm@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.6.0.tgz#9b95cd23a338e5842343aec1a104f094c5153e7c"
tiny-inflate@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.2.tgz#93d9decffc8805bd57eae4310f0b745e9b6fb3a7"
integrity sha1-k9nez/yIBb1X6uQxDwt0Xptvs6c=
uuid@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
windows-process-tree@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.3.tgz#6b781f0a320e8a0d6434c9399add4389c709cf6e"
integrity sha512-SzPJSubVVsToz1g5lr2P+4mQT70gvJ9u/nlnpfkOeQcAhOuhKz5DiO1TARgR0OnVsv21LPzxbA2m/4JQkGh1wA==
dependencies:
nan "^2.10.0"
xterm-addon-ligatures-tmp@^0.1.0-beta-1:
version "0.1.0-beta-2"
resolved "https://registry.yarnpkg.com/xterm-addon-ligatures-tmp/-/xterm-addon-ligatures-tmp-0.1.0-beta-2.tgz#1063a282b279b7586372dee7892cea59738c613e"
integrity sha512-d+UoX5dfP7ZSEE/DnQlqubs7Bpw5UxLfTAibpo4pOU2KFw+lRlsLgHg5fcmhXoEvD9rj01enYTsIjedNwnwC5Q==
dependencies:
font-finder "^1.0.2"
font-ligatures "^1.3.1"
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=

4187
yarn.lock

File diff suppressed because it is too large Load Diff