diff --git a/.gitignore b/.gitignore index 0dd74f39..929262fd 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,10 @@ dist deploy-*.sh postgres_data -keydb_data \ No newline at end of file + +# Turborepo build cache +.turbo/ + +# KeyDB database dumps +keydb_data/ + diff --git a/.npmrc b/.npmrc index fa0ab67b..bce8a6d8 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,3 @@ shamefully-hoist=true -auto-install-peers=true \ No newline at end of file +auto-install-peers=true +strict-peer-dependencies=false \ No newline at end of file diff --git a/README.md b/README.md index 56ad3fe0..1eaf5fd0 100644 --- a/README.md +++ b/README.md @@ -13,29 +13,274 @@ DeepNotes is an open source, end-to-end encrypted infinite canvas tool with deep - **Flexible note system:** Organize your notes in whatever way you want. - **Lifelong storage:** Never lose your notes ever again. +## Core Technologies + +> **Note on Developer Setup** +> +> This project uses both a `README.md` and a `machines.txt` file: +> +> - `README.md` provides general project documentation, usage instructions, and contribution guidelines. +> - `machines.txt` documents machine-specific setup, environment requirements, recommended tools, and VS Code extensions for contributors. +> +> Please consult both files when setting up your development environment to ensure reliability and consistency across all contributors’ machines. + +DeepNotes is built using modern open source technologies: + +- **[Vue.js](https://vuejs.org/):** Progressive JavaScript framework for building user interfaces and single-page applications. +- **[Quasar Framework](https://quasar.dev/):** Cross-platform frontend framework for building SPA, SSR, mobile, and desktop apps with Vue. +- **[Yjs](https://docs.yjs.dev/):** CRDT-based library for realtime collaboration and shared editing. +- **[Tiptap](https://tiptap.dev/):** Rich text editor framework built on top of ProseMirror, highly extensible for custom editors. +- **[Docker](https://www.docker.com/):** Containerization platform used to run databases and backend services in isolated environments. +- **[PostgreSQL](https://www.postgresql.org/):** Advanced open source relational database powering DeepNotes data storage. +- **[KeyDB](https://docs.keydb.dev/):** High-performance, multi-threaded database compatible with Redis, used for caching and pub/sub. +- **[Redis](https://redis.io/):** In-memory data structure store, used for caching and message brokering (via KeyDB compatibility). +- **[Turborepo](https://turbo.build/):** Monorepo build system for fast, incremental builds and caching across all packages and apps. +- **[pnpm](https://pnpm.io/):** Fast, disk-efficient package manager for JavaScript/TypeScript monorepos. +- **[Husky](https://typicode.github.io/husky/):** Git hooks manager used to enforce commit message style and automate checks. + +## Monorepo Structure and Turborepo + +DeepNotes uses a monorepo structure managed by [Turborepo](https://turbo.build/), which enables fast, incremental builds and caching for large codebases with many interdependent packages and apps. + +### Main Directories + +- **apps/**: Contains all main applications, such as backend servers, frontend clients, schedulers, and related services. Each app is in its own subfolder (e.g., `app-server`, `client`, `collab-server`). +- **packages/**: Contains shared libraries and modules, organized by namespace (e.g., `@stdlib`, `@deeplib`). These packages provide reusable code, utilities, and configuration used by the apps. + +### Other Folders Used by Turborepo + +- **.turbo/**: Local build cache for Turborepo. This folder should not be committed to version control (see `.gitignore`). +- **patches/**: Used for package manager patches (e.g., pnpm), not directly by Turborepo but often present in monorepos. + +Turborepo coordinates builds, tests, and other tasks across these directories, enabling efficient development and CI/CD for all parts of the project. + +For more details, see [Turborepo documentation](https://turbo.build/docs). + +## Development Scripts + +This project provides two main scripts for running each application: + +- `pnpm run dev`: Starts the app with the Node.js debugger enabled (`--inspect`), allowing you to attach a debugger at any time. The app runs normally and does not pause at startup. +- `pnpm run debug`: Starts the app with the Node.js debugger in break mode (`--inspect-brk`), pausing execution on the first line. Use this when you want to debug from the very start of the process. + +For regular development, use `pnpm run dev`. Use `pnpm run debug` only when you need to debug initialization code. + ## Development -```console -git clone https://github.com/DeepNotesApp/DeepNotes && cd DeepNotes && cp template.env .env && pnpm install && pnpm run repo:build && docker-compose up -d +To set up and run DeepNotes locally, follow these steps: + +### 1. Clone the repository + +```bash +git clone https://github.com/bluekeys/DeepNotes +cd DeepNotes +``` + +### 2. Prepare your configuration + +Copy the example environment file to create your own local config: + +```bash +cp template.env .env +``` + +Edit `.env` as needed for your local ports, database credentials, etc. + +### 3. Install dependencies + +Install all required packages for the monorepo: + +```bash +pnpm install +``` + +This also sets up commit message hooks (via Husky) to enforce commit style. + +### 4. Start the databases (Postgres & KeyDB) + +Start the required database services using Docker: + +```bash +docker-compose up -d +``` + +This launches Postgres and KeyDB containers. You need these running for backend services to work. + +### 5. Start backend application servers + +Run all backend services in parallel: + +```bash +pnpm run dev +``` + +This starts the app-server, collab-server, realtime-server, etc. These connect to the databases you started above. + +### 6. Start the frontend app + +Choose one of the following commands depending on your target platform: + +- **Single Page Application (SPA):** + ```bash + pnpm run dev:spa + ``` +- **Server Side Rendered (SSR) app:** + ```bash + pnpm run dev:ssr + ``` +- **Electron desktop app:** + ```bash + pnpm run dev:electron + ``` +- **Android app (requires Android Studio):** + ```bash + pnpm run dev:android + ``` +- **iOS app (requires Xcode):** + ```bash + pnpm run dev:ios + ``` + +> For SPA or SSR, open [http://localhost:60379](http://localhost:60379) in your browser. You can change the host and ports in the `.env` file. + +**Windows users:** Use WSL or Git Bash to run these commands. + +## Application Overview and Startup + +DeepNotes consists of several backend and frontend apps managed in the monorepo: + +| App | Role/Function | Depends On | +| --------------- | ---------------------------------------------------------- | ------------------------ | +| app-server | Main backend API, authentication, data access | PostgreSQL, KeyDB | +| client | Frontend SPA/SSR/Electron/mobile app | app-server, backend APIs | +| collab-server | Realtime collaborative editing (CRDT/Yjs) | PostgreSQL, KeyDB | +| realtime-server | Websocket server for realtime events | PostgreSQL, KeyDB | +| scheduler | Scheduled background tasks (cleanup, maintenance) | PostgreSQL, KeyDB | +| manager | Admin/maintenance CLI (user/group/email/Stripe management) | PostgreSQL, KeyDB | + +**Startup Order:** + +1. Start databases: + +```bash +docker-compose up -d ``` -(On Windows, use WSL or Git Bash to run the commands above) +2. Start backend servers (all at once, using Turborepo): + +```bash +pnpm run dev +``` + +This command uses Turborepo to run all backend apps in parallel. To run a specific app: + +To run a specific app, use one of the following commands: + +```bash +pnpm --filter app-server dev # Main backend API +``` + +```bash +pnpm --filter collab-server dev # Realtime collaborative editing +``` + +```bash +pnpm --filter realtime-server dev # Websocket server for realtime events +``` + +```bash +pnpm --filter scheduler dev # Scheduled background tasks +``` + +```bash +pnpm --filter manager dev # Admin/maintenance CLI +``` + +3. Start the frontend client (choose your platform): + +To start the frontend client, use one of the following commands: + +```bash +pnpm run spa:dev # Single Page App +``` + +```bash +pnpm run ssr:dev # Server Side Rendered +``` + +```bash +pnpm run electron:dev # Desktop +``` + +```bash +pnpm run android:dev # Android +``` + +```bash +pnpm run ios:dev # iOS +``` + +For more details on Turborepo configuration and advanced usage, see the [Turborepo documentation](https://turbo.build/docs). + +## Contributing + +### Commit Hooks and Husky + +This project uses [Husky](https://typicode.github.io/husky/) to manage Git hooks. After running `pnpm install`, Husky sets up a commit-msg hook that checks your commit messages using commitlint. This helps enforce a consistent commit history and automates changelog generation. + +If you commit before running `pnpm install`, the hooks will not be installed and your commit messages may not be checked. + +### Commit Message Guidelines + +This project uses [commitlint](https://github.com/conventional-changelog/commitlint) to enforce Conventional Commit messages. This helps keep the project history clean and automates changelog generation. + +#### Format + +Commit messages must follow this format: + +``` +type(scope): short description + +[optional body, each line ≤ 100 characters] +``` + +**Types:** + +- `feat`: a new feature +- `fix`: a bug fix +- `docs`: documentation only changes +- `style`: formatting, missing semi colons, etc; no code change +- `refactor`: code change that neither fixes a bug nor adds a feature +- `perf`: performance improvement +- `test`: adding or correcting tests +- `chore`: changes to the build process or auxiliary tools + +**Scope:** (optional) the part of the codebase affected, e.g. `client`, `server`, `docs` + +#### Examples + +- `feat: add new canvas drawing tool` +- `fix(client): resolve login bug` +- `chore: update dependencies` + +#### More Resources + +- [Commitlint documentation](https://commitlint.js.org/) +- [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) + +Commit messages that do not follow these rules will be rejected by the commit hook. If you need to add a longer description, use the commit body and keep each line under 100 characters. + +## Licensing + +DeepNotes is licensed under the **GNU Affero General Public License v3 (AGPL-3.0)**. -1. Run `pnpm run dev` to start the backend servers. -2. Run one of these commands to start the frontend server: - - `pnpm run dev:spa` to start the Single Page Application app. - - `pnpm run dev:ssr` to start the Server Side Rendered app. - - `pnpm run dev:electron` to start the Electron app. - - `pnpm run dev:android` to start the Android app (requires Android Studio). - - `pnpm run dev:ios` to start the iOS app (requires Xcode). +You are free to use, modify, and redistribute this software, provided that you also share your changes under the same license. +If you run a modified version of DeepNotes on a publicly accessible server, you must make the source code of your modifications available to users of that server. +The AGPL-3.0 ensures that improvements and changes remain open and accessible to the community, especially for network/server software. +For full license terms, see the [LICENSE](./LICENSE) file or visit [GNU AGPL v3](https://www.gnu.org/licenses/agpl-3.0.html). -(If you use SPA or SSR, you must access the app through `http://localhost:60379` by default. Other URLs won't work. You can configure the host and ports in the `.env` file.) +If you contribute to DeepNotes, your contributions will also be covered by the AGPL-3.0 license. -## Special thanks to these libraries for making DeepNotes possible: +## Credits -- [Vue.js](https://vuejs.org/): Reactivity, component system, and more -- [Quasar Framework](https://quasar.dev/): Cross-platform frontend framework -- [Yjs](https://docs.yjs.dev/): Realtime collaboration -- [Tiptap](https://tiptap.dev/): Rich text editor -- [KeyDB](https://docs.keydb.dev/) and [Redis](https://redis.io/): Scalable shared memory and communication -- And many more... +This project is a fork of [DeepNotesApp/DeepNotes](https://github.com/DeepNotesApp/DeepNotes) by DeepNotesApp. Special thanks to the original author and contributors for their work. diff --git a/TODO.md b/TODO.md new file mode 100644 index 00000000..8e1a2cdd --- /dev/null +++ b/TODO.md @@ -0,0 +1,46 @@ +# TODOs for DeepNotes Repository + +A starter list of tasks to help bring the project back to life and polish the codebase. Update this file as you progress! + +## Project Setup & Environment +- [ ] Ensure `.env` is present and correctly configured for all services +- [ ] Validate Docker Compose setup: all services start and communicate as expected +- [ ] Confirm KeyDB and PostgreSQL are running and accessible +- [ ] Check for database migration scripts or initial data setup + +## Codebase Review & Quality +- [ ] Run `pnpm install` and resolve any dependency issues +- [ ] Review and update custom patches in `patches/` for necessity and compatibility +- [ ] Run linting and formatting tools to catch style/code issues +- [ ] Check for outdated or vulnerable dependencies in all `package.json` files + +## Build & Run Scripts +- [ ] Test `pnpm run repo:build` and ensure all build steps succeed +- [ ] Start backend servers with `pnpm run dev` and verify functionality +- [ ] Start frontend (SPA/SSR/Electron/Android/iOS) and confirm builds work +- [ ] Review and document frontend build process for Quasar, Capacitor, Electron + +## Documentation & Troubleshooting +- [ ] Review and update `README.md` for setup instructions, architecture overview, and troubleshooting tips +- [ ] Add documentation for inter-service communication (e.g., WebSocket, REST, RPC) +- [ ] Add FAQ or troubleshooting section for common issues + +## Testing +- [ ] Run tests using `vitest` and review coverage +- [ ] Add or fix tests as needed for critical features + +## Service Architecture +- [ ] Document the role and interaction of each service (app-server, collab-server, realtime-server, scheduler, manager) +- [ ] Clarify which services are needed for local development vs. production/staging + +## Frontend Polish +- [ ] Ensure Quasar, Capacitor, and Electron builds work out of the box +- [ ] Verify platform-specific dependencies for mobile/desktop builds + +## General Improvements +- [ ] Add more inline `TODO:` comments in code for specific refactoring or fixes +- [ ] Organize and clean up unused files or legacy code + +--- + +_Keep this list updated as you discover new tasks or complete existing ones!_ diff --git a/apps/app-server/package.json b/apps/app-server/package.json index b0020e48..ed1e8023 100644 --- a/apps/app-server/package.json +++ b/apps/app-server/package.json @@ -59,7 +59,8 @@ "build:watch": "concurrently \"tsc --build ./tsconfig.json --watch\" \"tsc-alias -p tsconfig.json --watch\"", "bundle": "tsup", "clean": "rimraf --glob ./dist *.tsbuildinfo", - "dev": "tsx --inspect-brk ./src/index.ts", + "dev": "tsx --inspect=9229 ./src/index.ts", + "debug": "tsx --inspect-brk=9229 ./src/index.ts", "fix": "eslint --fix --ext .js,.ts,.vue ./", "npkill": "rimraf --glob ./node_modules", "preinstall": "npx only-allow pnpm", diff --git a/apps/app-server/src/fastify/app-store-webhook.ts b/apps/app-server/src/fastify/app-store-webhook.ts index 11cc27e6..81691638 100644 --- a/apps/app-server/src/fastify/app-store-webhook.ts +++ b/apps/app-server/src/fastify/app-store-webhook.ts @@ -99,16 +99,22 @@ export async function webhook({ _webhookLogger.info('Signed payload: %o', input); const decodedPayloadSignature = jws.decode(input.signedPayload); - const decodedPayload = - decodedPayloadSignature.payload as responseBodyV2DecodedPayload; + const decodedPayload = (() => { + if (!decodedPayloadSignature) + throw new Error('Missing decodedPayloadSignature'); + return decodedPayloadSignature.payload as responseBodyV2DecodedPayload; + })(); _webhookLogger.info('Decoded payload: %o', decodedPayload); const decodedTransactionSignature = jws.decode( decodedPayload.data.signedTransactionInfo, ); - const decodedTransaction = - decodedTransactionSignature.payload as JWSTransactionDecodedPayload; + const decodedTransaction = (() => { + if (!decodedTransactionSignature) + throw new Error('Missing decodedTransactionSignature'); + return decodedTransactionSignature.payload as JWSTransactionDecodedPayload; + })(); _webhookLogger.info('Decoded transaction: %o', decodedTransaction); } diff --git a/apps/app-server/src/fastify/stripe-webhook.ts b/apps/app-server/src/fastify/stripe-webhook.ts index 59c62fdc..62360c1b 100644 --- a/apps/app-server/src/fastify/stripe-webhook.ts +++ b/apps/app-server/src/fastify/stripe-webhook.ts @@ -28,7 +28,11 @@ export async function webhook({ const event = ctx.stripe.webhooks.constructEvent( ctx.req.rawBody!, ctx.req.headers['stripe-signature']!, - process.env.STRIPE_WEBHOOK_SECRET, + process.env.STRIPE_WEBHOOK_SECRET !== undefined + ? process.env.STRIPE_WEBHOOK_SECRET + : (() => { + throw new Error('Missing STRIPE_WEBHOOK_SECRET'); + })(), ); switch (event.type) { diff --git a/apps/app-server/src/index.ts b/apps/app-server/src/index.ts index 00d65830..59d7243c 100644 --- a/apps/app-server/src/index.ts +++ b/apps/app-server/src/index.ts @@ -7,7 +7,13 @@ import { fastify } from './fastify/server'; void fastify().then(async (fastify) => { await fastify.listen({ - port: parseInt(process.env.APP_SERVER_PORT), + port: parseInt( + process.env.APP_SERVER_PORT !== undefined + ? process.env.APP_SERVER_PORT + : (() => { + throw new Error('Missing APP_SERVER_PORT'); + })(), + ), host: '0.0.0.0', }); diff --git a/apps/app-server/src/stripe.ts b/apps/app-server/src/stripe.ts index 24ade7fd..09030f5c 100644 --- a/apps/app-server/src/stripe.ts +++ b/apps/app-server/src/stripe.ts @@ -1,6 +1,13 @@ import Stripe from 'stripe'; -export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { - apiVersion: '2023-10-16', - maxNetworkRetries: 2, -}); +export const stripe = new Stripe( + process.env.STRIPE_SECRET_KEY !== undefined + ? process.env.STRIPE_SECRET_KEY + : (() => { + throw new Error('Missing STRIPE_SECRET_KEY'); + })(), + { + apiVersion: '2023-10-16', + maxNetworkRetries: 2, + }, +); diff --git a/apps/app-server/src/trpc/api/sessions/start-demo.ts b/apps/app-server/src/trpc/api/sessions/start-demo.ts index 649c8f2f..cb460319 100644 --- a/apps/app-server/src/trpc/api/sessions/start-demo.ts +++ b/apps/app-server/src/trpc/api/sessions/start-demo.ts @@ -23,7 +23,7 @@ export async function startDemo({ // Generate random password values const passwordValues = { - hash: sodium.randombytes_buf(64), + hash: sodium.randombytes_buf(64) as Uint8Array, key: wrapSymmetricKey(sodium.randombytes_buf(32)), salt: new Uint8Array(sodium.randombytes_buf(16)), }; diff --git a/apps/app-server/src/utils/crypto.ts b/apps/app-server/src/utils/crypto.ts index 11ea3f3d..5b3711ba 100644 --- a/apps/app-server/src/utils/crypto.ts +++ b/apps/app-server/src/utils/crypto.ts @@ -69,7 +69,13 @@ export function getDeviceHash(input: { // User rehashed login hash const _userRehashedLoginHashEncryptionKey = wrapSymmetricKey( - base64ToBytes(process.env.USER_REHASHED_LOGIN_HASH_ENCRYPTION_KEY), + base64ToBytes( + process.env.USER_REHASHED_LOGIN_HASH_ENCRYPTION_KEY !== undefined + ? process.env.USER_REHASHED_LOGIN_HASH_ENCRYPTION_KEY + : (() => { + throw new Error('Missing USER_REHASHED_LOGIN_HASH_ENCRYPTION_KEY'); + })(), + ), ); export function encryptUserRehashedLoginHash(userRehashedLoginHash: string) { return _userRehashedLoginHashEncryptionKey.encrypt( @@ -91,7 +97,15 @@ export function decryptUserRehashedLoginHash( // Group rehashed password hash const _groupRehashedPasswordHashEncryptionKey = wrapSymmetricKey( - base64ToBytes(process.env.GROUP_REHASHED_PASSWORD_HASH_ENCRYPTION_KEY), + base64ToBytes( + process.env.GROUP_REHASHED_PASSWORD_HASH_ENCRYPTION_KEY !== undefined + ? process.env.GROUP_REHASHED_PASSWORD_HASH_ENCRYPTION_KEY + : (() => { + throw new Error( + 'Missing GROUP_REHASHED_PASSWORD_HASH_ENCRYPTION_KEY', + ); + })(), + ), ); export function encryptGroupRehashedPasswordHash( groupRehashedPasswordHash: string, @@ -115,7 +129,13 @@ export function decryptGroupRehashedPasswordHash( // User authenticator secret const _userAuthenticatorSecretEncryptionKey = wrapSymmetricKey( - base64ToBytes(process.env.USER_AUTHENTICATOR_SECRET_ENCRYPTION_KEY), + base64ToBytes( + process.env.USER_AUTHENTICATOR_SECRET_ENCRYPTION_KEY !== undefined + ? process.env.USER_AUTHENTICATOR_SECRET_ENCRYPTION_KEY + : (() => { + throw new Error('Missing USER_AUTHENTICATOR_SECRET_ENCRYPTION_KEY'); + })(), + ), ); export function encryptUserAuthenticatorSecret( userAuthenticatorSecret: string, @@ -139,7 +159,13 @@ export function decryptUserAuthenticatorSecret( // User recovery codes const _userRecoveryCodesEncryptionKey = wrapSymmetricKey( - base64ToBytes(process.env.USER_RECOVERY_CODES_ENCRYPTION_KEY), + base64ToBytes( + process.env.USER_RECOVERY_CODES_ENCRYPTION_KEY !== undefined + ? process.env.USER_RECOVERY_CODES_ENCRYPTION_KEY + : (() => { + throw new Error('Missing USER_RECOVERY_CODES_ENCRYPTION_KEY'); + })(), + ), ); export function encryptRecoveryCodes(userRecoveryCodes: Uint8Array[]) { return _userRecoveryCodesEncryptionKey.encrypt(pack(userRecoveryCodes), { diff --git a/apps/client/package.json b/apps/client/package.json index 3cdaaf5d..7ac88120 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -81,7 +81,7 @@ "prosemirror-state": "~1.4.3", "prosemirror-view": "~1.29.2", "qrcode": "^1.5.3", - "quasar": "npm:@deepnotes/quasar@^2.13.2", + "quasar": "^2.18.2", "serialize-javascript": "^6.0.1", "showdown": "^2.1.0", "superjson": "npm:@deepnotes/superjson@^1.12.4", diff --git a/apps/client/quasar.config.js b/apps/client/quasar.config.js index 9be36d5f..5d892899 100644 --- a/apps/client/quasar.config.js +++ b/apps/client/quasar.config.js @@ -98,7 +98,8 @@ module.exports = configure(function (ctx) { // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build build: { target: { - browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'], + // browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'], + browser: ['es2020'], node: 'node16', }, diff --git a/apps/client/src-capacitor/pnpm-lock.yaml b/apps/client/src-capacitor/pnpm-lock.yaml deleted file mode 100644 index a4b77993..00000000 --- a/apps/client/src-capacitor/pnpm-lock.yaml +++ /dev/null @@ -1,609 +0,0 @@ -lockfileVersion: 5.4 - -specifiers: - '@capacitor/app': ^1.0.0 - '@capacitor/cli': ^3.0.0 - '@capacitor/core': ^3.0.0 - '@capacitor/splash-screen': ^1.0.0 - -dependencies: - '@capacitor/app': 1.1.1_@capacitor+core@3.9.0 - '@capacitor/cli': 3.9.0 - '@capacitor/core': 3.9.0 - '@capacitor/splash-screen': 1.2.2_@capacitor+core@3.9.0 - -packages: - - /@capacitor/app/1.1.1_@capacitor+core@3.9.0: - resolution: {integrity: sha512-8ADkldHnoE1xkWvPUsGlERVGm6/Zvcxy6hCI80AxydIKyaCG7kbDAvUclebbnw/eFRxj2zBoVatGLjmJNvTbYw==} - peerDependencies: - '@capacitor/core': ^3.0.0 - dependencies: - '@capacitor/core': 3.9.0 - dev: false - - /@capacitor/cli/3.9.0: - resolution: {integrity: sha512-NkbVZhYb0oPdh/XArE2ZmOwPFJbla5meShGhv3DxKCXeKn1rt92ile+2xOgtB/j+mL7f9cqQzTQM/11sGQzMAg==} - engines: {node: '>=12.4.0'} - hasBin: true - dependencies: - '@ionic/cli-framework-output': 2.2.5 - '@ionic/utils-fs': 3.1.6 - '@ionic/utils-subprocess': 2.1.11 - '@ionic/utils-terminal': 2.3.3 - commander: 6.2.1 - debug: 4.3.4 - env-paths: 2.2.1 - kleur: 4.1.5 - native-run: 1.7.1 - open: 7.4.2 - plist: 3.0.6 - prompts: 2.4.2 - semver: 7.3.8 - tar: 6.1.11 - tslib: 2.4.0 - xml2js: 0.4.23 - transitivePeerDependencies: - - supports-color - dev: false - - /@capacitor/core/3.9.0: - resolution: {integrity: sha512-j1lL0+/7stY8YhIq1Lm6xixvUqIn89vtyH5ZpJNNmcZ0kwz6K9eLkcG6fvq1UWMDgSVZg9JrRGSFhb4LLoYOsw==} - dependencies: - tslib: 2.4.0 - dev: false - - /@capacitor/splash-screen/1.2.2_@capacitor+core@3.9.0: - resolution: {integrity: sha512-iGh9gc0rdS3R+Wr+bD/+tJl3qbmJZ5xVQAP5UsD6U6Y3ydCBo9KpA8DEqxaBZVsCDaLt67009hK5nxKBwjRn7Q==} - peerDependencies: - '@capacitor/core': ^3.0.0 - dependencies: - '@capacitor/core': 3.9.0 - dev: false - - /@ionic/cli-framework-output/2.2.5: - resolution: {integrity: sha512-YeDLTnTaE6V4IDUxT8GDIep0GuRIFaR7YZDLANMuuWJZDmnTku6DP+MmQoltBeLmVvz1BAAZgk41xzxdq6H2FQ==} - engines: {node: '>=10.3.0'} - dependencies: - '@ionic/utils-terminal': 2.3.3 - debug: 4.3.4 - tslib: 2.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@ionic/utils-array/2.1.5: - resolution: {integrity: sha512-HD72a71IQVBmQckDwmA8RxNVMTbxnaLbgFOl+dO5tbvW9CkkSFCv41h6fUuNsSEVgngfkn0i98HDuZC8mk+lTA==} - engines: {node: '>=10.3.0'} - dependencies: - debug: 4.3.4 - tslib: 2.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@ionic/utils-fs/3.1.6: - resolution: {integrity: sha512-eikrNkK89CfGPmexjTfSWl4EYqsPSBh0Ka7by4F0PLc1hJZYtJxUZV3X4r5ecA8ikjicUmcbU7zJmAjmqutG/w==} - engines: {node: '>=10.3.0'} - dependencies: - '@types/fs-extra': 8.1.2 - debug: 4.3.4 - fs-extra: 9.1.0 - tslib: 2.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@ionic/utils-object/2.1.5: - resolution: {integrity: sha512-XnYNSwfewUqxq+yjER1hxTKggftpNjFLJH0s37jcrNDwbzmbpFTQTVAp4ikNK4rd9DOebX/jbeZb8jfD86IYxw==} - engines: {node: '>=10.3.0'} - dependencies: - debug: 4.3.4 - tslib: 2.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@ionic/utils-process/2.1.10: - resolution: {integrity: sha512-mZ7JEowcuGQK+SKsJXi0liYTcXd2bNMR3nE0CyTROpMECUpJeAvvaBaPGZf5ERQUPeWBVuwqAqjUmIdxhz5bxw==} - engines: {node: '>=10.3.0'} - dependencies: - '@ionic/utils-object': 2.1.5 - '@ionic/utils-terminal': 2.3.3 - debug: 4.3.4 - signal-exit: 3.0.7 - tree-kill: 1.2.2 - tslib: 2.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@ionic/utils-stream/3.1.5: - resolution: {integrity: sha512-hkm46uHvEC05X/8PHgdJi4l4zv9VQDELZTM+Kz69odtO9zZYfnt8DkfXHJqJ+PxmtiE5mk/ehJWLnn/XAczTUw==} - engines: {node: '>=10.3.0'} - dependencies: - debug: 4.3.4 - tslib: 2.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@ionic/utils-subprocess/2.1.11: - resolution: {integrity: sha512-6zCDixNmZCbMCy5np8klSxOZF85kuDyzZSTTQKQP90ZtYNCcPYmuFSzaqDwApJT4r5L3MY3JrqK1gLkc6xiUPw==} - engines: {node: '>=10.3.0'} - dependencies: - '@ionic/utils-array': 2.1.5 - '@ionic/utils-fs': 3.1.6 - '@ionic/utils-process': 2.1.10 - '@ionic/utils-stream': 3.1.5 - '@ionic/utils-terminal': 2.3.3 - cross-spawn: 7.0.3 - debug: 4.3.4 - tslib: 2.4.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@ionic/utils-terminal/2.3.3: - resolution: {integrity: sha512-RnuSfNZ5fLEyX3R5mtcMY97cGD1A0NVBbarsSQ6yMMfRJ5YHU7hHVyUfvZeClbqkBC/pAqI/rYJuXKCT9YeMCQ==} - engines: {node: '>=10.3.0'} - dependencies: - '@types/slice-ansi': 4.0.0 - debug: 4.3.4 - signal-exit: 3.0.7 - slice-ansi: 4.0.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - tslib: 2.4.0 - untildify: 4.0.0 - wrap-ansi: 7.0.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@types/fs-extra/8.1.2: - resolution: {integrity: sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==} - dependencies: - '@types/node': 18.11.7 - dev: false - - /@types/node/18.11.7: - resolution: {integrity: sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==} - dev: false - - /@types/slice-ansi/4.0.0: - resolution: {integrity: sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==} - dev: false - - /ansi-regex/5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: false - - /ansi-styles/4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: false - - /astral-regex/2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - dev: false - - /at-least-node/1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - dev: false - - /base64-js/1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false - - /big-integer/1.6.51: - resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} - engines: {node: '>=0.6'} - dev: false - - /bplist-parser/0.3.2: - resolution: {integrity: sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==} - engines: {node: '>= 5.10.0'} - dependencies: - big-integer: 1.6.51 - dev: false - - /buffer-crc32/0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - dev: false - - /chownr/2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - dev: false - - /color-convert/2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: false - - /color-name/1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: false - - /commander/6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} - dev: false - - /cross-spawn/7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: false - - /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: false - - /elementtree/0.1.7: - resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==} - engines: {node: '>= 0.4.0'} - dependencies: - sax: 1.1.4 - dev: false - - /emoji-regex/8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: false - - /env-paths/2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - dev: false - - /fd-slicer/1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - dependencies: - pend: 1.2.0 - dev: false - - /fs-extra/9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.10 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: false - - /fs-minipass/2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: false - - /graceful-fs/4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: false - - /inherits/2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: false - - /ini/3.0.1: - resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dev: false - - /is-docker/2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: false - - /is-fullwidth-code-point/3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: false - - /is-wsl/2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - dev: false - - /isexe/2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: false - - /jsonfile/6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.10 - dev: false - - /kleur/3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: false - - /kleur/4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - dev: false - - /lru-cache/6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: false - - /minipass/3.3.4: - resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} - engines: {node: '>=8'} - dependencies: - yallist: 4.0.0 - dev: false - - /minizlib/2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - yallist: 4.0.0 - dev: false - - /mkdirp/1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: false - - /ms/2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: false - - /native-run/1.7.1: - resolution: {integrity: sha512-70ZneVVcOL1ifqw7SG5O2AJYIHEBSX5C25ShwwKCcdMcgbZ+MzvAc2fjHzfekcPYtInHqcJQOki6NXj9f6LgOg==} - engines: {node: '>=12.13.0'} - hasBin: true - dependencies: - '@ionic/utils-fs': 3.1.6 - '@ionic/utils-terminal': 2.3.3 - bplist-parser: 0.3.2 - debug: 4.3.4 - elementtree: 0.1.7 - ini: 3.0.1 - plist: 3.0.6 - split2: 4.1.0 - through2: 4.0.2 - tslib: 2.4.0 - yauzl: 2.10.0 - transitivePeerDependencies: - - supports-color - dev: false - - /open/7.4.2: - resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - is-wsl: 2.2.0 - dev: false - - /path-key/3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: false - - /pend/1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - dev: false - - /plist/3.0.6: - resolution: {integrity: sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==} - engines: {node: '>=6'} - dependencies: - base64-js: 1.5.1 - xmlbuilder: 15.1.1 - dev: false - - /prompts/2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: false - - /readable-stream/3.6.0: - resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} - engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: false - - /safe-buffer/5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false - - /sax/1.1.4: - resolution: {integrity: sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==} - dev: false - - /sax/1.2.4: - resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} - dev: false - - /semver/7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: false - - /shebang-command/2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: false - - /shebang-regex/3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: false - - /signal-exit/3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: false - - /sisteransi/1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: false - - /slice-ansi/4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: false - - /split2/4.1.0: - resolution: {integrity: sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==} - engines: {node: '>= 10.x'} - dev: false - - /string-width/4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: false - - /string_decoder/1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /strip-ansi/6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: false - - /tar/6.1.11: - resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} - engines: {node: '>= 10'} - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 3.3.4 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: false - - /through2/4.0.2: - resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} - dependencies: - readable-stream: 3.6.0 - dev: false - - /tree-kill/1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - dev: false - - /tslib/2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} - dev: false - - /universalify/2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: false - - /untildify/4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: false - - /util-deprecate/1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: false - - /which/2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: false - - /wrap-ansi/7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: false - - /xml2js/0.4.23: - resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==} - engines: {node: '>=4.0.0'} - dependencies: - sax: 1.2.4 - xmlbuilder: 11.0.1 - dev: false - - /xmlbuilder/11.0.1: - resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} - engines: {node: '>=4.0'} - dev: false - - /xmlbuilder/15.1.1: - resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} - engines: {node: '>=8.0'} - dev: false - - /yallist/4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: false - - /yauzl/2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - dev: false diff --git a/apps/client/src/code/pages/page/arrows/arrow.ts b/apps/client/src/code/pages/page/arrows/arrow.ts index 345b17aa..412705d6 100644 --- a/apps/client/src/code/pages/page/arrows/arrow.ts +++ b/apps/client/src/code/pages/page/arrows/arrow.ts @@ -264,16 +264,16 @@ export const PageArrow = once( this.react.looseEndpoint === 'source' && this.react.sourceNote == null ? new Vec2(1) - : this.react.sourceNote.react.relativeRect.halfSize ?? - new Vec2(1); + : (this.react.sourceNote.react.relativeRect.halfSize ?? + new Vec2(1)); const targetSize = this.react.fakePos != null && this.react.looseEndpoint === 'target' && this.react.targetNote == null ? new Vec2(1) - : this.react.targetNote.react.relativeRect.halfSize ?? - new Vec2(1); + : (this.react.targetNote.react.relativeRect.halfSize ?? + new Vec2(1)); return { source: sourceSize, target: targetSize }; }), @@ -364,13 +364,13 @@ export const PageArrow = once( targetHeadPos: computed(() => { if (this.react.collab.bodyType === 'line') { return this.react.targetNote != null - ? getLineRectIntersection( + ? (getLineRectIntersection( new Line(this.react.sourcePos, this.react.targetPos), (this.react.interregional ? this.react.targetNote.react.islandRect : this.react.targetNote.react.relativeRect ).grow(new Vec2(ARROW_OFFSET)), - ) ?? this.react.targetPos + ) ?? this.react.targetPos) : this.react.targetPos; } else { return this.react.targetPos.add( diff --git a/apps/client/src/code/utils/misc.ts b/apps/client/src/code/utils/misc.ts index 3263b924..44ff91ff 100644 --- a/apps/client/src/code/utils/misc.ts +++ b/apps/client/src/code/utils/misc.ts @@ -31,10 +31,10 @@ export function handleError(error: any, logger = mainLogger) { $quasar().notify({ message: isString(error) ? error - : error.response?.data?.errors?.[0]?.message ?? + : (error.response?.data?.errors?.[0]?.message ?? error.response?.data?.message ?? error.message ?? - 'An error has occurred.', + 'An error has occurred.'), type: 'negative', }); diff --git a/apps/client/src/code/utils/scroll-into-view.ts b/apps/client/src/code/utils/scroll-into-view.ts index 28882750..45271bd3 100644 --- a/apps/client/src/code/utils/scroll-into-view.ts +++ b/apps/client/src/code/utils/scroll-into-view.ts @@ -37,14 +37,14 @@ export function scrollIntoView( targetRect.x < ancestorRect.x ? targetRect.x - ancestorRect.x : targetRect.right > ancestorClientRight - ? targetRect.right - ancestorClientRight - : 0; + ? targetRect.right - ancestorClientRight + : 0; let offsetY = targetRect.y < ancestorRect.y ? targetRect.y - ancestorRect.y : targetRect.bottom > ancestorClientBottom - ? targetRect.bottom - ancestorClientBottom - : 0; + ? targetRect.bottom - ancestorClientBottom + : 0; // Clamp offset diff --git a/apps/client/src/components/EvaluatedPasswordField.vue b/apps/client/src/components/EvaluatedPasswordField.vue index 96599afb..f98ec8f5 100644 --- a/apps/client/src/components/EvaluatedPasswordField.vue +++ b/apps/client/src/components/EvaluatedPasswordField.vue @@ -23,12 +23,12 @@ passwordStrength === 0 ? '#f95e68' : passwordStrength === 1 - ? '#fb964d' - : passwordStrength === 2 - ? '#fdd244' - : passwordStrength === 3 - ? '#b0dc53' - : '#35cc62', + ? '#fb964d' + : passwordStrength === 2 + ? '#fdd244' + : passwordStrength === 3 + ? '#b0dc53' + : '#35cc62', }" > diff --git a/apps/client/src/components/ToolbarBtn.vue b/apps/client/src/components/ToolbarBtn.vue index 1df4cde4..3357d7ed 100644 --- a/apps/client/src/components/ToolbarBtn.vue +++ b/apps/client/src/components/ToolbarBtn.vue @@ -6,7 +6,7 @@ :round="round" style="padding: 0; margin: 4px 0px" :style="{ - 'min-width': round ? undefined : btnSize ?? '28px', + 'min-width': round ? undefined : (btnSize ?? '28px'), height: btnSize ?? '28px', width: btnSize ?? '28px', }" diff --git a/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteAnchor.vue b/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteAnchor.vue index f06c1dc3..81678995 100644 --- a/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteAnchor.vue +++ b/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteAnchor.vue @@ -14,13 +14,13 @@ left: note.react.resizing?.active ? `${note.react.resizing.newWorldRect.topLeft.x}px` : note.react.floating - ? `${note.react.collab?.pos?.x}px` - : undefined, + ? `${note.react.collab?.pos?.x}px` + : undefined, top: note.react.resizing?.active ? `${note.react.resizing.newWorldRect.topLeft.y}px` : note.react.floating - ? `${note.react.collab?.pos?.y}px` - : undefined, + ? `${note.react.collab?.pos?.y}px` + : undefined, width: note.react.floating || note.react.resizing?.active ? '0' : undefined, diff --git a/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeBar.vue b/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeBar.vue index 83b0e573..132143ef 100644 --- a/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeBar.vue +++ b/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeBar.vue @@ -60,8 +60,8 @@ const section = computed( (props.side.includes('n') ? note.react.topSection : props.side.includes('s') - ? note.react.bottomSection - : undefined), + ? note.react.bottomSection + : undefined), ); async function onLeftPointerDown(event: PointerEvent) { diff --git a/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeHandle.vue b/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeHandle.vue index fd3f5484..ac0089c1 100644 --- a/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeHandle.vue +++ b/apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteResizeHandles/NoteResizeHandle.vue @@ -11,13 +11,13 @@ left: props.side.includes('w') ? '0%' : props.side.includes('e') - ? '100%' - : '50%', + ? '100%' + : '50%', top: props.side.includes('n') ? '0%' : props.side.includes('s') - ? '100%' - : '50%', + ? '100%' + : '50%', cursor: `${side}-resize`, @@ -51,8 +51,8 @@ const section = computed( (props.side.includes('n') ? note.react.topSection : props.side.includes('s') - ? note.react.bottomSection - : undefined), + ? note.react.bottomSection + : undefined), ); async function onLeftPointerDown(event: PointerEvent) { diff --git a/apps/client/src/layouts/PagesLayout/MainToolbar/ObjectBtns.vue b/apps/client/src/layouts/PagesLayout/MainToolbar/ObjectBtns.vue index 9dff848e..c8a28d83 100644 --- a/apps/client/src/layouts/PagesLayout/MainToolbar/ObjectBtns.vue +++ b/apps/client/src/layouts/PagesLayout/MainToolbar/ObjectBtns.vue @@ -77,27 +77,29 @@ icon-size="24px" :disable="page.react.readOnly || !page.editing.react.active" @click=" - $q.dialog({ - title: 'Insert YouTube video', - message: 'Enter the video URL:', - - prompt: { - type: 'url', - model: '', - filled: true, - }, - color: 'primary', - - cancel: { flat: true, color: 'negative' }, - - focus: 'cancel', - }).onOk((url: string) => - page.selection.format((chain) => - chain.setYoutubeVideo({ - src: url, - }), - ), - ) + $q + .dialog({ + title: 'Insert YouTube video', + message: 'Enter the video URL:', + + prompt: { + type: 'url', + model: '', + filled: true, + }, + color: 'primary', + + cancel: { flat: true, color: 'negative' }, + + focus: 'cancel', + }) + .onOk((url: string) => + page.selection.format((chain) => + chain.setYoutubeVideo({ + src: url, + }), + ), + ) " /> diff --git a/apps/client/src/pages/home/Account/Security/TwoFactorAuth/RecoveryCodeDialog.vue b/apps/client/src/pages/home/Account/Security/TwoFactorAuth/RecoveryCodeDialog.vue index 9aeb3c65..5a529fb7 100644 --- a/apps/client/src/pages/home/Account/Security/TwoFactorAuth/RecoveryCodeDialog.vue +++ b/apps/client/src/pages/home/Account/Security/TwoFactorAuth/RecoveryCodeDialog.vue @@ -183,7 +183,8 @@ function printRecoveryCodes() {