diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/.classpath b/eclipse-distribution/org.springframework.boot.ide.branding/.classpath
new file mode 100644
index 000000000..cf36b5611
--- /dev/null
+++ b/eclipse-distribution/org.springframework.boot.ide.branding/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.classpath b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.classpath
new file mode 100644
index 000000000..751c8f2e5
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.gitignore b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.gitignore
new file mode 100644
index 000000000..5bbd8ca7d
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.gitignore
@@ -0,0 +1 @@
+/lib/node_modules
\ No newline at end of file
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.project b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.project
new file mode 100644
index 000000000..0f83c3e7c
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/.project
@@ -0,0 +1,34 @@
+
+
+ org.springframework.ide.eclipse.xterm.macosx.aarch64
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/META-INF/MANIFEST.MF b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..8345c6b04
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Node-Xterm package for Mac OSX
+Bundle-SymbolicName: org.springframework.ide.eclipse.xterm.macosx.aarch64
+Bundle-Version: 4.16.0.qualifier
+Bundle-Vendor: VMware
+Fragment-Host: org.springframework.ide.eclipse.xterm;bundle-version="4.8.2"
+Automatic-Module-Name: org.springframework.ide.eclipse.xterm.macosx.aarch64
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Eclipse-PlatformFilter: (& (osgi.ws=cocoa) (osgi.os=macosx) (|(osgi.arch=aarch64)(osgi.arch=ppc)))
+Eclipse-BundleShape: dir
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/build.properties b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/build.properties
new file mode 100644
index 000000000..efaa0a7ff
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ lib/
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/lib/package-lock.json b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/lib/package-lock.json
new file mode 100644
index 000000000..a1f846452
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/lib/package-lock.json
@@ -0,0 +1,1105 @@
+{
+ "name": "lib",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "node-xterm": "^0.0.4"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
+ "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.10.3",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
+ "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.0",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.5.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.2.0",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.10.3",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/nan": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
+ "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA=="
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-pty": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-0.10.1.tgz",
+ "integrity": "sha512-JTdtUS0Im/yRsWJSx7yiW9rtpfmxqxolrtnyKwPLI+6XqTAPW/O2MjS8FYL4I5TsMbH2lVgDb2VMjp+9LoQGNg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "nan": "^2.14.0"
+ }
+ },
+ "node_modules/node-xterm": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/node-xterm/-/node-xterm-0.0.4.tgz",
+ "integrity": "sha512-TjGYjtI/1xFprFBokVLijmrTucHbwRHylD/UubHUa8FvkYI1Qn1TpQuPYq3hu+2S8D/BFOrcQXbvAMtT5sF2kw==",
+ "dependencies": {
+ "express": "^4.17.1",
+ "node-pty": "^0.10.1",
+ "string-argv": "^0.3.1",
+ "ws": "^7.4.7"
+ },
+ "bin": {
+ "node-xterm": "terminal-server.js"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
+ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ws": {
+ "version": "7.5.9",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ }
+ },
+ "dependencies": {
+ "accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "requires": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "body-parser": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
+ "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
+ "requires": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.10.3",
+ "raw-body": "2.5.1",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ }
+ },
+ "bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "requires": {
+ "safe-buffer": "5.2.1"
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ },
+ "cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ },
+ "destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
+ },
+ "express": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
+ "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
+ "requires": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.0",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.5.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.2.0",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.10.3",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.18.0",
+ "serve-static": "1.15.0",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ }
+ },
+ "finalhandler": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
+ "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "get-intrinsic": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+ },
+ "http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "requires": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+ },
+ "mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "requires": {
+ "mime-db": "1.52.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "nan": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz",
+ "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA=="
+ },
+ "negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
+ },
+ "node-pty": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-0.10.1.tgz",
+ "integrity": "sha512-JTdtUS0Im/yRsWJSx7yiW9rtpfmxqxolrtnyKwPLI+6XqTAPW/O2MjS8FYL4I5TsMbH2lVgDb2VMjp+9LoQGNg==",
+ "requires": {
+ "nan": "^2.14.0"
+ }
+ },
+ "node-xterm": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/node-xterm/-/node-xterm-0.0.4.tgz",
+ "integrity": "sha512-TjGYjtI/1xFprFBokVLijmrTucHbwRHylD/UubHUa8FvkYI1Qn1TpQuPYq3hu+2S8D/BFOrcQXbvAMtT5sF2kw==",
+ "requires": {
+ "express": "^4.17.1",
+ "node-pty": "^0.10.1",
+ "string-argv": "^0.3.1",
+ "ws": "^7.4.7"
+ }
+ },
+ "object-inspect": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+ "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
+ },
+ "on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+ },
+ "proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "requires": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+ },
+ "raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "requires": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "send": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
+ "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
+ "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.18.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "requires": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ }
+ },
+ "statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
+ },
+ "string-argv": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
+ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg=="
+ },
+ "toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
+ },
+ "ws": {
+ "version": "7.5.9",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
+ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
+ "requires": {}
+ }
+ }
+}
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/lib/package.json b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/lib/package.json
new file mode 100644
index 000000000..d87a1e957
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/lib/package.json
@@ -0,0 +1,5 @@
+{
+ "dependencies": {
+ "node-xterm": "^0.0.4"
+ }
+}
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/pom.xml b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/pom.xml
new file mode 100644
index 000000000..5bc5951e5
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm.macosx.aarch64/pom.xml
@@ -0,0 +1,105 @@
+
+
+ 4.0.0
+
+ org.springframework.boot.ide
+ org.springframework.boot.ide
+ 4.16.0-SNAPSHOT
+ ../../eclipse-distribution/pom.xml
+
+ eclipse-plugin
+ org.springframework.ide.eclipse.xterm.macosx.aarch64
+
+
+ node-xterm-0.0.2-macosx-aarch64.zip
+
+
+
+
+
+
+ maven-clean-plugin
+ 3.1.0
+
+
+
+ ${project.basedir}
+
+ **/lib/**
+
+ false
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ wagon-maven-plugin
+ 2.0.0
+
+
+ download-nodejs-app
+ generate-resources
+
+ download-single
+
+
+ s3
+ https://dist.springsource.com/release/TOOLS/node-xterm
+ ${archive-file}
+ ${project.basedir}/lib/node-xterm.zip
+
+
+
+
+
+
+ maven-antrun-plugin
+
+
+ process-resources
+
+
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+
+
+ org.eclipse.tycho
+ target-platform-configuration
+ ${tycho-version}
+
+ p2
+ ignore
+
+
+ macosx
+ cocoa
+ x86_64
+
+
+
+
+
+
+
+
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/.gitignore b/eclipse-extensions/org.springframework.ide.eclipse.xterm/.gitignore
index dfdbc0787..fb7cde564 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.xterm/.gitignore
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/.gitignore
@@ -1,5 +1,6 @@
/target/
/.settings/
+/lib/
.DS_Store
/**/.DS_Store
.project
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/META-INF/MANIFEST.MF b/eclipse-extensions/org.springframework.ide.eclipse.xterm/META-INF/MANIFEST.MF
index 65c13c0f0..546b024ff 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.xterm/META-INF/MANIFEST.MF
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/META-INF/MANIFEST.MF
@@ -13,7 +13,10 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.115.0",
org.apache.httpcomponents.httpcore,
org.eclipse.wildwebdeveloper.embedder.node
Import-Package: javax.inject
-Bundle-ClassPath: .
+Bundle-ClassPath: .,
+ lib/ipcsocket-1.4.0.jar,
+ lib/jna-5.8.0.jar,
+ lib/jna-platform-5.8.0.jar
Bundle-ActivationPolicy: lazy
Export-Package: org.springframework.ide.eclipse.xterm,
org.springframework.ide.eclipse.xterm.views
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/build.properties b/eclipse-extensions/org.springframework.ide.eclipse.xterm/build.properties
index e01ef8df6..2bf7b3929 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.xterm/build.properties
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/build.properties
@@ -4,4 +4,8 @@ bin.includes = META-INF/,\
.,\
plugin.xml,\
css/,\
- icons/
+ icons/,\
+ lib/,\
+ lib/ipcsocket-1.4.0.jar,\
+ lib/jna-5.8.0.jar,\
+ lib/jna-platform-5.8.0.jar
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/pom.xml b/eclipse-extensions/org.springframework.ide.eclipse.xterm/pom.xml
index a85487d33..9ac4c8c01 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.xterm/pom.xml
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/pom.xml
@@ -11,6 +11,14 @@
eclipse-plugin
org.springframework.ide.eclipse.xterm
+
+
+
+ org.scala-sbt.ipcsocket
+ ipcsocket
+ 1.4.0
+
+
@@ -60,6 +68,48 @@
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+
+
+
+ get-libs
+
+ copy
+
+ validate
+
+
+
+ false
+
+
+ org.scala-sbt.ipcsocket
+ ipcsocket
+ 1.4.0
+ true
+
+
+ net.java.dev.jna
+ jna-platform
+ 5.8.0
+
+
+ net.java.dev.jna
+ jna
+ 5.8.0
+
+
+ ${basedir}/lib/
+
+ true
+
+
+
+
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/ElectronBrowserCanvas.java b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/ElectronBrowserCanvas.java
new file mode 100644
index 000000000..85a315be9
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/ElectronBrowserCanvas.java
@@ -0,0 +1,611 @@
+package org.springframework.ide.eclipse.chromium.browser;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseWheelListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.scalasbt.ipcsocket.UnixDomainServerSocket;
+import org.scalasbt.ipcsocket.Win32NamedPipeServerSocket;
+import org.scalasbt.ipcsocket.Win32SecurityLevel;
+
+public class ElectronBrowserCanvas extends Canvas
+{
+ private Image image;
+ private GC gc;
+
+ private Image createImage(int width, int height)
+ {
+ ImageData data = new ImageData(width, height, 32, new PaletteData(0xff0000,0x00ff00, 0x0000ff));
+ data.setAlpha(0, 0, 0);
+ Arrays.fill(data.alphaData, (byte) -1);
+ Arrays.fill(data.data, (byte) -1);
+ return new Image(null, data);
+ }
+
+ public ElectronBrowserCanvas(Composite parent)
+ {
+ this(parent, true);
+ }
+
+ public ElectronBrowserCanvas(Composite parent, boolean startElectron)
+ {
+ super(parent, SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND);
+
+ Display display = getDisplay();
+ image = createImage(display.getBounds().width, display.getBounds().height);
+ gc = new GC(image);
+ FPSText.initGC(gc);
+
+ addControlListener(new ControlListener() {
+ @Override
+ public void controlResized(ControlEvent e)
+ {
+ Rectangle oldBounds = image.getBounds();
+ Rectangle newBounds = getBounds();
+ if (oldBounds.width < newBounds.width || oldBounds.height < newBounds.height)
+ {
+ image.dispose();
+ image = createImage(newBounds.width, newBounds.height);
+ gc = new GC(image);
+ FPSText.initGC(gc);
+ }
+ sendResize(newBounds);
+ }
+
+ @Override
+ public void controlMoved(ControlEvent e)
+ {
+ }
+ });
+
+ addPaintListener(new PaintListener() {
+ @Override
+ public void paintControl(PaintEvent event)
+ {
+ event.gc.drawImage(image, event.x, event.y, event.width, event.height, event.x, event.y, event.width, event.height);
+ }
+ });
+
+ addMouseListener(new MouseListener() {
+ @Override
+ public void mouseUp(MouseEvent e)
+ {
+ handleEvent("mouseUp", e);
+
+ }
+
+ @Override
+ public void mouseDown(MouseEvent e)
+ {
+ handleEvent("mouseDown", e);
+ }
+
+ @Override
+ public void mouseDoubleClick(MouseEvent e)
+ {
+ }
+ });
+
+ addMouseMoveListener(new MouseMoveListener() {
+ @Override
+ public void mouseMove(MouseEvent e)
+ {
+ handleEvent("mouseMove", e);
+ }
+ });
+
+ addKeyListener(new KeyListener() {
+ @Override
+ public void keyReleased(KeyEvent e)
+ {
+ handleEvent("keyUp", e);
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ handleEvent("keyDown", e);
+ handleEvent("char", e);
+ }
+ });
+ addMouseWheelListener(new MouseWheelListener() {
+
+ @Override
+ public void mouseScrolled(MouseEvent e)
+ {
+ if (e.count != 0)
+ {
+ handleEvent("mouseWheel", e); // TODO how to correctly calculate deltaY etc.
+ }
+ }
+ });
+ addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e)
+ {
+ sendMessage("{\n" +
+ " \"type\":\"quit\"\n" + "}");
+ if (process != null) process.destroy();
+ }
+ });
+
+ new Thread(() -> {
+ listen();
+ }).start();
+
+ if (startElectron)
+ {
+ unzipAndStartElectron();
+ }
+ }
+
+ private ServerSocket server;
+
+ private void listen()
+ {
+ try
+ {
+ boolean win = System.getProperty("os.name", "").toLowerCase().startsWith("win");
+ String socketName;
+ if (win)
+ {
+ socketName = "\\\\.\\pipe\\electron_pipe";
+ server = new Win32NamedPipeServerSocket(socketName, false, Win32SecurityLevel.LOGON_DACL);
+ }
+ else
+ {
+ //Path pipe = Files.createTempDirectory("electron_pipe").resolve("electron.pipe");
+ Path pipe = Files.createDirectories(Paths.get("/tmp/electron_pipe")).resolve("electron.pipe");
+ Files.deleteIfExists(pipe);
+ socketName = pipe.toString();
+ server = new UnixDomainServerSocket(socketName, false);
+ }
+ //server = new ServerSocket(9090);
+ }
+ catch (IOException e)
+ {
+ System.err.println("Could not open socket.");
+ System.exit(-1);
+ }
+
+ new Thread(() -> {
+ while (!isDisposed())
+ {
+ run();
+ try
+ {
+ Thread.sleep(100);
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+
+ private PrintWriter out;
+
+ private void run()
+ {
+ try
+ {
+ System.out.println("Open connection");
+ final Socket socket = server.accept();
+ final InputStream inputStream = socket.getInputStream();
+ final BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
+
+ out = new PrintWriter(socket.getOutputStream());
+
+ Display display = getDisplay();
+ display.asyncExec(() -> sendResize(getBounds()));
+ browse("");
+
+ FPSText fps = new FPSText();
+
+ String command = null;
+ while (!isDisposed() && (command = new String(readBytesFromInputStream(bufferedInputStream, 32), "UTF-8")) != null)
+ {
+ if (command.startsWith("cursor:"))
+ {
+ String type = (command.substring("cursor:".length()).split(","))[0];
+ display.asyncExec(() -> setCursor(type));
+ }
+ else if (command.startsWith("paint:"))
+ {
+ String[] split = command.substring("paint:".length()).split(",");
+ Point point = new Point(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
+ Image newImage = new Image(null, new PartialInputStream(bufferedInputStream, Integer.parseInt(split[2])));
+ Rectangle bounds = newImage.getBounds();
+ if (isDisposed()) break;
+ display.syncExec(() -> { // TODO sync or async?
+ if (isDisposed()) return;
+ gc.drawImage(newImage, point.x, point.y);
+ fps.drawFPS(gc, this, point.x, point.y);
+ //gc.drawRectangle(point.x, point.y, bounds.width - 1, bounds.height - 1);
+ redraw(point.x, point.y, bounds.width, bounds.height, false);
+ newImage.dispose();
+ });
+ fps.calcFPS();
+ sendMessage("accept", Collections.singletonMap("imageCount", split[3]));
+ }
+ else
+ {
+ throw new IOException("Invalid command");
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ out = null;
+ System.err.println("Error: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ private byte[] readBytesFromInputStream(final InputStream inputStream, final int numberOfBytes) throws IOException
+ {
+ int bytesToRead = numberOfBytes;
+ int bytesRead = 0;
+ byte[] bytes = new byte[numberOfBytes];
+ while (bytesToRead > 0 && (bytesRead = inputStream.read(bytes, numberOfBytes - bytesToRead, bytesToRead)) > -1)
+ {
+ bytesToRead -= bytesRead;
+ }
+ return bytes;
+ }
+
+ private void sendMessage(String type, Map parameters)
+ {
+ StringBuilder builder = new StringBuilder();
+ parameters.forEach((key, value) -> builder.append(",\n" + " \"" + key + "\":" + value));
+ sendMessage("{\n" + " \"type\":\"" + type + "\"" + builder.toString() + "\n" + "}");
+ }
+
+ private void sendMessage(String message)
+ {
+ if (out != null)
+ {
+ out.write(message + "\n");
+ out.flush();
+ }
+ }
+
+ public void browse(String url)
+ {
+ sendMessage("browse", Collections.singletonMap("url", "\"" + url + "\""));
+ }
+
+ private void sendResize(Rectangle bounds)
+ {
+ Map params = new LinkedHashMap<>();
+ params.put("width", Integer.toString(bounds.width));
+ params.put("height", Integer.toString(bounds.height));
+ sendMessage("resize", params);
+ }
+
+ private void handleEvent(String type, MouseEvent e)
+ {
+ Map params = new LinkedHashMap<>();
+
+ if ((e.stateMask & SWT.BUTTON_MASK) != 0)
+ {
+ List modifiers = new ArrayList<>();
+ if ((e.stateMask & SWT.BUTTON1) != 0)
+ {
+ modifiers.add("\"leftButtonDown\"");
+ }
+ if ((e.stateMask & SWT.BUTTON2) != 0)
+ {
+ modifiers.add("\"middleButtonDown\"");
+ }
+ if ((e.stateMask & SWT.BUTTON3) != 0)
+ {
+ modifiers.add("\"rightButtonDown\"");
+ }
+ params.put("modifiers", "[" + String.join(",", modifiers) + "]");
+ }
+ String button;
+ switch (e.button)
+ {
+ case 1:
+ button = "left";
+ break;
+ case 2:
+ button = "middle";
+ break;
+ case 3:
+ button = "right";
+ break;
+ default:
+ button = null;
+ break;
+ }
+
+ params.put("x", Integer.toString(e.x));
+ params.put("y", Integer.toString(e.y));
+
+ /*if (oldMouseEvent != null && e.time - oldMouseEvent.time < 1000)
+ {
+ params.put("movementX", Integer.toString(oldMouseEvent.x - e.x));
+ params.put("movementY", Integer.toString(oldMouseEvent.y - e.y));
+ }
+ oldMouseEvent = e;*/
+
+ if (button != null) params.put("button", "\"" + button + "\"");
+ if (!"mouseWheel".equals(type))
+ {
+ params.put("clickCount", Integer.toString(e.count));
+ }
+ else
+ {
+ params.put("deltaY", Integer.toString(e.count * 100 / 3));
+ }
+ sendMessage(type, params);
+ }
+
+ private void handleEvent(String type, KeyEvent e)
+ {
+ String keyCode = null;
+ if (Character.isLetterOrDigit(e.character))
+ {
+ keyCode = Character.toString(e.character);
+ }
+ else
+ {
+ String c = null;
+ switch (e.keyCode)
+ {
+ case 8:
+ keyCode = "Backspace";
+ break;
+ case 9:
+ keyCode = "Tab";
+ break;
+ case 13:
+ keyCode = "Return";
+ c = "Return";
+ break;
+ case 27:
+ keyCode = "Escape";
+ break;
+ case 32:
+ keyCode = "Space";
+ c = " ";
+ break;
+ case 50:
+ keyCode = "\\\"";
+ c = keyCode;
+ break;
+ case SWT.ARROW_UP:
+ keyCode = "Up";
+ break;
+ case SWT.ARROW_DOWN:
+ keyCode = "Down";
+ break;
+ case SWT.ARROW_LEFT:
+ keyCode = "Left";
+ break;
+ case SWT.ARROW_RIGHT:
+ keyCode = "Right";
+ break;
+ case SWT.PAGE_UP:
+ keyCode = "PageUp";
+ break;
+ case SWT.PAGE_DOWN:
+ keyCode = "PageDown";
+ break;
+ case SWT.HOME:
+ keyCode = "Home";
+ break;
+ case SWT.END:
+ keyCode = "End";
+ break;
+ case SWT.KEYPAD_ADD:
+ keyCode = "numadd";
+ c = "+";
+ break;
+ case SWT.KEYPAD_SUBTRACT:
+ keyCode = "numsub";
+ c = "-";
+ break;
+ case SWT.KEYPAD_MULTIPLY:
+ keyCode = "nummult";
+ c = "*";
+ break;
+ case SWT.KEYPAD_DIVIDE:
+ keyCode = "numdiv";
+ c = "/";
+ break;
+ case SWT.KEYPAD_DECIMAL:
+ keyCode = "numdec";
+ c = ",";
+ break;
+ case SWT.KEYPAD_CR:
+ keyCode = "Enter";
+ break;
+ case SWT.KEYPAD_0:
+ case SWT.KEYPAD_1:
+ case SWT.KEYPAD_2:
+ case SWT.KEYPAD_3:
+ case SWT.KEYPAD_4:
+ case SWT.KEYPAD_5:
+ case SWT.KEYPAD_6:
+ case SWT.KEYPAD_7:
+ case SWT.KEYPAD_8:
+ case SWT.KEYPAD_9:
+ keyCode = "num" + (e.keyCode - SWT.KEYPAD_0);
+ break;
+ case SWT.F1:
+ case SWT.F2:
+ case SWT.F3:
+ case SWT.F4:
+ case SWT.F5:
+ case SWT.F6:
+ case SWT.F7:
+ case SWT.F8:
+ case SWT.F9:
+ case SWT.F10:
+ case SWT.F11:
+ case SWT.F12:
+ keyCode = "F" + (e.keyCode - SWT.F1 + 1);
+ break;
+ default:
+ break;
+ }
+ if (keyCode == null)
+ {
+ if (e.character == 0)
+ return;
+ keyCode = Character.toString(e.character);
+ }
+ else if ("char".equals(type))
+ {
+ if (c == null)
+ return;
+ keyCode = c;
+ }
+ }
+
+ sendMessage(type, Collections.singletonMap("keyCode", "\"" + keyCode + "\""));
+ }
+
+ private Map cursorMapping;
+
+ private void setCursor(String type)
+ {
+ if (cursorMapping == null)
+ {
+ cursorMapping = new HashMap<>();
+ // TODO col-resize, row-resize, m-panning, e-panning, n-panning, ne-panning, nw-panning, s-panning, se-panning, sw-panning, w-panning, move, vertical-text, cell, context-menu, alias, progress, nodrop, copy, not-allowed, zoom-in, zoom-out, grab, grabbing
+ cursorMapping.put("default", SWT.CURSOR_ARROW);
+ cursorMapping.put("crosshair", SWT.CURSOR_CROSS);
+ cursorMapping.put("pointer", SWT.CURSOR_HAND);
+ cursorMapping.put("text", SWT.CURSOR_IBEAM);
+ cursorMapping.put("wait", SWT.CURSOR_WAIT);
+ cursorMapping.put("help", SWT.CURSOR_HELP);
+ cursorMapping.put("e-resize", SWT.CURSOR_SIZEE);
+ cursorMapping.put("n-resize", SWT.CURSOR_SIZEN);
+ cursorMapping.put("ne-resize", SWT.CURSOR_SIZENE);
+ cursorMapping.put("nw-resize", SWT.CURSOR_SIZENW);
+ cursorMapping.put("s-resize", SWT.CURSOR_SIZES);
+ cursorMapping.put("se-resize", SWT.CURSOR_SIZESE);
+ cursorMapping.put("sw-resize", SWT.CURSOR_SIZESW);
+ cursorMapping.put("w-resize", SWT.CURSOR_SIZEW);
+ cursorMapping.put("ns-resize", SWT.CURSOR_SIZENS);
+ cursorMapping.put("ew-resize", SWT.CURSOR_SIZEWE);
+ cursorMapping.put("nesw-resize", SWT.CURSOR_SIZENESW);
+ cursorMapping.put("nwse-resize", SWT.CURSOR_SIZENWSE);
+ cursorMapping.put("none", SWT.CURSOR_NO);
+ //cursorMapping.put("", SWT.CURSOR_SIZEALL);
+ }
+
+ Integer swtType = cursorMapping.get(type);
+ if (swtType == null)
+ {
+ System.out.println("Cursor not found:" + type);
+ swtType = SWT.CURSOR_ARROW;
+ }
+
+ Cursor cursor = new Cursor(getDisplay(), swtType);
+ setCursor(cursor);
+ }
+
+ private Process process;
+
+ private void unzipAndStartElectron()
+ {
+ File tempDir = new File(System.getProperty("java.io.tmpdir") + File.separator + "headless-electron"); // TODO unzip to AppData
+ if(!tempDir.exists())
+ {
+ tempDir.mkdirs();
+ }
+ try
+ {
+ // TODO add Linux and Mac
+ unzip(getClass().getResourceAsStream("/headless-electron-darwin-x64-0.0.1.zip"), tempDir);
+ ProcessBuilder processBuilder = new ProcessBuilder(tempDir + File.separator + "headless-electron.app/Contents/MacOS/headless-electron");
+ process = processBuilder.start();
+ }
+ catch (IOException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+
+ private void unzip(InputStream is, File dest) throws IOException
+ {
+ try (ZipInputStream zip = new ZipInputStream(is))
+ {
+ ZipEntry entry = zip.getNextEntry();
+ while (entry != null)
+ {
+ File out = new File(dest, entry.getName());
+ File parentFile = out.getParentFile();
+ if (!parentFile.exists())
+ {
+ parentFile.mkdirs();
+ }
+ if (!entry.isDirectory())
+ {
+ byte[] buffer = new byte[4096];
+ try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(out)))
+ {
+ int count = 0;
+ while ((count = zip.read(buffer)) != -1)
+ {
+ bos.write(buffer, 0, count);
+ }
+ }
+ }
+ else
+ {
+ out.mkdirs();
+ }
+ zip.closeEntry();
+ entry = zip.getNextEntry();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/FPSText.java b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/FPSText.java
new file mode 100644
index 000000000..f8b0ea6a9
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/FPSText.java
@@ -0,0 +1,45 @@
+package org.springframework.ide.eclipse.chromium.browser;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+
+public class FPSText
+{
+ private long start = System.currentTimeMillis();
+ private long frames = 0;
+ private String fps = "";
+
+ public void calcFPS()
+ {
+ long end = System.currentTimeMillis();
+ frames++;
+ if (end - start > 1000)
+ {
+ fps = "FPS: " + String.format("%.2f", frames / ((end - start) / 1000.0));
+ frames = 0;
+ start = end;
+ }
+ }
+
+ public void drawFPS(GC gc, Composite comp, int x, int y)
+ {
+ Point textSize = gc.textExtent(fps);
+ int width = comp.getBounds().width;
+ int posX = width - textSize.x;
+ if ((x > posX && y < textSize.y) || frames == 0);
+ {
+ gc.drawText(fps, posX, 0, false);
+ comp.redraw(posX, 0, width, textSize.y, false);
+ }
+ }
+
+ public static void initGC(GC gc)
+ {
+ gc.setFont(new Font(null,"Arial", 16, SWT.BOLD ));
+ gc.setForeground(new Color(null, 255, 0, 0));
+ }
+}
\ No newline at end of file
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/PartialInputStream.java b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/PartialInputStream.java
new file mode 100644
index 000000000..61909f417
--- /dev/null
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/chromium/browser/PartialInputStream.java
@@ -0,0 +1,73 @@
+package org.springframework.ide.eclipse.chromium.browser;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+class PartialInputStream extends FilterInputStream
+{
+
+ private int bytesToRead;
+
+ protected PartialInputStream(InputStream in, int size)
+ {
+ super(in);
+ bytesToRead = size;
+ }
+
+ @Override
+ public int available() throws IOException
+ {
+ return Math.min(super.available(), bytesToRead);
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ bytesToRead = 0;
+ }
+
+ @Override
+ public synchronized void mark(int readlimit)
+ {
+ throw new UnsupportedOperationException("mark not supported");
+ }
+
+ @Override
+ public boolean markSupported()
+ {
+ return false;
+ }
+
+ @Override
+ public int read() throws IOException
+ {
+ if (bytesToRead == 0) return -1;
+ int read = super.read();
+ if (read != -1) bytesToRead--;
+ return read;
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException
+ {
+ if (bytesToRead == 0) return -1;
+ int read = super.read(b, off, Math.min(len, bytesToRead));
+ bytesToRead -= read;
+ return read;
+ }
+
+ @Override
+ public synchronized void reset() throws IOException
+ {
+ throw new UnsupportedOperationException("reset not supported");
+ }
+
+ @Override
+ public long skip(long n) throws IOException
+ {
+ long skip = super.skip(Math.min(n, bytesToRead));
+ bytesToRead -= skip;
+ return skip;
+ }
+}
\ No newline at end of file
diff --git a/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/xterm/views/TerminalView.java b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/xterm/views/TerminalView.java
index 674c28b5d..08b5aa82f 100644
--- a/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/xterm/views/TerminalView.java
+++ b/eclipse-extensions/org.springframework.ide.eclipse.xterm/src/org/springframework/ide/eclipse/xterm/views/TerminalView.java
@@ -20,16 +20,20 @@ import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.RGBA;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
@@ -38,6 +42,7 @@ import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.themes.ITheme;
+import org.springframework.ide.eclipse.chromium.browser.ElectronBrowserCanvas;
import org.springframework.ide.eclipse.xterm.XtermPlugin;
public class TerminalView extends ViewPart {
@@ -58,7 +63,8 @@ public class TerminalView extends ViewPart {
private Action refreshAction;
- private Browser browser;
+ private ElectronBrowserCanvas browser;
+ private Text addressBar;
private String terminalId = DEFAULT_TERMINAL_ID;
@@ -68,6 +74,8 @@ public class TerminalView extends ViewPart {
private boolean isNewView;
+ private Composite parent;
+
private final IPropertyChangeListener PROPERTY_LISTENER = new IPropertyChangeListener() {
@Override
@@ -89,8 +97,41 @@ public class TerminalView extends ViewPart {
@Override
public void createPartControl(Composite parent) {
+ this.parent = parent;
PlatformUI.getWorkbench().getThemeManager().addPropertyChangeListener(PROPERTY_LISTENER);
- browser = new Browser(parent, SWT.CHROMIUM);
+
+ Composite shell = new Composite(parent, SWT.None);
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ shell.setLayout(layout);
+
+
+ String url = "https://google.com";
+ addressBar = new Text(shell, SWT.SINGLE);
+ addressBar.setText(url);
+ GridData layoutData1 = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ addressBar.setLayoutData(layoutData1);
+
+ browser = new ElectronBrowserCanvas(shell, false);
+ GridData layoutData2 = new GridData(SWT.FILL, SWT.FILL, true, true);
+ browser.setLayoutData(layoutData2);
+
+ addressBar.addListener(SWT.Traverse, event -> {
+ if (event.detail == SWT.TRAVERSE_RETURN)
+ {
+ String text = addressBar.getText();
+ if (!text.startsWith("http") && !text.isEmpty())
+ {
+ text = "http://" + text;
+ addressBar.setText(text);
+ }
+ browser.browse(text);
+ }
+ });
+
+// browser = new ElectronBrowserCanvas(parent, false);
+// browser.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
makeActions();
contributeToActionBars();
if (isNewView) {
@@ -147,7 +188,10 @@ public class TerminalView extends ViewPart {
String serviceUrl = XtermPlugin.getDefault().xtermUrl(10_000).get();
if (Display.getCurrent() != null) {
if (browser != null && !browser.isDisposed() && terminalId.equals(TerminalView.this.terminalId)) {
- browser.setUrl(createUrl(serviceUrl, terminalId, cmd, cwd));
+ String url = createUrl(serviceUrl, terminalId, cmd, cwd);
+ addressBar.setText(url);
+ XtermPlugin.getDefault().getLog().info("Navigating to " + url);
+ browser.browse(url);
}
} else {
Display display = PlatformUI.getWorkbench().getDisplay();
@@ -155,7 +199,9 @@ public class TerminalView extends ViewPart {
display.asyncExec(() -> {
if (browser != null && !browser.isDisposed() && terminalId.equals(TerminalView.this.terminalId)) {
String url = createUrl(serviceUrl, terminalId, cmd, cwd);
- browser.setUrl(url);
+ addressBar.setText(url);
+ XtermPlugin.getDefault().getLog().info("Navigating to " + url);
+ browser.browse(url);
}
});
}