Merge branch 'TriliumNext:develop' into develop
							
								
								
									
										19
									
								
								.github/workflows/dev.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -37,6 +37,23 @@ jobs: | |||||||
|           context: . |           context: . | ||||||
|           cache-from: type=gha |           cache-from: type=gha | ||||||
|           cache-to: type=gha,mode=max |           cache-to: type=gha,mode=max | ||||||
|  |   test_dev: | ||||||
|  |     name: Test development | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout the repository | ||||||
|  |         uses: actions/checkout@v4 | ||||||
|  | 
 | ||||||
|  |       - name: Set up node & dependencies | ||||||
|  |         uses: actions/setup-node@v4 | ||||||
|  |         with: | ||||||
|  |           node-version: 20 | ||||||
|  |           cache: "npm" | ||||||
|  | 
 | ||||||
|  |       - run: npm ci | ||||||
|  | 
 | ||||||
|  |       - name: Run the TypeScript build | ||||||
|  |         run: npx tsc | ||||||
|   test_docker: |   test_docker: | ||||||
|     name: Check Docker build |     name: Check Docker build | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
| @ -87,7 +104,7 @@ jobs: | |||||||
|           echo "Container ID: $CONTAINER_ID" |           echo "Container ID: $CONTAINER_ID" | ||||||
|        |        | ||||||
|       - name: Wait for the healthchecks to pass |       - name: Wait for the healthchecks to pass | ||||||
|         uses: stringbean/docker-healthcheck-action@v1 |         uses: stringbean/docker-healthcheck-action@v3 | ||||||
|         with: |         with: | ||||||
|           container: trilium_local |           container: trilium_local | ||||||
|           wait-time: 50 |           wait-time: 50 | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								.github/workflows/main-docker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -72,7 +72,7 @@ jobs: | |||||||
|           echo "Container ID: $CONTAINER_ID" |           echo "Container ID: $CONTAINER_ID" | ||||||
|        |        | ||||||
|       - name: Wait for the healthchecks to pass |       - name: Wait for the healthchecks to pass | ||||||
|         uses: stringbean/docker-healthcheck-action@v1 |         uses: stringbean/docker-healthcheck-action@v3 | ||||||
|         with: |         with: | ||||||
|           container: trilium_local |           container: trilium_local | ||||||
|           wait-time: 50 |           wait-time: 50 | ||||||
| @ -120,7 +120,7 @@ jobs: | |||||||
|         uses: actions/checkout@v4 |         uses: actions/checkout@v4 | ||||||
|       - name: Docker meta |       - name: Docker meta | ||||||
|         id: meta |         id: meta | ||||||
|         uses: docker/metadata-action@v4 |         uses: docker/metadata-action@v5 | ||||||
|         with: |         with: | ||||||
|           images: | |           images: | | ||||||
|             ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} |             ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} | ||||||
| @ -151,14 +151,14 @@ jobs: | |||||||
|         run: cat package.json | grep -v electron > server-package.json |         run: cat package.json | grep -v electron > server-package.json | ||||||
| 
 | 
 | ||||||
|       - name: Login to GHCR |       - name: Login to GHCR | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           registry: ${{ env.GHCR_REGISTRY }} |           registry: ${{ env.GHCR_REGISTRY }} | ||||||
|           username: ${{ github.actor }} |           username: ${{ github.actor }} | ||||||
|           password: ${{ secrets.GITHUB_TOKEN }} |           password: ${{ secrets.GITHUB_TOKEN }} | ||||||
|        |        | ||||||
|       - name: Login to DockerHub |       - name: Login to DockerHub | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           registry: ${{ env.DOCKERHUB_REGISTRY }} |           registry: ${{ env.DOCKERHUB_REGISTRY }} | ||||||
|           username: ${{ secrets.DOCKERHUB_USERNAME }} |           username: ${{ secrets.DOCKERHUB_USERNAME }} | ||||||
| @ -210,7 +210,7 @@ jobs: | |||||||
|        |        | ||||||
|       - name: Docker meta |       - name: Docker meta | ||||||
|         id: meta |         id: meta | ||||||
|         uses: docker/metadata-action@v4 |         uses: docker/metadata-action@v5 | ||||||
|         with: |         with: | ||||||
|           images: | |           images: | | ||||||
|             ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} |             ${{ env.GHCR_REGISTRY }}/${{ env.IMAGE_NAME }} | ||||||
| @ -219,14 +219,14 @@ jobs: | |||||||
|             latest=false |             latest=false | ||||||
| 
 | 
 | ||||||
|       - name: Login to GHCR |       - name: Login to GHCR | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           registry: ${{ env.GHCR_REGISTRY }} |           registry: ${{ env.GHCR_REGISTRY }} | ||||||
|           username: ${{ github.actor }} |           username: ${{ github.actor }} | ||||||
|           password: ${{ secrets.GITHUB_TOKEN }} |           password: ${{ secrets.GITHUB_TOKEN }} | ||||||
|        |        | ||||||
|       - name: Login to DockerHub |       - name: Login to DockerHub | ||||||
|         uses: docker/login-action@v2 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           registry: ${{ env.DOCKERHUB_REGISTRY }} |           registry: ${{ env.DOCKERHUB_REGISTRY }} | ||||||
|           username: ${{ secrets.DOCKERHUB_USERNAME }} |           username: ${{ secrets.DOCKERHUB_USERNAME }} | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								.github/workflows/nightly.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -75,7 +75,7 @@ jobs: | |||||||
|           overwrite: true |           overwrite: true | ||||||
| 
 | 
 | ||||||
|       - name: Deploy release |       - name: Deploy release | ||||||
|         uses: WebFreak001/deploy-nightly@v3.1.0 |         uses: WebFreak001/deploy-nightly@v3.2.0 | ||||||
|         with: |         with: | ||||||
|           upload_url: ${{ env.GITHUB_UPLOAD_URL }} |           upload_url: ${{ env.GITHUB_UPLOAD_URL }} | ||||||
|           release_id: ${{ env.GITHUB_RELEASE_ID }} |           release_id: ${{ env.GITHUB_RELEASE_ID }} | ||||||
| @ -83,7 +83,7 @@ jobs: | |||||||
|           asset_name: TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-nightly.zip # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash |           asset_name: TriliumNextNotes-${{ matrix.os.name }}-${{ matrix.arch }}-nightly.zip # name to upload the release as, use $$ to insert date (YYYYMMDD) and 6 letter commit hash | ||||||
|           asset_content_type: application/zip # required by GitHub API |           asset_content_type: application/zip # required by GitHub API | ||||||
|       - name: Deploy installer release |       - name: Deploy installer release | ||||||
|         uses: WebFreak001/deploy-nightly@v3.1.0 |         uses: WebFreak001/deploy-nightly@v3.2.0 | ||||||
|         with: |         with: | ||||||
|           upload_url: ${{ env.GITHUB_UPLOAD_URL }} |           upload_url: ${{ env.GITHUB_UPLOAD_URL }} | ||||||
|           release_id: ${{ env.GITHUB_RELEASE_ID }} |           release_id: ${{ env.GITHUB_RELEASE_ID }} | ||||||
| @ -120,7 +120,7 @@ jobs: | |||||||
|           overwrite: true |           overwrite: true | ||||||
| 
 | 
 | ||||||
|       - name: Deploy release |       - name: Deploy release | ||||||
|         uses: WebFreak001/deploy-nightly@v3.1.0 |         uses: WebFreak001/deploy-nightly@v3.2.0 | ||||||
|         with: |         with: | ||||||
|           upload_url: ${{ env.GITHUB_UPLOAD_URL }} |           upload_url: ${{ env.GITHUB_UPLOAD_URL }} | ||||||
|           release_id: ${{ env.GITHUB_RELEASE_ID }} |           release_id: ${{ env.GITHUB_RELEASE_ID }} | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -21,4 +21,7 @@ | |||||||
|     "github-actions.workflows.pinned.workflows": [ |     "github-actions.workflows.pinned.workflows": [ | ||||||
|         ".github/workflows/nightly.yml" |         ".github/workflows/nightly.yml" | ||||||
|     ], |     ], | ||||||
|  |     "[css]": { | ||||||
|  |         "editor.defaultFormatter": "vscode.css-language-features" | ||||||
|  |     }, | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -1,17 +0,0 @@ | |||||||
| { |  | ||||||
|     "version": "2.0.0", |  | ||||||
|     "tasks": [ |  | ||||||
|       { |  | ||||||
|         "type": "npm", |  | ||||||
|         "script": "errors", |  | ||||||
|         "problemMatcher": "$tsc-watch", |  | ||||||
|         "isBackground": true, |  | ||||||
|         "presentation": { |  | ||||||
|           "revealProblems": "never" |  | ||||||
|         }, |  | ||||||
|         "runOptions": { |  | ||||||
|           "runOn": "folderOpen" |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     ] |  | ||||||
|   } |  | ||||||
| @ -1,5 +1,5 @@ | |||||||
| # Build stage | # Build stage | ||||||
| FROM node:20.15.1-bullseye-slim AS builder | FROM node:22.12.0-bullseye-slim AS builder | ||||||
| 
 | 
 | ||||||
| # Configure build dependencies in a single layer | # Configure build dependencies in a single layer | ||||||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | RUN apt-get update && apt-get install -y --no-install-recommends \ | ||||||
| @ -35,7 +35,7 @@ RUN cp -R build/src/* src/. && \ | |||||||
|     rm src/services/asset_path.ts |     rm src/services/asset_path.ts | ||||||
| 
 | 
 | ||||||
| # Runtime stage | # Runtime stage | ||||||
| FROM node:20.15.1-bullseye-slim | FROM node:22.12.0-bullseye-slim | ||||||
| 
 | 
 | ||||||
| # Install only runtime dependencies | # Install only runtime dependencies | ||||||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | RUN apt-get update && apt-get install -y --no-install-recommends \ | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| # Build stage | # Build stage | ||||||
| FROM node:20.15.1-alpine AS builder | FROM node:22.12.0-alpine AS builder | ||||||
| 
 | 
 | ||||||
| # Configure build dependencies | # Configure build dependencies | ||||||
| RUN apk add --no-cache --virtual .build-dependencies \ | RUN apk add --no-cache --virtual .build-dependencies \ | ||||||
| @ -34,7 +34,7 @@ RUN cp -R build/src/* src/. && \ | |||||||
|     rm src/services/asset_path.ts |     rm src/services/asset_path.ts | ||||||
| 
 | 
 | ||||||
| # Runtime stage | # Runtime stage | ||||||
| FROM node:20.15.1-alpine | FROM node:22.12.0-alpine | ||||||
| 
 | 
 | ||||||
| # Install runtime dependencies | # Install runtime dependencies | ||||||
| RUN apk add --no-cache su-exec shadow | RUN apk add --no-cache su-exec shadow | ||||||
|  | |||||||
| @ -114,7 +114,7 @@ Head on over to our [Docs repo](https://github.com/TriliumNext/Docs) | |||||||
| * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team | * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team | ||||||
| * [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it. | * [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it. | ||||||
| * [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages | * [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages | ||||||
| * [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/Relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/Link-map) | * [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map) | ||||||
| 
 | 
 | ||||||
| ## 🤝 Support | ## 🤝 Support | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -64,7 +64,8 @@ const copy = async () => { | |||||||
|     "node_modules/katex/dist/katex.min.js", |     "node_modules/katex/dist/katex.min.js", | ||||||
|     "node_modules/katex/dist/contrib/mhchem.min.js", |     "node_modules/katex/dist/contrib/mhchem.min.js", | ||||||
|     "node_modules/katex/dist/contrib/auto-render.min.js", |     "node_modules/katex/dist/contrib/auto-render.min.js", | ||||||
|     "node_modules/@highlightjs/cdn-assets/highlight.min.js" |     "node_modules/@highlightjs/cdn-assets/highlight.min.js", | ||||||
|  |     "node_modules/@mind-elixir/node-menu/dist/node-menu.umd.cjs", | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   for (const file of nodeModulesFile) { |   for (const file of nodeModulesFile) { | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ cp -R "$script_dir/../build/src" "$DIR" | |||||||
| cp "$script_dir/../build/electron-main.js" "$DIR" | cp "$script_dir/../build/electron-main.js" "$DIR" | ||||||
| 
 | 
 | ||||||
| # run in subshell (so we return to original dir) | # run in subshell (so we return to original dir) | ||||||
| (cd $DIR && npm install --omit=dev) | (cd $DIR && npm install --omit=dev --legacy-peer-deps) | ||||||
| 
 | 
 | ||||||
| if [[ -d "$DIR"/node_modules ]]; then | if [[ -d "$DIR"/node_modules ]]; then | ||||||
|     # cleanup of useless files in dependencies |     # cleanup of useless files in dependencies | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								bin/watch-dist.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,18 @@ | |||||||
|  | import chokidar from "chokidar"; | ||||||
|  | import fs from "fs"; | ||||||
|  | import path from "path"; | ||||||
|  | 
 | ||||||
|  | const emptyCallback = () => {}; | ||||||
|  | 
 | ||||||
|  | function onFileChanged(sourceFile: string) { | ||||||
|  |     const destFile = path.join("dist", sourceFile); | ||||||
|  |     console.log(`${sourceFile} -> ${destFile}`); | ||||||
|  |     fs.copyFile(sourceFile, destFile, emptyCallback); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const sourceDir = "src/public"; | ||||||
|  | 
 | ||||||
|  | chokidar | ||||||
|  |     .watch(sourceDir) | ||||||
|  |     .on("change", onFileChanged); | ||||||
|  | console.log(`Watching for changes to ${sourceDir}...`); | ||||||
							
								
								
									
										
											BIN
										
									
								
								db/demo.zip
									
									
									
									
									
								
							
							
						
						| @ -13,7 +13,9 @@ services: | |||||||
|     ports: |     ports: | ||||||
|       # By default, Trilium will be available at http://localhost:8080 |       # By default, Trilium will be available at http://localhost:8080 | ||||||
|       # It will also be accessible at http://<host-ip>:8080 |       # It will also be accessible at http://<host-ip>:8080 | ||||||
|       # You might want to limit this with something like Docker Networks, reverse proxies, or firewall rules, such as UFW |       # You might want to limit this with something like Docker Networks, reverse proxies, or firewall rules, | ||||||
|  |       # however be aware that using UFW is known to not work with default Docker installations, see: | ||||||
|  |       # https://docs.docker.com/engine/network/packet-filtering-firewalls/#docker-and-ufw | ||||||
|       - '8080:8080' |       - '8080:8080' | ||||||
|     volumes: |     volumes: | ||||||
|       # Unless TRILIUM_DATA_DIR is set, the data will be stored in the "trilium-data" directory in the home directory. |       # Unless TRILIUM_DATA_DIR is set, the data will be stored in the "trilium-data" directory in the home directory. | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								docs/backend_api/.nojekyll
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | |||||||
|  | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. | ||||||
							
								
								
									
										1
									
								
								docs/backend_api/assets/hierarchy.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | |||||||
|  | window.hierarchyData = "eJylk91uwyAMhd+Fa7cjdGl+XmWqIiCugkqgAmfSVOXd52y72GUibpA4Fuezjf0SKUbKov9QNxAJ7x4tuRhYeQm1HUHPKHox4l0vngSIhwuj6CvVgliS55D1OmfMbwat1QMGcuQwD9pkStrS8E//Ov/5nCeaPZv9vGUPyuNpMz79ChyYnB8TBs6skVB1ElTXwuXawPtVQn2R0HUKKlm3UFWqvq0gGlmUr9FE2k4zCzuzZCYnVgxNziyE+5nciDKm8dHsx3HPC3FJBzvtB/IHlwGR9NMNFB8Y9lN5pMqoIR75RJ7eMlx8bnt6YFJ5VcqICS1fhmN1bstZiv10+UCp6/oNzPWfkA==" | ||||||
							
								
								
									
										50
									
								
								docs/backend_api/assets/highlight.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,50 @@ | |||||||
|  | :root { | ||||||
|  |     --light-hl-0: #795E26; | ||||||
|  |     --dark-hl-0: #DCDCAA; | ||||||
|  |     --light-hl-1: #000000; | ||||||
|  |     --dark-hl-1: #D4D4D4; | ||||||
|  |     --light-hl-2: #0000FF; | ||||||
|  |     --dark-hl-2: #569CD6; | ||||||
|  |     --light-hl-3: #A31515; | ||||||
|  |     --dark-hl-3: #CE9178; | ||||||
|  |     --light-code-background: #FFFFFF; | ||||||
|  |     --dark-code-background: #1E1E1E; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (prefers-color-scheme: light) { :root { | ||||||
|  |     --hl-0: var(--light-hl-0); | ||||||
|  |     --hl-1: var(--light-hl-1); | ||||||
|  |     --hl-2: var(--light-hl-2); | ||||||
|  |     --hl-3: var(--light-hl-3); | ||||||
|  |     --code-background: var(--light-code-background); | ||||||
|  | } } | ||||||
|  | 
 | ||||||
|  | @media (prefers-color-scheme: dark) { :root { | ||||||
|  |     --hl-0: var(--dark-hl-0); | ||||||
|  |     --hl-1: var(--dark-hl-1); | ||||||
|  |     --hl-2: var(--dark-hl-2); | ||||||
|  |     --hl-3: var(--dark-hl-3); | ||||||
|  |     --code-background: var(--dark-code-background); | ||||||
|  | } } | ||||||
|  | 
 | ||||||
|  | :root[data-theme='light'] { | ||||||
|  |     --hl-0: var(--light-hl-0); | ||||||
|  |     --hl-1: var(--light-hl-1); | ||||||
|  |     --hl-2: var(--light-hl-2); | ||||||
|  |     --hl-3: var(--light-hl-3); | ||||||
|  |     --code-background: var(--light-code-background); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | :root[data-theme='dark'] { | ||||||
|  |     --hl-0: var(--dark-hl-0); | ||||||
|  |     --hl-1: var(--dark-hl-1); | ||||||
|  |     --hl-2: var(--dark-hl-2); | ||||||
|  |     --hl-3: var(--dark-hl-3); | ||||||
|  |     --code-background: var(--dark-code-background); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .hl-0 { color: var(--hl-0); } | ||||||
|  | .hl-1 { color: var(--hl-1); } | ||||||
|  | .hl-2 { color: var(--hl-2); } | ||||||
|  | .hl-3 { color: var(--hl-3); } | ||||||
|  | pre, code { background: var(--code-background); } | ||||||
							
								
								
									
										18
									
								
								docs/backend_api/assets/icons.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/assets/icons.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 12 KiB | 
							
								
								
									
										60
									
								
								docs/backend_api/assets/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1
									
								
								docs/backend_api/assets/navigation.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | |||||||
|  | window.navigationData = "eJytlltLwzAYhv9Lr8XDxNPuJu5OnOhARCSkaaTBrqnJt6mI/9006yHdIf0qYVej7/vkSZZ+7OUnAv4F0TiKOWP0iOcgQHAdHUQsFVmieB6NX5oQjTUoyoDYNLHpb5MtKKTm8UImy4zrI+epYZGdrcMUFpmpvos8icaj3esl/I0uM2hXYBnVGrtC1e6udDK6/H39PWj3TQEoSxem07sRJxtU3+WipZWIl8BRzutocOUKizOOMxn3y5apsJ6WiFRUNGcpQtLmAmuumThRDrQQBOS7WazX1gmHVXbBOO9cYi5smQpraok4RVmAkIhTXefCalZMnKjizDQJ7kidcFhlF4z1XgmNOuI6Gdq4oqJ0lfzUvaZlCCU5acb8g/xssSIHrt4o20PutDbWOTt3ZCf1SB5Ib0o++LWZo0O4Vd6LtDNvELRu+LDTci7Ny7E0BN1p+fB3ctgBV3kfcmZf/CHQpuHDPtiXc6hvp+XHr9+kYfCmg7rJ8+/CGW9gvvXc4rKwQT6+ujg5G238glhwne1jTm5vZ0/TG3I3m0/J/Pl++tjSV1QJGu8bHNvN7lqnIzOR3JmkuVoJtvc/ekyZucQJ0UyJAoi51dsDrEaQ7fD/pm27RR9658i1+3N295F5fM3TYIIla7+R+fwBbqmgig==" | ||||||
							
								
								
									
										1
									
								
								docs/backend_api/assets/search.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										1610
									
								
								docs/backend_api/assets/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -1,360 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/abstract_becca_entity.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/abstract_becca_entity.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const utils = require('../../services/utils'); |  | ||||||
| const sql = require('../../services/sql'); |  | ||||||
| const entityChangesService = require('../../services/entity_changes'); |  | ||||||
| const eventService = require("../../services/events"); |  | ||||||
| const dateUtils = require("../../services/date_utils"); |  | ||||||
| const cls = require("../../services/cls"); |  | ||||||
| const log = require("../../services/log"); |  | ||||||
| const protectedSessionService = require("../../services/protected_session"); |  | ||||||
| const blobService = require("../../services/blob"); |  | ||||||
| 
 |  | ||||||
| let becca = null; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Base class for all backend entities. |  | ||||||
|  */ |  | ||||||
| class AbstractBeccaEntity { |  | ||||||
|     /** @protected */ |  | ||||||
|     beforeSaving() { |  | ||||||
|         if (!this[this.constructor.primaryKeyName]) { |  | ||||||
|             this[this.constructor.primaryKeyName] = utils.newEntityId(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @protected */ |  | ||||||
|     getUtcDateChanged() { |  | ||||||
|         return this.utcDateModified || this.utcDateCreated; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @protected |  | ||||||
|      * @returns {Becca} |  | ||||||
|      */ |  | ||||||
|     get becca() { |  | ||||||
|         if (!becca) { |  | ||||||
|             becca = require('../becca'); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return becca; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @protected */ |  | ||||||
|     putEntityChange(isDeleted) { |  | ||||||
|         entityChangesService.putEntityChange({ |  | ||||||
|             entityName: this.constructor.entityName, |  | ||||||
|             entityId: this[this.constructor.primaryKeyName], |  | ||||||
|             hash: this.generateHash(isDeleted), |  | ||||||
|             isErased: false, |  | ||||||
|             utcDateChanged: this.getUtcDateChanged(), |  | ||||||
|             isSynced: this.constructor.entityName !== 'options' || !!this.isSynced |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @protected |  | ||||||
|      * @returns {string} |  | ||||||
|      */ |  | ||||||
|     generateHash(isDeleted) { |  | ||||||
|         let contentToHash = ""; |  | ||||||
| 
 |  | ||||||
|         for (const propertyName of this.constructor.hashedProperties) { |  | ||||||
|             contentToHash += `|${this[propertyName]}`; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (isDeleted) { |  | ||||||
|             contentToHash += "|deleted"; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return utils.hash(contentToHash).substr(0, 10); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @protected */ |  | ||||||
|     getPojoToSave() { |  | ||||||
|         return this.getPojo(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @protected |  | ||||||
|      * @abstract |  | ||||||
|      */ |  | ||||||
|     getPojo() { |  | ||||||
|         throw new Error(`Unimplemented getPojo() for entity '${this.constructor.name}'`) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Saves entity - executes SQL, but doesn't commit the transaction on its own |  | ||||||
|      * |  | ||||||
|      * @returns {this} |  | ||||||
|      */ |  | ||||||
|     save(opts = {}) { |  | ||||||
|         const entityName = this.constructor.entityName; |  | ||||||
|         const primaryKeyName = this.constructor.primaryKeyName; |  | ||||||
| 
 |  | ||||||
|         const isNewEntity = !this[primaryKeyName]; |  | ||||||
| 
 |  | ||||||
|         this.beforeSaving(opts); |  | ||||||
| 
 |  | ||||||
|         const pojo = this.getPojoToSave(); |  | ||||||
| 
 |  | ||||||
|         sql.transactional(() => { |  | ||||||
|             sql.upsert(entityName, primaryKeyName, pojo); |  | ||||||
| 
 |  | ||||||
|             if (entityName === 'recent_notes') { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             this.putEntityChange(!!this.isDeleted); |  | ||||||
| 
 |  | ||||||
|             if (!cls.isEntityEventsDisabled()) { |  | ||||||
|                 const eventPayload = { |  | ||||||
|                     entityName, |  | ||||||
|                     entity: this |  | ||||||
|                 }; |  | ||||||
| 
 |  | ||||||
|                 if (isNewEntity) { |  | ||||||
|                     eventService.emit(eventService.ENTITY_CREATED, eventPayload); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 eventService.emit(eventService.ENTITY_CHANGED, eventPayload); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @protected */ |  | ||||||
|     _setContent(content, opts = {}) { |  | ||||||
|         // client code asks to save entity even if blobId didn't change (something else was changed) |  | ||||||
|         opts.forceSave = !!opts.forceSave; |  | ||||||
|         opts.forceFrontendReload = !!opts.forceFrontendReload; |  | ||||||
| 
 |  | ||||||
|         if (content === null || content === undefined) { |  | ||||||
|             throw new Error(`Cannot set null content to ${this.constructor.primaryKeyName} '${this[this.constructor.primaryKeyName]}'`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (this.hasStringContent()) { |  | ||||||
|             content = content.toString(); |  | ||||||
|         } else { |  | ||||||
|             content = Buffer.isBuffer(content) ? content : Buffer.from(content); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         const unencryptedContentForHashCalculation = this.#getUnencryptedContentForHashCalculation(content); |  | ||||||
| 
 |  | ||||||
|         if (this.isProtected) { |  | ||||||
|             if (protectedSessionService.isProtectedSessionAvailable()) { |  | ||||||
|                 content = protectedSessionService.encrypt(content); |  | ||||||
|             } else { |  | ||||||
|                 throw new Error(`Cannot update content of blob since protected session is not available.`); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         sql.transactional(() => { |  | ||||||
|             const newBlobId = this.#saveBlob(content, unencryptedContentForHashCalculation, opts); |  | ||||||
|             const oldBlobId = this.blobId; |  | ||||||
| 
 |  | ||||||
|             if (newBlobId !== oldBlobId || opts.forceSave) { |  | ||||||
|                 this.blobId = newBlobId; |  | ||||||
|                 this.save(); |  | ||||||
| 
 |  | ||||||
|                 if (newBlobId !== oldBlobId) { |  | ||||||
|                     this.#deleteBlobIfNotUsed(oldBlobId); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     #deleteBlobIfNotUsed(oldBlobId) { |  | ||||||
|         if (sql.getValue("SELECT 1 FROM notes WHERE blobId = ? LIMIT 1", [oldBlobId])) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (sql.getValue("SELECT 1 FROM attachments WHERE blobId = ? LIMIT 1", [oldBlobId])) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (sql.getValue("SELECT 1 FROM revisions WHERE blobId = ? LIMIT 1", [oldBlobId])) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         sql.execute("DELETE FROM blobs WHERE blobId = ?", [oldBlobId]); |  | ||||||
|         // blobs are not marked as erased in entity_changes, they are just purged completely |  | ||||||
|         // this is because technically every keystroke can create a new blob, and there would be just too many |  | ||||||
|         sql.execute("DELETE FROM entity_changes WHERE entityName = 'blobs' AND entityId = ?", [oldBlobId]); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     #getUnencryptedContentForHashCalculation(unencryptedContent) { |  | ||||||
|         if (this.isProtected) { |  | ||||||
|             // a "random" prefix makes sure that the calculated hash/blobId is different for a decrypted/encrypted content |  | ||||||
|             const encryptedPrefixSuffix = "t$[nvQg7q)&_ENCRYPTED_?M:Bf&j3jr_"; |  | ||||||
|             return Buffer.isBuffer(unencryptedContent) |  | ||||||
|                 ? Buffer.concat([Buffer.from(encryptedPrefixSuffix), unencryptedContent]) |  | ||||||
|                 : `${encryptedPrefixSuffix}${unencryptedContent}`; |  | ||||||
|         } else { |  | ||||||
|             return unencryptedContent; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     #saveBlob(content, unencryptedContentForHashCalculation, opts = {}) { |  | ||||||
|         /* |  | ||||||
|          * We're using the unencrypted blob for the hash calculation, because otherwise the random IV would |  | ||||||
|          * cause every content blob to be unique which would balloon the database size (esp. with revisioning). |  | ||||||
|          * This has minor security implications (it's easy to infer that given content is shared between different |  | ||||||
|          * notes/attachments), but the trade-off comes out clearly positive. |  | ||||||
|          */ |  | ||||||
|         const newBlobId = utils.hashedBlobId(unencryptedContentForHashCalculation); |  | ||||||
|         const blobNeedsInsert = !sql.getValue('SELECT 1 FROM blobs WHERE blobId = ?', [newBlobId]); |  | ||||||
| 
 |  | ||||||
|         if (!blobNeedsInsert) { |  | ||||||
|             return newBlobId; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         const pojo = { |  | ||||||
|             blobId: newBlobId, |  | ||||||
|             content: content, |  | ||||||
|             dateModified: dateUtils.localNowDateTime(), |  | ||||||
|             utcDateModified: dateUtils.utcNowDateTime() |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         sql.upsert("blobs", "blobId", pojo); |  | ||||||
| 
 |  | ||||||
|         // we can't reuse blobId as an entity_changes hash, because this one has to be calculatable without having |  | ||||||
|         // access to the decrypted content |  | ||||||
|         const hash = blobService.calculateContentHash(pojo); |  | ||||||
| 
 |  | ||||||
|         entityChangesService.putEntityChange({ |  | ||||||
|             entityName: 'blobs', |  | ||||||
|             entityId: newBlobId, |  | ||||||
|             hash: hash, |  | ||||||
|             isErased: false, |  | ||||||
|             utcDateChanged: pojo.utcDateModified, |  | ||||||
|             isSynced: true, |  | ||||||
|             // overriding componentId will cause the frontend to think the change is coming from a different component |  | ||||||
|             // and thus reload |  | ||||||
|             componentId: opts.forceFrontendReload ? utils.randomString(10) : null |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         eventService.emit(eventService.ENTITY_CHANGED, { |  | ||||||
|             entityName: 'blobs', |  | ||||||
|             entity: this |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         return newBlobId; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @protected |  | ||||||
|      * @returns {string|Buffer} |  | ||||||
|      */ |  | ||||||
|     _getContent() { |  | ||||||
|         const row = sql.getRow(`SELECT content FROM blobs WHERE blobId = ?`, [this.blobId]); |  | ||||||
| 
 |  | ||||||
|         if (!row) { |  | ||||||
|             throw new Error(`Cannot find content for ${this.constructor.primaryKeyName} '${this[this.constructor.primaryKeyName]}', blobId '${this.blobId}'`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return blobService.processContent(row.content, this.isProtected, this.hasStringContent()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Mark the entity as (soft) deleted. It will be completely erased later. |  | ||||||
|      * |  | ||||||
|      * This is a low-level method, for notes and branches use `note.deleteNote()` and 'branch.deleteBranch()` instead. |  | ||||||
|      * |  | ||||||
|      * @param [deleteId=null] |  | ||||||
|      */ |  | ||||||
|     markAsDeleted(deleteId = null) { |  | ||||||
|         const entityId = this[this.constructor.primaryKeyName]; |  | ||||||
|         const entityName = this.constructor.entityName; |  | ||||||
| 
 |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
| 
 |  | ||||||
|         sql.execute(`UPDATE ${entityName} SET isDeleted = 1, deleteId = ?, utcDateModified = ? |  | ||||||
|                            WHERE ${this.constructor.primaryKeyName} = ?`, |  | ||||||
|             [deleteId, this.utcDateModified, entityId]); |  | ||||||
| 
 |  | ||||||
|         if (this.dateModified) { |  | ||||||
|             this.dateModified = dateUtils.localNowDateTime(); |  | ||||||
| 
 |  | ||||||
|             sql.execute(`UPDATE ${entityName} SET dateModified = ? WHERE ${this.constructor.primaryKeyName} = ?`, |  | ||||||
|                 [this.dateModified, entityId]); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         log.info(`Marking ${entityName} ${entityId} as deleted`); |  | ||||||
| 
 |  | ||||||
|         this.putEntityChange(true); |  | ||||||
| 
 |  | ||||||
|         eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     markAsDeletedSimple() { |  | ||||||
|         const entityId = this[this.constructor.primaryKeyName]; |  | ||||||
|         const entityName = this.constructor.entityName; |  | ||||||
| 
 |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
| 
 |  | ||||||
|         sql.execute(`UPDATE ${entityName} SET isDeleted = 1, utcDateModified = ? |  | ||||||
|                            WHERE ${this.constructor.primaryKeyName} = ?`, |  | ||||||
|             [this.utcDateModified, entityId]); |  | ||||||
| 
 |  | ||||||
|         log.info(`Marking ${entityName} ${entityId} as deleted`); |  | ||||||
| 
 |  | ||||||
|         this.putEntityChange(true); |  | ||||||
| 
 |  | ||||||
|         eventService.emit(eventService.ENTITY_DELETED, { entityName, entityId, entity: this }); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = AbstractBeccaEntity; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,294 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/battachment.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/battachment.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const utils = require('../../services/utils'); |  | ||||||
| const dateUtils = require('../../services/date_utils'); |  | ||||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); |  | ||||||
| const sql = require("../../services/sql"); |  | ||||||
| const protectedSessionService = require("../../services/protected_session"); |  | ||||||
| const log = require("../../services/log"); |  | ||||||
| 
 |  | ||||||
| const attachmentRoleToNoteTypeMapping = { |  | ||||||
|     'image': 'image' |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Attachment represent data related/attached to the note. Conceptually similar to attributes, but intended for |  | ||||||
|  * larger amounts of data and generally not accessible to the user. |  | ||||||
|  * |  | ||||||
|  * @extends AbstractBeccaEntity |  | ||||||
|  */ |  | ||||||
| class BAttachment extends AbstractBeccaEntity { |  | ||||||
|     static get entityName() { return "attachments"; } |  | ||||||
|     static get primaryKeyName() { return "attachmentId"; } |  | ||||||
|     static get hashedProperties() { return ["attachmentId", "ownerId", "role", "mime", "title", "blobId", "utcDateScheduledForErasureSince"]; } |  | ||||||
| 
 |  | ||||||
|     constructor(row) { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         if (!row.ownerId?.trim()) { |  | ||||||
|             throw new Error("'ownerId' must be given to initialize a Attachment entity"); |  | ||||||
|         } else if (!row.role?.trim()) { |  | ||||||
|             throw new Error("'role' must be given to initialize a Attachment entity"); |  | ||||||
|         } else if (!row.mime?.trim()) { |  | ||||||
|             throw new Error("'mime' must be given to initialize a Attachment entity"); |  | ||||||
|         } else if (!row.title?.trim()) { |  | ||||||
|             throw new Error("'title' must be given to initialize a Attachment entity"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.attachmentId = row.attachmentId; |  | ||||||
|         /**  |  | ||||||
|          * either noteId or revisionId to which this attachment belongs |  | ||||||
|          * @type {string} |  | ||||||
|          */ |  | ||||||
|         this.ownerId = row.ownerId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.role = row.role; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.mime = row.mime; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.title = row.title; |  | ||||||
|         /** @type {int} */ |  | ||||||
|         this.position = row.position; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.blobId = row.blobId; |  | ||||||
|         /** @type {boolean} */ |  | ||||||
|         this.isProtected = !!row.isProtected; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.dateModified = row.dateModified; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateModified = row.utcDateModified; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateScheduledForErasureSince = row.utcDateScheduledForErasureSince; |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * optionally added to the entity |  | ||||||
|          * @type {int} |  | ||||||
|          */ |  | ||||||
|         this.contentLength = row.contentLength; |  | ||||||
| 
 |  | ||||||
|         this.decrypt(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BAttachment} */ |  | ||||||
|     copy() { |  | ||||||
|         return new BAttachment({ |  | ||||||
|             ownerId: this.ownerId, |  | ||||||
|             role: this.role, |  | ||||||
|             mime: this.mime, |  | ||||||
|             title: this.title, |  | ||||||
|             blobId: this.blobId, |  | ||||||
|             isProtected: this.isProtected |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BNote} */ |  | ||||||
|     getNote() { |  | ||||||
|         return this.becca.notes[this.ownerId]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {boolean} true if the note has string content (not binary) */ |  | ||||||
|     hasStringContent() { |  | ||||||
|         return utils.isStringNote(this.type, this.mime); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     isContentAvailable() { |  | ||||||
|         return !this.attachmentId // new attachment which was not encrypted yet |  | ||||||
|             || !this.isProtected |  | ||||||
|             || protectedSessionService.isProtectedSessionAvailable() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getTitleOrProtected() { |  | ||||||
|         return this.isContentAvailable() ? this.title : '[protected]'; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     decrypt() { |  | ||||||
|         if (!this.isProtected || !this.attachmentId) { |  | ||||||
|             this.isDecrypted = true; |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.isDecrypted && protectedSessionService.isProtectedSessionAvailable()) { |  | ||||||
|             try { |  | ||||||
|                 this.title = protectedSessionService.decryptString(this.title); |  | ||||||
|                 this.isDecrypted = true; |  | ||||||
|             } |  | ||||||
|             catch (e) { |  | ||||||
|                 log.error(`Could not decrypt attachment ${this.attachmentId}: ${e.message} ${e.stack}`); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {string|Buffer}  */ |  | ||||||
|     getContent() { |  | ||||||
|         return this._getContent(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @param content |  | ||||||
|      * @param {object} [opts] |  | ||||||
|      * @param {object} [opts.forceSave=false] - will also save this BAttachment entity |  | ||||||
|      * @param {object} [opts.forceFrontendReload=false] - override frontend heuristics on when to reload, instruct to reload |  | ||||||
|      */ |  | ||||||
|     setContent(content, opts) { |  | ||||||
|         this._setContent(content, opts); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {{note: BNote, branch: BBranch}} */ |  | ||||||
|     convertToNote() { |  | ||||||
|         if (this.type === 'search') { |  | ||||||
|             throw new Error(`Note of type search cannot have child notes`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.getNote()) { |  | ||||||
|             throw new Error("Cannot find note of this attachment. It is possible that this is note revision's attachment. " + |  | ||||||
|                 "Converting note revision's attachments to note is not (yet) supported."); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!(this.role in attachmentRoleToNoteTypeMapping)) { |  | ||||||
|             throw new Error(`Mapping from attachment role '${this.role}' to note's type is not defined`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.isContentAvailable()) { // isProtected is the same for attachment |  | ||||||
|             throw new Error(`Cannot convert protected attachment outside of protected session`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         const noteService = require('../../services/notes'); |  | ||||||
| 
 |  | ||||||
|         const { note, branch } = noteService.createNewNote({ |  | ||||||
|             parentNoteId: this.ownerId, |  | ||||||
|             title: this.title, |  | ||||||
|             type: attachmentRoleToNoteTypeMapping[this.role], |  | ||||||
|             mime: this.mime, |  | ||||||
|             content: this.getContent(), |  | ||||||
|             isProtected: this.isProtected |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         this.markAsDeleted(); |  | ||||||
| 
 |  | ||||||
|         const parentNote = this.getNote(); |  | ||||||
| 
 |  | ||||||
|         if (this.role === 'image' && parentNote.type === 'text') { |  | ||||||
|             const origContent = parentNote.getContent(); |  | ||||||
|             const oldAttachmentUrl = `api/attachments/${this.attachmentId}/image/`; |  | ||||||
|             const newNoteUrl = `api/images/${note.noteId}/`; |  | ||||||
| 
 |  | ||||||
|             const fixedContent = utils.replaceAll(origContent, oldAttachmentUrl, newNoteUrl); |  | ||||||
| 
 |  | ||||||
|             if (fixedContent !== origContent) { |  | ||||||
|                 parentNote.setContent(fixedContent); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             noteService.asyncPostProcessContent(note, fixedContent); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return { note, branch }; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getFileName() { |  | ||||||
|         const type = this.role === 'image' ? 'image' : 'file'; |  | ||||||
| 
 |  | ||||||
|         return utils.formatDownloadTitle(this.title, type, this.mime); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     beforeSaving() { |  | ||||||
|         super.beforeSaving(); |  | ||||||
| 
 |  | ||||||
|         if (this.position === undefined || this.position === null) { |  | ||||||
|             this.position = 10 + sql.getValue(`SELECT COALESCE(MAX(position), 0) |  | ||||||
|                                               FROM attachments |  | ||||||
|                                               WHERE ownerId = ?`, [this.noteId]); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.dateModified = dateUtils.localNowDateTime(); |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             attachmentId: this.attachmentId, |  | ||||||
|             ownerId: this.ownerId, |  | ||||||
|             role: this.role, |  | ||||||
|             mime: this.mime, |  | ||||||
|             title: this.title, |  | ||||||
|             position: this.position, |  | ||||||
|             blobId: this.blobId, |  | ||||||
|             isProtected: !!this.isProtected, |  | ||||||
|             isDeleted: false, |  | ||||||
|             dateModified: this.dateModified, |  | ||||||
|             utcDateModified: this.utcDateModified, |  | ||||||
|             utcDateScheduledForErasureSince: this.utcDateScheduledForErasureSince, |  | ||||||
|             contentLength: this.contentLength |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojoToSave() { |  | ||||||
|         const pojo = this.getPojo(); |  | ||||||
|         delete pojo.contentLength; |  | ||||||
| 
 |  | ||||||
|         if (pojo.isProtected) { |  | ||||||
|             if (this.isDecrypted) { |  | ||||||
|                 pojo.title = protectedSessionService.encrypt(pojo.title); |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 // updating protected note outside of protected session means we will keep original ciphertexts |  | ||||||
|                 delete pojo.title; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return pojo; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BAttachment; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,293 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/battribute.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/battribute.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const BNote = require('./bnote'); |  | ||||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); |  | ||||||
| const sql = require("../../services/sql"); |  | ||||||
| const dateUtils = require("../../services/date_utils"); |  | ||||||
| const promotedAttributeDefinitionParser = require("../../services/promoted_attribute_definition_parser"); |  | ||||||
| const {sanitizeAttributeName} = require("../../services/sanitize_attribute_name"); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * There are currently only two types of attributes, labels or relations. |  | ||||||
|  * @typedef {"label" | "relation"} AttributeType |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Attribute is an abstract concept which has two real uses - label (key - value pair) |  | ||||||
|  * and relation (representing named relationship between source and target note) |  | ||||||
|  * |  | ||||||
|  * @extends AbstractBeccaEntity |  | ||||||
|  */ |  | ||||||
| class BAttribute extends AbstractBeccaEntity { |  | ||||||
|     static get entityName() { return "attributes"; } |  | ||||||
|     static get primaryKeyName() { return "attributeId"; } |  | ||||||
|     static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable"]; } |  | ||||||
| 
 |  | ||||||
|     constructor(row) { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         if (!row) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.updateFromRow(row); |  | ||||||
|         this.init(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     updateFromRow(row) { |  | ||||||
|         this.update([ |  | ||||||
|             row.attributeId, |  | ||||||
|             row.noteId, |  | ||||||
|             row.type, |  | ||||||
|             row.name, |  | ||||||
|             row.value, |  | ||||||
|             row.isInheritable, |  | ||||||
|             row.position, |  | ||||||
|             row.utcDateModified |  | ||||||
|         ]); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     update([attributeId, noteId, type, name, value, isInheritable, position, utcDateModified]) { |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.attributeId = attributeId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.noteId = noteId; |  | ||||||
|         /** @type {AttributeType} */ |  | ||||||
|         this.type = type; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.name = name; |  | ||||||
|         /** @type {int} */ |  | ||||||
|         this.position = position; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.value = value || ""; |  | ||||||
|         /** @type {boolean} */ |  | ||||||
|         this.isInheritable = !!isInheritable; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateModified = utcDateModified; |  | ||||||
| 
 |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     init() { |  | ||||||
|         if (this.attributeId) { |  | ||||||
|             this.becca.attributes[this.attributeId] = this; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!(this.noteId in this.becca.notes)) { |  | ||||||
|             // entities can come out of order in sync, create skeleton which will be filled later |  | ||||||
|             this.becca.addNote(this.noteId, new BNote({noteId: this.noteId})); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.becca.notes[this.noteId].ownedAttributes.push(this); |  | ||||||
| 
 |  | ||||||
|         const key = `${this.type}-${this.name.toLowerCase()}`; |  | ||||||
|         this.becca.attributeIndex[key] = this.becca.attributeIndex[key] || []; |  | ||||||
|         this.becca.attributeIndex[key].push(this); |  | ||||||
| 
 |  | ||||||
|         const targetNote = this.targetNote; |  | ||||||
| 
 |  | ||||||
|         if (targetNote) { |  | ||||||
|             targetNote.targetRelations.push(this); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     validate() { |  | ||||||
|         if (!["label", "relation"].includes(this.type)) { |  | ||||||
|             throw new Error(`Invalid attribute type '${this.type}' in attribute '${this.attributeId}' of note '${this.noteId}'`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.name?.trim()) { |  | ||||||
|             throw new Error(`Invalid empty name in attribute '${this.attributeId}' of note '${this.noteId}'`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (this.type === 'relation' && !(this.value in this.becca.notes)) { |  | ||||||
|             throw new Error(`Cannot save relation '${this.name}' of note '${this.noteId}' since it targets not existing note '${this.value}'.`); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     get isAffectingSubtree() { |  | ||||||
|         return this.isInheritable |  | ||||||
|             || (this.type === 'relation' && ['template', 'inherit'].includes(this.name)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     get targetNoteId() { // alias |  | ||||||
|         return this.type === 'relation' ? this.value : undefined; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     isAutoLink() { |  | ||||||
|         return this.type === 'relation' && ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     get note() { |  | ||||||
|         return this.becca.notes[this.noteId]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     get targetNote() { |  | ||||||
|         if (this.type === 'relation') { |  | ||||||
|             return this.becca.notes[this.value]; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @returns {BNote|null} |  | ||||||
|      */ |  | ||||||
|     getNote() { |  | ||||||
|         const note = this.becca.getNote(this.noteId); |  | ||||||
| 
 |  | ||||||
|         if (!note) { |  | ||||||
|             throw new Error(`Note '${this.noteId}' of attribute '${this.attributeId}', type '${this.type}', name '${this.name}' does not exist.`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return note; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @returns {BNote|null} |  | ||||||
|      */ |  | ||||||
|     getTargetNote() { |  | ||||||
|         if (this.type !== 'relation') { |  | ||||||
|             throw new Error(`Attribute '${this.attributeId}' is not a relation.`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.value) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return this.becca.getNote(this.value); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @returns {boolean} |  | ||||||
|      */ |  | ||||||
|     isDefinition() { |  | ||||||
|         return this.type === 'label' && (this.name.startsWith('label:') || this.name.startsWith('relation:')); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getDefinition() { |  | ||||||
|         return promotedAttributeDefinitionParser.parse(this.value); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getDefinedName() { |  | ||||||
|         if (this.type === 'label' && this.name.startsWith('label:')) { |  | ||||||
|             return this.name.substr(6); |  | ||||||
|         } else if (this.type === 'label' && this.name.startsWith('relation:')) { |  | ||||||
|             return this.name.substr(9); |  | ||||||
|         } else { |  | ||||||
|             return this.name; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     get isDeleted() { |  | ||||||
|         return !(this.attributeId in this.becca.attributes); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     beforeSaving(opts = {}) { |  | ||||||
|         if (!opts.skipValidation) { |  | ||||||
|             this.validate(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.name = sanitizeAttributeName(this.name); |  | ||||||
| 
 |  | ||||||
|         if (!this.value) { |  | ||||||
|             // null value isn't allowed |  | ||||||
|             this.value = ""; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (this.position === undefined || this.position === null) { |  | ||||||
|             const maxExistingPosition = this.getNote().getAttributes() |  | ||||||
|                 .reduce((maxPosition, attr) => Math.max(maxPosition, attr.position || 0), 0); |  | ||||||
| 
 |  | ||||||
|             this.position = maxExistingPosition + 10; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.isInheritable) { |  | ||||||
|             this.isInheritable = false; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
| 
 |  | ||||||
|         super.beforeSaving(); |  | ||||||
| 
 |  | ||||||
|         this.becca.attributes[this.attributeId] = this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             attributeId: this.attributeId, |  | ||||||
|             noteId: this.noteId, |  | ||||||
|             type: this.type, |  | ||||||
|             name: this.name, |  | ||||||
|             position: this.position, |  | ||||||
|             value: this.value, |  | ||||||
|             isInheritable: this.isInheritable, |  | ||||||
|             utcDateModified: this.utcDateModified, |  | ||||||
|             isDeleted: false |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     createClone(type, name, value, isInheritable) { |  | ||||||
|         return new BAttribute({ |  | ||||||
|             noteId: this.noteId, |  | ||||||
|             type: type, |  | ||||||
|             name: name, |  | ||||||
|             value: value, |  | ||||||
|             position: this.position, |  | ||||||
|             isInheritable: isInheritable, |  | ||||||
|             utcDateModified: this.utcDateModified |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BAttribute; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,81 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/bblob.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/bblob.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>class BBlob { |  | ||||||
|     static get entityName() { return "blobs"; } |  | ||||||
|     static get primaryKeyName() { return "blobId"; } |  | ||||||
|     static get hashedProperties() { return ["blobId", "content"]; } |  | ||||||
| 
 |  | ||||||
|     constructor(row) { |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.blobId = row.blobId; |  | ||||||
|         /** @type {string|Buffer} */ |  | ||||||
|         this.content = row.content; |  | ||||||
|         /** @type {int} */ |  | ||||||
|         this.contentLength = row.contentLength; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.dateModified = row.dateModified; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateModified = row.utcDateModified; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             blobId: this.blobId, |  | ||||||
|             content: this.content, |  | ||||||
|             contentLength: this.contentLength, |  | ||||||
|             dateModified: this.dateModified, |  | ||||||
|             utcDateModified: this.utcDateModified |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BBlob; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,333 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/bbranch.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/bbranch.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const BNote = require('./bnote'); |  | ||||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); |  | ||||||
| const dateUtils = require("../../services/date_utils"); |  | ||||||
| const utils = require("../../services/utils"); |  | ||||||
| const TaskContext = require("../../services/task_context"); |  | ||||||
| const cls = require("../../services/cls"); |  | ||||||
| const log = require("../../services/log"); |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Branch represents a relationship between a child note and its parent note. Trilium allows a note to have multiple |  | ||||||
|  * parents. |  | ||||||
|  * |  | ||||||
|  * Note that you should not rely on the branch's identity, since it can change easily with a note's move. |  | ||||||
|  * Always check noteId instead. |  | ||||||
|  * |  | ||||||
|  * @extends AbstractBeccaEntity |  | ||||||
|  */ |  | ||||||
| class BBranch extends AbstractBeccaEntity { |  | ||||||
|     static get entityName() { return "branches"; } |  | ||||||
|     static get primaryKeyName() { return "branchId"; } |  | ||||||
|     // notePosition is not part of hash because it would produce a lot of updates in case of reordering |  | ||||||
|     static get hashedProperties() { return ["branchId", "noteId", "parentNoteId", "prefix"]; } |  | ||||||
| 
 |  | ||||||
|     constructor(row) { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         if (!row) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.updateFromRow(row); |  | ||||||
|         this.init(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     updateFromRow(row) { |  | ||||||
|         this.update([ |  | ||||||
|             row.branchId, |  | ||||||
|             row.noteId, |  | ||||||
|             row.parentNoteId, |  | ||||||
|             row.prefix, |  | ||||||
|             row.notePosition, |  | ||||||
|             row.isExpanded, |  | ||||||
|             row.utcDateModified |  | ||||||
|         ]); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     update([branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified]) { |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.branchId = branchId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.noteId = noteId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.parentNoteId = parentNoteId; |  | ||||||
|         /** @type {string|null} */ |  | ||||||
|         this.prefix = prefix; |  | ||||||
|         /** @type {int} */ |  | ||||||
|         this.notePosition = notePosition; |  | ||||||
|         /** @type {boolean} */ |  | ||||||
|         this.isExpanded = !!isExpanded; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateModified = utcDateModified; |  | ||||||
| 
 |  | ||||||
|         return this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     init() { |  | ||||||
|         if (this.branchId) { |  | ||||||
|             this.becca.branches[this.branchId] = this; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.becca.childParentToBranch[`${this.noteId}-${this.parentNoteId}`] = this; |  | ||||||
| 
 |  | ||||||
|         const childNote = this.childNote; |  | ||||||
| 
 |  | ||||||
|         if (!childNote.parentBranches.includes(this)) { |  | ||||||
|             childNote.parentBranches.push(this); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (this.noteId === 'root') { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         const parentNote = this.parentNote; |  | ||||||
| 
 |  | ||||||
|         if (!childNote.parents.includes(parentNote)) { |  | ||||||
|             childNote.parents.push(parentNote); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!parentNote.children.includes(childNote)) { |  | ||||||
|             parentNote.children.push(childNote); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BNote} */ |  | ||||||
|     get childNote() { |  | ||||||
|         if (!(this.noteId in this.becca.notes)) { |  | ||||||
|             // entities can come out of order in sync/import, create skeleton which will be filled later |  | ||||||
|             this.becca.addNote(this.noteId, new BNote({noteId: this.noteId})); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return this.becca.notes[this.noteId]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BNote} */ |  | ||||||
|     getNote() { |  | ||||||
|         return this.childNote; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BNote|undefined} - root branch will have undefined parent, all other branches have to have a parent note */ |  | ||||||
|     get parentNote() { |  | ||||||
|         if (!(this.parentNoteId in this.becca.notes) && this.parentNoteId !== 'none') { |  | ||||||
|             // entities can come out of order in sync/import, create skeleton which will be filled later |  | ||||||
|             this.becca.addNote(this.parentNoteId, new BNote({noteId: this.parentNoteId})); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return this.becca.notes[this.parentNoteId]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     get isDeleted() { |  | ||||||
|         return !(this.branchId in this.becca.branches); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Branch is weak when its existence should not hinder deletion of its note. |  | ||||||
|      * As a result, note with only weak branches should be immediately deleted. |  | ||||||
|      * An example is shared or bookmarked clones - they are created automatically and exist for technical reasons, |  | ||||||
|      * not as user-intended actions. From user perspective, they don't count as real clones and for the purpose |  | ||||||
|      * of deletion should not act as a clone. |  | ||||||
|      * |  | ||||||
|      * @returns {boolean} |  | ||||||
|      */ |  | ||||||
|     get isWeak() { |  | ||||||
|         return ['_share', '_lbBookmarks'].includes(this.parentNoteId); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Delete a branch. If this is a last note's branch, delete the note as well. |  | ||||||
|      * |  | ||||||
|      * @param {string} [deleteId] - optional delete identified |  | ||||||
|      * @param {TaskContext} [taskContext] |  | ||||||
|      * |  | ||||||
|      * @returns {boolean} - true if note has been deleted, false otherwise |  | ||||||
|      */ |  | ||||||
|     deleteBranch(deleteId, taskContext) { |  | ||||||
|         if (!deleteId) { |  | ||||||
|             deleteId = utils.randomString(10); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!taskContext) { |  | ||||||
|             taskContext = new TaskContext('no-progress-reporting'); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         taskContext.increaseProgressCount(); |  | ||||||
| 
 |  | ||||||
|         const note = this.getNote(); |  | ||||||
| 
 |  | ||||||
|         if (!taskContext.noteDeletionHandlerTriggered) { |  | ||||||
|             const parentBranches = note.getParentBranches(); |  | ||||||
| 
 |  | ||||||
|             if (parentBranches.length === 1 && parentBranches[0] === this) { |  | ||||||
|                 // needs to be run before branches and attributes are deleted and thus attached relations disappear |  | ||||||
|                 const handlers = require("../../services/handlers"); |  | ||||||
|                 handlers.runAttachedRelations(note, 'runOnNoteDeletion', note); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (this.noteId === 'root' |  | ||||||
|             || this.noteId === cls.getHoistedNoteId()) { |  | ||||||
| 
 |  | ||||||
|             throw new Error("Can't delete root or hoisted branch/note"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.markAsDeleted(deleteId); |  | ||||||
| 
 |  | ||||||
|         const notDeletedBranches = note.getStrongParentBranches(); |  | ||||||
| 
 |  | ||||||
|         if (notDeletedBranches.length === 0) { |  | ||||||
|             for (const weakBranch of note.getParentBranches()) { |  | ||||||
|                 weakBranch.markAsDeleted(deleteId); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             for (const childBranch of note.getChildBranches()) { |  | ||||||
|                 childBranch.deleteBranch(deleteId, taskContext); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // first delete children and then parent - this will show up better in recent changes |  | ||||||
| 
 |  | ||||||
|             log.info(`Deleting note '${note.noteId}'`); |  | ||||||
| 
 |  | ||||||
|             this.becca.notes[note.noteId].isBeingDeleted = true; |  | ||||||
| 
 |  | ||||||
|             for (const attribute of note.getOwnedAttributes().slice()) { |  | ||||||
|                 attribute.markAsDeleted(deleteId); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             for (const relation of note.getTargetRelations()) { |  | ||||||
|                 relation.markAsDeleted(deleteId); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             for (const attachment of note.getAttachments()) { |  | ||||||
|                 attachment.markAsDeleted(deleteId); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             note.markAsDeleted(deleteId); |  | ||||||
| 
 |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     beforeSaving() { |  | ||||||
|         if (!this.noteId || !this.parentNoteId) { |  | ||||||
|             throw new Error(`noteId and parentNoteId are mandatory properties for Branch`); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.branchId = `${this.parentNoteId}_${this.noteId}`; |  | ||||||
| 
 |  | ||||||
|         if (this.notePosition === undefined || this.notePosition === null) { |  | ||||||
|             let maxNotePos = 0; |  | ||||||
| 
 |  | ||||||
|             for (const childBranch of this.parentNote.getChildBranches()) { |  | ||||||
|                 if (maxNotePos < childBranch.notePosition |  | ||||||
|                     && childBranch.noteId !== '_hidden' // hidden has a very large notePosition to always stay last |  | ||||||
|                 ) { |  | ||||||
|                     maxNotePos = childBranch.notePosition; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             this.notePosition = maxNotePos + 10; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.isExpanded) { |  | ||||||
|             this.isExpanded = false; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (!this.prefix?.trim()) { |  | ||||||
|             this.prefix = null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
| 
 |  | ||||||
|         super.beforeSaving(); |  | ||||||
| 
 |  | ||||||
|         this.becca.branches[this.branchId] = this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             branchId: this.branchId, |  | ||||||
|             noteId: this.noteId, |  | ||||||
|             parentNoteId: this.parentNoteId, |  | ||||||
|             prefix: this.prefix, |  | ||||||
|             notePosition: this.notePosition, |  | ||||||
|             isExpanded: this.isExpanded, |  | ||||||
|             isDeleted: false, |  | ||||||
|             utcDateModified: this.utcDateModified |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     createClone(parentNoteId, notePosition) { |  | ||||||
|         const existingBranch = this.becca.getBranchFromChildAndParent(this.noteId, parentNoteId); |  | ||||||
| 
 |  | ||||||
|         if (existingBranch) { |  | ||||||
|             existingBranch.notePosition = notePosition; |  | ||||||
|             return existingBranch; |  | ||||||
|         } else { |  | ||||||
|             return new BBranch({ |  | ||||||
|                 noteId: this.noteId, |  | ||||||
|                 parentNoteId: parentNoteId, |  | ||||||
|                 notePosition: notePosition, |  | ||||||
|                 prefix: this.prefix, |  | ||||||
|                 isExpanded: this.isExpanded |  | ||||||
|             }); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BBranch; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,129 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/betapi_token.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/betapi_token.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const dateUtils = require('../../services/date_utils'); |  | ||||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * EtapiToken is an entity representing token used to authenticate against Trilium REST API from client applications. |  | ||||||
|  * Used by: |  | ||||||
|  * - Trilium Sender |  | ||||||
|  * - ETAPI clients |  | ||||||
|  * |  | ||||||
|  * The format user is presented with is "<etapiTokenId>_<tokenHash>". This is also called "authToken" to distinguish it |  | ||||||
|  * from tokenHash and token. |  | ||||||
|  * |  | ||||||
|  * @extends AbstractBeccaEntity |  | ||||||
|  */ |  | ||||||
| class BEtapiToken extends AbstractBeccaEntity { |  | ||||||
|     static get entityName() { return "etapi_tokens"; } |  | ||||||
|     static get primaryKeyName() { return "etapiTokenId"; } |  | ||||||
|     static get hashedProperties() { return ["etapiTokenId", "name", "tokenHash", "utcDateCreated", "utcDateModified", "isDeleted"]; } |  | ||||||
| 
 |  | ||||||
|     constructor(row) { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         if (!row) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         this.updateFromRow(row); |  | ||||||
|         this.init(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     updateFromRow(row) { |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.etapiTokenId = row.etapiTokenId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.name = row.name; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.tokenHash = row.tokenHash; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime(); |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateModified = row.utcDateModified || this.utcDateCreated; |  | ||||||
|         /** @type {boolean} */ |  | ||||||
|         this.isDeleted = !!row.isDeleted; |  | ||||||
| 
 |  | ||||||
|         if (this.etapiTokenId) { |  | ||||||
|             this.becca.etapiTokens[this.etapiTokenId] = this; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     init() { |  | ||||||
|         if (this.etapiTokenId) { |  | ||||||
|             this.becca.etapiTokens[this.etapiTokenId] = this; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             etapiTokenId: this.etapiTokenId, |  | ||||||
|             name: this.name, |  | ||||||
|             tokenHash: this.tokenHash, |  | ||||||
|             utcDateCreated: this.utcDateCreated, |  | ||||||
|             utcDateModified: this.utcDateModified, |  | ||||||
|             isDeleted: this.isDeleted |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     beforeSaving() { |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
| 
 |  | ||||||
|         super.beforeSaving(); |  | ||||||
| 
 |  | ||||||
|         this.becca.etapiTokens[this.etapiTokenId] = this; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BEtapiToken; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,101 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/boption.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/boption.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const dateUtils = require('../../services/date_utils'); |  | ||||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Option represents a name-value pair, either directly configurable by the user or some system property. |  | ||||||
|  * |  | ||||||
|  * @extends AbstractBeccaEntity |  | ||||||
|  */ |  | ||||||
| class BOption extends AbstractBeccaEntity { |  | ||||||
|     static get entityName() { return "options"; } |  | ||||||
|     static get primaryKeyName() { return "name"; } |  | ||||||
|     static get hashedProperties() { return ["name", "value"]; } |  | ||||||
| 
 |  | ||||||
|     constructor(row) { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         this.updateFromRow(row); |  | ||||||
|         this.becca.options[this.name] = this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     updateFromRow(row) { |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.name = row.name; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.value = row.value; |  | ||||||
|         /** @type {boolean} */ |  | ||||||
|         this.isSynced = !!row.isSynced; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateModified = row.utcDateModified; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     beforeSaving() { |  | ||||||
|         super.beforeSaving(); |  | ||||||
| 
 |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             name: this.name, |  | ||||||
|             value: this.value, |  | ||||||
|             isSynced: this.isSynced, |  | ||||||
|             utcDateModified: this.utcDateModified |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BOption; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,86 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/brecent_note.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/brecent_note.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const dateUtils = require('../../services/date_utils'); |  | ||||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * RecentNote represents recently visited note. |  | ||||||
|  * |  | ||||||
|  * @extends AbstractBeccaEntity |  | ||||||
|  */ |  | ||||||
| class BRecentNote extends AbstractBeccaEntity { |  | ||||||
|     static get entityName() { return "recent_notes"; } |  | ||||||
|     static get primaryKeyName() { return "noteId"; } |  | ||||||
| 
 |  | ||||||
|     constructor(row) { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.noteId = row.noteId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.notePath = row.notePath; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateCreated = row.utcDateCreated || dateUtils.utcNowDateTime(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             noteId: this.noteId, |  | ||||||
|             notePath: this.notePath, |  | ||||||
|             utcDateCreated: this.utcDateCreated |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BRecentNote; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| @ -1,259 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Source: becca/entities/brevision.js</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Source: becca/entities/brevision.js</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <section> |  | ||||||
|         <article> |  | ||||||
|             <pre class="prettyprint source linenums"><code>"use strict"; |  | ||||||
| 
 |  | ||||||
| const protectedSessionService = require('../../services/protected_session'); |  | ||||||
| const utils = require('../../services/utils'); |  | ||||||
| const dateUtils = require('../../services/date_utils'); |  | ||||||
| const becca = require('../becca'); |  | ||||||
| const AbstractBeccaEntity = require("./abstract_becca_entity"); |  | ||||||
| const sql = require("../../services/sql"); |  | ||||||
| const BAttachment = require("./battachment"); |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Revision represents a snapshot of note's title and content at some point in the past. |  | ||||||
|  * It's used for seamless note versioning. |  | ||||||
|  * |  | ||||||
|  * @extends AbstractBeccaEntity |  | ||||||
|  */ |  | ||||||
| class BRevision extends AbstractBeccaEntity { |  | ||||||
|     static get entityName() { return "revisions"; } |  | ||||||
|     static get primaryKeyName() { return "revisionId"; } |  | ||||||
|     static get hashedProperties() { return ["revisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", |  | ||||||
|                                             "utcDateLastEdited", "utcDateCreated", "utcDateModified", "blobId"]; } |  | ||||||
| 
 |  | ||||||
|     constructor(row, titleDecrypted = false) { |  | ||||||
|         super(); |  | ||||||
| 
 |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.revisionId = row.revisionId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.noteId = row.noteId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.type = row.type; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.mime = row.mime; |  | ||||||
|         /** @type {boolean} */ |  | ||||||
|         this.isProtected = !!row.isProtected; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.title = row.title; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.blobId = row.blobId; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.dateLastEdited = row.dateLastEdited; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.dateCreated = row.dateCreated; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateLastEdited = row.utcDateLastEdited; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateCreated = row.utcDateCreated; |  | ||||||
|         /** @type {string} */ |  | ||||||
|         this.utcDateModified = row.utcDateModified; |  | ||||||
|         /** @type {int} */ |  | ||||||
|         this.contentLength = row.contentLength; |  | ||||||
| 
 |  | ||||||
|         if (this.isProtected && !titleDecrypted) { |  | ||||||
|             this.title = protectedSessionService.isProtectedSessionAvailable() |  | ||||||
|                 ? protectedSessionService.decryptString(this.title) |  | ||||||
|                 : "[protected]"; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getNote() { |  | ||||||
|         return becca.notes[this.noteId]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {boolean} true if the note has string content (not binary) */ |  | ||||||
|     hasStringContent() { |  | ||||||
|         return utils.isStringNote(this.type, this.mime); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     isContentAvailable() { |  | ||||||
|         return !this.revisionId // new note which was not encrypted yet |  | ||||||
|             || !this.isProtected |  | ||||||
|             || protectedSessionService.isProtectedSessionAvailable() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* |  | ||||||
|      * Note revision content has quite special handling - it's not a separate entity, but a lazily loaded |  | ||||||
|      * part of Revision entity with its own sync. The reason behind this hybrid design is that |  | ||||||
|      * content can be quite large, and it's not necessary to load it / fill memory for any note access even |  | ||||||
|      * if we don't need a content, especially for bulk operations like search. |  | ||||||
|      * |  | ||||||
|      * This is the same approach as is used for Note's content. |  | ||||||
|      */ |  | ||||||
| 
 |  | ||||||
|     /** @returns {string|Buffer} */ |  | ||||||
|     getContent() { |  | ||||||
|         return this._getContent(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @returns {*} |  | ||||||
|      * @throws Error in case of invalid JSON */ |  | ||||||
|     getJsonContent() { |  | ||||||
|         const content = this.getContent(); |  | ||||||
| 
 |  | ||||||
|         if (!content || !content.trim()) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return JSON.parse(content); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {*|null} valid object or null if the content cannot be parsed as JSON */ |  | ||||||
|     getJsonContentSafely() { |  | ||||||
|         try { |  | ||||||
|             return this.getJsonContent(); |  | ||||||
|         } |  | ||||||
|         catch (e) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * @param content |  | ||||||
|      * @param {object} [opts] |  | ||||||
|      * @param {object} [opts.forceSave=false] - will also save this BRevision entity |  | ||||||
|      */ |  | ||||||
|     setContent(content, opts) { |  | ||||||
|         this._setContent(content, opts); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BAttachment[]} */ |  | ||||||
|     getAttachments() { |  | ||||||
|         return sql.getRows(` |  | ||||||
|                 SELECT attachments.* |  | ||||||
|                 FROM attachments  |  | ||||||
|                 WHERE ownerId = ?  |  | ||||||
|                   AND isDeleted = 0`, [this.revisionId]) |  | ||||||
|             .map(row => new BAttachment(row)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BAttachment|null} */ |  | ||||||
|     getAttachmentById(attachmentId, opts = {}) { |  | ||||||
|         opts.includeContentLength = !!opts.includeContentLength; |  | ||||||
| 
 |  | ||||||
|         const query = opts.includeContentLength |  | ||||||
|             ? `SELECT attachments.*, LENGTH(blobs.content) AS contentLength |  | ||||||
|                FROM attachments  |  | ||||||
|                JOIN blobs USING (blobId)  |  | ||||||
|                WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0` |  | ||||||
|             : `SELECT * FROM attachments WHERE ownerId = ? AND attachmentId = ? AND isDeleted = 0`; |  | ||||||
| 
 |  | ||||||
|         return sql.getRows(query, [this.revisionId, attachmentId]) |  | ||||||
|             .map(row => new BAttachment(row))[0]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BAttachment[]} */ |  | ||||||
|     getAttachmentsByRole(role) { |  | ||||||
|         return sql.getRows(` |  | ||||||
|                 SELECT attachments.* |  | ||||||
|                 FROM attachments  |  | ||||||
|                 WHERE ownerId = ?  |  | ||||||
|                   AND role = ? |  | ||||||
|                   AND isDeleted = 0 |  | ||||||
|                 ORDER BY position`, [this.revisionId, role]) |  | ||||||
|             .map(row => new BAttachment(row)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** @returns {BAttachment} */ |  | ||||||
|     getAttachmentByTitle(title) { |  | ||||||
|         // cannot use SQL to filter by title since it can be encrypted |  | ||||||
|         return this.getAttachments().filter(attachment => attachment.title === title)[0]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     beforeSaving() { |  | ||||||
|         super.beforeSaving(); |  | ||||||
| 
 |  | ||||||
|         this.utcDateModified = dateUtils.utcNowDateTime(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojo() { |  | ||||||
|         return { |  | ||||||
|             revisionId: this.revisionId, |  | ||||||
|             noteId: this.noteId, |  | ||||||
|             type: this.type, |  | ||||||
|             mime: this.mime, |  | ||||||
|             isProtected: this.isProtected, |  | ||||||
|             title: this.title, |  | ||||||
|             blobId: this.blobId, |  | ||||||
|             dateLastEdited: this.dateLastEdited, |  | ||||||
|             dateCreated: this.dateCreated, |  | ||||||
|             utcDateLastEdited: this.utcDateLastEdited, |  | ||||||
|             utcDateCreated: this.utcDateCreated, |  | ||||||
|             utcDateModified: this.utcDateModified, |  | ||||||
|             content: this.content, // used when retrieving full note revision to frontend |  | ||||||
|             contentLength: this.contentLength |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     getPojoToSave() { |  | ||||||
|         const pojo = this.getPojo(); |  | ||||||
|         delete pojo.content; // not getting persisted |  | ||||||
|         delete pojo.contentLength; // not getting persisted |  | ||||||
| 
 |  | ||||||
|         if (pojo.isProtected) { |  | ||||||
|             if (protectedSessionService.isProtectedSessionAvailable()) { |  | ||||||
|                 pojo.title = protectedSessionService.encrypt(this.title); |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 // updating protected note outside of protected session means we will keep original ciphertexts |  | ||||||
|                 delete pojo.title; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return pojo; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = BRevision; |  | ||||||
| </code></pre> |  | ||||||
|         </article> |  | ||||||
|     </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
							
								
								
									
										34
									
								
								docs/backend_api/classes/becca_entities_bblob.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										57
									
								
								docs/backend_api/classes/becca_entities_bbranch.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										347
									
								
								docs/backend_api/classes/becca_entities_bnote.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										34
									
								
								docs/backend_api/classes/becca_entities_boption.default.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| Before Width: | Height: | Size: 116 KiB | 
| Before Width: | Height: | Size: 118 KiB | 
| Before Width: | Height: | Size: 120 KiB | 
| Before Width: | Height: | Size: 114 KiB | 
| Before Width: | Height: | Size: 120 KiB | 
| Before Width: | Height: | Size: 117 KiB | 
| @ -1,657 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="utf-8"> |  | ||||||
|     <title>JSDoc: Global</title> |  | ||||||
| 
 |  | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> |  | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> |  | ||||||
|     <!--[if lt IE 9]> |  | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |  | ||||||
|     <![endif]--> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |  | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| 
 |  | ||||||
| <div id="main"> |  | ||||||
| 
 |  | ||||||
|     <h1 class="page-title">Global</h1> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <section> |  | ||||||
| 
 |  | ||||||
| <header> |  | ||||||
|      |  | ||||||
|         <h2></h2> |  | ||||||
|          |  | ||||||
|      |  | ||||||
| </header> |  | ||||||
| 
 |  | ||||||
| <article> |  | ||||||
|     <div class="container-overview"> |  | ||||||
|      |  | ||||||
|          |  | ||||||
| 
 |  | ||||||
|          |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <dl class="details"> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| </dl> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|          |  | ||||||
|      |  | ||||||
|     </div> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|         <h3 class="subsection-title">Members</h3> |  | ||||||
| 
 |  | ||||||
|          |  | ||||||
|              |  | ||||||
| <h4 class="name" id="api"><span class="type-signature"></span>api<span class="type-signature"> :<a href="BackendScriptApi.html">BackendScriptApi</a></span></h4> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <div class="description"> |  | ||||||
|     An instance of the frontend api available globally. |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <h5>Type:</h5> |  | ||||||
|     <ul> |  | ||||||
|         <li> |  | ||||||
|              |  | ||||||
| <span class="param-type"><a href="BackendScriptApi.html">BackendScriptApi</a></span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         </li> |  | ||||||
|     </ul> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <dl class="details"> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <dt class="tag-source">Source:</dt> |  | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |  | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line32">line 32</a> |  | ||||||
|     </li></ul></dd> |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| </dl> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|          |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|         <h3 class="subsection-title">Type Definitions</h3> |  | ||||||
| 
 |  | ||||||
|          |  | ||||||
|                  |  | ||||||
| <h4 class="name" id="AttributeType">AttributeType</h4> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <div class="description"> |  | ||||||
|     There are currently only two types of attributes, labels or relations. |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <h5>Type:</h5> |  | ||||||
|     <ul> |  | ||||||
|         <li> |  | ||||||
|              |  | ||||||
| <span class="param-type">"label"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"relation"</span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         </li> |  | ||||||
|     </ul> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <dl class="details"> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <dt class="tag-source">Source:</dt> |  | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |  | ||||||
|         <a href="becca_entities_battribute.js.html">becca/entities/battribute.js</a>, <a href="becca_entities_battribute.js.html#line11">line 11</a> |  | ||||||
|     </li></ul></dd> |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| </dl> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <h4 class="name" id="NotePathRecord">NotePathRecord</h4> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <h5>Type:</h5> |  | ||||||
|     <ul> |  | ||||||
|         <li> |  | ||||||
|              |  | ||||||
| <span class="param-type">Object</span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         </li> |  | ||||||
|     </ul> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <h5 class="subsection-title">Properties:</h5> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| <table class="props"> |  | ||||||
|     <thead> |  | ||||||
|     <tr> |  | ||||||
|          |  | ||||||
|         <th>Name</th> |  | ||||||
|          |  | ||||||
| 
 |  | ||||||
|         <th>Type</th> |  | ||||||
| 
 |  | ||||||
|          |  | ||||||
| 
 |  | ||||||
|          |  | ||||||
| 
 |  | ||||||
|         <th class="last">Description</th> |  | ||||||
|     </tr> |  | ||||||
|     </thead> |  | ||||||
| 
 |  | ||||||
|     <tbody> |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>isArchived</code></td> |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">boolean</span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="description last"></td> |  | ||||||
|         </tr> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>isInHoistedSubTree</code></td> |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">boolean</span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="description last"></td> |  | ||||||
|         </tr> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>notePath</code></td> |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">Array.<string></span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="description last"></td> |  | ||||||
|         </tr> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|         <tr> |  | ||||||
|              |  | ||||||
|                 <td class="name"><code>isHidden</code></td> |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="type"> |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <span class="param-type">boolean</span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|             </td> |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
| 
 |  | ||||||
|             <td class="description last"></td> |  | ||||||
|         </tr> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     </tbody> |  | ||||||
| </table> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <dl class="details"> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <dt class="tag-source">Source:</dt> |  | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |  | ||||||
|         <a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line27">line 27</a> |  | ||||||
|     </li></ul></dd> |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| </dl> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <h4 class="name" id="NoteType">NoteType</h4> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <div class="description"> |  | ||||||
|     There are many different Note types, some of which are entirely opaque to the |  | ||||||
| end user. Those types should be used only for checking against, they are |  | ||||||
| not for direct use. |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <h5>Type:</h5> |  | ||||||
|     <ul> |  | ||||||
|         <li> |  | ||||||
|              |  | ||||||
| <span class="param-type">"file"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"image"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"search"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"noteMap"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"launcher"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"doc"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"contentWidget"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"text"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"relationMap"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"render"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"canvas"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"mermaid"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"book"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"webView"</span> |  | ||||||
| | |  | ||||||
| 
 |  | ||||||
| <span class="param-type">"code"</span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         </li> |  | ||||||
|     </ul> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <dl class="details"> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <dt class="tag-source">Source:</dt> |  | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |  | ||||||
|         <a href="becca_entities_bnote.js.html">becca/entities/bnote.js</a>, <a href="becca_entities_bnote.js.html#line20">line 20</a> |  | ||||||
|     </li></ul></dd> |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| </dl> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|                  |  | ||||||
| <h4 class="name" id="int">int</h4> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <div class="description"> |  | ||||||
|     A whole number |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <h5>Type:</h5> |  | ||||||
|     <ul> |  | ||||||
|         <li> |  | ||||||
|              |  | ||||||
| <span class="param-type">number</span> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         </li> |  | ||||||
|     </ul> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| <dl class="details"> |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     <dt class="tag-source">Source:</dt> |  | ||||||
|     <dd class="tag-source"><ul class="dummy"><li> |  | ||||||
|         <a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line27">line 27</a> |  | ||||||
|     </li></ul></dd> |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| </dl> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|              |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| </article> |  | ||||||
| 
 |  | ||||||
| </section> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
							
								
								
									
										1
									
								
								docs/backend_api/hierarchy.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -1,65 +1,87 @@ | |||||||
| <!DOCTYPE html> | <!DOCTYPE html><html class="default" lang="en" data-base="."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>trilium</title><meta name="description" content="Documentation for trilium"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script><script async src="assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">trilium</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h1>trilium</h1></div><div class="tsd-panel tsd-typography"><a id="triliumnext-notes" class="tsd-anchor"></a><h1 class="tsd-anchor-link">TriliumNext Notes<a href="#triliumnext-notes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p><img src="https://img.shields.io/docker/pulls/triliumnext/notes" alt="Docker Pulls"> <img src="https://img.shields.io/github/downloads/triliumnext/notes/total" alt="GitHub Downloads (all assets, all releases)"></p> | ||||||
| <html lang="en"> | <p><a href="media/README.md">English</a> | <a href="media/README-ZH_CN.md">Chinese</a> | <a href="media/README.ru.md">Russian</a> | <a href="media/README.ja.md">Japanese</a> | <a href="media/README.it.md">Italian</a> | <a href="media/README.es.md">Spanish</a></p> | ||||||
| <head> | <p>TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.</p> | ||||||
|     <meta charset="utf-8"> | <p>See <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour" target="_blank" class="external">screenshots</a> for quick overview:</p> | ||||||
|     <title>JSDoc: Home</title> | <p><a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a></p> | ||||||
|  | <a id="⚠️-why-triliumnext" class="tsd-anchor"></a><h2 class="tsd-anchor-link">⚠️ Why TriliumNext?<a href="#⚠️-why-triliumnext" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="https://github.com/zadam/trilium/issues/4620" target="_blank" class="external">The original Trilium project is in maintenance mode</a></p> | ||||||
|  | <a id="migrating-from-trilium" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Migrating from Trilium?<a href="#migrating-from-trilium" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Notes instance. Just upgrade your Trilium instance to the latest version and <a href="#-installation">install TriliumNext/Notes as usual</a></p> | ||||||
|  | <p>Versions up to and including <a href="https://github.com/TriliumNext/Notes/releases/tag/v0.90.4" target="_blank" class="external">v0.90.4</a> are compatible with the latest zadam/trilium version of <a href="https://github.com/zadam/trilium/releases/tag/v0.63.7" target="_blank" class="external">v0.63.7</a>. Any later versions of TriliumNext have their sync versions incremented.</p> | ||||||
|  | <a id="💬-discuss-with-us" class="tsd-anchor"></a><h2 class="tsd-anchor-link">💬 Discuss with us<a href="#💬-discuss-with-us" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have!</p> | ||||||
|  | <ul> | ||||||
|  | <li><a href="https://matrix.to/#/#triliumnext:matrix.org" target="_blank" class="external">Matrix</a> (For synchronous discussions) | ||||||
|  | <ul> | ||||||
|  | <li>The <code>General</code> Matrix room is also bridged to <a href="xmpp:discuss@trilium.thisgreat.party?join">XMPP</a></li> | ||||||
|  | </ul> | ||||||
|  | </li> | ||||||
|  | <li><a href="https://github.com/TriliumNext/Notes/discussions" target="_blank" class="external">Github Discussions</a> (For Asynchronous discussions)</li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/" target="_blank" class="external">Wiki</a> (For common how-to questions and user guides)</li> | ||||||
|  | </ul> | ||||||
|  | <a id="🎁-features" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🎁 Features<a href="#🎁-features" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul> | ||||||
|  | <li>Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see <a href="https://triliumnext.github.io/Docs/Wiki/cloning-notes" target="_blank" class="external">cloning</a>)</li> | ||||||
|  | <li>Rich WYSIWYG note editing including e.g. tables, images and <a href="https://triliumnext.github.io/Docs/Wiki/text-notes" target="_blank" class="external">math</a> with markdown <a href="https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat" target="_blank" class="external">autoformat</a></li> | ||||||
|  | <li>Support for editing <a href="https://triliumnext.github.io/Docs/Wiki/code-notes" target="_blank" class="external">notes with source code</a>, including syntax highlighting</li> | ||||||
|  | <li>Fast and easy <a href="https://triliumnext.github.io/Docs/Wiki/note-navigation" target="_blank" class="external">navigation between notes</a>, full text search and <a href="https://triliumnext.github.io/Docs/Wiki/note-hoisting" target="_blank" class="external">note hoisting</a></li> | ||||||
|  | <li>Seamless <a href="https://triliumnext.github.io/Docs/Wiki/note-revisions" target="_blank" class="external">note versioning</a></li> | ||||||
|  | <li>Note <a href="https://triliumnext.github.io/Docs/Wiki/attributes" target="_blank" class="external">attributes</a> can be used for note organization, querying and advanced <a href="https://triliumnext.github.io/Docs/Wiki/scripts" target="_blank" class="external">scripting</a></li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/synchronization" target="_blank" class="external">Synchronization</a> with self-hosted sync server | ||||||
|  | <ul> | ||||||
|  | <li>there's a <a href="https://trilium.cc/paid-hosting" target="_blank" class="external">3rd party service for hosting synchronisation server</a></li> | ||||||
|  | </ul> | ||||||
|  | </li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/sharing" target="_blank" class="external">Sharing</a> (publishing) notes to public internet</li> | ||||||
|  | <li>Strong <a href="https://triliumnext.github.io/Docs/Wiki/protected-notes" target="_blank" class="external">note encryption</a> with per-note granularity</li> | ||||||
|  | <li>Sketching diagrams with built-in Excalidraw (note type "canvas")</li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/relation-map" target="_blank" class="external">Relation maps</a> and <a href="https://triliumnext.github.io/Docs/Wiki/link-map" target="_blank" class="external">link maps</a> for visualizing notes and their relations</li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/scripts" target="_blank" class="external">Scripting</a> - see <a href="https://triliumnext.github.io/Docs/Wiki/advanced-showcases" target="_blank" class="external">Advanced showcases</a></li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/etapi" target="_blank" class="external">REST API</a> for automation</li> | ||||||
|  | <li>Scales well in both usability and performance upwards of 100 000 notes</li> | ||||||
|  | <li>Touch optimized <a href="https://triliumnext.github.io/Docs/Wiki/mobile-frontend" target="_blank" class="external">mobile frontend</a> for smartphones and tablets</li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/themes" target="_blank" class="external">Night theme</a></li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/evernote-import" target="_blank" class="external">Evernote</a> and <a href="https://triliumnext.github.io/Docs/Wiki/markdown" target="_blank" class="external">Markdown import & export</a></li> | ||||||
|  | <li><a href="https://triliumnext.github.io/Docs/Wiki/web-clipper" target="_blank" class="external">Web Clipper</a> for easy saving of web content</li> | ||||||
|  | </ul> | ||||||
|  | <p>✨ Check out the following third-party resources/communities for more TriliumNext related goodies:</p> | ||||||
|  | <ul> | ||||||
|  | <li><a href="https://github.com/Nriver/awesome-trilium" target="_blank" class="external">awesome-trilium</a> for 3rd party themes, scripts, plugins and more.</li> | ||||||
|  | <li><a href="https://trilium.rocks/" target="_blank" class="external">TriliumRocks!</a> for tutorials, guides, and much more.</li> | ||||||
|  | </ul> | ||||||
|  | <a id="🏗-installation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🏗 Installation<a href="#🏗-installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="desktop" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Desktop<a href="#desktop" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To use TriliumNext on your desktop machine (Linux, MacOS, and Windows) you have a few options:</p> | ||||||
|  | <ul> | ||||||
|  | <li>Download the binary release for your platform from the <a href="https://github.com/TriliumNext/Notes/releases/latest" target="_blank" class="external">latest release page</a>, unzip the package and run the <code>trilium</code> executable.</li> | ||||||
|  | <li>Access TriliumNext via the web interface of a server installation (see below) | ||||||
|  | <ul> | ||||||
|  | <li>Currently only the latest versions of Chrome & Firefox are supported (and tested).</li> | ||||||
|  | </ul> | ||||||
|  | </li> | ||||||
|  | <li>(Coming Soon) TriliumNext will also be provided as a Flatpak</li> | ||||||
|  | </ul> | ||||||
|  | <a id="macos" class="tsd-anchor"></a><h4 class="tsd-anchor-link">MacOS<a href="#macos" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h4><p>Currently when running TriliumNext/Notes on MacOS, you may get the following error:</p> | ||||||
|  | <blockquote> | ||||||
|  | <p>Apple could not verify "TriliumNext Notes" is free of malware and may harm your Mac or compromise your privacy.</p> | ||||||
|  | </blockquote> | ||||||
|  | <p>You will need to run the command on your shell to resolve the error (documented <a href="https://github.com/TriliumNext/Notes/issues/329#issuecomment-2287164137" target="_blank" class="external">here</a>):</p> | ||||||
|  | <pre><code class="bash"><span class="hl-0">xattr</span><span class="hl-1"> </span><span class="hl-2">-c</span><span class="hl-1"> </span><span class="hl-3">"/path/to/Trilium Next.app"</span> | ||||||
|  | </code><button type="button">Copy</button></pre> | ||||||
| 
 | 
 | ||||||
|     <script src="scripts/prettify/prettify.js"> </script> | <a id="mobile" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Mobile<a href="#mobile" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To use TriliumNext on a mobile device:</p> | ||||||
|     <script src="scripts/prettify/lang-css.js"> </script> | <ul> | ||||||
|     <!--[if lt IE 9]> | <li>Use a mobile web browser to access the mobile interface of a server installation (see below)</li> | ||||||
|       <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> | <li>Use of a mobile app is not yet supported (<a href="https://github.com/TriliumNext/Notes/issues/72" target="_blank" class="external">see here</a>) to track mobile improvements.</li> | ||||||
|     <![endif]--> | </ul> | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> | <a id="server" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Server<a href="#server" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>To install TriliumNext on your own server (including via Docker from <a href="https://hub.docker.com/r/triliumnext/notes" target="_blank" class="external">Dockerhub</a>) follow <a href="https://triliumnext.github.io/Docs/Wiki/server-installation" target="_blank" class="external">the server installation docs</a>.</p> | ||||||
|     <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> | <a id="📝-documentation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">📝 Documentation<a href="#📝-documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p><a href="https://triliumnext.github.io/Docs" target="_blank" class="external">See wiki for complete list of documentation pages.</a></p> | ||||||
| </head> | <p>You can also read <a href="https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge" target="_blank" class="external">Patterns of personal knowledge base</a> to get some inspiration on how you might use TriliumNext.</p> | ||||||
|  | <a id="💻-contribute" class="tsd-anchor"></a><h2 class="tsd-anchor-link">💻 Contribute<a href="#💻-contribute" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="code" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Code<a href="#code" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><pre><code class="shell"><span class="hl-0">git</span><span class="hl-1"> </span><span class="hl-3">clone</span><span class="hl-1"> </span><span class="hl-3">https://github.com/TriliumNext/Notes.git</span><br/><span class="hl-0">cd</span><span class="hl-1"> </span><span class="hl-3">Notes</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">install</span><br/><span class="hl-0">npm</span><span class="hl-1"> </span><span class="hl-3">run</span><span class="hl-1"> </span><span class="hl-3">start-server</span> | ||||||
|  | </code><button type="button">Copy</button></pre> | ||||||
| 
 | 
 | ||||||
| <body> | <a id="documentation" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Documentation<a href="#documentation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Head on over to our <a href="https://github.com/TriliumNext/Docs" target="_blank" class="external">Docs repo</a></p> | ||||||
| 
 | <a id="👏-shoutouts" class="tsd-anchor"></a><h2 class="tsd-anchor-link">👏 Shoutouts<a href="#👏-shoutouts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul> | ||||||
| <div id="main"> | <li><a href="https://github.com/ckeditor/ckeditor5" target="_blank" class="external">CKEditor 5</a> - best WYSIWYG editor on the market, very interactive and listening team</li> | ||||||
| 
 | <li><a href="https://github.com/mar10/fancytree" target="_blank" class="external">FancyTree</a> - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it.</li> | ||||||
|     <h1 class="page-title">Home</h1> | <li><a href="https://github.com/codemirror/CodeMirror" target="_blank" class="external">CodeMirror</a> - code editor with support for huge amount of languages</li> | ||||||
| 
 | <li><a href="https://github.com/jsplumb/jsplumb" target="_blank" class="external">jsPlumb</a> - visual connectivity library without competition. Used in <a href="https://triliumnext.github.io/Docs/Wiki/relation-map.html" target="_blank" class="external">relation maps</a> and <a href="https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map" target="_blank" class="external">link maps</a></li> | ||||||
|      | </ul> | ||||||
| 
 | <a id="🤝-support" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🤝 Support<a href="#🤝-support" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>You can support the original Trilium developer using GitHub Sponsors, <a href="https://paypal.me/za4am" target="_blank" class="external">PayPal</a> or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||||
| 
 | Support for the TriliumNext organization will be possible in the near future.</p> | ||||||
| 
 | <a id="🔑-license" class="tsd-anchor"></a><h2 class="tsd-anchor-link">🔑 License<a href="#🔑-license" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><p>This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</p> | ||||||
|      | </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#triliumnext-notes"><span>Trilium<wbr/>Next <wbr/>Notes</span></a><ul><li><a href="#⚠️-why-triliumnext"><span>⚠️ <wbr/>Why <wbr/>Trilium<wbr/>Next?</span></a></li><li><ul><li><a href="#migrating-from-trilium"><span>Migrating from <wbr/>Trilium?</span></a></li></ul></li><li><a href="#💬-discuss-with-us"><span>💬 <wbr/>Discuss with us</span></a></li><li><a href="#🎁-features"><span>🎁 <wbr/>Features</span></a></li><li><a href="#🏗-installation"><span>🏗 <wbr/>Installation</span></a></li><li><ul><li><a href="#desktop"><span>Desktop</span></a></li><li><ul><li><a href="#macos"><span>MacOS</span></a></li></ul></li><li><a href="#mobile"><span>Mobile</span></a></li><li><a href="#server"><span>Server</span></a></li></ul></li><li><a href="#📝-documentation"><span>📝 <wbr/>Documentation</span></a></li><li><a href="#💻-contribute"><span>💻 <wbr/>Contribute</span></a></li><li><ul><li><a href="#code"><span>Code</span></a></li><li><a href="#documentation"><span>Documentation</span></a></li></ul></li><li><a href="#👏-shoutouts"><span>👏 <wbr/>Shoutouts</span></a></li><li><a href="#🤝-support"><span>🤝 <wbr/>Support</span></a></li><li><a href="#🔑-license"><span>🔑 <wbr/>License</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html">trilium</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html> | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <h3> </h3> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <nav> |  | ||||||
|     <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-sql.html">sql</a></li></ul><h3>Classes</h3><ul><li><a href="AbstractBeccaEntity.html">AbstractBeccaEntity</a></li><li><a href="BAttachment.html">BAttachment</a></li><li><a href="BAttribute.html">BAttribute</a></li><li><a href="BBranch.html">BBranch</a></li><li><a href="BEtapiToken.html">BEtapiToken</a></li><li><a href="BNote.html">BNote</a></li><li><a href="BOption.html">BOption</a></li><li><a href="BRecentNote.html">BRecentNote</a></li><li><a href="BRevision.html">BRevision</a></li><li><a href="BackendScriptApi.html">BackendScriptApi</a></li></ul><h3>Global</h3><ul><li><a href="global.html#api">api</a></li></ul> |  | ||||||
| </nav> |  | ||||||
| 
 |  | ||||||
| <br class="clear"> |  | ||||||
| 
 |  | ||||||
| <footer> |  | ||||||
|     Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.2</a> |  | ||||||
| </footer> |  | ||||||
| 
 |  | ||||||
| <script> prettyPrint(); </script> |  | ||||||
| <script src="scripts/linenumber.js"> </script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								docs/backend_api/interfaces/becca_entities_rows.NoteRow.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,11 @@ | |||||||
|  | <!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>OptionRow | trilium</title><meta name="description" content="Documentation for trilium"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">trilium</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">trilium</a></li><li><a href="../modules/becca_entities_rows.html">becca/entities/rows</a></li><li><a href="becca_entities_rows.OptionRow.html">OptionRow</a></li></ul><h1>Interface OptionRow</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>Database representation of an option.</p> | ||||||
|  | <p>Options are key-value pairs that are used to store information such as user preferences (for example | ||||||
|  | the current theme, sync server information), but also information about the state of the application).</p> | ||||||
|  | </div><div class="tsd-comment tsd-typography"></div></section><div class="tsd-signature"><span class="tsd-signature-keyword">interface</span> <span class="tsd-kind-interface">OptionRow</span> <span class="tsd-signature-symbol">{</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#issynced">isSynced</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#name">name</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#utcdatemodified">utcDateModified</a><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="becca_entities_rows.OptionRow.html#value">value</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/><span class="tsd-signature-symbol">}</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/84d173808523b9d88c8992ee8ef26b563610c591/src/becca/entities/rows.ts#L47">becca/entities/rows.ts:47</a></li></ul></aside><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Properties</h3><div class="tsd-index-list"><a href="becca_entities_rows.OptionRow.html#issynced" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>is<wbr/>Synced</span></a> | ||||||
|  | <a href="becca_entities_rows.OptionRow.html#name" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>name</span></a> | ||||||
|  | <a href="becca_entities_rows.OptionRow.html#utcdatemodified" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>utc<wbr/>Date<wbr/>Modified?</span></a> | ||||||
|  | <a href="becca_entities_rows.OptionRow.html#value" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>value</span></a> | ||||||
|  | </div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Properties"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Properties</h2></summary><section><section class="tsd-panel tsd-member"><a id="issynced" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>is<wbr/>Synced</span><a href="#issynced" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">isSynced</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">boolean</span></div><div class="tsd-comment tsd-typography"><p><code>true</code> if the value should be synced across multiple instances (e.g. locale) or <code>false</code> if it should be local-only (e.g. theme).</p> | ||||||
|  | </div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/84d173808523b9d88c8992ee8ef26b563610c591/src/becca/entities/rows.ts#L53">becca/entities/rows.ts:53</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="name" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>name</span><a href="#name" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">name</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>The name of the option.</p> | ||||||
|  | </div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/84d173808523b9d88c8992ee8ef26b563610c591/src/becca/entities/rows.ts#L49">becca/entities/rows.ts:49</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="utcdatemodified" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><code class="tsd-tag">Optional</code><span>utc<wbr/>Date<wbr/>Modified</span><a href="#utcdatemodified" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">utcDateModified</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">string</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/84d173808523b9d88c8992ee8ef26b563610c591/src/becca/entities/rows.ts#L54">becca/entities/rows.ts:54</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="value" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>value</span><a href="#value" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">value</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>The value of the option.</p> | ||||||
|  | </div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/TriliumNext/Notes/blob/84d173808523b9d88c8992ee8ef26b563610c591/src/becca/entities/rows.ts#L51">becca/entities/rows.ts:51</a></li></ul></aside></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#issynced" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>is<wbr/>Synced</span></a><a href="#name" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>name</span></a><a href="#utcdatemodified" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>utc<wbr/>Date<wbr/>Modified</span></a><a href="#value" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>value</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">trilium</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html> | ||||||
							
								
								
									
										97
									
								
								docs/backend_api/media/README-ZH_CN.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,97 @@ | |||||||
|  | # TriliumNext Notes | ||||||
|  | 
 | ||||||
|  | [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||||
|  | 
 | ||||||
|  | TriliumNext Notes 是一个层次化的笔记应用程序,专注于建立大型个人知识库。请参阅[屏幕截图](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)以快速了解: | ||||||
|  | 
 | ||||||
|  | <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||||
|  | 
 | ||||||
|  | ## ⚠️ 为什么选择TriliumNext? | ||||||
|  | 
 | ||||||
|  | [原始的Trilium项目目前处于维护模式](https://github.com/zadam/trilium/issues/4620) | ||||||
|  | 
 | ||||||
|  | ## 🗭 与我们讨论 | ||||||
|  | 
 | ||||||
|  | 欢迎加入我们的官方讨论和社区。我们专注于Trilium的开发,乐于听取您对功能、建议或问题的意见! | ||||||
|  | 
 | ||||||
|  | - [Matrix](https://matrix.to/#/#triliumnext:matrix.org)(用于同步讨论) | ||||||
|  | - [Github Discussions](https://github.com/TriliumNext/Notes/discussions)(用于异步讨论) | ||||||
|  | - [Wiki](https://triliumnext.github.io/Docs/)(用于常见操作问题和用户指南) | ||||||
|  | 
 | ||||||
|  | 上面链接的两个房间是镜像的,所以您可以在任意平台上使用XMPP或者Matrix来和我们交流。 | ||||||
|  | 
 | ||||||
|  | ### 非官方社区 | ||||||
|  | 
 | ||||||
|  | [Trilium Rocks](https://discord.gg/aqdX9mXX4r) | ||||||
|  | 
 | ||||||
|  | ## 🎁 特性 | ||||||
|  | 
 | ||||||
|  | * 笔记可以排列成任意深的树。单个笔记可以放在树中的多个位置(请参阅[克隆](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||||
|  | * 丰富的所见即所得笔记编辑功能,包括带有 Markdown [自动格式化功能的](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)表格,图像和[数学公式](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) | ||||||
|  | * 支持编辑[使用源代码的笔记](https://triliumnext.github.io/Docs/Wiki/code-notes),包括语法高亮显示 | ||||||
|  | * 笔记之间快速[导航](https://triliumnext.github.io/Docs/Wiki/note-navigation),全文搜索和[提升笔记](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||||
|  | * 无缝[笔记版本控制](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||||
|  | * 笔记[属性](https://triliumnext.github.io/Docs/Wiki/attributes)可用于笔记组织,查询和高级[脚本编写](https://triliumnext.github.io/Docs/Wiki/scripts) | ||||||
|  | * [同步](https://triliumnext.github.io/Docs/Wiki/synchronization)与自托管同步服务器 | ||||||
|  |   * 有一个[第三方提供的同步服务器托管服务](https://trilium.cc/paid-hosting) | ||||||
|  | * 公开地[分享](https://triliumnext.github.io/Docs/Wiki/sharing)(发布)笔记到互联网 | ||||||
|  | * 具有按笔记粒度的强大的[笔记加密](https://triliumnext.github.io/Docs/Wiki/protected-notes) | ||||||
|  | * 使用自带的 Excalidraw 来绘制图表(笔记类型“画布”) | ||||||
|  | * [关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[链接图](https://triliumnext.github.io/Docs/Wiki/link-map),用于可视化笔记及其关系 | ||||||
|  | * [脚本](https://triliumnext.github.io/Docs/Wiki/scripts) - 请参阅[高级功能展示](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||||
|  | * 可用于自动化的 [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) | ||||||
|  | * 在拥有超过 10 万条笔记时仍能保持良好的可用性和性能 | ||||||
|  | * 针对智能手机和平板电脑进行优化的[用于移动设备的前端](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) | ||||||
|  | * [夜间主题](https://triliumnext.github.io/Docs/Wiki/themes) | ||||||
|  | * [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) 和 [Markdown 导入导出](https://triliumnext.github.io/Docs/Wiki/markdown)功能 | ||||||
|  | * 使用[网页剪藏](https://triliumnext.github.io/Docs/Wiki/web-clipper)轻松保存互联网上的内容 | ||||||
|  | 
 | ||||||
|  | ✨ 查看以下第三方资源,获取更多关于TriliumNext的好东西: | ||||||
|  | 
 | ||||||
|  | - [awesome-trilium](https://github.com/Nriver/awesome-trilium):提供第三方主题、脚本、插件等资源的列表。 | ||||||
|  | - [TriliumRocks!](https://trilium.rocks/):提供教程、指南等更多内容。 | ||||||
|  | 
 | ||||||
|  | ## 🏗 构建 | ||||||
|  | 
 | ||||||
|  | Trilium 可以用作桌面应用程序(Linux 和 Windows)或服务器(Linux)上托管的 Web 应用程序。虽然有 macOS 版本的桌面应用程序,但它[不受支持](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support)。 | ||||||
|  | 
 | ||||||
|  | * 如果要在桌面上使用 Trilium,请从[最新版本](https://github.com/TriliumNext/Notes/releases/latest)下载适用于您平台的二进制版本,解压缩该软件包并运行`trilium`可执行文件。 | ||||||
|  | * 如果要在服务器上安装 Trilium,请参考[此页面](https://triliumnext.github.io/Docs/Wiki/server-installation)。 | ||||||
|  |   * 当前仅支持(测试过)最近发布的 Chrome 和 Firefox 浏览器。 | ||||||
|  | 
 | ||||||
|  | Trilium 也提供 Flatpak: | ||||||
|  | 
 | ||||||
|  | [<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium) | ||||||
|  | 
 | ||||||
|  | ## 📝 文档 | ||||||
|  | 
 | ||||||
|  | [有关文档页面的完整列表,请参见 Wiki。](https://triliumnext.github.io/Docs/) | ||||||
|  | 
 | ||||||
|  | * [Wiki 的中文翻译版本](https://github.com/baddate/trilium/wiki/) | ||||||
|  | 
 | ||||||
|  | 您还可以阅读[个人知识库模式](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge),以获取有关如何使用 Trilium 的灵感。 | ||||||
|  | 
 | ||||||
|  | ## 💻 贡献 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 或者克隆本仓库到本地,并运行 | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | npm install | ||||||
|  | npm run start-server | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 👏 致谢 | ||||||
|  | 
 | ||||||
|  | * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - 市面上最好的所见即所得编辑器,拥有互动性强且聆听能力强的团队 | ||||||
|  | * [FancyTree](https://github.com/mar10/fancytree) - 一个非常丰富的关于树的库,强大到没有对手。没有它,Trilium Notes 将不会如此。 | ||||||
|  | * [CodeMirror](https://github.com/codemirror/CodeMirror) - 支持大量语言的代码编辑器 | ||||||
|  | * [jsPlumb](https://github.com/jsplumb/jsplumb) - 强大的可视化连接库。用于[关系图](https://triliumnext.github.io/Docs/Wiki/relation-map)和[链接图](https://triliumnext.github.io/Docs/Wiki/link-map) | ||||||
|  | 
 | ||||||
|  | ## 🤝 捐赠 | ||||||
|  | 
 | ||||||
|  | 你可以通过 GitHub Sponsors,[PayPal](https://paypal.me/za4am) 或者比特币 (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) 来捐赠。 | ||||||
|  | 
 | ||||||
|  | ## 🔑 许可证 | ||||||
|  | 
 | ||||||
|  | 本程序是自由软件:你可以再发布本软件和/或修改本软件,只要你遵循 Free Software Foundation 发布的 GNU Affero General Public License 的第三版或者任何(由你选择)更晚的版本。 | ||||||
							
								
								
									
										106
									
								
								docs/backend_api/media/README.es.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,106 @@ | |||||||
|  | # TriliumNext Notes | ||||||
|  | 
 | ||||||
|  | [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||||
|  | 
 | ||||||
|  | TriliumNext Notes es una aplicación de toma de notas jerárquicas multi-plataforma y de código libre con un enfoque en la construcción de grandes bases de conocimiento personal. | ||||||
|  | 
 | ||||||
|  | Vea estas [capturas de pantalla](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) para un vistazo rápido: | ||||||
|  | 
 | ||||||
|  | <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||||
|  | 
 | ||||||
|  | ## ⚠️ ¿Por qué usar TriliumNext? | ||||||
|  | 
 | ||||||
|  | [El proyecto Trilium original está en modo de mantenimiento](https://github.com/zadam/trilium/issues/4620) | ||||||
|  | 
 | ||||||
|  | ### ¿Cómo migrar desde Trilium? | ||||||
|  | 
 | ||||||
|  | No hay pasos de migración especiales para migrar de una instancia de zadam/Trilium a una instancia de TriliumNext/Notes. Simplemente actualice su instancia de Trilium a la última versión e [instale TriliumNext/Notes como de costumbre](#-Instalación) | ||||||
|  | 
 | ||||||
|  | ## 💬 Discuta con nosotros | ||||||
|  | 
 | ||||||
|  | Siéntase libre de unirse a nuestras conversaciones oficiales. ¡Nos encantaría escuchar de las características, sugerencias o problemas que pueda tener! | ||||||
|  | 
 | ||||||
|  | - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Para discusiones síncronas) | ||||||
|  |   - La sala `General` es replicada a [XMPP](xmpp:discuss@trilium.thisgreat.party?join) | ||||||
|  | - [Discusiones de GitHub](https://github.com/TriliumNext/Notes/discussions) (Para discusiones asíncronas) | ||||||
|  | - [Wiki](https://triliumnext.github.io/Docs/) (Para preguntas frecuentes y guías de usuario) | ||||||
|  | 
 | ||||||
|  | ## 🎁 Características | ||||||
|  | 
 | ||||||
|  | - Las notas pueden ser acomodadas en un árbol de profundidad arbitraria. Una sola nota puede ser colocada en múltiples lugares del árbol (vea [clonar](https://triliumnext.github.io/Docs/Wiki/cloning-notes) | ||||||
|  | - Edición de notas WYSIWYG enriquecida que incluye, por ejemplo, tablas, imágenes y [matemáticas](https://triliumnext.github.io/Docs/Wiki/text-notes) con [autoformato](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) markdown | ||||||
|  | - Soporte para editar [notas con código fuente](https://triliumnext.github.io/Docs/Wiki/code-notes), incluyendo resaltado de sintaxis | ||||||
|  | - Rápida y sencilla [navegación entre notas](https://triliumnext.github.io/Docs/Wiki/note-navigation), búsqueda de texto completo y [elevación de notas](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||||
|  | - [Versionado de notas](https://triliumnext.github.io/Docs/Wiki/note-revisions) sutil | ||||||
|  | - Los [atributos](https://triliumnext.github.io/Docs/Wiki/attributes) de las notas pueden utilizarse para organización, realizar consultas y [scripts](https://triliumnext.github.io/Docs/Wiki/scripts) avanzados | ||||||
|  | - [Sincronización](https://triliumnext.github.io/Docs/Wiki/synchronization) con servidor de sincronización propio | ||||||
|  |   - existe un [servicio de terceros para alojar el servidor de sincronización](https://trilium.cc/paid-hosting) | ||||||
|  | - [Compartir](https://triliumnext.github.io/Docs/Wiki/sharing) (publicar) notas al Internet público | ||||||
|  | - Fuerte [encriptación de notas](https://triliumnext.github.io/Docs/Wiki/protected-notes) con granularidad para cada nota | ||||||
|  | - Esbozo de diagramas con Excalidraw incorporado (tipo de nota «canvas») | ||||||
|  | - [Mapas de relaciones](<https://triliumnext.github.io/Docs/Wiki/relation-map>) y [mapas de enlaces](https://triliumnext.github.io/Docs/Wiki/link-map) para visualizar las notas y sus relaciones | ||||||
|  | - [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vea [casos de uso avanzados](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||||
|  | - [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) para automatización | ||||||
|  | - Escala bien tanto en uso como en rendimiento a partir de 100,000 notas | ||||||
|  | - [Interfaz móvil](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) optimizada para teléfonos inteligentes y tabletas | ||||||
|  | - [Tema nocturno](https://triliumnext.github.io/Docs/Wiki/themes) | ||||||
|  | - Importación y exportación de [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) y [Markdown](https://triliumnext.github.io/Docs/Wiki/markdown) | ||||||
|  | - [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) para guardar fácilmente contenido web | ||||||
|  | 
 | ||||||
|  | ✨ Consulte los/las siguientes recursos/comunidades de terceros para obtener más información sobre complementos para TriliumNext: | ||||||
|  | 
 | ||||||
|  | - [awesome-trilium](https://github.com/Nriver/awesome-trilium) para temas, scripts, plugins y más de terceros. | ||||||
|  | - [TriliumRocks!](https://trilium.rocks/) para tutoriales, guías y mucho más. | ||||||
|  | 
 | ||||||
|  | ## 🏗 Instalación | ||||||
|  | 
 | ||||||
|  | ### Escritorio | ||||||
|  | 
 | ||||||
|  | Para usar TriliumNext en su máquina de escritorio (Linux, MacOS y Windows) tiene algunas opciones: | ||||||
|  | 
 | ||||||
|  | - Descargue la versión binaria para su plataforma desde la [página de lanzamientos](https://github.com/TriliumNext/Notes/releases/latest), descomprima el paquete y ejecute el ejecutable `trilium`. | ||||||
|  | - Acceda a TriliumNext a través de la interfaz web de una instalación de servidor (ver más abajo) | ||||||
|  |   - Actualmente solo las últimas versiones de Chrome y Firefox son compatibles (y están probadas). | ||||||
|  | - (Próximamente) TriliumNext también se proporcionará como un Flatpak | ||||||
|  | 
 | ||||||
|  | ### Móvil | ||||||
|  | 
 | ||||||
|  | Para usar TriliumNext en un dispositivo móvil: | ||||||
|  | 
 | ||||||
|  | - Utilice un navegador web móvil para acceder a la interfaz móvil de una instalación de servidor (ver más abajo) | ||||||
|  | - El uso de una aplicación móvil aún no está soportado ([vea aquí](https://github.com/TriliumNext/Notes/issues/72)) para seguir las mejoras móviles. | ||||||
|  | 
 | ||||||
|  | ### Servidor | ||||||
|  | 
 | ||||||
|  | Para instalar TriliumNext en su servidor (incluyendo vía Docker desde [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) siga la [documentación de instalación de servidor](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||||
|  | 
 | ||||||
|  | ## 📝 Documentación | ||||||
|  | 
 | ||||||
|  | [Vea la Wiki para la lista completa de páginas de documentación.](https://triliumnext.github.io/Docs) | ||||||
|  | 
 | ||||||
|  | También puede leer [Patrones para una base de conocimiento personal](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) para obtener un poco de inspiración de como podría usar TriliumNext. | ||||||
|  | 
 | ||||||
|  | ## 💻 Contribuir | ||||||
|  | 
 | ||||||
|  | Clone localmente y ejecute | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | npm install | ||||||
|  | npm run start-server | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 👏 Reconocimientos | ||||||
|  | 
 | ||||||
|  | - [CKEditor 5](https://github.com/ckeditor/ckeditor5) - el mejor editor WYSIWYG en el mercado, equipo muy interactivo y atento | ||||||
|  | - [FancyTree](https://github.com/mar10/fancytree) - biblioteca de árbol muy rica en funciones sin competencia real. TriliumNext Notes no sería lo mismo sin esta. | ||||||
|  | - [CodeMirror](https://github.com/codemirror/CodeMirror) - editor de código con soporte para una gran cantidad de lenguajes | ||||||
|  | - [jsPlumb](https://github.com/jsplumb/jsplumb) - biblioteca de conectividad visual sin competencia. Usado en [mapas de relación](https://triliumnext.github.io/Docs/Wiki/Relation-map) y [mapas de enlace](https://triliumnext.github.io/Docs/Wiki/Link-map) | ||||||
|  | 
 | ||||||
|  | ## 🤝 Soporte | ||||||
|  | 
 | ||||||
|  | Puede apoyar al desarrollador original de Trilium usando GitHub Sponsors, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||||
|  | Apoyo para la organización TriliumNext será posible en un futuro próximo. | ||||||
|  | 
 | ||||||
|  | ## 🔑 Licencia | ||||||
|  | 
 | ||||||
|  | Este programa es software libre: puede redistribuirlo y/o modificarlo bajo los términos de la Licencia Pública General de Affero GNU publicada por la Free Software Foundation, ya sea la versión 3 de la Licencia, o (a su elección) cualquier versión posterior. | ||||||
							
								
								
									
										93
									
								
								docs/backend_api/media/README.it.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,93 @@ | |||||||
|  | # TriliumNext Notes | ||||||
|  | 
 | ||||||
|  | [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||||
|  | 
 | ||||||
|  | TriliumNext Notes è un'applicazione per appunti ad organizzazione gerarchica, studiata per la costruzione di archivi di conoscenza personali di grandi dimensioni. | ||||||
|  | 
 | ||||||
|  | Vedi [fotografie](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) per una panoramica veloce: | ||||||
|  | 
 | ||||||
|  | <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||||
|  | 
 | ||||||
|  | ## ⚠️ Perchè TriliumNext? | ||||||
|  | [Il progetto originale Trilium è in modalità di manutenzione](https://github.com/zadam/trilium/issues/4620) | ||||||
|  | 
 | ||||||
|  | ## 🗭 Discuti con noi | ||||||
|  | Sentiti libero di unirti alle nostre discussioni ufficiali e alla nostra comunità. Siamo concentrati sullo sviluppo di Trilium e ci piacerebbe sapere quali funzioni, suggerimenti o eventuali problemi hai! | ||||||
|  | 
 | ||||||
|  | - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (Per discussioni sincrone) | ||||||
|  | - [Discussioni Github](https://github.com/TriliumNext/Notes/discussions) (Per discussioni asincrone) | ||||||
|  | - [Wiki](https://triliumnext.github.io/Docs/) (Per le domande più comuni e le guide per l'utente) | ||||||
|  | 
 | ||||||
|  | Le due stanze linkate sopra sono connesse e contengono gli stessi messaggi, quindi puoi usare XMPP o Matrix da qualsiasi client tu preferisca, praticamente su qualsiasi piattaforma! | ||||||
|  | ### Comunità non ufficiali | ||||||
|  | 
 | ||||||
|  | [Trilium Rocks](https://discord.gg/aqdX9mXX4r) | ||||||
|  | ## 🎁 Funzionalità | ||||||
|  | 
 | ||||||
|  | * Gli appunti possono essere organizzati in un albero di profondità arbitraria. Un singolo appunto può essere collocato in più posti nell'albero (vedi [clonazione](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||||
|  | * Ricco editor visuale (WYSIWYG), con supporto -tra l'altro- per tabelle, immagini ed [espressioni matematiche](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) e con [formattazione automatica](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) per markdown | ||||||
|  | * Supporto per la modifica di [appunti con codice sorgente](https://triliumnext.github.io/Docs/Wiki/code-notes), con evidenziazione della sintassi | ||||||
|  | * [Navigazione veloce](https://triliumnext.github.io/Docs/Wiki/note-navigation) tra gli appunti, ricerca testuale completa e [fissaggio degli appunti](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||||
|  | * Supporto integrato ed automatico per le [revisioni degli appunti](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||||
|  | * Gli [attributi](https://triliumnext.github.io/Docs/Wiki/attributes) degli appunti possono essere utilizzati per l'organizzazione, per l'interrogazione e per lo scripting avanzato (prorgrammazione). | ||||||
|  | * [Sincronizzazione](https://triliumnext.github.io/Docs/Wiki/synchronization) con un server di sincronizzazione auto-ospitato | ||||||
|  |   * c'è un [servizio di terze parti per ospitare server di sincronizzazione](https://trilium.cc/paid-hosting) | ||||||
|  | * [Condivisione](https://triliumnext.github.io/Docs/Wiki/sharing)  (pubblicazione) di appunti sull'internet pubblico | ||||||
|  | * Robusta [crittografia](https://triliumnext.github.io/Docs/Wiki/protected-notes) configurabile singolarmente per ogni appunto | ||||||
|  | * Disegno di diagrammi con Excalidraw (tipo di appunto "canvas") | ||||||
|  | * [Mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map) per visualizzare gli appunti e le loro relazioni | ||||||
|  | * [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - vedi [Esempi avanzati](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||||
|  | * [API REST](https://triliumnext.github.io/Docs/Wiki/etapi) per l'automazione | ||||||
|  | * Si adatta bene sia in termini di usabilità che di prestazioni fino ad oltre 100 000 appunti | ||||||
|  | * Interfaccia utente ottimizzata per il [mobile](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) (smartphone e tablet) | ||||||
|  | * [Tema Notturno](https://triliumnext.github.io/Docs/Wiki/themes) | ||||||
|  | * Supporto per importazione ed esportazione da e per [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) e [Markdown import](https://triliumnext.github.io/Docs/Wiki/markdown) | ||||||
|  | * [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) per il salvataggio facile di contenuti web | ||||||
|  | 
 | ||||||
|  | ✨ Dai un'occhiata alle seguenti risorse di terze parti per scoprire altre bellezze legate a TriliumNext: | ||||||
|  | 
 | ||||||
|  | -[awesome-trilium](https://github.com/Nriver/awesome-trilium) per temi, script, plugin e altro di terze parti. | ||||||
|  | - [TriliumRocks!](https://trilium.rocks/) per tutorial, guide e molto altro. | ||||||
|  | ## 🏗 Rilasci | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Trilium è fornito come applicazione desktop (Linux e Windows) o come applicazione web ospitata sul tuo server (Linux). La versione desktop per Mac OS è disponibile, ma [non è supportata](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). | ||||||
|  | 
 | ||||||
|  | * Se vuoi usare Trilium sul tuo desktop, scarica il rilascio binario per la tua piattaforma dall'[ultimo rilascio](https://github.com/TriliumNext/Notes/releases/latest), decomprimi l'archivio e avvia l'eseguibile ```trilium```. | ||||||
|  | * Se vuoi installare Trilium su un server, segui [questa pagina](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||||
|  |   * Per ora solo Chrome e Firefox sono i browser supportati (testati). | ||||||
|  | 
 | ||||||
|  | TriliumNext sarà fornito anche come Flatpak: | ||||||
|  | 
 | ||||||
|  | <img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png"> | ||||||
|  | 
 | ||||||
|  | ## 📝 Documentazione | ||||||
|  | 
 | ||||||
|  | [Vedi la wiki per una lista completa delle pagine di documentazione.](https://triliumnext.github.io/Docs/) | ||||||
|  | 
 | ||||||
|  | Puoi anche leggere ["Patterns of personal knowledge base"](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) per avere un'ispirazione su come potresti utilizzare Trilium. | ||||||
|  | 
 | ||||||
|  | ## 💻 Contribuire | ||||||
|  | 
 | ||||||
|  | Clona localmente ed esegui | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | npm install | ||||||
|  | npm run start-server | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 👏 Riconoscimenti | ||||||
|  | 
 | ||||||
|  | * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - miglior editor visuale (WYSIWYG) sul mercato, squadra di sviluppo attenta e reattiva | ||||||
|  | * [FancyTree](https://github.com/mar10/fancytree) -  libreria per alberi molto ricca di funzionalità, senza pari. Trilium Notes non sarebbe lo stesso senza di essa. | ||||||
|  | * [CodeMirror](https://github.com/codemirror/CodeMirror) - editor di codice con supporto per un'enorme quantità di linguaggi. | ||||||
|  | * [jsPlumb](https://github.com/jsplumb/jsplumb) - libreria per la  connettività visuale senza pari. Utilizzata per [mappe relazionali](https://triliumnext.github.io/Docs/Wiki/relation-map) e [mappe di collegamenti](https://triliumnext.github.io/Docs/Wiki/link-map). | ||||||
|  | 
 | ||||||
|  | ## 🤝 Supporto | ||||||
|  | 
 | ||||||
|  | Puoi sostenere lo sviluppatore originale di Trilium utilizzando gli sponsor di GitHub, [PayPal](https://paypal.me/za4am) o Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||||
|  | Il supporto all'organizzazione TriliumNext sarà possibile nel prossimo futuro. | ||||||
|  | 
 | ||||||
|  | ## 🔑 Licenza | ||||||
|  | 
 | ||||||
|  | Questo programma è software libero: è possibile redistribuirlo e/o modificarlo nei termini della GNU Affero General Public License come pubblicata dalla Free Software Foundation, sia la versione 3 della Licenza, o (a propria scelta) qualsiasi versione successiva. | ||||||
							
								
								
									
										73
									
								
								docs/backend_api/media/README.ja.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,73 @@ | |||||||
|  | # TriliumNext Notes | ||||||
|  | 
 | ||||||
|  | [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||||
|  | 
 | ||||||
|  | Trilium Notes は、大規模な個人知識ベースの構築に焦点を当てた、階層型ノートアプリケーションです。概要は[スクリーンショット](https://triliumnext.github.io/Docs/Wiki/screenshot-tour)をご覧ください: | ||||||
|  | 
 | ||||||
|  | <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://raw.githubusercontent.com/wiki/zadam/trilium/images/screenshot.png" alt="Trilium Screenshot" width="1000"></a> | ||||||
|  | 
 | ||||||
|  | ## 🎁 特徴 | ||||||
|  | 
 | ||||||
|  | * ノートは、任意の深さのツリーに配置できます。単一のノートをツリー内の複数の場所に配置できます ([cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes) を参照) | ||||||
|  | * マークダウン[オートフォーマット](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)による、表、画像、[数学](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support)などの豊富な WYSIWYG ノート編集機能 | ||||||
|  | * シンタックスハイライトを含む[ソースコード付きノート](https://triliumnext.github.io/Docs/Wiki/code-notes)の編集をサポート | ||||||
|  | * [ノート間のナビゲーション](https://triliumnext.github.io/Docs/Wiki/note-navigation)、全文検索、[ノートホイスト](https://triliumnext.github.io/Docs/Wiki/note-hoisting)が高速かつ簡単に行えます | ||||||
|  | * シームレスな[ノートのバージョン管理](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||||
|  | * ノート[属性](https://triliumnext.github.io/Docs/Wiki/Attributes)は、ノート整理、クエリ、高度な[スクリプト](https://triliumnext.github.io/Docs/Wiki/scripts)に使用できます | ||||||
|  | * 自己ホスト型同期サーバーとの[同期](https://triliumnext.github.io/Docs/Wiki/synchronization) | ||||||
|  |   * [同期サーバーをホストするサードパーティ・サービス](https://trilium.cc/paid-hosting)があります | ||||||
|  | * 公開インターネットへのノートの[共有](https://triliumnext.github.io/Docs/Wiki/sharing)(公開) | ||||||
|  | * ノートごとの粒度を持つ強力な[ノート暗号化](https://triliumnext.github.io/Docs/Wiki/protected-notes) | ||||||
|  | * 組み込みの Excalidraw を使用した図のスケッチ (ノート タイプ"キャンバス") | ||||||
|  | * ノートとその関係を可視化するための[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)と[リンクマップ](https://triliumnext.github.io/Docs/Wiki/link-map) | ||||||
|  | * [スクリプティング](https://triliumnext.github.io/Docs/Wiki/scripts) - [高度なショーケース](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)を参照 | ||||||
|  | * 自動化のための [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) | ||||||
|  | * ユーザビリティとパフォーマンスの両方で 100 000 ノート以上に拡張可能 | ||||||
|  | * スマートフォンとタブレット向けのタッチ最適化[モバイルフロントエンド](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) | ||||||
|  | * [ナイトテーマ](https://triliumnext.github.io/Docs/Wiki/themes) | ||||||
|  | * [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) と [Markdown のインポートとエクスポート](https://triliumnext.github.io/Docs/Wiki/Markdown) | ||||||
|  | * Web コンテンツを簡単に保存するための [Web クリッパー](https://triliumnext.github.io/Docs/Wiki/web-clipper) | ||||||
|  | 
 | ||||||
|  | サードパーティのテーマ、スクリプト、プラグインなどは、 [awesome-trilium](https://github.com/Nriver/awesome-trilium) をチェックしてください。 | ||||||
|  | 
 | ||||||
|  | ## 🏗 ビルド | ||||||
|  | 
 | ||||||
|  | Trilium は、デスクトップアプリケーション(Linux、Windows)またはサーバー上でホストされるウェブアプリケーション(Linux)として提供されます。 Mac OS のデスクトップビルドも利用可能ですが、 [unsupported](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support) となっています。 | ||||||
|  | 
 | ||||||
|  | * デスクトップで Trilium を使用したい場合は、 [latest release](https://github.com/TriliumNext/Notes/releases/latest) からお使いのプラットフォームのバイナリリリースをダウンロードし、パッケージを解凍して ``trilium`` の実行ファイルを実行してください。 | ||||||
|  | * サーバーに Trilium をインストールする場合は、[このページ](https://triliumnext.github.io/Docs/Wiki/server-installation)に従ってください。 | ||||||
|  |   * 現在、対応(動作確認)しているブラウザは、最近の Chrome と Firefox のみです。 | ||||||
|  | 
 | ||||||
|  | Trilium は Flatpak としても提供されます: | ||||||
|  | 
 | ||||||
|  | [<img width="240" src="https://flathub.org/assets/badges/flathub-badge-en.png">](https://flathub.org/apps/details/com.github.zadam.trilium) | ||||||
|  | 
 | ||||||
|  | ## 📝 ドキュメント | ||||||
|  | 
 | ||||||
|  | [ドキュメントページの全リストはwikiをご覧ください。](https://triliumnext.github.io/Docs/) | ||||||
|  | 
 | ||||||
|  | また、[個人的な知識基盤のパターン](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)を読むと、 Trilium の使い方のヒントを得ることができます。 | ||||||
|  | 
 | ||||||
|  | ## 💻 コントリビュート | ||||||
|  | 
 | ||||||
|  | または、ローカルにクローンして実行 | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | npm install | ||||||
|  | npm run start-server | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 📢 シャウトアウト | ||||||
|  | 
 | ||||||
|  | * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - 市場で最高の WYSIWYG エディター、非常にインタラクティブで聞き上手なチーム | ||||||
|  | * [FancyTree](https://github.com/mar10/fancytree) - 真の競争相手がいない、非常に機能豊富なツリーライブラリです。 Trilium Notes は、これなしでは成り立たないでしょう。 | ||||||
|  | * [CodeMirror](https://github.com/codemirror/CodeMirror) - 膨大な数の言語をサポートするコードエディタ | ||||||
|  | * [jsPlumb](https://github.com/jsplumb/jsplumb) - 競合のないビジュアルコネクティビティライブラリです。[関係図](https://triliumnext.github.io/Docs/Wiki/relation-map)、[リンク図](https://triliumnext.github.io/Docs/Wiki/link-map)で使用。 | ||||||
|  | 
 | ||||||
|  | ## 🤝 サポート | ||||||
|  | 
 | ||||||
|  | GitHub スポンサー、[PayPal](https://paypal.me/za4am)もしくは Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2) にて Trilium をサポートすることができます。 | ||||||
|  | 
 | ||||||
|  | ## 🔑 ライセンス | ||||||
|  | 
 | ||||||
|  | このプログラムはフリーソフトウェアです:フリーソフトウェア財団が発行した GNU Affero General Public License のバージョン3、またはそれ以降のバージョンのいずれかに従って、再配布および/または改変することができます。 | ||||||
							
								
								
									
										126
									
								
								docs/backend_api/media/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,126 @@ | |||||||
|  | # TriliumNext Notes | ||||||
|  | 
 | ||||||
|  |   | ||||||
|  | 
 | ||||||
|  | [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||||
|  | 
 | ||||||
|  | TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases. | ||||||
|  | 
 | ||||||
|  | See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for quick overview: | ||||||
|  | 
 | ||||||
|  | <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||||
|  | 
 | ||||||
|  | ## ⚠️ Why TriliumNext? | ||||||
|  | 
 | ||||||
|  | [The original Trilium project is in maintenance mode](https://github.com/zadam/trilium/issues/4620) | ||||||
|  | 
 | ||||||
|  | ### Migrating from Trilium? | ||||||
|  | 
 | ||||||
|  | There are no special migration steps to migrate from a zadam/Trilium instance to a TriliumNext/Notes instance. Just upgrade your Trilium instance to the latest version and [install TriliumNext/Notes as usual](#-installation) | ||||||
|  | 
 | ||||||
|  | Versions up to and including [v0.90.4](https://github.com/TriliumNext/Notes/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext have their sync versions incremented. | ||||||
|  | 
 | ||||||
|  | ## 💬 Discuss with us | ||||||
|  | 
 | ||||||
|  | Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have! | ||||||
|  | 
 | ||||||
|  | - [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions) | ||||||
|  |   - The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join) | ||||||
|  | - [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For Asynchronous discussions) | ||||||
|  | - [Wiki](https://triliumnext.github.io/Docs/) (For common how-to questions and user guides) | ||||||
|  | 
 | ||||||
|  | ## 🎁 Features | ||||||
|  | 
 | ||||||
|  | * Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||||
|  | * Rich WYSIWYG note editing including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) | ||||||
|  | * Support for editing [notes with source code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax highlighting | ||||||
|  | * Fast and easy [navigation between notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text search and [note hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting) | ||||||
|  | * Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||||
|  | * Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts) | ||||||
|  | * [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server | ||||||
|  |   * there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting) | ||||||
|  | * [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet | ||||||
|  | * Strong [note encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with per-note granularity | ||||||
|  | * Sketching diagrams with built-in Excalidraw (note type "canvas") | ||||||
|  | * [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing notes and their relations | ||||||
|  | * [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||||
|  | * [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation | ||||||
|  | * Scales well in both usability and performance upwards of 100 000 notes | ||||||
|  | * Touch optimized [mobile frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for smartphones and tablets | ||||||
|  | * [Night theme](https://triliumnext.github.io/Docs/Wiki/themes) | ||||||
|  | * [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and [Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown) | ||||||
|  | * [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy saving of web content | ||||||
|  | 
 | ||||||
|  | ✨ Check out the following third-party resources/communities for more TriliumNext related goodies: | ||||||
|  | 
 | ||||||
|  | - [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more. | ||||||
|  | - [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more. | ||||||
|  | 
 | ||||||
|  | ## 🏗 Installation | ||||||
|  | 
 | ||||||
|  | ### Desktop | ||||||
|  | 
 | ||||||
|  | To use TriliumNext on your desktop machine (Linux, MacOS, and Windows) you have a few options: | ||||||
|  | 
 | ||||||
|  | * Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the ```trilium``` executable. | ||||||
|  | * Access TriliumNext via the web interface of a server installation (see below) | ||||||
|  |     * Currently only the latest versions of Chrome & Firefox are supported (and tested). | ||||||
|  | * (Coming Soon) TriliumNext will also be provided as a Flatpak | ||||||
|  | 
 | ||||||
|  | #### MacOS | ||||||
|  | Currently when running TriliumNext/Notes on MacOS, you may get the following error: | ||||||
|  | > Apple could not verify "TriliumNext Notes" is free of malware and may harm your Mac or compromise your privacy. | ||||||
|  | 
 | ||||||
|  | You will need to run the command on your shell to resolve the error (documented [here](https://github.com/TriliumNext/Notes/issues/329#issuecomment-2287164137)): | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | xattr -c "/path/to/Trilium Next.app" | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Mobile | ||||||
|  | 
 | ||||||
|  | To use TriliumNext on a mobile device: | ||||||
|  | 
 | ||||||
|  | * Use a mobile web browser to access the mobile interface of a server installation (see below) | ||||||
|  | * Use of a mobile app is not yet supported ([see here](https://github.com/TriliumNext/Notes/issues/72)) to track mobile improvements. | ||||||
|  | 
 | ||||||
|  | ### Server | ||||||
|  | 
 | ||||||
|  | To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||||
|  | 
 | ||||||
|  | ## 📝 Documentation | ||||||
|  | 
 | ||||||
|  | [See wiki for complete list of documentation pages.](https://triliumnext.github.io/Docs) | ||||||
|  | 
 | ||||||
|  | You can also read [Patterns of personal knowledge base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) to get some inspiration on how you might use TriliumNext. | ||||||
|  | 
 | ||||||
|  | ## 💻 Contribute | ||||||
|  | 
 | ||||||
|  | ### Code | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | git clone https://github.com/TriliumNext/Notes.git | ||||||
|  | cd Notes | ||||||
|  | npm install | ||||||
|  | npm run start-server | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Documentation | ||||||
|  | 
 | ||||||
|  | Head on over to our [Docs repo](https://github.com/TriliumNext/Docs) | ||||||
|  | 
 | ||||||
|  | ## 👏 Shoutouts | ||||||
|  | 
 | ||||||
|  | * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team | ||||||
|  | * [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it. | ||||||
|  | * [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages | ||||||
|  | * [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map) | ||||||
|  | 
 | ||||||
|  | ## 🤝 Support | ||||||
|  | 
 | ||||||
|  | You can support the original Trilium developer using GitHub Sponsors, [PayPal](https://paypal.me/za4am) or Bitcoin (bitcoin:bc1qv3svjn40v89mnkre5vyvs2xw6y8phaltl385d2). | ||||||
|  | Support for the TriliumNext organization will be possible in the near future. | ||||||
|  | 
 | ||||||
|  | ## 🔑 License | ||||||
|  | 
 | ||||||
|  | This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. | ||||||
							
								
								
									
										59
									
								
								docs/backend_api/media/README.ru.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,59 @@ | |||||||
|  | # TriliumNext Notes | ||||||
|  | 
 | ||||||
|  | [English](./README.md) | [Chinese](./README-ZH_CN.md) | [Russian](./README.ru.md) | [Japanese](./README.ja.md) | [Italian](./README.it.md) | [Spanish](./README.es.md) | ||||||
|  | 
 | ||||||
|  | Trilium Notes – это приложение для заметок с иерархической структурой, ориентированное на создание больших персональных баз знаний. Для быстрого ознакомления посмотрите [скриншот-тур](https://triliumnext.github.io/Docs/Wiki/screenshot-tour): | ||||||
|  | 
 | ||||||
|  | <a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="https://github.com/TriliumNext/Docs/blob/main/Wiki/images/screenshot.png?raw=true" alt="Trilium Screenshot" width="1000"></a> | ||||||
|  | 
 | ||||||
|  | ## 🎁 Возможности | ||||||
|  | 
 | ||||||
|  | * Заметки можно расположить в виде дерева произвольной глубины. Отдельную заметку можно разместить в нескольких местах дерева (см. [клонирование](https://triliumnext.github.io/Docs/Wiki/cloning-notes)) | ||||||
|  | * Продвинутый визуальный редактор (WYSIWYG) позволяет работать с таблицами, изображениями, [формулами](https://triliumnext.github.io/Docs/Wiki/text-notes#math-support) и разметкой markdown, имеет [автоформатирование](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat) | ||||||
|  | * Редактирование [заметок с исходным кодом](https://triliumnext.github.io/Docs/Wiki/code-notes), включая подсветку синтаксиса | ||||||
|  | * Быстрая и простая [навигация между заметками](https://triliumnext.github.io/Docs/Wiki/note-navigation), полнотекстовый поиск и [выделение заметок](https://triliumnext.github.io/Docs/Wiki/note-hoisting) в отдельный блок | ||||||
|  | * Бесшовное [версионирование заметки](https://triliumnext.github.io/Docs/Wiki/note-revisions) | ||||||
|  | * Специальные [атрибуты](https://triliumnext.github.io/Docs/Wiki/attributes) позволяют гибко организовать структуру, используются для поиска и продвинутого [скриптинга](https://triliumnext.github.io/Docs/Wiki/scripts) | ||||||
|  | * [Синхронизация](https://triliumnext.github.io/Docs/Wiki/synchronization) заметок со своим сервером | ||||||
|  | * Надёжное [шифрование](https://triliumnext.github.io/Docs/Wiki/protected-notes) с детализацией по каждой заметке | ||||||
|  | * [Карты связей](https://triliumnext.github.io/Docs/Wiki/relation-map) и [карты ссылок](https://triliumnext.github.io/Docs/Wiki/link-map) для визуализации их взяимосвязей | ||||||
|  | * [Скрипты](https://triliumnext.github.io/Docs/Wiki/scripts) - см. [продвинутые примеры](https://triliumnext.github.io/Docs/Wiki/advanced-showcases) | ||||||
|  | * Хорошо масштабируется, как по удобству использования, так и по производительности до 100000 заметок | ||||||
|  | * Оптимизированный [мобильный фронтенд](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) смартфонов и планшетов | ||||||
|  | * [Темная тема](https://triliumnext.github.io/Docs/Wiki/themes) | ||||||
|  | * Импорт и экпорт [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) и данных в [markdown](https://triliumnext.github.io/Docs/Wiki/markdown) формате | ||||||
|  | * [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) для удобного сохранения веб-контента | ||||||
|  | 
 | ||||||
|  | ## 🏗 Сборки | ||||||
|  | 
 | ||||||
|  | Trilium предоставляется в виде десктопного приложения (Linux и Windows) или веб-приложения, размещенного на вашем сервере (Linux). Доступна сборка Mac OS, но она [не поддерживается](https://triliumnext.github.io/Docs/Wiki/faq#mac-os-support). | ||||||
|  | 
 | ||||||
|  | * Если вы хотите использовать Trilium на десктопе, скачайте архив для своей платформы со страницы [релизов](https://github.com/TriliumNext/Notes/releases/latest), распакуйте и запустите исполняемый файл ```trilium```. | ||||||
|  | * Если вы хотите установить Trilium на сервере, следуйте этой [инструкции](https://triliumnext.github.io/Docs/Wiki/server-installation). | ||||||
|  |   * В данный момент поддерживаются (протестированы) последние версии браузеров Chrome и Firefox. | ||||||
|  | 
 | ||||||
|  | ## 📝 Документация | ||||||
|  | 
 | ||||||
|  | [Полный список страниц документации доступен в Wiki.](https://triliumnext.github.io/Docs/) | ||||||
|  | 
 | ||||||
|  | Вы также можете ознакомиться с [шаблонами персональных баз знаний](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge), чтобы получить представление о том, как можно использовать Trilium. | ||||||
|  | 
 | ||||||
|  | ## 💻 Участвуйте в разработке | ||||||
|  | 
 | ||||||
|  | Или склонируйте на своё устройство и запустите | ||||||
|  | 
 | ||||||
|  | ```shell | ||||||
|  | npm install | ||||||
|  | npm run start-server | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ## 👏 Благодарности | ||||||
|  | 
 | ||||||
|  | * [CKEditor 5](https://github.com/ckeditor/ckeditor5) - лучший WYSIWYG редактор, очень активная и внимательная команда. | ||||||
|  | * [FancyTree](https://github.com/mar10/fancytree) - многофункциональная библиотека для создания древовидных структур. Вне конкуренции. Без него Trilium Notes не были бы таким. | ||||||
|  | * [CodeMirror](https://github.com/codemirror/CodeMirror) - редактор кода с поддержкой огромного количество языков. | ||||||
|  | * [jsPlumb](https://github.com/jsplumb/jsplumb) - библиотека для визуализации связей. Вне конкуренции. Используется в [картах связей](https://triliumnext.github.io/Docs/Wiki/relation-map) и [картах ссылок](https://triliumnext.github.io/Docs/Wiki/link-map). | ||||||
|  | 
 | ||||||
|  | ## 🔑 Лицензия | ||||||
|  | 
 | ||||||
|  | Эта программа является бесплатным программным обеспечением: вы можете распространять и/или изменять ее в соответствии с условиями GNU Affero General Public License, опубликованной Free Software Foundation, либо версии 3 Лицензии, либо (по вашему выбору) любой более поздней версии. | ||||||
 CobriMediaJulien
						CobriMediaJulien