Compare commits
41 changed files with 13053 additions and 2777 deletions
29
.gitignore
vendored
29
.gitignore
vendored
|
|
@ -1,30 +1,5 @@
|
|||
.DS_Store
|
||||
/node_modules
|
||||
/dist
|
||||
/crate/target/*
|
||||
/.log
|
||||
/out
|
||||
|
||||
crash.log
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
.env
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
#Electron-builder output
|
||||
/dist_electron
|
||||
*.sublime-workspace
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
stages:
|
||||
- Build
|
||||
- Upload
|
||||
- Release
|
||||
|
||||
build:
|
||||
stage: Build
|
||||
tags:
|
||||
# Use a macos runner to build.
|
||||
- darwin
|
||||
before_script:
|
||||
- yarn
|
||||
script:
|
||||
- export VERSION=$(node -e "console.log(require('./package.json').version)")
|
||||
- echo "VERSION=$VERSION" >> variables.env
|
||||
- export APPNAME=$(node -e "console.log(require('./package.json').productName)")
|
||||
- echo "APPNAME=$APPNAME" >> variables.env
|
||||
- yarn build
|
||||
artifacts:
|
||||
reports:
|
||||
dotenv: variables.env
|
||||
name: $CI_COMMIT_REF_SLUG
|
||||
paths:
|
||||
- dist_electron/*.dmg
|
||||
- dist_electron/*.zip
|
||||
- dist_electron/*.yml
|
||||
when: on_success
|
||||
only:
|
||||
- main
|
||||
|
||||
variables:
|
||||
PACKAGE: '${APPNAME}-${VERSION}.dmg'
|
||||
PACKAGE_REGISTRY_URL: '${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${APPNAME}/${VERSION}'
|
||||
|
||||
# Upload package to gitlab registry.
|
||||
upload:
|
||||
stage: Upload
|
||||
needs:
|
||||
- job: build
|
||||
artifacts: true
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never # Do not run this job when a tag is created manually
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when when commits are pushed to the default branch
|
||||
script:
|
||||
# Take the package we built and place it in the package registry.
|
||||
- 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file "dist_electron/${PACKAGE}" "${PACKAGE_REGISTRY_URL}/${PACKAGE}"'
|
||||
|
||||
auto-release-master:
|
||||
image: registry.gitlab.com/gitlab-org/release-cli
|
||||
needs:
|
||||
- job: build
|
||||
artifacts: true
|
||||
- job: upload
|
||||
artifacts: true
|
||||
stage: Release
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
when: never # Do not run this job when a tag is created manually
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when when commits are pushed to the default branch
|
||||
script:
|
||||
- echo "Release $VERSION"
|
||||
- release-cli create --name "Release $VERSION" --tag-name v$VERSION --description "Release $CI_COMMIT_TITLE" --ref $CI_COMMIT_SHA --assets-link "{\"name\":\"${APPNAME}\",\"url\":\"${PACKAGE_REGISTRY_URL}/${PACKAGE}\"}"
|
||||
2
.npmrc
2
.npmrc
|
|
@ -1,2 +1,2 @@
|
|||
@crimata:registry=https://gitlab.com/api/v4/projects/28849281/packages/npm/
|
||||
//gitlab.com/api/v4/projects/28849281/packages/npm/:_authToken=${NPM_TOKEN}
|
||||
//gitlab.com/api/v4/projects/28849281/packages/npm
|
||||
29
README.md
29
README.md
|
|
@ -1,29 +0,0 @@
|
|||
# crimata-electron
|
||||
|
||||
## Project setup
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
yarn electron:serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
yarn electron:build
|
||||
```
|
||||
|
||||
<!-- ### Run your unit tests
|
||||
```
|
||||
yarn test:unit
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
yarn lint
|
||||
``` -->
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
8
electron.sublime-project
Normal file
8
electron.sublime-project
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"folders":
|
||||
[
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
14
entitlements.plist
Normal file
14
entitlements.plist
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.debugger</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
<!--<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>-->
|
||||
BIN
icon.png
Normal file
BIN
icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
11766
package-lock.json
generated
11766
package-lock.json
generated
File diff suppressed because it is too large
Load diff
54
package.json
54
package.json
|
|
@ -1,24 +1,54 @@
|
|||
{
|
||||
"name": "Crimata",
|
||||
"productName": "crimata-messenger",
|
||||
"name": "crimata",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "Cross-platform messenger app (Electron, Vue3, and TS)",
|
||||
"author": {
|
||||
"name": "Andrew Gundersen"
|
||||
},
|
||||
"description": "Cross-platform messenger app (Electron, Vue3)",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
"start": "electron ."
|
||||
"start": "electron-forge start",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"package": "electron-forge package",
|
||||
"make": "electron-forge make"
|
||||
},
|
||||
"author": "Andrew Gundersen",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.0.0-beta.63",
|
||||
"@electron-forge/maker-deb": "^6.0.0-beta.63",
|
||||
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
|
||||
"@electron-forge/maker-squirrel": "^6.0.0-beta.63",
|
||||
"@electron-forge/maker-zip": "^6.0.0-beta.63",
|
||||
"electron": "^18.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@crimata/nodeaudio": "^0.0.0",
|
||||
"axios": "^0.21.1",
|
||||
"base64-arraybuffer": "^1.0.1",
|
||||
"electron-store": "^8.0.0",
|
||||
"ws": "^7.3.1"
|
||||
"ws": "^7.3.1",
|
||||
"electron-squirrel-startup": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^13.2.3"
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
"makers": [
|
||||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {}
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-zip",
|
||||
"platforms": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-deb",
|
||||
"config": {}
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-rpm",
|
||||
"config": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +1,43 @@
|
|||
const { ipcMain } = require("electron");
|
||||
|
||||
const { post } = require("./api");
|
||||
const store = require("./utils/store");
|
||||
const { postLogin } = require("./api");
|
||||
const { ipcEmit } = require("./utils/emitter");
|
||||
const { launchSession, endSession } = require("./session");
|
||||
const { backgroundMitt, ipcEmit } = require("./utils/emitter");
|
||||
|
||||
// store.set("account", "smith12@gmail.com");
|
||||
store.set("account", "adgundersen@gmail.com");
|
||||
store.set("account", process.env.ACCOUNT);
|
||||
|
||||
async function login(_e, email, password)
|
||||
async function auth(_e, creds)
|
||||
{
|
||||
const res = await postLogin(email, password);
|
||||
if (res)
|
||||
const { error, data } = await post("/auth", creds);
|
||||
|
||||
if (error)
|
||||
{
|
||||
const account = res.crimataId;
|
||||
store.set("account", account);
|
||||
ipcEmit("set-account", account);
|
||||
launchSession(account);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
return data;
|
||||
}
|
||||
|
||||
store.set("account", data);
|
||||
ipcEmit("account", data);
|
||||
launchSession(data);
|
||||
};
|
||||
|
||||
function logout()
|
||||
function logout(_e, reason)
|
||||
{
|
||||
store.delete("account");
|
||||
ipcEmit("set-account", false);
|
||||
ipcEmit("account", false, reason);
|
||||
endSession();
|
||||
};
|
||||
|
||||
function initAccount()
|
||||
{
|
||||
ipcMain.handle("login", login);
|
||||
ipcMain.handle("auth", auth);
|
||||
ipcMain.on("logout", logout);
|
||||
|
||||
const account = store.get("account");
|
||||
if (account) launchSession(account);
|
||||
}
|
||||
|
||||
backgroundMitt.on("logout", (reason) => logout(null, reason));
|
||||
|
||||
|
||||
exports.initAccount = initAccount;
|
||||
|
|
|
|||
39
src/api.js
39
src/api.js
|
|
@ -2,18 +2,37 @@ const axios = require('axios').default;
|
|||
|
||||
const config = require("./config");
|
||||
|
||||
const baseUrl = config.BUSINESS_URL + config.BUSINESS_PREFIX;
|
||||
|
||||
async function postLogin(email, password)
|
||||
async function post(route, body)
|
||||
{
|
||||
try {
|
||||
const res = await axios.post(baseUrl + "/account/login", {
|
||||
email: email, password: password
|
||||
});
|
||||
return res.data;
|
||||
} catch (e) {
|
||||
return false;
|
||||
let error;
|
||||
let data;
|
||||
|
||||
try
|
||||
{
|
||||
const res = await axios.post(config.API + route, body);
|
||||
data = res.data;
|
||||
error = false;
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (e.response)
|
||||
{
|
||||
data = e.response.data;
|
||||
}
|
||||
else if (e.request)
|
||||
{
|
||||
data = "Can't connect to the server."
|
||||
}
|
||||
else
|
||||
{
|
||||
data = "Unknown error occured."
|
||||
}
|
||||
|
||||
error = true;
|
||||
}
|
||||
|
||||
return { error, data };
|
||||
}
|
||||
|
||||
exports.postLogin = postLogin;
|
||||
exports.post = post;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ backgroundMitt.on("data", (int16Arr) => {
|
|||
|
||||
backgroundMitt.on("write", (int16Arr) => {
|
||||
clearTimeout(setWriteId);
|
||||
setWriteId = setTimeout(setPlaybackStatus.prototype.bind(null, false), 500);
|
||||
setWriteId = setTimeout(() => {
|
||||
setPlaybackStatus(false);
|
||||
}, 500);
|
||||
});
|
||||
|
||||
function setStreams()
|
||||
|
|
@ -130,8 +132,3 @@ exports.initAudio = initAudio;
|
|||
exports.terminateAudio = terminateAudio;
|
||||
exports.playback = playback;
|
||||
exports.streamState = streamState;
|
||||
|
||||
|
||||
// setWriteId = setTimeout(() => {
|
||||
// setPlaybackStatus(false);
|
||||
// }, 500);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
const { app } = require("electron");
|
||||
|
||||
const env = process.env;
|
||||
const DOMAIN = "crimata.com";
|
||||
|
||||
const PLATFORM_PORT = env.PLATFORM_PORT || 8760;
|
||||
const PLATFORM_IP = env.PLATFORM_IP || 'http://127.0.0.1';
|
||||
|
||||
const BUSINESS_PORT = env.BUSINESS_PORT || 3000;
|
||||
const BUSINESS_IP = env.BUSINESS_IP || 'http://127.0.0.1';
|
||||
/* If PROD env variable exists */
|
||||
const prod = process.env.PROD;
|
||||
|
||||
module.exports = {
|
||||
PLATFORM_URL: `${PLATFORM_IP}:${PLATFORM_PORT}`,
|
||||
BUSINESS_URL: `${BUSINESS_IP}:${BUSINESS_PORT}`,
|
||||
BUSINESS_PREFIX: '/api',
|
||||
configPath: app.getPath('userData'),
|
||||
}
|
||||
PLATFORM: prod ? `https://app.${DOMAIN}` : `http://localhost:5000`,
|
||||
API: prod ? `https://${DOMAIN}/api` : `http://localhost:5001`
|
||||
}
|
||||
|
|
|
|||
23
src/io.js
23
src/io.js
|
|
@ -14,7 +14,7 @@ function connectToPlatform(account)
|
|||
{
|
||||
if (pingId) clearInterval(pingId);
|
||||
|
||||
connection = new WebSocket(`${config.PLATFORM_URL}/${account}`)
|
||||
connection = new WebSocket(`${config.PLATFORM}/${account}`)
|
||||
|
||||
.on("open", () => pingId = setInterval(() => connection.ping(null, true), 1000))
|
||||
|
||||
|
|
@ -24,11 +24,22 @@ function connectToPlatform(account)
|
|||
|
||||
.on("message", (payload) => backgroundMitt.emit("message", JSON.parse(payload)))
|
||||
|
||||
.on("close", (code, reason) => {
|
||||
.on("close", (_code, reason) => {
|
||||
|
||||
setConnectionStatus(1);
|
||||
if (reason !== "logout") {
|
||||
reconnectId = setTimeout(() => connectToPlatform(account), 500);
|
||||
|
||||
if (reason)
|
||||
{
|
||||
if (reason == "unauthorized")
|
||||
{
|
||||
backgroundMitt.emit("logout", reason);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
reconnectId = setTimeout(() => connectToPlatform(account), 500);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -42,13 +53,13 @@ function sendMessage(message)
|
|||
function disconnectFromPlatform()
|
||||
{
|
||||
clearTimeout(reconnectId);
|
||||
connection.close(1000, "logout");
|
||||
if (connection.open) connection.close(1000, "logout");
|
||||
}
|
||||
|
||||
function setConnectionStatus(status)
|
||||
{
|
||||
updateTray("disconnect", status);
|
||||
ipcEmit("ws-status", status);
|
||||
ipcEmit("ws", status);
|
||||
}
|
||||
|
||||
ipcMain.on("message", (_e, message) => sendMessage(message));
|
||||
|
|
|
|||
|
|
@ -3,12 +3,9 @@ const { app, protocol, ipcMain, nativeTheme } = require("electron");
|
|||
const store = require("./utils/store");
|
||||
|
||||
const { initTray } = require("./tray");
|
||||
const { postLogin } = require("./api");
|
||||
const { createWin } = require("./window");
|
||||
const { initAccount } = require("./account");
|
||||
const { terminateAudio } = require("./audio");
|
||||
|
||||
app.commandLine.appendSwitch("enable-transparent-visuals");
|
||||
// const { terminateAudio } = require("./audio");
|
||||
|
||||
// Assert a light theme
|
||||
nativeTheme.themeSource = "light";
|
||||
|
|
@ -28,4 +25,4 @@ app.on("ready", () =>
|
|||
app.on("activate", createWin);
|
||||
|
||||
// Prevents app from quitting on window close event
|
||||
app.on('window-all-closed', (e) => e.preventDefault());
|
||||
app.on('window-all-closed', (e) => e.preventDefault());
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "SF Pro Text";
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#titlebar {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 54px;
|
||||
opacity: 0;
|
||||
-webkit-app-region: drag;
|
||||
border: none;
|
||||
outline: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.building {
|
||||
width: 250px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.email {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.email-subject {
|
||||
font-size: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<button id="titlebar"></button>
|
||||
|
||||
<div id="content"></div>
|
||||
|
||||
<script>
|
||||
window.mainApi.on("preview-init", (content) => {
|
||||
document.getElementById("content").innerHTML = content;
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
BIN
src/render/assets/fonts/SF-Compact-Display-Bold.otf
Executable file
BIN
src/render/assets/fonts/SF-Compact-Display-Bold.otf
Executable file
Binary file not shown.
BIN
src/render/assets/fonts/SF-Compact-Rounded-Bold.otf
Executable file
BIN
src/render/assets/fonts/SF-Compact-Rounded-Bold.otf
Executable file
Binary file not shown.
BIN
src/render/assets/fonts/SF-Pro-Text-Regular.otf
Executable file
BIN
src/render/assets/fonts/SF-Pro-Text-Regular.otf
Executable file
Binary file not shown.
|
|
@ -20,21 +20,25 @@ const App =
|
|||
},
|
||||
|
||||
template: `
|
||||
<main id="app" v-if="account !== null">
|
||||
<div id="app" v-if="account !== null">
|
||||
|
||||
<Header />
|
||||
|
||||
<Messenger v-if="account"/>
|
||||
<Login v-else />
|
||||
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<Splash v-else />`
|
||||
}
|
||||
|
||||
window.mainApi.on("set-account", (account_) => {
|
||||
account.value = account_;
|
||||
window.mainApi.on("account", (value, reason) => {
|
||||
if (reason) alert(reason);
|
||||
account.value = value;
|
||||
});
|
||||
|
||||
export default App;
|
||||
export { account };
|
||||
|
||||
// Is called when window is about to close or reload
|
||||
window.onbeforeunload = () => console.log("beforeunload");
|
||||
|
|
|
|||
|
|
@ -9,15 +9,27 @@ const Bubble =
|
|||
}
|
||||
|
||||
Vue.onMounted(() => {
|
||||
document.dispatchEvent(new CustomEvent("scroll"));
|
||||
|
||||
const el = document.getElementById("messenger");
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
el.dispatchEvent(new CustomEvent('adjust-scroll'));
|
||||
|
||||
}, 100);
|
||||
|
||||
});
|
||||
|
||||
if (!props.text) props.text = "...";
|
||||
|
||||
return { getUrl };
|
||||
},
|
||||
|
||||
template: `
|
||||
<div :class="'bubble ' + modifier + '-bubble ' + modifier +'-'+ child">
|
||||
|
||||
<small class="bubble-notify" v-if="modifier=='ai'"></small>
|
||||
|
||||
<p v-if="category=='text'">{{ text }}</p>
|
||||
|
||||
<p v-else-if="category=='audio'">{{ text }}</p>
|
||||
|
|
@ -26,11 +38,11 @@ const Bubble =
|
|||
|
||||
<img v-else-if="category == 'image'" :src="getUrl()" />
|
||||
|
||||
<a v-else :href="getUrl()">{{ text }}</a>
|
||||
<a v-else :download="text" :href="getUrl()">{{ text }}</a>
|
||||
|
||||
</div>`
|
||||
};
|
||||
|
||||
export default Bubble;
|
||||
|
||||
// TODO: should include other styling/actions for audio bubbles
|
||||
// TODO: should include other styling/actions for audio bubbles
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const saveLocation = "input_item_position";
|
||||
const defaultPosition = { x: 15, y: window.innerHeight - 300 };
|
||||
const defaultPosition = { x: 15, y: 400 };
|
||||
|
||||
//---Dragabble Helper Funcs--------------------------------------
|
||||
|
||||
|
|
@ -33,9 +33,10 @@ function calcPosition (elementPosition, elementLength, percent, short, win) {
|
|||
return elementPosition
|
||||
}
|
||||
|
||||
function draggify(elementId, margin) {
|
||||
function draggify(elementId, parentId, margin) {
|
||||
|
||||
let element;
|
||||
let parent;
|
||||
|
||||
/* only compatible with elements having equal width and height */
|
||||
let elementLength;
|
||||
|
|
@ -52,23 +53,20 @@ function draggify(elementId, margin) {
|
|||
let xShort;
|
||||
let yShort;
|
||||
|
||||
// Keep track of window size;
|
||||
let winW = window.innerWidth;
|
||||
let winH = window.innerHeight;
|
||||
|
||||
//---Reposition Anime-----------------------------------------------
|
||||
|
||||
// Move element to target smoothly.
|
||||
const repositionAnime = (xChange, yChange) => {
|
||||
const xStep = xChange / 6000;
|
||||
const yStep = yChange / 6000;
|
||||
|
||||
for (let i = 1; i <= 6000; i++) {
|
||||
const xStep = xChange / 1000;
|
||||
const yStep = yChange / 1000;
|
||||
|
||||
for (let i = 1; i <= 1000; i++) {
|
||||
|
||||
setTimeout(() => {
|
||||
elementX.value += xStep;
|
||||
elementY.value += yStep;
|
||||
}, 16) // 60fps
|
||||
}, 30) // 60fps
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -79,9 +77,8 @@ function draggify(elementId, margin) {
|
|||
const onMouseMove = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const inputItemRect = element.getBoundingClientRect();
|
||||
elementX.value = inputItemRect.left + e.movementX;
|
||||
elementY.value = inputItemRect.top + e.movementY;
|
||||
elementX.value = element.offsetLeft + e.movementX;
|
||||
elementY.value = element.offsetTop + e.movementY;
|
||||
}
|
||||
|
||||
// Add an event listener for dragging.
|
||||
|
|
@ -102,6 +99,9 @@ function draggify(elementId, margin) {
|
|||
let x = 0; // vector change
|
||||
let y = 0;
|
||||
|
||||
const winW = parent.clientWidth;
|
||||
const winH = parent.clientHeight;
|
||||
|
||||
if (elementX.value < 0) {
|
||||
x = (elementX.value - margin)*-1
|
||||
}
|
||||
|
|
@ -138,12 +138,8 @@ function draggify(elementId, margin) {
|
|||
// Update position of targetEl on windowResize.
|
||||
const onWindowResize = (_e) => {
|
||||
|
||||
// Update window dimensions.
|
||||
winW = window.innerWidth;
|
||||
winH = window.innerHeight;
|
||||
|
||||
elementX.value = calcPosition(elementX.value, elementLength, percentX, xShort, winW);
|
||||
elementY.value = calcPosition(elementY.value, elementLength, percentY, yShort, winH);
|
||||
elementX.value = calcPosition(elementX.value, elementLength, percentX, xShort, parent.clientWidth);
|
||||
elementY.value = calcPosition(elementY.value, elementLength, percentY, yShort, parent.clientHeight);
|
||||
|
||||
savePosition();
|
||||
}
|
||||
|
|
@ -160,27 +156,28 @@ function draggify(elementId, margin) {
|
|||
Vue.onMounted(() => {
|
||||
|
||||
element = document.getElementById(elementId);
|
||||
parent = document.getElementById(parentId);
|
||||
|
||||
elementLength = element.offsetWidth;
|
||||
|
||||
// Initialize the positional references.
|
||||
percentX = elementX.value / window.innerWidth;
|
||||
percentY = elementY.value / window.innerHeight;
|
||||
percentX = elementX.value / parent.clientWidth;
|
||||
percentY = elementY.value / parent.clientHeight;
|
||||
|
||||
xShort = calcSideProximity(elementX.value, elementLength, window.innerWidth);
|
||||
yShort = calcSideProximity(elementX.value, elementLength, window.innerHeight);
|
||||
xShort = calcSideProximity(elementX.value, elementLength, parent.clientWidth);
|
||||
yShort = calcSideProximity(elementX.value, elementLength, parent.clientHeight);
|
||||
|
||||
// Then, we can listen for window resize (and mousedown).
|
||||
element.addEventListener("mousedown", onMouseDown);
|
||||
window.addEventListener('resize', onWindowResize)
|
||||
parent.addEventListener('resize', onWindowResize)
|
||||
});
|
||||
|
||||
// remove event listeners on component dismount.
|
||||
Vue.onUnmounted(() => {
|
||||
element.removeEventListener('mousedown', onMouseDown);
|
||||
window.removeEventListener('resize', onWindowResize)
|
||||
window.removeEventListener('mouseup', onMouseUp)
|
||||
window.removeEventListener('mousemove', onMouseMove);
|
||||
parent.removeEventListener('resize', onWindowResize)
|
||||
parent.removeEventListener('mouseup', onMouseUp)
|
||||
parent.removeEventListener('mousemove', onMouseMove);
|
||||
});
|
||||
|
||||
// Try loading initPosition, otherwise set default values
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
const onDrop = async (e) => {
|
||||
const file = e.dataTransfer.items[0].getAsFile();
|
||||
|
||||
if (file.size >= 1 * 1000 * 1000) {
|
||||
alert("File must be under 1MB.");
|
||||
return;
|
||||
}
|
||||
|
||||
const buffer = await file.arrayBuffer();
|
||||
const b64String = await window.mainApi.invoke("encode", buffer);
|
||||
|
||||
|
|
@ -16,4 +21,4 @@ const onDrop = async (e) => {
|
|||
});
|
||||
}
|
||||
|
||||
export default onDrop;
|
||||
export default onDrop;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,20 @@
|
|||
let el;
|
||||
|
||||
const initScroll = (elementId) => {
|
||||
el = document.getElementById(elementId);
|
||||
el.addEventListener('adjust-scroll', adjustScroll);
|
||||
window.addEventListener('resize', adjustScroll);
|
||||
}
|
||||
|
||||
const isBottom = () => {
|
||||
return el.scrollHeight - el.clientHeight <= el.scrollTop + 1;
|
||||
}
|
||||
|
||||
const adjustScroll = () => {
|
||||
if (isBottom()) {
|
||||
const scroll = () => {
|
||||
if (!el) {
|
||||
el = document.getElementById("messenger");
|
||||
window.addEventListener('resize', scroll);
|
||||
}
|
||||
el.scrollTo({
|
||||
top: el.scrollHeight - el.clientHeight,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default initScroll;
|
||||
export default scroll;
|
||||
|
||||
// const isBottom = () => {
|
||||
// if (el) {
|
||||
// return el.scrollHeight - el.clientHeight <= el.scrollTop + 1;
|
||||
// }
|
||||
// }
|
||||
|
|
@ -17,21 +17,23 @@ const metaKeys = [
|
|||
"Escape"
|
||||
];
|
||||
|
||||
function useText(elementId, left, typing)
|
||||
function useText(elementId, parentId, left)
|
||||
{
|
||||
let el;
|
||||
let parent;
|
||||
|
||||
const show = Vue.ref(false);
|
||||
const leftSide = Vue.ref(false);
|
||||
|
||||
const calcSide = () => {
|
||||
window.innerWidth - left.value < inputLength ? leftSide.value = true : leftSide.value = false;
|
||||
parent.clientWidth - left.value < inputLength ? leftSide.value = true : leftSide.value = false;
|
||||
}
|
||||
|
||||
/* handle user typing */
|
||||
Vue.onMounted(() => {
|
||||
|
||||
el = document.getElementById(elementId);
|
||||
parent = document.getElementById(parentId);
|
||||
|
||||
window.addEventListener("keydown", (e) => {
|
||||
|
||||
|
|
@ -46,15 +48,23 @@ function useText(elementId, left, typing)
|
|||
|
||||
if (e.key === "Enter" && el.value)
|
||||
{
|
||||
if (el.value.length >= 250) {
|
||||
alert("250 character limit")
|
||||
return;
|
||||
}
|
||||
|
||||
window.mainApi.send("message", {
|
||||
category: "text",
|
||||
text: el.value,
|
||||
blob: null
|
||||
});
|
||||
|
||||
show.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
calcSide();
|
||||
|
||||
});
|
||||
|
||||
Vue.watch(left, calcSide);
|
||||
|
|
@ -68,8 +78,6 @@ function useText(elementId, left, typing)
|
|||
}
|
||||
});
|
||||
|
||||
calcSide();
|
||||
|
||||
return { leftSide, show };
|
||||
}
|
||||
|
||||
|
|
|
|||
23
src/render/components/control/valid.js
Normal file
23
src/render/components/control/valid.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
export const isEmail = (value) => {
|
||||
console.log(value);
|
||||
if (!/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/.test(value)) {
|
||||
return "Not a valid email."
|
||||
}
|
||||
}
|
||||
|
||||
export const isPassword = (value) => {
|
||||
if (!/^(?=.*[0-9])(?=.*[!@#$%^&*])[a-zA-Z0-9!@#$%^&*]{6,16}$/.test(value)) {
|
||||
return "Password must have symbol, number, uppercase and be 6-16 length.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Name is optional and therefore doesn't return error if no value.
|
||||
*/
|
||||
export const isName = (value) => {
|
||||
if (value) {
|
||||
if (!/^([a-zA-Z ]){5,30}$/.test(value)) {
|
||||
return "Name must be at least 5 long.";
|
||||
}
|
||||
}
|
||||
}
|
||||
86
src/render/components/form.js
Normal file
86
src/render/components/form.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
|
||||
// Basic debounce implentation
|
||||
const debounce = (fn, delay) => {
|
||||
let timeoutId;
|
||||
return (...args) => {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => {
|
||||
fn(...args);
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic form component with auto submission and validation.
|
||||
*
|
||||
* props
|
||||
* .fields => List of field objects
|
||||
* .channel => e.g. "/login"
|
||||
* .modifier => Form description
|
||||
*/
|
||||
const SmartForm =
|
||||
{
|
||||
props: ["fields", "channel", "modifier"],
|
||||
|
||||
setup(props)
|
||||
{
|
||||
// Error log below form
|
||||
const log = Vue.ref(props.modifier);
|
||||
|
||||
/**
|
||||
* Valid and submit form data to channel.
|
||||
*/
|
||||
const submit = async () => {
|
||||
|
||||
// Validate each field
|
||||
for (let field of props.fields) {
|
||||
const error = field.valid(field.value);
|
||||
if (error) return error;
|
||||
}
|
||||
|
||||
// Reduce fields into the form
|
||||
const form = props.fields.reduce((v, n) => {
|
||||
v[n.name] = n.value;
|
||||
return v;
|
||||
}, {});
|
||||
|
||||
console.log("Submitting =>", form);
|
||||
return await window.mainApi.invoke(props.channel, form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for submit that is debounced and updates UI elements
|
||||
*/
|
||||
const preSub = debounce(async () => {
|
||||
|
||||
const error = await submit();
|
||||
|
||||
log.value = error ? error : props.modifier
|
||||
|
||||
}, 2000);
|
||||
|
||||
return { preSub, log };
|
||||
},
|
||||
|
||||
template: `
|
||||
<form id="smart-form" class="smart-form" v-on:input="preSub">
|
||||
|
||||
<div v-for="field in fields" style="display:flex">
|
||||
|
||||
<input type="text" class="text-field"
|
||||
v-model="field.value"
|
||||
:name="field.name"
|
||||
:placeholder="field.placeholder"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="smart-form-logs">{{ log }}</div>
|
||||
|
||||
</form>`
|
||||
}
|
||||
|
||||
export default SmartForm;
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
const Header =
|
||||
{
|
||||
setup() {
|
||||
const onNavBar = (command) => window.mainApi.send('nav-bar', command);
|
||||
const onNavBar = (command) => window.mainApi.send("nav", command);
|
||||
return { onNavBar };
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ const Input =
|
|||
|
||||
const recording = Vue.ref(false);
|
||||
|
||||
const { elementX, elementY } = draggify("input", 15);
|
||||
const { elementX, elementY } = draggify("input", "app", 15);
|
||||
|
||||
const { leftSide, show } = useText("input-text", elementX);
|
||||
const { leftSide, show } = useText("input-text", "app", elementX);
|
||||
|
||||
window.mainApi.on("record", (status) => recording.value = status);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,58 +1,44 @@
|
|||
import SmartForm from "./form.js";
|
||||
import { isEmail, isPassword, isName } from "./control/valid.js";
|
||||
|
||||
const Login =
|
||||
{
|
||||
components: {
|
||||
SmartForm
|
||||
},
|
||||
|
||||
setup()
|
||||
{
|
||||
const usr = Vue.ref("");
|
||||
const pwd = Vue.ref("");
|
||||
|
||||
const submitForm = async () => {
|
||||
const success = await window.mainApi.invoke("login", usr.value, pwd.value);
|
||||
if (!success) shake("login-form");
|
||||
}
|
||||
|
||||
return { usr, pwd, submitForm };
|
||||
return { isEmail, isPassword, isName };
|
||||
},
|
||||
|
||||
template: `
|
||||
<form id="login" @submit.prevent="submitForm">
|
||||
<div id="login">
|
||||
|
||||
<!-- username and password forms -->
|
||||
<div id="login-form">
|
||||
<!-- username -->
|
||||
<div class="login-input-box">
|
||||
<input class="login-input" type="text" v-model="usr" />
|
||||
<div class="login-input-modifier">Email</div>
|
||||
</div>
|
||||
<SmartForm
|
||||
:fields="[{
|
||||
name: 'email',
|
||||
value: null,
|
||||
placeholder: 'Email',
|
||||
valid: isEmail
|
||||
},
|
||||
{
|
||||
name: 'password',
|
||||
value: null,
|
||||
placeholder: 'Password',
|
||||
valid: isPassword
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
value: null,
|
||||
placeholder: 'Name',
|
||||
valid: isName
|
||||
}]"
|
||||
:channel="'auth'"
|
||||
:modifier="'Login or enter name to register.'"
|
||||
/>
|
||||
|
||||
<!-- password -->
|
||||
<div class="login-input-box">
|
||||
<input class="login-input" type="password" v-model="pwd" />
|
||||
<div class="login-input-modifier">Password</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- submit button; position: fixed -->
|
||||
<button
|
||||
class="login-submit-button button"
|
||||
type="submit"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
|
||||
</form> `
|
||||
</div>`
|
||||
}
|
||||
|
||||
/** Shake a div to indicate incorrect credentials */
|
||||
const shake = (elementId) =>
|
||||
{
|
||||
const el = document.getElementById(elementId);
|
||||
|
||||
if (el)
|
||||
el.classList.remove("shake");
|
||||
|
||||
setTimeout(() => {
|
||||
if (el) el.classList.add("shake");
|
||||
}, 250);
|
||||
}
|
||||
|
||||
export default Login;
|
||||
export default Login;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const Message =
|
|||
Context
|
||||
},
|
||||
|
||||
props: ["modifier", "content", "context", "avatar", "id"],
|
||||
props: ["modifier", "content", "context", "avatar", "id", "seen"],
|
||||
|
||||
setup(props)
|
||||
{
|
||||
|
|
@ -18,8 +18,9 @@ const Message =
|
|||
template: `
|
||||
<div :id="id" :class="'message ' + modifier + '-message'">
|
||||
|
||||
<Bubble
|
||||
<Bubble
|
||||
v-for="(c, index) in content"
|
||||
:id="'bubble-' + id + '-' + index"
|
||||
:category="c.category"
|
||||
:text="c.text"
|
||||
:html="c.html"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import onDrop from "./control/drop.js";
|
||||
import adjustScroll from "./control/scroll.js";
|
||||
import scroll from "./control/scroll.js";
|
||||
|
||||
import WS from "./ws.js";
|
||||
import Input from "./input.js";
|
||||
|
|
@ -20,26 +20,45 @@ const Messenger = {
|
|||
const person = Vue.ref("");
|
||||
const messages = Vue.ref([]);
|
||||
|
||||
let current = Vue.ref();
|
||||
|
||||
Vue.onMounted(() => {
|
||||
|
||||
window.mainApi.on("update", (update) => {
|
||||
window.mainApi.on("message", (update) => {
|
||||
|
||||
if (update.name)
|
||||
if (update.person)
|
||||
{
|
||||
person.value = update;
|
||||
person.value = update.person;
|
||||
messages.value = update.messages;
|
||||
current.value = messages.value.at(-1);
|
||||
}
|
||||
else if (message.content)
|
||||
else if (update.name)
|
||||
{
|
||||
messages.value.push(update);
|
||||
person.value = update.name;
|
||||
}
|
||||
else if (update.modifier)
|
||||
{
|
||||
messages.value.push(update);
|
||||
current.value = update;
|
||||
}
|
||||
else if (update.category)
|
||||
{
|
||||
current.value.content.push(update);
|
||||
}
|
||||
else if (update.context)
|
||||
{
|
||||
current.value.context = update.context;
|
||||
}
|
||||
else
|
||||
{
|
||||
messages.value.at(-1).content.push(update);
|
||||
current.value.content.at(-1).text = update.text;
|
||||
}
|
||||
|
||||
setTimeout(scroll, 10);
|
||||
|
||||
});
|
||||
|
||||
window.mainApi.send("message", {route: "window", open: true});
|
||||
window.mainApi.send("messenger");
|
||||
});
|
||||
|
||||
return { person, messages, onDrop };
|
||||
|
|
@ -55,18 +74,13 @@ const Messenger = {
|
|||
@dragover.prevent
|
||||
@dragenter.prevent
|
||||
>
|
||||
<Message
|
||||
v-for="message in messages"
|
||||
:modifier="message.modifier"
|
||||
:content="message.content"
|
||||
:context="message.context"
|
||||
:avatar="message.avatar"
|
||||
:id="message.id"
|
||||
|
||||
<Message
|
||||
v-for="message in messages"
|
||||
v-bind="message"
|
||||
/>
|
||||
</div> `
|
||||
|
||||
</div>`
|
||||
}
|
||||
|
||||
export default Messenger;
|
||||
|
||||
// Is called when window is about to close or reload
|
||||
window.onbeforeunload = () => window.mainApi.send("message", {route: "window", open: true});
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ const Settings =
|
|||
await window.mainApi.send("logout");
|
||||
}
|
||||
|
||||
return { showSettings, active, logout };
|
||||
return { showSettings, active, logout, window };
|
||||
},
|
||||
|
||||
template: `
|
||||
<div v-if="active" id="settings" >
|
||||
<div v-if="active" id="settings">
|
||||
|
||||
<button class="settings-logout-button button" @click="logout">
|
||||
Logout
|
||||
|
|
@ -33,7 +33,7 @@ const Settings =
|
|||
</div>
|
||||
|
||||
<button v-else class="settings-icon" @click="showSettings">
|
||||
<img src="./assets/settingsIcon.svg">
|
||||
<img :src="window.path + 'assets/settingsIcon.svg'">
|
||||
</button>`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,19 +7,19 @@ const WS =
|
|||
|
||||
Vue.onMounted(() => {
|
||||
|
||||
window.mainApi.on("ws-status", (val) => {
|
||||
window.mainApi.on("ws", (val) => {
|
||||
status.value = val;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return { status }
|
||||
return { status, window }
|
||||
},
|
||||
|
||||
template: `
|
||||
<div id="ws">
|
||||
|
||||
<img id="ws-logo" src="./assets/connectLogo.svg"
|
||||
<img id="ws-logo" :src="window.path + 'assets/connectLogo.svg'"
|
||||
:class="{ move: status }"
|
||||
>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,5 @@
|
|||
import App from "./components/app.js";
|
||||
|
||||
window.path = "./";
|
||||
|
||||
Vue.createApp(App).mount("#app");
|
||||
|
|
|
|||
|
|
@ -1,30 +1,48 @@
|
|||
|
||||
@font-face {
|
||||
font-family: "Default";
|
||||
src: url("assets/fonts/SF-Pro-Text-Regular.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Compact";
|
||||
src: url("assets/fonts/SF-Compact-Display-Bold.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Rounded";
|
||||
src: url("assets/fonts/SF-Compact-Rounded-Bold.otf");
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: rgba(235, 235, 235, 0.75);
|
||||
/*background-color: rgba(235, 235, 235, 0.75);*/
|
||||
}
|
||||
|
||||
/* The first word of the class is the component that it modifys. */
|
||||
|
||||
#splash {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#app {
|
||||
font-family: "SF Pro Text";
|
||||
position: relative; /* must explicitly be declared */
|
||||
font-family: "Default";
|
||||
-webkit-font-smoothing: antialiased;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
height: 100vh; /* 100% for website */
|
||||
width: 100vw; /* 100% for website */
|
||||
/* Does not work on Linux */
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
#header-titlebar {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 54px;
|
||||
opacity: 0.75;
|
||||
background-color: #EBEBEB;
|
||||
|
|
@ -32,6 +50,8 @@ html, body {
|
|||
border: none;
|
||||
outline: none;
|
||||
z-index: 1;
|
||||
border-top-left-radius: 15px;
|
||||
border-top-right-radius: 15px;
|
||||
}
|
||||
|
||||
.contacts {
|
||||
|
|
@ -61,22 +81,26 @@ html, body {
|
|||
}
|
||||
|
||||
.contacts .email {
|
||||
font-family: SF Compact Display;
|
||||
font-family: "Compact";
|
||||
font-size: 12px;
|
||||
color: #898989;
|
||||
overflow: w;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#header-menu {
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
margin-left: 20px;
|
||||
margin-top: 20px;
|
||||
z-index: 2;
|
||||
/* Needed for Linux even with higher Z index */
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.header-menu-button {
|
||||
min-width: 14px;
|
||||
min-height: 14px;
|
||||
border-radius: 7px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.header-exit-button {
|
||||
|
|
@ -105,87 +129,9 @@ html, body {
|
|||
justify-content: center;
|
||||
}
|
||||
|
||||
#login-form {
|
||||
font-family: "SF Compact Display";
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.login-input-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.login-input {
|
||||
background-color: #B9B9B9;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 16px;
|
||||
text-decoration: none;
|
||||
margin: 4px 2px;
|
||||
cursor: pointer;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.login-input-modifier {
|
||||
min-width: 181px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.login-submit-button {
|
||||
font-family: "SF Compact Display";
|
||||
position: fixed;
|
||||
margin-top: 260px;
|
||||
background-color: #58C4FD;
|
||||
color: white;
|
||||
padding: 10px 30px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.login-submit-button:active {
|
||||
background-color: #4296C3;
|
||||
}
|
||||
|
||||
/* generic shaking functionality */
|
||||
.shake {
|
||||
animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
|
||||
transform: translate3d(0, 0, 0);
|
||||
backface-visibility: hidden;
|
||||
perspective: 1000px;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
10%, 90% {
|
||||
transform: translate3d(-1px, 0, 0);
|
||||
}
|
||||
|
||||
20%, 80% {
|
||||
transform: translate3d(2px, 0, 0);
|
||||
}
|
||||
|
||||
30%, 50%, 70% {
|
||||
transform: translate3d(-4px, 0, 0);
|
||||
}
|
||||
|
||||
40%, 60% {
|
||||
transform: translate3d(4px, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#messenger {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
|
@ -195,8 +141,8 @@ html, body {
|
|||
}
|
||||
|
||||
#ws {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 54px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -284,7 +230,6 @@ html, body {
|
|||
border-radius: 50%;
|
||||
/* Set opacity here to not affect child. */
|
||||
background-color: rgba(235, 235, 235, 0.75);
|
||||
cursor: pointer;
|
||||
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.15);
|
||||
}
|
||||
|
||||
|
|
@ -296,6 +241,7 @@ html, body {
|
|||
padding: 10px;
|
||||
outline: none;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
pointer-events: none;
|
||||
background-color: white;
|
||||
z-index: -1;
|
||||
|
|
@ -315,9 +261,9 @@ html, body {
|
|||
}
|
||||
|
||||
#settings {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(235, 235, 235, 0.75);
|
||||
z-index: 4;
|
||||
display: flex;
|
||||
|
|
@ -326,6 +272,7 @@ html, body {
|
|||
align-items: center;
|
||||
animation-name: settings-appear;
|
||||
animation-duration: 0.5s;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
@keyframes settings-appear {
|
||||
|
|
@ -338,7 +285,7 @@ html, body {
|
|||
}
|
||||
|
||||
.settings-icon {
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
|
@ -349,10 +296,8 @@ html, body {
|
|||
margin-top: 19px;
|
||||
z-index: 2;
|
||||
background-color: Transparent;
|
||||
}
|
||||
|
||||
.settings-icon:hover {
|
||||
cursor: pointer;
|
||||
/* Needed for Linux */
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.settings-account {
|
||||
|
|
@ -362,16 +307,11 @@ html, body {
|
|||
}
|
||||
|
||||
.settings-logout-button {
|
||||
font-family: "SF Compact Display";
|
||||
font-family: "Compact";
|
||||
background-color: #B7B7B7;
|
||||
padding: 10px 30px;
|
||||
padding: 10px 20px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.settings-logout-button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.settings-version {
|
||||
|
|
@ -385,7 +325,7 @@ html, body {
|
|||
}
|
||||
|
||||
.message {
|
||||
width: 100vw;
|
||||
width: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top: 9px;
|
||||
|
|
@ -410,6 +350,17 @@ html, body {
|
|||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.message-session {
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: "Compact";
|
||||
font-size: 12px;
|
||||
color: #9B9B9B;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.client-message {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
|
@ -418,13 +369,40 @@ html, body {
|
|||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.admin-message {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
position: relative;
|
||||
max-width: 66vw;
|
||||
font-family: "SF Pro Text";
|
||||
max-width: 66%;
|
||||
font-size: 14px;
|
||||
border-radius: 18px;
|
||||
margin-bottom: 4px;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.bubble-notify {
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background-color: #58D9FF;
|
||||
top: -5px;
|
||||
left: -5px;
|
||||
border: 2px solid #EBEBEB;
|
||||
transform: scale(0);
|
||||
animation-name: bubble-notify-anim;
|
||||
animation-duration: 5s;
|
||||
}
|
||||
|
||||
@keyframes bubble-notify-anim {
|
||||
0%, 90% {
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(0);
|
||||
}
|
||||
}
|
||||
|
||||
.ai-bubble {
|
||||
|
|
@ -476,15 +454,15 @@ html, body {
|
|||
.bubble > img {
|
||||
border-radius: inherit;
|
||||
display: block;
|
||||
max-width: inherit;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.bubble a {
|
||||
display:inline-block;
|
||||
display: inline-block;
|
||||
font-family: "Rounded";
|
||||
text-decoration: none;
|
||||
border-radius: inherit;
|
||||
background-color: #D9D9D9;
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
color: #727272;
|
||||
}
|
||||
|
|
@ -494,9 +472,8 @@ html, body {
|
|||
min-height: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: "SF Compact Display";
|
||||
font-family: "Compact";
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
|
|
@ -526,6 +503,32 @@ html, body {
|
|||
cursor: pointer;
|
||||
}*/
|
||||
|
||||
/* shake a div to signal error*/
|
||||
.shake {
|
||||
animation: shake 0.82s cubic-bezier(.36,.07,.19,.97) both;
|
||||
transform: translate3d(0, 0, 0);
|
||||
backface-visibility: hidden;
|
||||
perspective: 1000px;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
10%, 90% {
|
||||
transform: translate3d(-1px, 0, 0);
|
||||
}
|
||||
|
||||
20%, 80% {
|
||||
transform: translate3d(2px, 0, 0);
|
||||
}
|
||||
|
||||
30%, 50%, 70% {
|
||||
transform: translate3d(-4px, 0, 0);
|
||||
}
|
||||
|
||||
40%, 60% {
|
||||
transform: translate3d(4px, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.audio {
|
||||
animation-name: audio-anim;
|
||||
animation-duration: 2s;
|
||||
|
|
@ -547,3 +550,29 @@ html, body {
|
|||
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25), 0 0 0 0.55em rgba(195, 195, 195, 0.45);
|
||||
}
|
||||
}
|
||||
|
||||
.smart-form {
|
||||
width: 225px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.text-field {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
background: none;
|
||||
border: none;
|
||||
margin: 4px;
|
||||
font-size: 14px;
|
||||
border-radius: 10px;
|
||||
background-color: #d1d1d1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.smart-form-logs {
|
||||
font-family: "Compact";
|
||||
font-size: 12px;
|
||||
text-align: left;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,21 +3,20 @@ const { contextBridge, ipcRenderer } = require("electron");
|
|||
/** The main <-> render interface */
|
||||
|
||||
const validFromMainChannels = [
|
||||
"set-account",
|
||||
"update",
|
||||
"ws-status",
|
||||
"playback",
|
||||
"account",
|
||||
"message",
|
||||
"record",
|
||||
"playback"
|
||||
"ws"
|
||||
];
|
||||
|
||||
const validToMain = [
|
||||
"messenger",
|
||||
"message",
|
||||
"login",
|
||||
"logout",
|
||||
"encode",
|
||||
"decode",
|
||||
"nav-bar"
|
||||
"auth",
|
||||
"nav"
|
||||
]
|
||||
|
||||
ipcRenderer.setMaxListeners(250);
|
||||
|
|
|
|||
|
|
@ -3,40 +3,90 @@ const { Notification, ipcMain } = require("electron");
|
|||
const store = require("./utils/store");
|
||||
const { backgroundMitt, ipcEmit } = require("./utils/emitter");
|
||||
const { connectToPlatform, disconnectFromPlatform } = require("./io");
|
||||
const { initAudio, terminateAudio, playback, streamState } = require("./audio");
|
||||
// const { initAudio, terminateAudio, playback, streamState } = require("./audio");
|
||||
|
||||
const util = require('util');
|
||||
|
||||
let ui;
|
||||
let current;
|
||||
|
||||
const messageQueue = [];
|
||||
|
||||
let processContentId;
|
||||
|
||||
/* Possible messages:
|
||||
* - New UI (set ui)
|
||||
* - New message (add message to ui.messages)
|
||||
* - New content (add content to existing message)
|
||||
* - Update person
|
||||
* - Notification
|
||||
*/
|
||||
backgroundMitt.on("message", (message) => messageQueue.push(message));
|
||||
|
||||
function handleUpdateQueue()
|
||||
function handleMessageQueue()
|
||||
{
|
||||
if (!streamState.pb && !streamState.rec)
|
||||
{
|
||||
// if (!streamState.pb && !streamState.rec)
|
||||
// {
|
||||
const update = messageQueue.shift();
|
||||
|
||||
console.log(update);
|
||||
|
||||
if (update)
|
||||
{
|
||||
if (update.title)
|
||||
{
|
||||
if (update.person)
|
||||
{
|
||||
new Notification(update).show();
|
||||
ui = update;
|
||||
current = update.messages.at(-1);
|
||||
}
|
||||
else if (update.audio)
|
||||
else if (update.name)
|
||||
{
|
||||
playback(update);
|
||||
ui.person = update;
|
||||
}
|
||||
else { ipcEmit("update", update); }
|
||||
else if (update.modifier)
|
||||
{
|
||||
ui.messages.push(update);
|
||||
current = update;
|
||||
}
|
||||
else if (update.category)
|
||||
{
|
||||
current.content.push(update);
|
||||
}
|
||||
else if (update.context)
|
||||
{
|
||||
current.context = update.context;
|
||||
}
|
||||
else if (update.text)
|
||||
{
|
||||
current.content.at(-1).text = update.text;
|
||||
}
|
||||
else
|
||||
{
|
||||
const content = current.content.at(-1);
|
||||
|
||||
new Notification({
|
||||
title: current.context,
|
||||
body: content.text
|
||||
}).show();
|
||||
|
||||
/* Ideally, we want a more native solution than this */
|
||||
// if (current.modifier == "ai" && content.category == "audio")
|
||||
// {
|
||||
// playback(content.blob, current.id);
|
||||
// }
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ipcEmit("message", update);
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
function launchSession(account)
|
||||
{
|
||||
connectToPlatform(account);
|
||||
// initAudio();
|
||||
processContentId = setInterval(handleUpdateQueue, 100);
|
||||
processContentId = setInterval(handleMessageQueue, 100);
|
||||
}
|
||||
|
||||
function endSession()
|
||||
|
|
@ -44,7 +94,14 @@ function endSession()
|
|||
clearInterval(processContentId);
|
||||
// terminateAudio();
|
||||
disconnectFromPlatform();
|
||||
ui = null;
|
||||
}
|
||||
|
||||
ipcMain.on("messenger", () => {
|
||||
if (ui) {
|
||||
ipcEmit("message", ui);
|
||||
}
|
||||
});
|
||||
|
||||
exports.launchSession = launchSession;
|
||||
exports.endSession = endSession;
|
||||
|
|
|
|||
17
src/tray.js
17
src/tray.js
|
|
@ -5,7 +5,7 @@ const { Tray } = require("electron");
|
|||
const { backgroundMitt } = require("./utils/emitter");
|
||||
|
||||
let tray;
|
||||
const TRAY_PATH = "./src/assets/tray/";
|
||||
const TRAY_PATH = path.join(__dirname, "assets/tray");
|
||||
|
||||
/* Current state of recording, playback, and ws connection */
|
||||
const state = {
|
||||
|
|
@ -19,25 +19,24 @@ const state = {
|
|||
* @param {"recording" | "playback" | "disconnect"} attribute
|
||||
* @param {boolean} newState
|
||||
*/
|
||||
function updateTray(attribute, newState) {
|
||||
|
||||
function updateTray(attribute, newState)
|
||||
{
|
||||
state[attribute] = newState;
|
||||
|
||||
// convert boolean to number
|
||||
const bi = (b) => b ? 1 : 0;
|
||||
|
||||
// Make sure we have the icon we're looking for.
|
||||
tray.setImage(
|
||||
TRAY_PATH +
|
||||
tray.setImage(path.join(
|
||||
TRAY_PATH,
|
||||
`${bi(state.recording)}${bi(state.playback)}${bi(state.disconnect)}` +
|
||||
".png"
|
||||
);
|
||||
|
||||
));
|
||||
}
|
||||
|
||||
function initTray()
|
||||
function initTray()
|
||||
{
|
||||
tray = new Tray(TRAY_PATH + "000" + ".png");
|
||||
tray = new Tray(path.join(TRAY_PATH, "000.png"));
|
||||
}
|
||||
|
||||
exports.initTray = initTray;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ function updateWindowPosition()
|
|||
}
|
||||
|
||||
|
||||
function onNavBar(_e, cmd)
|
||||
function onNav(_e, cmd)
|
||||
{
|
||||
cmd === "close" ? win.close() : win.minimize();
|
||||
}
|
||||
|
|
@ -42,7 +42,8 @@ function createWin()
|
|||
frame: false,
|
||||
minWidth: 350,
|
||||
minHeight: 500,
|
||||
webPreferences: { preload: path.join(__dirname, "/render/preload.js") }
|
||||
backgroundColor: "#EBEBEB",
|
||||
webPreferences: { preload: path.join(__dirname, "render/preload.js") }
|
||||
})
|
||||
|
||||
// TODO: find a simpler way to notify platform of user events
|
||||
|
|
@ -70,10 +71,10 @@ function createWin()
|
|||
}
|
||||
});
|
||||
|
||||
win.webContents.send("set-account", store.get("account"));
|
||||
win.webContents.send("account", store.get("account"));
|
||||
});
|
||||
}
|
||||
|
||||
ipcMain.on("nav-bar", onNavBar);
|
||||
ipcMain.on("nav", onNav);
|
||||
|
||||
exports.createWin = createWin;
|
||||
|
|
|
|||
785
yarn.lock
785
yarn.lock
|
|
@ -1,785 +0,0 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@crimata/nodeaudio@^0.0.0":
|
||||
"integrity" "sha1-KTpDGuL8j3x72BLNb4Iyg8zgARo="
|
||||
"resolved" "https://gitlab.com/api/v4/projects/28849281/packages/npm/@crimata/nodeaudio/-/@crimata/nodeaudio-0.0.0.tgz"
|
||||
"version" "0.0.0"
|
||||
dependencies:
|
||||
"bindings" "~1.2.1"
|
||||
"sleep" "^6.3.0"
|
||||
|
||||
"@electron/get@^1.0.1":
|
||||
"integrity" "sha512-+SjZhRuRo+STTO1Fdhzqnv9D2ZhjxXP6egsJ9kiO8dtP68cDx7dFCwWi64dlMQV7sWcfW1OYCW4wviEBzmRsfQ=="
|
||||
"resolved" "https://registry.npmjs.org/@electron/get/-/get-1.13.0.tgz"
|
||||
"version" "1.13.0"
|
||||
dependencies:
|
||||
"debug" "^4.1.1"
|
||||
"env-paths" "^2.2.0"
|
||||
"fs-extra" "^8.1.0"
|
||||
"got" "^9.6.0"
|
||||
"progress" "^2.0.3"
|
||||
"semver" "^6.2.0"
|
||||
"sumchecker" "^3.0.1"
|
||||
optionalDependencies:
|
||||
"global-agent" "^2.0.2"
|
||||
"global-tunnel-ng" "^2.7.1"
|
||||
|
||||
"@sindresorhus/is@^0.14.0":
|
||||
"integrity" "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ=="
|
||||
"resolved" "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz"
|
||||
"version" "0.14.0"
|
||||
|
||||
"@szmarczak/http-timer@^1.1.2":
|
||||
"integrity" "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA=="
|
||||
"resolved" "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz"
|
||||
"version" "1.1.2"
|
||||
dependencies:
|
||||
"defer-to-connect" "^1.0.1"
|
||||
|
||||
"@types/node@^14.6.2":
|
||||
"integrity" "sha512-vhUqgjJR1qxwTWV5Ps5txuy2XMdf7Fw+OrdChRboy8BmWUPkckOhphaohzFG6b8DW7CrxaBMdrdJ47SYFq1okw=="
|
||||
"resolved" "https://registry.npmjs.org/@types/node/-/node-14.17.12.tgz"
|
||||
"version" "14.17.12"
|
||||
|
||||
"ajv-formats@^2.0.2":
|
||||
"integrity" "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="
|
||||
"resolved" "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz"
|
||||
"version" "2.1.1"
|
||||
dependencies:
|
||||
"ajv" "^8.0.0"
|
||||
|
||||
"ajv@^8.0.0", "ajv@^8.1.0":
|
||||
"integrity" "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w=="
|
||||
"resolved" "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz"
|
||||
"version" "8.6.2"
|
||||
dependencies:
|
||||
"fast-deep-equal" "^3.1.1"
|
||||
"json-schema-traverse" "^1.0.0"
|
||||
"require-from-string" "^2.0.2"
|
||||
"uri-js" "^4.2.2"
|
||||
|
||||
"atomically@^1.7.0":
|
||||
"integrity" "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w=="
|
||||
"resolved" "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz"
|
||||
"version" "1.7.0"
|
||||
|
||||
"axios@^0.21.1":
|
||||
"integrity" "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA=="
|
||||
"resolved" "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz"
|
||||
"version" "0.21.1"
|
||||
dependencies:
|
||||
"follow-redirects" "^1.10.0"
|
||||
|
||||
"base64-arraybuffer@^1.0.1":
|
||||
"integrity" "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA=="
|
||||
"resolved" "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"bindings@~1.2.1":
|
||||
"integrity" "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
|
||||
"resolved" "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
|
||||
"version" "1.2.1"
|
||||
|
||||
"boolean@^3.0.1":
|
||||
"integrity" "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w=="
|
||||
"resolved" "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz"
|
||||
"version" "3.1.4"
|
||||
|
||||
"buffer-crc32@~0.2.3":
|
||||
"integrity" "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
|
||||
"resolved" "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz"
|
||||
"version" "0.2.13"
|
||||
|
||||
"buffer-from@^1.0.0":
|
||||
"integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
"resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
|
||||
"version" "1.1.2"
|
||||
|
||||
"cacheable-request@^6.0.0":
|
||||
"integrity" "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg=="
|
||||
"resolved" "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz"
|
||||
"version" "6.1.0"
|
||||
dependencies:
|
||||
"clone-response" "^1.0.2"
|
||||
"get-stream" "^5.1.0"
|
||||
"http-cache-semantics" "^4.0.0"
|
||||
"keyv" "^3.0.0"
|
||||
"lowercase-keys" "^2.0.0"
|
||||
"normalize-url" "^4.1.0"
|
||||
"responselike" "^1.0.2"
|
||||
|
||||
"clone-response@^1.0.2":
|
||||
"integrity" "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws="
|
||||
"resolved" "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
dependencies:
|
||||
"mimic-response" "^1.0.0"
|
||||
|
||||
"concat-stream@^1.6.2":
|
||||
"integrity" "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw=="
|
||||
"resolved" "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz"
|
||||
"version" "1.6.2"
|
||||
dependencies:
|
||||
"buffer-from" "^1.0.0"
|
||||
"inherits" "^2.0.3"
|
||||
"readable-stream" "^2.2.2"
|
||||
"typedarray" "^0.0.6"
|
||||
|
||||
"conf@^10.0.0":
|
||||
"integrity" "sha512-iyy4ArqyQ/yrzNASNBN+jaylu53JRuq0ztvL6KAWYHj4iN56BVuhy2SrzEEHBodNbacZr2Pd/4nWhoAwc66T1g=="
|
||||
"resolved" "https://registry.npmjs.org/conf/-/conf-10.0.2.tgz"
|
||||
"version" "10.0.2"
|
||||
dependencies:
|
||||
"ajv" "^8.1.0"
|
||||
"ajv-formats" "^2.0.2"
|
||||
"atomically" "^1.7.0"
|
||||
"debounce-fn" "^4.0.0"
|
||||
"dot-prop" "^6.0.1"
|
||||
"env-paths" "^2.2.1"
|
||||
"json-schema-typed" "^7.0.3"
|
||||
"onetime" "^5.1.2"
|
||||
"pkg-up" "^3.1.0"
|
||||
"semver" "^7.3.5"
|
||||
|
||||
"config-chain@^1.1.11":
|
||||
"integrity" "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="
|
||||
"resolved" "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz"
|
||||
"version" "1.1.13"
|
||||
dependencies:
|
||||
"ini" "^1.3.4"
|
||||
"proto-list" "~1.2.1"
|
||||
|
||||
"core-js@^3.6.5":
|
||||
"integrity" "sha512-lM3GftxzHNtPNUJg0v4pC2RC6puwMd6VZA7vXUczi+SKmCWSf4JwO89VJGMqbzmB7jlK7B5hr3S64PqwFL49cA=="
|
||||
"resolved" "https://registry.npmjs.org/core-js/-/core-js-3.16.3.tgz"
|
||||
"version" "3.16.3"
|
||||
|
||||
"core-util-is@~1.0.0":
|
||||
"integrity" "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
"resolved" "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"debounce-fn@^4.0.0":
|
||||
"integrity" "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ=="
|
||||
"resolved" "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
dependencies:
|
||||
"mimic-fn" "^3.0.0"
|
||||
|
||||
"debug@^2.6.9":
|
||||
"integrity" "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="
|
||||
"resolved" "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz"
|
||||
"version" "2.6.9"
|
||||
dependencies:
|
||||
"ms" "2.0.0"
|
||||
|
||||
"debug@^4.1.0", "debug@^4.1.1":
|
||||
"integrity" "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw=="
|
||||
"resolved" "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz"
|
||||
"version" "4.3.2"
|
||||
dependencies:
|
||||
"ms" "2.1.2"
|
||||
|
||||
"decompress-response@^3.3.0":
|
||||
"integrity" "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M="
|
||||
"resolved" "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz"
|
||||
"version" "3.3.0"
|
||||
dependencies:
|
||||
"mimic-response" "^1.0.0"
|
||||
|
||||
"defer-to-connect@^1.0.1":
|
||||
"integrity" "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ=="
|
||||
"resolved" "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz"
|
||||
"version" "1.1.3"
|
||||
|
||||
"define-properties@^1.1.3":
|
||||
"integrity" "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ=="
|
||||
"resolved" "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz"
|
||||
"version" "1.1.3"
|
||||
dependencies:
|
||||
"object-keys" "^1.0.12"
|
||||
|
||||
"detect-node@^2.0.4":
|
||||
"integrity" "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="
|
||||
"resolved" "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
|
||||
"version" "2.1.0"
|
||||
|
||||
"dot-prop@^6.0.1":
|
||||
"integrity" "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA=="
|
||||
"resolved" "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz"
|
||||
"version" "6.0.1"
|
||||
dependencies:
|
||||
"is-obj" "^2.0.0"
|
||||
|
||||
"duplexer3@^0.1.4":
|
||||
"integrity" "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
|
||||
"resolved" "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz"
|
||||
"version" "0.1.4"
|
||||
|
||||
"electron-store@^8.0.0":
|
||||
"integrity" "sha512-ZgRPUZkfrrjWSqxZeaxu7lEvmYf6tgl49dLMqxXGnEmliSiwv3u4rJPG+mH3fBQP9PBqgSh4TCuxHZImMMUgWg=="
|
||||
"resolved" "https://registry.npmjs.org/electron-store/-/electron-store-8.0.0.tgz"
|
||||
"version" "8.0.0"
|
||||
dependencies:
|
||||
"conf" "^10.0.0"
|
||||
"type-fest" "^1.0.2"
|
||||
|
||||
"electron@^13.2.3":
|
||||
"integrity" "sha512-FzWhbKHjq7ZTpPQFaYiLPL64erC8/BOsu5NlNN9nQ6f7rIP8ygKlNAlQit3vbOcksQAwItDUCIw4sW0mcaRpCA=="
|
||||
"resolved" "https://registry.npmjs.org/electron/-/electron-13.2.3.tgz"
|
||||
"version" "13.2.3"
|
||||
dependencies:
|
||||
"@electron/get" "^1.0.1"
|
||||
"@types/node" "^14.6.2"
|
||||
"extract-zip" "^1.0.3"
|
||||
|
||||
"encodeurl@^1.0.2":
|
||||
"integrity" "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
"resolved" "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"end-of-stream@^1.1.0":
|
||||
"integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="
|
||||
"resolved" "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz"
|
||||
"version" "1.4.4"
|
||||
dependencies:
|
||||
"once" "^1.4.0"
|
||||
|
||||
"env-paths@^2.2.0", "env-paths@^2.2.1":
|
||||
"integrity" "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="
|
||||
"resolved" "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz"
|
||||
"version" "2.2.1"
|
||||
|
||||
"es6-error@^4.1.1":
|
||||
"integrity" "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="
|
||||
"resolved" "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz"
|
||||
"version" "4.1.1"
|
||||
|
||||
"escape-string-regexp@^4.0.0":
|
||||
"integrity" "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
"resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
|
||||
"extract-zip@^1.0.3":
|
||||
"integrity" "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA=="
|
||||
"resolved" "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz"
|
||||
"version" "1.7.0"
|
||||
dependencies:
|
||||
"concat-stream" "^1.6.2"
|
||||
"debug" "^2.6.9"
|
||||
"mkdirp" "^0.5.4"
|
||||
"yauzl" "^2.10.0"
|
||||
|
||||
"fast-deep-equal@^3.1.1":
|
||||
"integrity" "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
"resolved" "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
"version" "3.1.3"
|
||||
|
||||
"fd-slicer@~1.1.0":
|
||||
"integrity" "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4="
|
||||
"resolved" "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz"
|
||||
"version" "1.1.0"
|
||||
dependencies:
|
||||
"pend" "~1.2.0"
|
||||
|
||||
"find-up@^3.0.0":
|
||||
"integrity" "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="
|
||||
"resolved" "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"locate-path" "^3.0.0"
|
||||
|
||||
"follow-redirects@^1.10.0":
|
||||
"integrity" "sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA=="
|
||||
"resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.2.tgz"
|
||||
"version" "1.14.2"
|
||||
|
||||
"fs-extra@^8.1.0":
|
||||
"integrity" "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="
|
||||
"resolved" "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz"
|
||||
"version" "8.1.0"
|
||||
dependencies:
|
||||
"graceful-fs" "^4.2.0"
|
||||
"jsonfile" "^4.0.0"
|
||||
"universalify" "^0.1.0"
|
||||
|
||||
"get-stream@^4.1.0":
|
||||
"integrity" "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w=="
|
||||
"resolved" "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz"
|
||||
"version" "4.1.0"
|
||||
dependencies:
|
||||
"pump" "^3.0.0"
|
||||
|
||||
"get-stream@^5.1.0":
|
||||
"integrity" "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="
|
||||
"resolved" "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz"
|
||||
"version" "5.2.0"
|
||||
dependencies:
|
||||
"pump" "^3.0.0"
|
||||
|
||||
"global-agent@^2.0.2":
|
||||
"integrity" "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg=="
|
||||
"resolved" "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz"
|
||||
"version" "2.2.0"
|
||||
dependencies:
|
||||
"boolean" "^3.0.1"
|
||||
"core-js" "^3.6.5"
|
||||
"es6-error" "^4.1.1"
|
||||
"matcher" "^3.0.0"
|
||||
"roarr" "^2.15.3"
|
||||
"semver" "^7.3.2"
|
||||
"serialize-error" "^7.0.1"
|
||||
|
||||
"global-tunnel-ng@^2.7.1":
|
||||
"integrity" "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg=="
|
||||
"resolved" "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz"
|
||||
"version" "2.7.1"
|
||||
dependencies:
|
||||
"encodeurl" "^1.0.2"
|
||||
"lodash" "^4.17.10"
|
||||
"npm-conf" "^1.1.3"
|
||||
"tunnel" "^0.0.6"
|
||||
|
||||
"globalthis@^1.0.1":
|
||||
"integrity" "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ=="
|
||||
"resolved" "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
dependencies:
|
||||
"define-properties" "^1.1.3"
|
||||
|
||||
"got@^9.6.0":
|
||||
"integrity" "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q=="
|
||||
"resolved" "https://registry.npmjs.org/got/-/got-9.6.0.tgz"
|
||||
"version" "9.6.0"
|
||||
dependencies:
|
||||
"@sindresorhus/is" "^0.14.0"
|
||||
"@szmarczak/http-timer" "^1.1.2"
|
||||
"cacheable-request" "^6.0.0"
|
||||
"decompress-response" "^3.3.0"
|
||||
"duplexer3" "^0.1.4"
|
||||
"get-stream" "^4.1.0"
|
||||
"lowercase-keys" "^1.0.1"
|
||||
"mimic-response" "^1.0.1"
|
||||
"p-cancelable" "^1.0.0"
|
||||
"to-readable-stream" "^1.0.0"
|
||||
"url-parse-lax" "^3.0.0"
|
||||
|
||||
"graceful-fs@^4.1.6", "graceful-fs@^4.2.0":
|
||||
"integrity" "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
|
||||
"resolved" "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz"
|
||||
"version" "4.2.8"
|
||||
|
||||
"http-cache-semantics@^4.0.0":
|
||||
"integrity" "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
|
||||
"resolved" "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz"
|
||||
"version" "4.1.0"
|
||||
|
||||
"inherits@^2.0.3", "inherits@~2.0.3":
|
||||
"integrity" "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
"resolved" "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
||||
"version" "2.0.4"
|
||||
|
||||
"ini@^1.3.4":
|
||||
"integrity" "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||
"resolved" "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
|
||||
"version" "1.3.8"
|
||||
|
||||
"is-obj@^2.0.0":
|
||||
"integrity" "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
|
||||
"resolved" "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"isarray@~1.0.0":
|
||||
"integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
"resolved" "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"json-buffer@3.0.0":
|
||||
"integrity" "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
|
||||
"resolved" "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
|
||||
"json-schema-traverse@^1.0.0":
|
||||
"integrity" "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
|
||||
"resolved" "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"json-schema-typed@^7.0.3":
|
||||
"integrity" "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A=="
|
||||
"resolved" "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz"
|
||||
"version" "7.0.3"
|
||||
|
||||
"json-stringify-safe@^5.0.1":
|
||||
"integrity" "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
"resolved" "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
|
||||
"version" "5.0.1"
|
||||
|
||||
"jsonfile@^4.0.0":
|
||||
"integrity" "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss="
|
||||
"resolved" "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
optionalDependencies:
|
||||
"graceful-fs" "^4.1.6"
|
||||
|
||||
"keyv@^3.0.0":
|
||||
"integrity" "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA=="
|
||||
"resolved" "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz"
|
||||
"version" "3.1.0"
|
||||
dependencies:
|
||||
"json-buffer" "3.0.0"
|
||||
|
||||
"locate-path@^3.0.0":
|
||||
"integrity" "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="
|
||||
"resolved" "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"p-locate" "^3.0.0"
|
||||
"path-exists" "^3.0.0"
|
||||
|
||||
"lodash@^4.17.10":
|
||||
"integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
"resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
||||
"version" "4.17.21"
|
||||
|
||||
"lowercase-keys@^1.0.0", "lowercase-keys@^1.0.1":
|
||||
"integrity" "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
|
||||
"resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"lowercase-keys@^2.0.0":
|
||||
"integrity" "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
|
||||
"resolved" "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"lru-cache@^6.0.0":
|
||||
"integrity" "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="
|
||||
"resolved" "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
|
||||
"version" "6.0.0"
|
||||
dependencies:
|
||||
"yallist" "^4.0.0"
|
||||
|
||||
"matcher@^3.0.0":
|
||||
"integrity" "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="
|
||||
"resolved" "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"escape-string-regexp" "^4.0.0"
|
||||
|
||||
"mimic-fn@^2.1.0":
|
||||
"integrity" "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
|
||||
"resolved" "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
|
||||
"version" "2.1.0"
|
||||
|
||||
"mimic-fn@^3.0.0":
|
||||
"integrity" "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ=="
|
||||
"resolved" "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz"
|
||||
"version" "3.1.0"
|
||||
|
||||
"mimic-response@^1.0.0", "mimic-response@^1.0.1":
|
||||
"integrity" "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
|
||||
"resolved" "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"minimist@^1.2.5":
|
||||
"integrity" "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
"resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz"
|
||||
"version" "1.2.5"
|
||||
|
||||
"mkdirp@^0.5.4":
|
||||
"integrity" "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ=="
|
||||
"resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz"
|
||||
"version" "0.5.5"
|
||||
dependencies:
|
||||
"minimist" "^1.2.5"
|
||||
|
||||
"ms@2.0.0":
|
||||
"integrity" "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
"resolved" "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"ms@2.1.2":
|
||||
"integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
"resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
|
||||
"version" "2.1.2"
|
||||
|
||||
"nan@^2.14.1":
|
||||
"integrity" "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ=="
|
||||
"resolved" "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz"
|
||||
"version" "2.15.0"
|
||||
|
||||
"normalize-url@^4.1.0":
|
||||
"integrity" "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA=="
|
||||
"resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz"
|
||||
"version" "4.5.1"
|
||||
|
||||
"npm-conf@^1.1.3":
|
||||
"integrity" "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw=="
|
||||
"resolved" "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz"
|
||||
"version" "1.1.3"
|
||||
dependencies:
|
||||
"config-chain" "^1.1.11"
|
||||
"pify" "^3.0.0"
|
||||
|
||||
"object-keys@^1.0.12":
|
||||
"integrity" "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
|
||||
"resolved" "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
|
||||
"version" "1.1.1"
|
||||
|
||||
"once@^1.3.1", "once@^1.4.0":
|
||||
"integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E="
|
||||
"resolved" "https://registry.npmjs.org/once/-/once-1.4.0.tgz"
|
||||
"version" "1.4.0"
|
||||
dependencies:
|
||||
"wrappy" "1"
|
||||
|
||||
"onetime@^5.1.2":
|
||||
"integrity" "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="
|
||||
"resolved" "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz"
|
||||
"version" "5.1.2"
|
||||
dependencies:
|
||||
"mimic-fn" "^2.1.0"
|
||||
|
||||
"p-cancelable@^1.0.0":
|
||||
"integrity" "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw=="
|
||||
"resolved" "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz"
|
||||
"version" "1.1.0"
|
||||
|
||||
"p-limit@^2.0.0":
|
||||
"integrity" "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="
|
||||
"resolved" "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz"
|
||||
"version" "2.3.0"
|
||||
dependencies:
|
||||
"p-try" "^2.0.0"
|
||||
|
||||
"p-locate@^3.0.0":
|
||||
"integrity" "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="
|
||||
"resolved" "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"p-limit" "^2.0.0"
|
||||
|
||||
"p-try@^2.0.0":
|
||||
"integrity" "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
|
||||
"resolved" "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
|
||||
"version" "2.2.0"
|
||||
|
||||
"path-exists@^3.0.0":
|
||||
"integrity" "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||
"resolved" "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
|
||||
"pend@~1.2.0":
|
||||
"integrity" "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
|
||||
"resolved" "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz"
|
||||
"version" "1.2.0"
|
||||
|
||||
"pify@^3.0.0":
|
||||
"integrity" "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
|
||||
"resolved" "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
|
||||
"pkg-up@^3.1.0":
|
||||
"integrity" "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA=="
|
||||
"resolved" "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz"
|
||||
"version" "3.1.0"
|
||||
dependencies:
|
||||
"find-up" "^3.0.0"
|
||||
|
||||
"prepend-http@^2.0.0":
|
||||
"integrity" "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
|
||||
"resolved" "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"process-nextick-args@~2.0.0":
|
||||
"integrity" "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
"resolved" "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
|
||||
"progress@^2.0.3":
|
||||
"integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
|
||||
"resolved" "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz"
|
||||
"version" "2.0.3"
|
||||
|
||||
"proto-list@~1.2.1":
|
||||
"integrity" "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk="
|
||||
"resolved" "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz"
|
||||
"version" "1.2.4"
|
||||
|
||||
"pump@^3.0.0":
|
||||
"integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="
|
||||
"resolved" "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"end-of-stream" "^1.1.0"
|
||||
"once" "^1.3.1"
|
||||
|
||||
"punycode@^2.1.0":
|
||||
"integrity" "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
"resolved" "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
|
||||
"version" "2.1.1"
|
||||
|
||||
"readable-stream@^2.2.2":
|
||||
"integrity" "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw=="
|
||||
"resolved" "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
|
||||
"version" "2.3.7"
|
||||
dependencies:
|
||||
"core-util-is" "~1.0.0"
|
||||
"inherits" "~2.0.3"
|
||||
"isarray" "~1.0.0"
|
||||
"process-nextick-args" "~2.0.0"
|
||||
"safe-buffer" "~5.1.1"
|
||||
"string_decoder" "~1.1.1"
|
||||
"util-deprecate" "~1.0.1"
|
||||
|
||||
"require-from-string@^2.0.2":
|
||||
"integrity" "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
|
||||
"resolved" "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
||||
"version" "2.0.2"
|
||||
|
||||
"responselike@^1.0.2":
|
||||
"integrity" "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec="
|
||||
"resolved" "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
dependencies:
|
||||
"lowercase-keys" "^1.0.0"
|
||||
|
||||
"roarr@^2.15.3":
|
||||
"integrity" "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="
|
||||
"resolved" "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz"
|
||||
"version" "2.15.4"
|
||||
dependencies:
|
||||
"boolean" "^3.0.1"
|
||||
"detect-node" "^2.0.4"
|
||||
"globalthis" "^1.0.1"
|
||||
"json-stringify-safe" "^5.0.1"
|
||||
"semver-compare" "^1.0.0"
|
||||
"sprintf-js" "^1.1.2"
|
||||
|
||||
"safe-buffer@~5.1.0", "safe-buffer@~5.1.1":
|
||||
"integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
|
||||
"version" "5.1.2"
|
||||
|
||||
"semver-compare@^1.0.0":
|
||||
"integrity" "sha1-De4hahyUGrN+nvsXiPavxf9VN/w="
|
||||
"resolved" "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"semver@^6.2.0":
|
||||
"integrity" "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
||||
"resolved" "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
|
||||
"version" "6.3.0"
|
||||
|
||||
"semver@^7.3.2", "semver@^7.3.5":
|
||||
"integrity" "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ=="
|
||||
"resolved" "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz"
|
||||
"version" "7.3.5"
|
||||
dependencies:
|
||||
"lru-cache" "^6.0.0"
|
||||
|
||||
"serialize-error@^7.0.1":
|
||||
"integrity" "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="
|
||||
"resolved" "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz"
|
||||
"version" "7.0.1"
|
||||
dependencies:
|
||||
"type-fest" "^0.13.1"
|
||||
|
||||
"sleep@^6.3.0":
|
||||
"integrity" "sha512-+WgYl951qdUlb1iS97UvQ01pkauoBK9ML9I/CMPg41v0Ze4EyMlTgFTDDo32iYj98IYqxIjDMRd+L71lawFfpQ=="
|
||||
"resolved" "https://registry.npmjs.org/sleep/-/sleep-6.3.0.tgz"
|
||||
"version" "6.3.0"
|
||||
dependencies:
|
||||
"nan" "^2.14.1"
|
||||
|
||||
"sprintf-js@^1.1.2":
|
||||
"integrity" "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
|
||||
"resolved" "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz"
|
||||
"version" "1.1.2"
|
||||
|
||||
"string_decoder@~1.1.1":
|
||||
"integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="
|
||||
"resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
|
||||
"version" "1.1.1"
|
||||
dependencies:
|
||||
"safe-buffer" "~5.1.0"
|
||||
|
||||
"sumchecker@^3.0.1":
|
||||
"integrity" "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="
|
||||
"resolved" "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz"
|
||||
"version" "3.0.1"
|
||||
dependencies:
|
||||
"debug" "^4.1.0"
|
||||
|
||||
"to-readable-stream@^1.0.0":
|
||||
"integrity" "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q=="
|
||||
"resolved" "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"tunnel@^0.0.6":
|
||||
"integrity" "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||
"resolved" "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz"
|
||||
"version" "0.0.6"
|
||||
|
||||
"type-fest@^0.13.1":
|
||||
"integrity" "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="
|
||||
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz"
|
||||
"version" "0.13.1"
|
||||
|
||||
"type-fest@^1.0.2":
|
||||
"integrity" "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
|
||||
"resolved" "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz"
|
||||
"version" "1.4.0"
|
||||
|
||||
"typedarray@^0.0.6":
|
||||
"integrity" "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
"resolved" "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
|
||||
"version" "0.0.6"
|
||||
|
||||
"universalify@^0.1.0":
|
||||
"integrity" "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
"resolved" "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz"
|
||||
"version" "0.1.2"
|
||||
|
||||
"uri-js@^4.2.2":
|
||||
"integrity" "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="
|
||||
"resolved" "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz"
|
||||
"version" "4.4.1"
|
||||
dependencies:
|
||||
"punycode" "^2.1.0"
|
||||
|
||||
"url-parse-lax@^3.0.0":
|
||||
"integrity" "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww="
|
||||
"resolved" "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz"
|
||||
"version" "3.0.0"
|
||||
dependencies:
|
||||
"prepend-http" "^2.0.0"
|
||||
|
||||
"util-deprecate@~1.0.1":
|
||||
"integrity" "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
"resolved" "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"wrappy@1":
|
||||
"integrity" "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"resolved" "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"ws@^7.3.1":
|
||||
"integrity" "sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg=="
|
||||
"resolved" "https://registry.npmjs.org/ws/-/ws-7.5.4.tgz"
|
||||
"version" "7.5.4"
|
||||
|
||||
"yallist@^4.0.0":
|
||||
"integrity" "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
"resolved" "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
|
||||
"yauzl@^2.10.0":
|
||||
"integrity" "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk="
|
||||
"resolved" "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz"
|
||||
"version" "2.10.0"
|
||||
dependencies:
|
||||
"buffer-crc32" "~0.2.3"
|
||||
"fd-slicer" "~1.1.0"
|
||||
Loading…
Reference in a new issue