├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .idea ├── .gitignore ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── copyright │ ├── Knowledge_Copyright.xml │ └── profiles_settings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── jsLinters │ └── eslint.xml ├── knowledge.iml ├── modules.xml ├── prettier.xml ├── scopes │ ├── HTML_Files.xml │ └── Typescript_Files.xml ├── vcs.xml └── watcherTasks.xml ├── .yarn ├── plugins │ └── @yarnpkg │ │ ├── plugin-interactive-tools.cjs │ │ ├── plugin-typescript.cjs │ │ └── plugin-workspace-tools.cjs └── releases │ └── yarn-3.2.4.cjs ├── .yarnrc.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Resources ├── app.env ├── entitlements.mac.plist ├── examples_v3.json ├── icon.icns ├── icon.ico ├── icon.png ├── icon.svg └── notarize.js ├── package.json ├── src ├── kc_angular │ ├── .browserslistrc │ ├── .editorconfig │ ├── .gitignore │ ├── angular.json │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── animations.ts │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.scss │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── components │ │ │ │ ├── calendar.component.ts │ │ │ │ ├── chat-components │ │ │ │ │ ├── api.component.ts │ │ │ │ │ ├── chat.actions.component.ts │ │ │ │ │ ├── chat.input.component.ts │ │ │ │ │ ├── chat.message.component.ts │ │ │ │ │ ├── chat.toolbar.component.ts │ │ │ │ │ ├── chat.view.component.html │ │ │ │ │ ├── chat.view.component.scss │ │ │ │ │ └── chat.view.component.ts │ │ │ │ ├── chat.component.ts │ │ │ │ ├── graph-components │ │ │ │ │ ├── graph-search.component.ts │ │ │ │ │ ├── graph.canvas.component.ts │ │ │ │ │ ├── graph.controls.component.ts │ │ │ │ │ ├── graph.layouts.ts │ │ │ │ │ ├── graph.status.ts │ │ │ │ │ └── graph.styles.ts │ │ │ │ ├── graph.component.ts │ │ │ │ ├── grid.component.ts │ │ │ │ ├── history.component.ts │ │ │ │ ├── home.component.ts │ │ │ │ ├── project-components │ │ │ │ │ ├── project-breadcrumb.component.ts │ │ │ │ │ ├── project-calendar.component.ts │ │ │ │ │ ├── project-card.component.ts │ │ │ │ │ ├── project-creation-dialog.component.ts │ │ │ │ │ ├── project-details.component.ts │ │ │ │ │ ├── project-selector.component.ts │ │ │ │ │ └── projects-tree.component.ts │ │ │ │ ├── search.component.ts │ │ │ │ ├── settings │ │ │ │ │ ├── chat-settings.component.ts │ │ │ │ │ ├── display-settings.component.ts │ │ │ │ │ ├── graph-settings.component.ts │ │ │ │ │ ├── ingest-settings.component.ts │ │ │ │ │ ├── search-settings.component.ts │ │ │ │ │ ├── setting-template.component.ts │ │ │ │ │ ├── settings.component.ts │ │ │ │ │ └── storage-settings.component.ts │ │ │ │ ├── shared │ │ │ │ │ ├── create.component.ts │ │ │ │ │ ├── icon.component.ts │ │ │ │ │ ├── loading.component.ts │ │ │ │ │ ├── pro-tips.component.ts │ │ │ │ │ └── timeline.component.ts │ │ │ │ ├── source-components │ │ │ │ │ ├── ks-actions.component.ts │ │ │ │ │ ├── ks-card-list.component.html │ │ │ │ │ ├── ks-card-list.component.ts │ │ │ │ │ ├── ks-card.component.ts │ │ │ │ │ ├── ks-details.component.ts │ │ │ │ │ ├── ks-dropzone.component.ts │ │ │ │ │ ├── ks-export.component.ts │ │ │ │ │ ├── ks-icon.component.ts │ │ │ │ │ ├── ks-message.component.ts │ │ │ │ │ ├── ks-preview.component.ts │ │ │ │ │ ├── ks-table.component.ts │ │ │ │ │ ├── ks-thumbnail.component.ts │ │ │ │ │ ├── ks-viewport │ │ │ │ │ │ ├── browser-view.component.ts │ │ │ │ │ │ ├── file-view.component.ts │ │ │ │ │ │ └── viewport-header.component.ts │ │ │ │ │ ├── source.browser.component.ts │ │ │ │ │ ├── source.chat.component.ts │ │ │ │ │ ├── source.component.ts │ │ │ │ │ ├── source.details.component.ts │ │ │ │ │ ├── source.document.component.ts │ │ │ │ │ ├── source.metadata.component.ts │ │ │ │ │ ├── source.notes.component.ts │ │ │ │ │ ├── source.styles.scss │ │ │ │ │ ├── source.timeline.component.ts │ │ │ │ │ └── source.video.component.ts │ │ │ │ └── table.component.ts │ │ │ ├── directives │ │ │ │ ├── pro-tip.directive.ts │ │ │ │ └── recreate-view.directive.ts │ │ │ ├── models │ │ │ │ ├── cards.model.ts │ │ │ │ ├── chat.model.ts │ │ │ │ ├── knowledge.source.model.ts │ │ │ │ ├── project.model.ts │ │ │ │ └── project.tree.model.ts │ │ │ ├── pipes │ │ │ │ ├── countdown.pipe.ts │ │ │ │ ├── import-method.pipe.ts │ │ │ │ ├── ks-ingest-type-icon.pipe.ts │ │ │ │ ├── markdown.pipe.ts │ │ │ │ ├── project-as-tree-node.pipe.ts │ │ │ │ ├── project-breadcrumb.pipe.ts │ │ │ │ ├── project-name.pipe.ts │ │ │ │ ├── sanitize-html.pipe.ts │ │ │ │ ├── switch-label.pipe.ts │ │ │ │ ├── truncate.pipe.ts │ │ │ │ └── view-icon.pipe.ts │ │ │ ├── services │ │ │ │ ├── chat-services │ │ │ │ │ ├── chat.service.ts │ │ │ │ │ ├── guard.ts │ │ │ │ │ ├── project.ts │ │ │ │ │ ├── prompts.ts │ │ │ │ │ └── source.ts │ │ │ │ ├── command-services │ │ │ │ │ ├── ks-command.service.ts │ │ │ │ │ ├── pro-tip.service.ts │ │ │ │ │ └── project-command.service.ts │ │ │ │ ├── factory-services │ │ │ │ │ ├── chat-context-menu.service.ts │ │ │ │ │ ├── ks-context-menu.service.ts │ │ │ │ │ ├── ks-factory.service.ts │ │ │ │ │ ├── markdown.service.ts │ │ │ │ │ ├── project-context-menu.service.ts │ │ │ │ │ ├── project-tree-factory.service.ts │ │ │ │ │ ├── project.service.ts │ │ │ │ │ └── sidebar.service.ts │ │ │ │ ├── ingest-services │ │ │ │ │ ├── autoscan.service.ts │ │ │ │ │ ├── drag-and-drop.service.ts │ │ │ │ │ ├── extension.service.ts │ │ │ │ │ ├── extractor.service.ts │ │ │ │ │ ├── favicon.service.ts │ │ │ │ │ └── ingest.service.ts │ │ │ │ ├── ipc-services │ │ │ │ │ ├── browser-view-dialog.service.ts │ │ │ │ │ ├── electron-ipc.service.ts │ │ │ │ │ ├── settings.service.ts │ │ │ │ │ ├── startup.service.ts │ │ │ │ │ ├── storage.service.ts │ │ │ │ │ └── uuid.service.ts │ │ │ │ └── user-services │ │ │ │ │ ├── data.service.ts │ │ │ │ │ ├── event.service.ts │ │ │ │ │ ├── icon.service.ts │ │ │ │ │ ├── notifications.service.ts │ │ │ │ │ ├── search.service.ts │ │ │ │ │ ├── theme.service.ts │ │ │ │ │ └── topic.service.ts │ │ │ └── workers │ │ │ │ ├── graph.worker.ts │ │ │ │ └── tree.worker.ts │ │ ├── assets │ │ │ ├── .gitkeep │ │ │ ├── favicon.ico │ │ │ └── img │ │ │ │ ├── default.png │ │ │ │ ├── icons │ │ │ │ ├── chrome_icon.svg │ │ │ │ └── firefox_icon.svg │ │ │ │ ├── kc-icon-greyscale.png │ │ │ │ ├── kc-icon-transparent.png │ │ │ │ ├── kc-icon.png │ │ │ │ ├── kc-logo-transparent.svg │ │ │ │ └── kc-logo.svg │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ ├── styles.scss │ │ └── styles │ │ │ ├── kc-styles.scss │ │ │ └── themes │ │ │ ├── arya-blue.scss │ │ │ ├── arya-green.scss │ │ │ ├── arya-orange.scss │ │ │ ├── arya-purple.scss │ │ │ ├── lara-dark-blue.scss │ │ │ ├── lara-dark-indigo.scss │ │ │ ├── lara-dark-purple.scss │ │ │ ├── lara-dark-teal.scss │ │ │ ├── lara-light-blue.scss │ │ │ ├── lara-light-indigo.scss │ │ │ ├── lara-light-purple.scss │ │ │ ├── lara-light-teal.scss │ │ │ ├── saga-blue.scss │ │ │ ├── saga-green.scss │ │ │ ├── saga-orange.scss │ │ │ ├── saga-purple.scss │ │ │ ├── vela-blue.scss │ │ │ ├── vela-green.scss │ │ │ ├── vela-orange.scss │ │ │ └── vela-purple.scss │ ├── tsconfig.json │ └── tsconfig.worker.json ├── kc_electron │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── ipc │ │ │ │ ├── index.ts │ │ │ │ ├── ipc-auto-update.ts │ │ │ │ ├── ipc-browser.ts │ │ │ │ ├── ipc-files.ts │ │ │ │ └── ipc-misc.ts │ │ │ └── services │ │ │ │ ├── auto.update.service.ts │ │ │ │ ├── autoscan.service.ts │ │ │ │ ├── extension.service.ts │ │ │ │ ├── index.ts │ │ │ │ ├── settings.service.ts │ │ │ │ └── window.service.ts │ │ ├── ipc │ │ │ └── chat.ipc.ts │ │ ├── local │ │ │ ├── autoscan.api.ts │ │ │ ├── browser.api.ts │ │ │ ├── chat.api.ts │ │ │ ├── constants │ │ │ │ └── source.prompts.ts │ │ │ ├── controllers │ │ │ │ ├── api.controller.ts │ │ │ │ ├── chat.controller.ts │ │ │ │ ├── project.controller.ts │ │ │ │ └── source.controller.ts │ │ │ ├── middleware │ │ │ │ └── ErrorHandler.ts │ │ │ ├── routes │ │ │ │ ├── api.routes.ts │ │ │ │ ├── chat.routes.ts │ │ │ │ └── source.routes.ts │ │ │ └── utils │ │ │ │ ├── chat.utils.ts │ │ │ │ ├── encrypt.utils.ts │ │ │ │ ├── ipc.utils.ts │ │ │ │ ├── response.util.ts │ │ │ │ ├── text.utils.ts │ │ │ │ └── tokenizer.utils.ts │ │ ├── main.ts │ │ ├── preload.js │ │ └── test │ │ │ ├── autoscan.spec.ts │ │ │ ├── browser.spec.ts │ │ │ ├── chat.spec.ts │ │ │ └── ipc.spec.ts │ ├── tsconfig.json │ ├── webpack.common.js │ ├── webpack.dev.js │ └── webpack.prod.js └── kc_shared │ └── models │ ├── author.model.ts │ ├── browser.view.model.ts │ ├── electron.ipc.model.ts │ ├── event.model.ts │ ├── file.source.model.ts │ ├── graph.model.ts │ ├── hashable.model.ts │ ├── knowledge.source.model.ts │ ├── markup.model.ts │ ├── project.model.ts │ ├── settings.model.ts │ ├── style.model.ts │ ├── topic.model.ts │ ├── uuid.model.ts │ └── web.source.model.ts ├── tsconfig.json └── yarn.lock /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report about: Create a report to help us improve title: '[Bug]: ' 3 | labels: 'bug' assignees: '' 4 | knowledge version: '' 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | --- 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | --- 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | --- 26 | 27 | **Screenshots** 28 | If applicable, add screenshots to help explain your problem. 29 | 30 | --- 31 | 32 | **Operating System (please complete the following information):** 33 | 34 | - OS: [e.g. MacOS /w Apple Slicion (M1), Windows 10, etc.] 35 | - Version: [e.g. Big Sur, 20.04, etc.] 36 | 37 | --- 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template about: Describe this issue template's purpose here. title: '[Request]: ' 3 | labels: 'request' assignees: '' 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request about: Suggest an idea for this project title: '[Feature]: ' 3 | labels: 'feature' assignees: '' 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | 9 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 10 | 11 | --- 12 | 13 | **Describe the solution you'd like** 14 | 15 | A clear and concise description of what you want to happen. 16 | 17 | --- 18 | 19 | **Describe alternatives you've considered** 20 | 21 | A clear and concise description of any alternative solutions or features you've considered. 22 | 23 | --- 24 | 25 | **Additional context** 26 | 27 | Add any other context or screenshots about the feature request here. 28 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '43 6 * * 1' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript', 'typescript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v2 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v2 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS files 2 | .DS_Store 3 | 4 | # Angular files 5 | **/.angular 6 | 7 | 8 | # Jupyter notebook checkpoints 9 | **/*.ipynb_checkpoints 10 | 11 | # Node modules 12 | **/node_modules 13 | 14 | # Build artifacts 15 | **/dist 16 | 17 | # Python stuff 18 | __pycache__ 19 | 20 | # Secret stuff 21 | auth.json 22 | 23 | .pnp.* 24 | .yarn/* 25 | !.yarn/patches 26 | !.yarn/plugins 27 | !.yarn/releases 28 | !.yarn/sdks 29 | !.yarn/versions 30 | 31 | *.d.ts 32 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 23 | 24 | 27 | 28 | 35 | 36 | 43 | 44 | 51 | 52 | 57 | 58 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/copyright/Knowledge_Copyright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/jsLinters/eslint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/knowledge.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/prettier.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/scopes/HTML_Files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/scopes/Typescript_Files.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/watcherTasks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | 3 | plugins: 4 | - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs 5 | spec: "@yarnpkg/plugin-typescript" 6 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs 7 | spec: "@yarnpkg/plugin-workspace-tools" 8 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 9 | spec: "@yarnpkg/plugin-interactive-tools" 10 | 11 | yarnPath: .yarn/releases/yarn-3.2.4.cjs 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | Please make sure you understand the Apache 2.0 license terms before contributing 4 | to this repository. 5 | 6 | # Conventional Commits 7 | 8 | Please read [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) and review the guidelines listed therein. 9 | 10 | We are using the `standard-version` package, which is a tool that automatically updates version numbers, changelog, etc. You can read more 11 | about `standard-version` [here](https://github.com/conventional-changelog/standard-version) 12 | 13 | ## Commit Message Structure 14 | 15 | Commits should use the following structure. This allows `standard-version` to craft a changelog based solely on commits, which should make things easier for us as the project 16 | expands. See [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#examples) for examples. 17 | 18 | ``` 19 | [optional scope]: 20 | 21 | [optional body] 22 | 23 | [optional footer(s)] 24 | ``` 25 | 26 | ## Commit Types 27 | 28 | The following is a non-exhaustive list of commit types (``): 29 | 30 | * `feat` 31 | * `fix` 32 | * `docs` 33 | * `refactor` 34 | * `style` 35 | * `chore` 36 | 37 | # Tags, Releases, and Changelog 38 | 39 | For each release, we create a new branch with the format `release-x.y.z`. 40 | Changes meant to be included in a specific release should be created within a 41 | new branch created from the release in question, and a pull request should be 42 | made to that release branch (not `main`). 43 | 44 | **Example Feature-to-Release Pull Requests** 45 | 46 | - `release-0.5.4 <- feat-ks-info` 47 | - `release-0.5.3 <- feat-extraction-pipeline` 48 | 49 | Once a release is ready for production, a pull request should be created from 50 | `release-x.y.z` to `main`. Then, if/when the release is approved and merged, 51 | an administrator will run the `release` command (as defined in package.json). 52 | This command searches for commit messages of the formats described above, 53 | automatically populates the CHANGELOG, increments the application version number 54 | accordingly, and creates a new tag/release. 55 | 56 | **Example Release-to-Production Pull Request** 57 | 58 | - `main <- release-0.5.4` 59 | 60 | # Installers and Auto-Update 61 | 62 | The final build is currently done manually using 63 | `yarn build -> yarn dist-all -> yarn publish-all`. This creates the relevant 64 | binaries and places them in the `dist` folder, as well as publishes the binaries 65 | to a publicly accessible AWS S3 bucket (requires secret API key to publish). We 66 | push the binaries to AWS S3 to take advantage of Electrons auto-update feature, 67 | which automatically checks for and installs new versions when the application 68 | starts. 69 | 70 | Previously, releases were uploaded to GitHub directly, but due to lack of 71 | transparency in GitHubs metrics and monitoring, we will henceforth link 72 | to the binaries stored on S3 in all of our GitHub releases. This give us a 73 | better insight into things like popularity metrics (total downloads) as well as 74 | more fine-grained control and convenience in distribution. 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introducing Knowledge + Chat 2 | 3 | Dive into a more interactive learning experience with Knowledge's new Chat feature! Engage in dynamic conversations with your Projects and Sources, leveraging the power of Large Language Models. Ask questions, explore concepts, and deepen your understanding, all within an intuitive chat interface. 4 | 5 | The Chat feature is designed to transform the way you interact with your data, offering a more engaging and exploratory approach to learning. Whether you're looking to better comprehend a complex topic or simply exploring new ideas, the Chat feature is your personal knowledge companion. 6 | 7 | # Screenshots 8 | 9 | **Inbox** 10 | 11 | image 12 | 13 | **Graph** 14 | 15 | image 16 | 17 | **Grid** 18 | 19 | image 20 | 21 | # Disclaimer 22 | 23 | *Knowledge* ("this software") is not a consumer product and provides no warranty of any kind. By using this software, 24 | you agree that you are doing so at your own risk. The creators of this software are not responsible for loss of data or 25 | other damages that may result in its operation. You are welcome to open an issue or a pull request. Contributors and 26 | testers are welcome and appreciated. 27 | -------------------------------------------------------------------------------- /Resources/app.env: -------------------------------------------------------------------------------- 1 | appTitle="Knowledge" 2 | settingsFilename="knowledge.settings.json" 3 | DEFAULT_WINDOW_WIDTH=1920 4 | DEFAULT_WINDOW_HEIGHT=1080 5 | STARTUP_WINDOW_WIDTH=1920 6 | STARTUP_WINDOW_HEIGHT=1080 7 | -------------------------------------------------------------------------------- /Resources/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-unsigned-executable-memory 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.cs.disable-library-validation 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Resources/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/Resources/icon.icns -------------------------------------------------------------------------------- /Resources/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/Resources/icon.ico -------------------------------------------------------------------------------- /Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/Resources/icon.png -------------------------------------------------------------------------------- /Resources/notarize.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | require("dotenv").config(); 18 | const { notarize } = require("electron-notarize"); 19 | 20 | exports.default = async function notarizing(context) { 21 | const { electronPlatformName, appOutDir } = context; 22 | if (electronPlatformName !== "darwin") { 23 | return; 24 | } 25 | 26 | const appName = context.packager.appInfo.productFilename; 27 | const appleId = process.env.APPLEID; 28 | const password = process.env.APPLEPWD; 29 | 30 | return await notarize({ 31 | appBundleId: "com.knowledge.canvas.app", 32 | appPath: `${appOutDir}/${appName}.app`, 33 | appleId: appleId, 34 | appleIdPassword: password, 35 | }); 36 | }; 37 | -------------------------------------------------------------------------------- /src/kc_angular/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 18 | -------------------------------------------------------------------------------- /src/kc_angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /src/kc_angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | 16 | # IDEs and editors 17 | /.idea 18 | .project 19 | .classpath 20 | .c9/ 21 | *.launch 22 | .settings/ 23 | *.sublime-workspace 24 | 25 | # IDE - VSCode 26 | .vscode/* 27 | !.vscode/settings.json 28 | !.vscode/tasks.json 29 | !.vscode/launch.json 30 | !.vscode/extensions.json 31 | .history/* 32 | 33 | # misc 34 | /.sass-cache 35 | /connect.lock 36 | /coverage 37 | /libpeerconnection.log 38 | npm-debug.log 39 | yarn-error.log 40 | testem.log 41 | /typings 42 | 43 | # System Files 44 | .DS_Store 45 | Thumbs.db 46 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/animations.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { 17 | animate, 18 | animateChild, 19 | group, 20 | query, 21 | state, 22 | style, 23 | transition, 24 | trigger, 25 | } from '@angular/animations'; 26 | 27 | export const fadeInAndOut = trigger('routeAnimations', [ 28 | transition('* <=> *', [ 29 | style({ position: 'relative' }), 30 | query(':enter, :leave', [ 31 | style({ 32 | position: 'absolute', 33 | top: 0, 34 | left: 0, 35 | width: '100%', 36 | }), 37 | ]), 38 | query(':enter', [style({ opacity: 0 })]), 39 | query(':leave', animateChild(), { optional: true }), 40 | group([ 41 | query(':leave', [animate('300ms ease-out', style({ opacity: 0 }))], { 42 | optional: true, 43 | }), 44 | query(':enter', [animate('500ms ease-out', style({ opacity: 1 }))]), 45 | query('@*', animateChild(), { optional: true }), 46 | ]), 47 | ]), 48 | ]); 49 | 50 | export const flyInOut = [ 51 | trigger('flyInOut', [ 52 | state( 53 | 'in', 54 | style({ 55 | transform: 'translateX(0)', 56 | }) 57 | ), 58 | transition('void => *', [ 59 | style({ 60 | transform: 'translateX(-100%)', 61 | }), 62 | animate(100), 63 | ]), 64 | transition('* => void', [ 65 | animate( 66 | 100, 67 | style({ 68 | transform: 'translateX(-100%)', 69 | }) 70 | ), 71 | ]), 72 | ]), 73 | ]; 74 | 75 | export const fadeIn = [ 76 | trigger('fadeIn', [ 77 | transition(':enter', [ 78 | style({ opacity: 0 }), 79 | animate('1000ms', style({ opacity: 1 })), 80 | ]), 81 | ]), 82 | ]; 83 | 84 | export const fadeOut = [ 85 | trigger('fadeOut', [ 86 | transition(':leave', [ 87 | style({ opacity: 1 }), 88 | animate('1000ms', style({ opacity: 0 })), 89 | ]), 90 | ]), 91 | ]; 92 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | ::ng-deep { 18 | .p-submenu-list { 19 | z-index: 99 !important; 20 | } 21 | 22 | .p-sidebar-content { 23 | height: 100%; 24 | } 25 | } 26 | 27 | .macos-window-button { 28 | height: 1rem; 29 | width: 1rem; 30 | margin-right: 0.6rem; 31 | border-radius: 50%; 32 | } 33 | 34 | .macos-window-button:hover { 35 | box-shadow: inset 0 0 3px 0 black; 36 | } 37 | 38 | .window-button { 39 | height: 32px; 40 | width: 45px; 41 | } 42 | 43 | .window-button-close { 44 | margin-left: 2px; 45 | background-color: #ff5f57; 46 | } 47 | 48 | .window-button-maximize { 49 | background-color: #2bc840; 50 | } 51 | 52 | .window-button-minimize { 53 | background-color: #ffbc2e; 54 | } 55 | 56 | #app-footer { 57 | height: 4rem; 58 | } 59 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/api.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component } from '@angular/core'; 18 | import { DynamicDialogRef } from 'primeng/dynamicdialog'; 19 | import { ChatService } from '@services/chat-services/chat.service'; 20 | 21 | @Component({ 22 | selector: 'app-api', 23 | template: ` 24 |
25 |
26 | OpenAI API Key required to use the Chat feature. The key will be 27 | encrypted and stored locally. 28 |
29 |
30 | 39 |
40 |
41 | 42 |
43 |
44 | `, 45 | styles: [], 46 | }) 47 | export class ChatApiComponent { 48 | constructor(private ref: DynamicDialogRef, private chat: ChatService) {} 49 | 50 | async saveApiKey(apiKey: string) { 51 | this.chat.setApiKey(apiKey).subscribe( 52 | (result: { success: boolean }) => { 53 | this.ref.close(result.success); 54 | }, 55 | () => { 56 | this.ref.close(false); 57 | } 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/chat.actions.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 18 | import { AgentType } from '@app/models/chat.model'; 19 | 20 | @Component({ 21 | selector: 'chat-actions', 22 | template: ` 23 |
24 | 34 | 41 | 51 |
52 | `, 53 | styles: [ 54 | ` 55 | .message-actions { 56 | display: flex; 57 | align-items: center; 58 | opacity: 0; 59 | transition: opacity 0.3s ease; 60 | } 61 | 62 | :host:hover .message-actions { 63 | opacity: 1; 64 | } 65 | 66 | .user-action { 67 | color: var(--primary-text-color) !important; 68 | } 69 | 70 | .agent-action { 71 | color: var(--primary-color) !important; 72 | } 73 | `, 74 | ], 75 | }) 76 | export class ChatActionsComponent { 77 | /** 78 | * The type of the message sender (determines the color of the action buttons) 79 | */ 80 | @Input() type!: AgentType; 81 | 82 | /** 83 | * Event emitted when the user clicks the delete button 84 | */ 85 | @Output() onDeleteMessage: EventEmitter = new EventEmitter(); 86 | 87 | /** 88 | * Event emitted when the user clicks the regenerate button 89 | */ 90 | @Output() onRegenerateMessage: EventEmitter = new EventEmitter(); 91 | 92 | /** 93 | * Event emitted when the user clicks the generate next question button 94 | */ 95 | @Output() onGenerateNextQuestion: EventEmitter = 96 | new EventEmitter(); 97 | } 98 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/chat.view.component.html: -------------------------------------------------------------------------------- 1 | 16 | 17 |
22 | 26 | 27 |
31 |
35 | 36 | 37 |
43 | 56 | 57 |
58 |
59 |
60 |
61 | 62 | 67 |
68 | 69 | 77 | 78 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/chat-components/chat.view.component.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .user-message { 18 | background-color: var(--primary-color) !important; 19 | color: var(--primary-color-text) !important; 20 | border-radius: 10px; 21 | padding: 0 10px 0 10px; 22 | margin: 10px; 23 | text-align: right; 24 | max-width: 80%; 25 | } 26 | 27 | .agent-message { 28 | color: var(--primary-color) !important; 29 | background-color: var(--primary-color-text) !important; 30 | border-radius: 10px; 31 | padding: 0 10px 0 10px; 32 | margin: 10px; 33 | text-align: left; 34 | max-width: 80%; 35 | } 36 | 37 | #chat-toolbar { 38 | height: 2rem; 39 | background-color: var(--surface-ground); 40 | } 41 | 42 | .next-question-suggestion:hover { 43 | opacity: 1 !important; 44 | } 45 | 46 | .html2canvas-container { 47 | width: 3000px !important; 48 | height: 3000px !important; 49 | } 50 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/graph-components/graph.status.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; 18 | 19 | @Component({ 20 | selector: 'graph-status', 21 | template: ` 22 |
23 |
26 |
27 | Running... ({{ runtime | number : '1.1' }}s elapsed) 28 |
29 | Done 30 |
31 |
32 | `, 33 | styles: [ 34 | ` 35 | .graph-status { 36 | height: 1rem; 37 | position: absolute; 38 | bottom: 5rem; 39 | padding-left: 0.5rem; 40 | } 41 | `, 42 | ], 43 | }) 44 | export class GraphStatusComponent implements OnChanges { 45 | @Input() running = false; 46 | 47 | runtime = 0; 48 | 49 | runtimeInterval?: NodeJS.Timer; 50 | 51 | ngOnChanges(changes: SimpleChanges) { 52 | if (changes?.running?.currentValue !== undefined) { 53 | if (changes?.running?.currentValue) { 54 | this.runtime = 0; 55 | this.runtimeInterval = setInterval(() => { 56 | this.runtime += 0.5; 57 | }, 500); 58 | } else { 59 | if (this.runtimeInterval) { 60 | clearInterval(this.runtimeInterval); 61 | } 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/grid.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component } from '@angular/core'; 17 | import { ActivatedRoute } from '@angular/router'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { DataService } from '@services/user-services/data.service'; 20 | import { ProjectService } from '@services/factory-services/project.service'; 21 | import { NotificationsService } from '@services/user-services/notifications.service'; 22 | import { KsCommandService } from '@services/command-services/ks-command.service'; 23 | import { TopicService } from '@services/user-services/topic.service'; 24 | import { Observable } from 'rxjs'; 25 | 26 | @Component({ 27 | selector: 'app-grid', 28 | template: ` 29 |
30 |
33 | 39 | 40 |
41 |
42 | `, 43 | styles: [], 44 | }) 45 | export class GridComponent { 46 | sources: Observable; 47 | 48 | constructor( 49 | private data: DataService, 50 | private activated: ActivatedRoute, 51 | private command: KsCommandService, 52 | private notifications: NotificationsService, 53 | private projects: ProjectService, 54 | private topics: TopicService 55 | ) { 56 | this.sources = data.ksList; 57 | } 58 | 59 | onKsRemove($event: KnowledgeSource) { 60 | this.command.remove([$event]); 61 | } 62 | 63 | onTopicSearch($event: string) { 64 | this.topics.search($event); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/settings/setting-template.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, Input } from '@angular/core'; 17 | 18 | @Component({ 19 | selector: 'app-setting-template', 20 | template: ` 21 |
24 |
25 |
26 |
27 | {{ label }} 28 |
29 |
30 |
37 |
38 |
39 |
40 | {{ labelSubtext }} 41 |
42 |
43 | 44 |
45 | 46 |
47 | 48 | 49 |
50 |
51 |
52 | `, 53 | styles: [ 54 | ` 55 | :host { 56 | margin-top: 1rem; 57 | } 58 | `, 59 | ], 60 | }) 61 | export class SettingTemplateComponent { 62 | @Input() label = ''; 63 | 64 | @Input() labelSubtext = ''; 65 | 66 | @Input() labelHelp = ''; 67 | 68 | @Input() labelHelpLink = ''; 69 | 70 | @Input() actionSubtext = ''; 71 | 72 | @Input() actionDisabled = false; 73 | 74 | helpClick() { 75 | if (this.labelHelpLink) { 76 | window.open(this.labelHelpLink); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/settings/settings.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component } from '@angular/core'; 17 | import { MenuItem } from 'primeng/api'; 18 | 19 | @Component({ 20 | selector: 'app-settings', 21 | template: ` 22 |
25 |
26 |
27 | 32 |
33 |
34 | 35 |
36 |
37 |
38 | `, 39 | styles: [ 40 | ` 41 | ::ng-deep { 42 | .p-menuitem-link-active { 43 | background-color: var(--primary-color) !important; 44 | 45 | .p-menuitem-icon, 46 | .p-menuitem-text { 47 | color: var(--primary-color-text) !important; 48 | } 49 | } 50 | } 51 | `, 52 | ], 53 | }) 54 | export class SettingsComponent { 55 | modules: MenuItem[] = [ 56 | { 57 | label: 'Display', 58 | icon: 'pi pi-fw pi-image', 59 | routerLinkActiveOptions: {}, 60 | routerLink: ['app', { outlets: { settings: ['display'] } }], 61 | }, 62 | { 63 | label: 'Search', 64 | icon: 'pi pi-fw pi-search', 65 | routerLink: ['app', { outlets: { settings: ['search'] } }], 66 | }, 67 | { 68 | label: 'Import', 69 | icon: 'pi pi-fw pi-arrow-circle-down', 70 | routerLink: ['app', { outlets: { settings: ['import'] } }], 71 | }, 72 | { 73 | label: 'Graph', 74 | icon: 'pi pi-fw pi-sitemap', 75 | routerLink: ['app', { outlets: { settings: ['graph'] } }], 76 | }, 77 | { 78 | label: 'Chat', 79 | icon: 'pi pi-fw pi-comments', 80 | routerLink: ['app', { outlets: { settings: ['chat'] } }], 81 | }, 82 | // { TODO: reinstate once storage settings component is implemented 83 | // label: 'Storage', 84 | // icon: 'pi pi-fw pi-database', 85 | // routerLink: ['app', {outlets: {settings: ['storage']}}] 86 | // } 87 | ]; 88 | } 89 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/shared/icon.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 18 | import { PrimeIcons } from 'primeng/api'; 19 | import { OverlayPanel } from 'primeng/overlaypanel'; 20 | import { FormBuilder, FormGroup } from '@angular/forms'; 21 | import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators'; 22 | import { IconService } from '@services/user-services/icon.service'; 23 | 24 | @Component({ 25 | selector: 'app-icon', 26 | template: ` 27 |
31 | 32 |
33 | 34 |
35 |
36 | 42 |
43 |
44 | 50 |
51 |

No icons found

52 |
53 |
54 |
55 |
56 | `, 57 | styles: [ 58 | ` 59 | :host { 60 | width: 3rem !important; 61 | height: 3rem !important; 62 | margin-left: 0.5rem !important; 63 | } 64 | `, 65 | ], 66 | }) 67 | export class IconComponent { 68 | @Input() icon?: string = PrimeIcons.FOLDER; 69 | 70 | @Output() changed = new EventEmitter(); 71 | 72 | form: FormGroup; 73 | 74 | filteredIcons: string[] = this.icons.iconValues; 75 | 76 | constructor(private icons: IconService, private fb: FormBuilder) { 77 | this.form = fb.group({ 78 | filter: [''], 79 | }); 80 | 81 | this.form.valueChanges 82 | .pipe( 83 | debounceTime(400), 84 | distinctUntilChanged(), 85 | tap((formValue) => { 86 | this.filteredIcons = this.icons.iconValues.filter((i) => 87 | i.includes(formValue.filter) 88 | ); 89 | }) 90 | ) 91 | .subscribe(); 92 | } 93 | 94 | change(i: any, op: OverlayPanel) { 95 | this.icon = i; 96 | op.hide(); 97 | this.changed.emit(i); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/shared/loading.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component } from '@angular/core'; 18 | import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; 19 | 20 | @Component({ 21 | selector: 'app-loading', 22 | template: ` 23 |
26 |
{{ message }}
27 |
{{ subMessage }}
28 | 34 |
35 | `, 36 | styles: [], 37 | }) 38 | export class LoadingComponent { 39 | message = 'Loading...'; 40 | subMessage = ''; 41 | progressBar = false; 42 | 43 | constructor( 44 | private ref: DynamicDialogRef, 45 | private config: DynamicDialogConfig 46 | ) { 47 | if (this.config.data) { 48 | this.message = this.config.data.message || this.message; 49 | this.subMessage = this.config.data.subMessage || this.subMessage; 50 | this.progressBar = this.config.data.progressBar || this.progressBar; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/shared/pro-tips.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | Component, 19 | EventEmitter, 20 | HostListener, 21 | OnDestroy, 22 | Output, 23 | } from '@angular/core'; 24 | import { SettingsService } from '@services/ipc-services/settings.service'; 25 | 26 | @Component({ 27 | selector: 'app-pro-tips', 28 | template: ` 29 |
30 |
31 |

{{ header }}

32 |
33 |

{{ body }}

34 |
35 | 53 |
54 | `, 55 | styles: [ 56 | ` 57 | .pro-tip { 58 | max-width: 30rem !important; 59 | } 60 | `, 61 | ], 62 | }) 63 | export class ProTipsComponent implements OnDestroy { 64 | header = 'Pro Tips'; 65 | 66 | body = ''; 67 | 68 | icon = 'pi pi-info-circle'; 69 | 70 | @Output() previous = new EventEmitter(); 71 | 72 | @Output() next = new EventEmitter(); 73 | 74 | @Output() close = new EventEmitter(); 75 | 76 | constructor(private settings: SettingsService) {} 77 | 78 | ngOnDestroy() { 79 | this.close.emit(); 80 | } 81 | 82 | /* Listen for left and right arrow keys, emit previous and next events */ 83 | @HostListener('window:keydown', ['$event']) 84 | handleKeyDown(event: KeyboardEvent) { 85 | if (event.key === 'ArrowRight') { 86 | this.next.emit(); 87 | } else if (event.key === 'ArrowLeft') { 88 | this.previous.emit(); 89 | } 90 | } 91 | 92 | showAgainChanged($event: { checked: boolean }) { 93 | console.log('Show again changed: ', $event.checked); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/shared/timeline.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, Input } from '@angular/core'; 17 | import { EventModel } from '@shared/models/event.model'; 18 | import { KnowledgeSourceEvent } from '@app/models/knowledge.source.model'; 19 | 20 | @Component({ 21 | selector: 'app-timeline', 22 | template: ` 23 |
24 | 25 | 31 | 32 |
36 | 37 | {{ event.status }} 38 | 39 |
40 |
41 | 42 | 43 |
44 |
48 |
49 |
50 | 51 |
52 | 53 | 54 | {{ event.date ?? event.timestamp | date : 'short' }} 55 | 56 |
57 |
58 |
59 |
60 |
61 | `, 62 | }) 63 | export class TimelineComponent { 64 | @Input() events?: EventModel[] | KnowledgeSourceEvent[] = []; 65 | } 66 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/ks-details.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component } from '@angular/core'; 17 | import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { NotificationsService } from '@services/user-services/notifications.service'; 20 | import { KsCommandService } from '@services/command-services/ks-command.service'; 21 | 22 | @Component({ 23 | selector: 'app-details', 24 | template: ` 25 |
26 |
27 | 28 |
{{ ks.title }}
29 |
30 |
31 |
32 |
33 |
Saved
34 |
35 |
36 | 42 |
43 |
44 |
45 |
46 | 51 |
52 |
53 | 57 | 58 |
59 | `, 60 | styles: [''], 61 | }) 62 | export class KsDetailsComponent { 63 | ks!: KnowledgeSource; 64 | 65 | collapsed = false; 66 | 67 | saved = false; 68 | 69 | constructor( 70 | private config: DynamicDialogConfig, 71 | private ref: DynamicDialogRef, 72 | private notifications: NotificationsService, 73 | private command: KsCommandService 74 | ) { 75 | if (config?.data?.ks) { 76 | this.ks = config.data.ks; 77 | } else { 78 | this.notifications.error( 79 | 'Source Details', 80 | 'Invalid Source', 81 | 'Could not find a source to display.' 82 | ); 83 | } 84 | } 85 | 86 | onClose() { 87 | this.ref.close(); 88 | } 89 | 90 | onSaved() { 91 | /* Show the "Saved" notice for 5 seconds */ 92 | this.saved = true; 93 | setTimeout(() => { 94 | this.saved = false; 95 | }, 5000); 96 | } 97 | 98 | update($event: KnowledgeSource) { 99 | if ($event) { 100 | this.command.update([$event]); 101 | this.onSaved(); 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/ks-dropzone.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, Input } from '@angular/core'; 17 | import { 18 | animate, 19 | state, 20 | style, 21 | transition, 22 | trigger, 23 | } from '@angular/animations'; 24 | 25 | @Component({ 26 | selector: 'app-dropzone', 27 | template: ` 28 |
37 |
38 | {{ emptyMessage }} 39 |
40 |
41 |
{{ hintMessage }}
42 |
43 |
44 | `, 45 | styles: [ 46 | ` 47 | .dropzone { 48 | width: 100%; 49 | color: var(--text-color); 50 | background-image: linear-gradient( 51 | 225deg, 52 | var(--surface-b) 25%, 53 | var(--surface-c) 25%, 54 | var(--surface-c) 50%, 55 | var(--surface-b) 50%, 56 | var(--surface-b) 75%, 57 | var(--surface-c) 75%, 58 | var(--surface-c) 100% 59 | ); 60 | background-size: 64px 64px; 61 | display: flex; 62 | flex-direction: column; 63 | flex-wrap: nowrap; 64 | align-items: center; 65 | justify-content: center; 66 | align-content: center; 67 | } 68 | `, 69 | ], 70 | animations: [ 71 | trigger('dropzone-shorten', [ 72 | state('dropzone-lg', style({ height: '20vh', top: 0, left: 0 })), 73 | state('dropzone-sm', style({ height: '4rem', top: 0, left: 0 })), 74 | transition('dropzone-lg => dropzone-sm', [animate('0.1s')]), 75 | transition('dropzone-sm => dropzone-lg', [animate('0.1s')]), 76 | ]), 77 | ], 78 | }) 79 | export class KsDropzoneComponent { 80 | @Input() shouldShorten = false; 81 | 82 | @Input() supportedTypes: string[] = []; 83 | 84 | @Input() emptyMessage = 'Drag and drop here!'; 85 | 86 | @Input() hintMessage = 87 | 'Hint: You can drag files and links directly into this window.'; 88 | } 89 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/ks-viewport/file-view.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { 17 | Component, 18 | EventEmitter, 19 | Input, 20 | OnChanges, 21 | OnInit, 22 | Output, 23 | SimpleChanges, 24 | } from '@angular/core'; 25 | import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; 26 | import { 27 | BrowserViewHeaderConfig, 28 | BrowserViewHeaderEvent, 29 | FileViewClickEvent, 30 | FileViewConfig, 31 | } from '@shared/models/browser.view.model'; 32 | 33 | @Component({ 34 | selector: 'ks-lib-file-view', 35 | template: ` 36 | 41 | 42 | 43 | `, 44 | styles: [ 45 | ` 46 | .file-view { 47 | height: calc(100vh - 68px); 48 | width: 100%; 49 | } 50 | `, 51 | ], 52 | }) 53 | export class FileViewComponent implements OnInit, OnChanges { 54 | @Input() config!: FileViewConfig; 55 | @Input() showHeader = false; 56 | @Output() viewReady = new EventEmitter(); 57 | @Output() clickEvent = new EventEmitter(); 58 | @Output() fileError = new EventEmitter(); 59 | safeUrl: SafeUrl | undefined; 60 | headerConfig: BrowserViewHeaderConfig | undefined; 61 | ready = false; 62 | 63 | constructor(private sanitizer: DomSanitizer) {} 64 | 65 | ngOnInit(): void { 66 | this.headerConfig = { 67 | canCopy: true, 68 | canClose: this.config.isDialog, 69 | displayText: this.config.filePath, 70 | displayTextReadOnly: true, 71 | showActionButtons: true, 72 | showDisplayText: true, 73 | showCloseButton: true, 74 | showOpenButton: true, 75 | }; 76 | } 77 | 78 | ngOnChanges(changes: SimpleChanges) { 79 | const config: FileViewConfig = changes.config.currentValue; 80 | if (config) { 81 | if (config.filePath) { 82 | if (this.validateFileURI(config.filePath)) { 83 | this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl( 84 | 'file://' + encodeURI(config.filePath) 85 | ); 86 | this.ready = true; 87 | this.viewReady.emit(true); 88 | } else { 89 | this.fileError.emit( 90 | 'The file path contains invalid characters and cannot be previewed.' 91 | ); 92 | } 93 | } 94 | } 95 | } 96 | 97 | headerEvents(headerEvent: BrowserViewHeaderEvent) { 98 | this.clickEvent.emit(headerEvent); 99 | } 100 | 101 | validateFileURI(uri: string) { 102 | return !uri.includes('#'); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.document.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; 20 | 21 | @Component({ 22 | selector: 'source-document', 23 | template: ` 24 |
25 |
26 | 33 |
34 |
35 | `, 36 | styles: [ 37 | ` 38 | :host { 39 | display: flex !important; 40 | flex-direction: column !important; 41 | height: 100% !important; 42 | width: 100% !important; 43 | overflow: auto !important; 44 | padding: 1.5rem !important; 45 | } 46 | 47 | .source-pdf-viewer { 48 | height: 100% !important; 49 | } 50 | `, 51 | ], 52 | }) 53 | export class SourceDocumentComponent implements OnInit { 54 | source!: KnowledgeSource; 55 | 56 | safeUrl: SafeUrl | undefined; 57 | 58 | style = { 59 | width: '100%', 60 | height: '100%', 61 | 'max-width': '100%', 62 | 'max-height': '100%', 63 | }; 64 | 65 | styles = { 66 | unset: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'tif'], 67 | full: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'], 68 | }; 69 | 70 | @ViewChild('document', { static: true }) document!: ElementRef; 71 | 72 | @ViewChild('documentContainer', { static: true }) 73 | documentContainer!: ElementRef; 74 | 75 | constructor(private sanitizer: DomSanitizer) {} 76 | 77 | ngOnInit(): void { 78 | setTimeout(() => { 79 | if (typeof this.source.accessLink === 'string') { 80 | this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl( 81 | 'file://' + encodeURI(this.source.accessLink) 82 | ); 83 | 84 | for (const type of this.styles.unset) { 85 | if (this.source.accessLink?.endsWith(type)) { 86 | this.style = { 87 | 'max-height': '100%', 88 | 'max-width': '100%', 89 | width: 'unset', 90 | height: 'unset', 91 | }; 92 | break; 93 | } 94 | } 95 | } 96 | }, 500); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.notes.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component } from '@angular/core'; 18 | 19 | @Component({ 20 | selector: 'source-notes', 21 | template: ``, 22 | styles: [``], 23 | }) 24 | export class SourceNotesComponent { 25 | constructor() {} 26 | } 27 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.styles.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/source-components/source.video.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Component, OnInit, ViewChild } from '@angular/core'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { SettingsService } from '@services/ipc-services/settings.service'; 20 | import { YouTubePlayer } from '@angular/youtube-player'; 21 | 22 | @Component({ 23 | selector: 'source-video', 24 | template: ` 25 |
26 |
27 | 28 | 29 |
30 |
31 | `, 32 | styleUrls: ['./source.styles.scss'], 33 | }) 34 | export class SourceVideoComponent implements OnInit { 35 | @ViewChild('youtubePlayer') youtubePlayer!: YouTubePlayer; 36 | 37 | source!: KnowledgeSource; 38 | 39 | ksYoutubeVideoId = 'y5icPgca8JI'; 40 | 41 | loaded = false; 42 | 43 | constructor(private settings: SettingsService) {} 44 | 45 | ngOnInit(): void { 46 | this.source.accessLink = new URL(this.source.accessLink); 47 | const urlParam = this.source.accessLink.searchParams.get('v'); 48 | if (this.source.accessLink.hostname === 'www.youtube.com' && urlParam) { 49 | this.loadYoutubeApi(urlParam); 50 | if (this.settings.get().display.autoplay) { 51 | setTimeout(() => { 52 | this.youtubePlayer.playVideo(); 53 | }, 1000); 54 | } 55 | } 56 | } 57 | 58 | loadYoutubeApi(urlParam: string) { 59 | this.ksYoutubeVideoId = urlParam; 60 | if (!this.loaded) { 61 | // This code loads the IFrame Player API code asynchronously, according to the instructions at 62 | // https://developers.google.com/youtube/iframe_api_reference#Getting_Started 63 | const tag = document.createElement('script'); 64 | tag.src = 'https://www.youtube.com/iframe_api'; 65 | document.body.appendChild(tag); 66 | this.loaded = true; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/components/table.component.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Component, OnDestroy } from '@angular/core'; 17 | import { ActivatedRoute } from '@angular/router'; 18 | import { KnowledgeSource } from '../models/knowledge.source.model'; 19 | import { Observable, Subject, tap } from 'rxjs'; 20 | import { DataService } from '@services/user-services/data.service'; 21 | import { takeUntil } from 'rxjs/operators'; 22 | 23 | @Component({ 24 | selector: 'app-table', 25 | template: ` 26 |
27 |
30 | 34 |
35 |
36 | `, 37 | styles: [], 38 | }) 39 | export class TableComponent implements OnDestroy { 40 | sources: Observable; 41 | 42 | projectId = ''; 43 | 44 | private cleanUp: Subject = new Subject(); 45 | 46 | constructor(private data: DataService, private route: ActivatedRoute) { 47 | route.paramMap 48 | .pipe( 49 | takeUntil(this.cleanUp), 50 | tap((params) => { 51 | this.projectId = params.get('projectId') ?? ''; 52 | }) 53 | ) 54 | .subscribe(); 55 | 56 | this.sources = data.ksList; 57 | } 58 | 59 | ngOnDestroy() { 60 | this.cleanUp.next({}); 61 | this.cleanUp.complete(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/directives/recreate-view.directive.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { 18 | Directive, 19 | EmbeddedViewRef, 20 | Input, 21 | OnChanges, 22 | SimpleChanges, 23 | TemplateRef, 24 | ViewContainerRef, 25 | } from '@angular/core'; 26 | 27 | @Directive({ 28 | selector: '[appRecreateView]', 29 | }) 30 | export class RecreateViewDirective implements OnChanges { 31 | @Input('appRecreateView') key: any; 32 | 33 | viewRef: EmbeddedViewRef | null = null; 34 | 35 | constructor( 36 | private templateRef: TemplateRef, 37 | private viewContainer: ViewContainerRef 38 | ) {} 39 | 40 | ngOnChanges(changes: SimpleChanges) { 41 | if (changes.key) { 42 | if (this.viewRef) { 43 | this.destroyView(); 44 | } 45 | 46 | this.createView(); 47 | } 48 | } 49 | 50 | private destroyView() { 51 | this.viewRef?.destroy(); 52 | this.viewRef = null; 53 | } 54 | 55 | private createView() { 56 | this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/models/chat.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { KcProject } from './project.model'; 18 | import { KnowledgeSource } from './knowledge.source.model'; 19 | 20 | export enum AgentType { 21 | Assistant = 'assistant', 22 | Knowledge = 'knowledge', 23 | Project = 'project', 24 | Source = 'source', 25 | System = 'system', 26 | User = 'user', 27 | } 28 | 29 | export type MessageRating = 'thumbs-up' | 'thumbs-down' | 'none'; 30 | 31 | export interface ChatMessage { 32 | id: string; 33 | sender: AgentType; 34 | recipient: AgentType; 35 | text: string; 36 | timestamp: Date; 37 | project?: KcProject; 38 | source?: KnowledgeSource; 39 | suggestion?: boolean; 40 | regenerated?: boolean; 41 | rating?: MessageRating; 42 | } 43 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/models/project.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { EventModel, ProjectCalendar } from '@shared/models/event.model'; 17 | import { KcProjectModel, KcProjectType } from '@shared/models/project.model'; 18 | import { KnowledgeSource } from './knowledge.source.model'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | import { PrimeIcons } from 'primeng/api'; 21 | 22 | export class KcProject implements KcProjectModel { 23 | readonly id: UUID; 24 | name = ''; 25 | authors: string[] = []; 26 | description = ''; 27 | parentId: UUID = { value: '' }; 28 | subprojects: string[] = []; 29 | topics: string[] = []; 30 | type: KcProjectType; 31 | expanded = false; 32 | icon?: string; 33 | 34 | // TODO: this needs to be changed to an array of UUID instead of KS. The KS should be looked up 35 | sources: UUID[]; 36 | knowledgeSource: KnowledgeSource[] = []; 37 | 38 | // TODO: Should we remove calendar, or events? 39 | calendar: ProjectCalendar; 40 | events?: EventModel[] = []; 41 | 42 | // TODO: these should be completely removed and replaced by calendar/events 43 | readonly dateCreated: Date; 44 | dateModified: Date; 45 | dateAccessed: Date; 46 | 47 | constructor(name: string, id: UUID, type?: KcProjectType, parentId?: UUID) { 48 | this.name = name; 49 | this.id = id; 50 | this.type = type ? type : 'default'; 51 | this.parentId = parentId ?? { value: '' }; 52 | this.dateCreated = new Date(); 53 | this.dateModified = new Date(); 54 | this.dateAccessed = new Date(); 55 | this.calendar = { events: [], start: null, end: null }; 56 | this.sources = []; 57 | this.icon = PrimeIcons.FOLDER; 58 | } 59 | } 60 | 61 | export interface ProjectCreationRequest { 62 | name: string; 63 | parentId: UUID; 64 | description: string; 65 | 66 | // TODO: this needs to be replaced with UUID[] 67 | knowledgeSource: KnowledgeSource[]; 68 | sources: UUID[]; 69 | authors: string[]; 70 | topics: string[]; 71 | type: KcProjectType; 72 | subProjects: ProjectCreationRequest[]; 73 | calendar: ProjectCalendar; 74 | icon?: string; 75 | } 76 | 77 | export type ProjectMoveRequest = { ks: KnowledgeSource; new: UUID }; 78 | 79 | export interface ProjectUpdateRequest { 80 | id: UUID; 81 | name?: string; 82 | description?: string; 83 | notes?: string; 84 | expanded?: boolean; 85 | parentId?: string; 86 | addSubprojects?: string[]; 87 | removeSubprojects?: string[]; 88 | authors?: string[]; 89 | addTopic?: string[]; 90 | removeTopic?: string[]; 91 | updateTopic?: string[]; 92 | overWriteTopics?: string[]; 93 | addKnowledgeSource?: KnowledgeSource[]; 94 | removeKnowledgeSource?: KnowledgeSource[]; 95 | updateKnowledgeSource?: KnowledgeSource[]; 96 | moveKnowledgeSource?: ProjectMoveRequest; 97 | } 98 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/models/project.tree.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ProjectGraphNode } from '@shared/models/graph.model'; 18 | 19 | export class ProjectTreeNode implements ProjectGraphNode { 20 | name: string; 21 | id: string; 22 | type: string; 23 | expanded = false; 24 | subprojects: ProjectTreeNode[]; 25 | icon?: string; 26 | parentId?: string; 27 | 28 | constructor( 29 | name: string, 30 | id: string, 31 | type: string, 32 | subprojects: ProjectTreeNode[], 33 | expanded: boolean, 34 | icon?: string 35 | ) { 36 | this.name = name ? name : ''; 37 | this.id = id ? id : ''; 38 | this.type = type ? type : ''; 39 | this.subprojects = subprojects ? subprojects : []; 40 | this.expanded = expanded; 41 | this.icon = icon; 42 | } 43 | } 44 | 45 | export class ProjectTree { 46 | root: ProjectTreeNode; 47 | 48 | constructor() { 49 | this.root = new ProjectTreeNode('root', '0', 'root', [], true); 50 | } 51 | 52 | asArray(): ProjectTreeNode[] { 53 | const arr: ProjectTreeNode[] = []; 54 | this.root.subprojects.forEach((value) => { 55 | arr.push(value); 56 | }); 57 | return arr; 58 | } 59 | 60 | add(node: ProjectTreeNode, parentId?: string): void { 61 | if (parentId) { 62 | this.addChild(node, parentId, this.root); 63 | } else { 64 | this.root.subprojects.push(node); 65 | } 66 | } 67 | 68 | find(id: string, node?: ProjectTreeNode): ProjectTreeNode | null { 69 | if (!node) { 70 | node = this.root; 71 | } 72 | 73 | if (node.id === id) { 74 | return node; 75 | } else { 76 | for (const sub of node.subprojects) { 77 | const found = this.find(id, sub); 78 | if (found) { 79 | return found; 80 | } 81 | } 82 | return null; 83 | } 84 | } 85 | 86 | private addChild( 87 | node: ProjectTreeNode, 88 | parentId: string, 89 | current: ProjectTreeNode 90 | ): void { 91 | if (current.id === parentId) { 92 | current.subprojects.push(node); 93 | } else { 94 | for (const sub of current.subprojects) { 95 | this.addChild(node, parentId, sub); 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/countdown.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | 19 | @Pipe({ 20 | name: 'countdown', 21 | }) 22 | export class CountdownPipe implements PipeTransform { 23 | transform(value: Date): unknown { 24 | const then = new Date(value); 25 | const now = new Date(); 26 | const diffTime = this.dateDiffInDays(then, now); 27 | let countdown; 28 | if (diffTime > 365 || diffTime <= -365) { 29 | countdown = `1yr+`; 30 | } else if (diffTime >= 90 || diffTime <= -90) { 31 | countdown = '90d+'; 32 | } else { 33 | countdown = `${Math.abs(diffTime)}d`; 34 | } 35 | return countdown; 36 | } 37 | 38 | // a and b are javascript Date objects 39 | dateDiffInDays(a: any, b: any) { 40 | const _MS_PER_DAY = 1000 * 60 * 60 * 24; 41 | // Discard the time and time-zone information. 42 | const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate()); 43 | const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate()); 44 | return Math.floor((utc2 - utc1) / _MS_PER_DAY); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/import-method.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { ImportMethod } from '@shared/models/knowledge.source.model'; 19 | 20 | @Pipe({ 21 | name: 'importMethod', 22 | }) 23 | export class ImportMethodPipe implements PipeTransform { 24 | transform(value?: ImportMethod): unknown { 25 | if (!value) { 26 | return ''; 27 | } 28 | switch (value) { 29 | case 'autoscan': 30 | return 'Autoscan'; 31 | case 'dnd': 32 | return 'Drag/Drop'; 33 | case 'extension': 34 | return 'Browser Extension'; 35 | case 'manual': 36 | return 'Manual'; 37 | case 'example': 38 | return 'Example'; 39 | case 'recommend': 40 | return 'Recommended'; 41 | default: 42 | return ''; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/ks-ingest-type-icon.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Pipe, PipeTransform } from '@angular/core'; 17 | 18 | @Pipe({ 19 | name: 'ksIngestTypeIcon', 20 | }) 21 | export class KsIngestTypeIconPipe implements PipeTransform { 22 | transform(type?: string): string { 23 | if (!type) { 24 | return ''; 25 | } 26 | switch (type) { 27 | case 'topic': 28 | return 'sitemap'; 29 | case 'website': 30 | return 'link'; 31 | case 'search': 32 | return 'search'; 33 | case 'file': 34 | return 'file'; 35 | case 'google': 36 | return 'google'; 37 | default: 38 | return ''; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/markdown.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { MarkdownService } from '@services/factory-services/markdown.service'; 18 | import { Pipe, PipeTransform } from '@angular/core'; 19 | 20 | @Pipe({ 21 | name: 'markdown', 22 | }) 23 | export class MarkdownPipe implements PipeTransform { 24 | constructor(private markdownService: MarkdownService) {} 25 | 26 | transform(markdown: string, topics?: string[]): string { 27 | return this.markdownService.parseMarkdown(markdown, topics) ?? markdown; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/project-as-tree-node.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Pipe, PipeTransform } from '@angular/core'; 17 | import { ProjectTreeFactoryService } from '@services/factory-services/project-tree-factory.service'; 18 | import { TreeNode } from 'primeng/api'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | @Pipe({ 22 | name: 'projectAsTreeNode', 23 | }) 24 | export class ProjectAsTreeNodePipe implements PipeTransform { 25 | constructor(private tree: ProjectTreeFactoryService) {} 26 | 27 | transform(id: UUID, treeNodes: TreeNode[]): TreeNode { 28 | return this.tree.findTreeNode(id.value, treeNodes) ?? {}; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/project-breadcrumb.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { ProjectService } from '@services/factory-services/project.service'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | @Pipe({ 22 | name: 'projectBreadcrumb', 23 | }) 24 | export class ProjectBreadcrumbPipe implements PipeTransform { 25 | constructor(private projectService: ProjectService) {} 26 | 27 | transform(id: UUID | string, ...args: unknown[]): string { 28 | if (typeof id === 'string') { 29 | id = { value: id }; 30 | } 31 | 32 | const ancestors = this.projectService.getAncestors(id.value); 33 | if (!ancestors) { 34 | return ''; 35 | } 36 | 37 | let start, end, prefix; 38 | 39 | const SEP = '>'; 40 | const ELLIPSIS = '...'; 41 | 42 | if (args && args.length > 0 && args[0] && args[0] == 'no-truncate') { 43 | start = 0; 44 | end = ancestors.length; 45 | prefix = ''; 46 | } else { 47 | start = Math.max(0, ancestors.length - 3); 48 | end = ancestors.length; 49 | 50 | if (args && args.length > 0 && args[0] && args[0] == 'no-ellipse') { 51 | prefix = ''; 52 | } else { 53 | prefix = 54 | start > 0 55 | ? `${ancestors[0].title} ${SEP} ${start > 1 ? ELLIPSIS : ''} ${ 56 | start > 1 ? SEP : '' 57 | } ` 58 | : ''; 59 | } 60 | } 61 | 62 | return ( 63 | prefix + 64 | ancestors 65 | .slice(start, end) 66 | .map((a) => a.title) 67 | .join(` ${SEP} `) 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/project-name.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { ProjectService } from '@services/factory-services/project.service'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | @Pipe({ 22 | name: 'projectName', 23 | }) 24 | export class ProjectNamePipe implements PipeTransform { 25 | constructor(private projectService: ProjectService) {} 26 | 27 | transform(id: UUID | string | null): string { 28 | if (!id) { 29 | return 'None'; 30 | } else { 31 | const pid: UUID = typeof id === 'string' ? { value: id } : id; 32 | return ( 33 | this.projectService.ProjectIdentifiers.find((p) => p.id === pid.value) 34 | ?.title ?? 'None' 35 | ); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/sanitize-html.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; 19 | 20 | @Pipe({ 21 | name: 'sanitizeHtml', 22 | }) 23 | export class SanitizeHtmlPipe implements PipeTransform { 24 | constructor(private _sanitizer: DomSanitizer) {} 25 | 26 | transform(v: string): SafeHtml { 27 | return this._sanitizer.bypassSecurityTrustHtml(v); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/switch-label.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | 19 | @Pipe({ 20 | name: 'switchLabel', 21 | }) 22 | export class SwitchLabelPipe implements PipeTransform { 23 | transform(value: boolean): string { 24 | return value ? 'Enabled' : 'Disabled'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/truncate.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Pipe, PipeTransform } from '@angular/core'; 18 | 19 | @Pipe({ 20 | name: 'truncate', 21 | }) 22 | export class TruncatePipe implements PipeTransform { 23 | transform(value: string | undefined, args: any[]): string { 24 | if (!value) return ''; 25 | const ELLIPSIS = '...'; 26 | const limit = args.length > 0 ? parseInt(args[0], 10) : 20; 27 | const trail = args.length > 1 ? args[1] : ELLIPSIS; 28 | return value.length > limit ? value.substring(0, limit) + trail : value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/pipes/view-icon.pipe.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022-2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Pipe, PipeTransform } from '@angular/core'; 17 | 18 | @Pipe({ 19 | name: 'viewIcon', 20 | }) 21 | export class ViewIconPipe implements PipeTransform { 22 | transform(viewLabel: string): string { 23 | switch (viewLabel) { 24 | case 'inbox': 25 | return 'pi pi-inbox'; 26 | case 'projects': 27 | return 'pi pi-list'; 28 | case 'table': 29 | return 'pi pi-table'; 30 | case 'grid': 31 | return 'pi pi-th-large'; 32 | case 'graph': 33 | return 'pi pi-sitemap'; 34 | case 'calendar': 35 | return 'pi pi-calendar'; 36 | default: 37 | return ''; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/chat-services/guard.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Injectable } from '@angular/core'; 18 | import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router'; 19 | import { ChatService } from '@services/chat-services/chat.service'; 20 | import { DialogService } from 'primeng/dynamicdialog'; 21 | import { NotificationsService } from '@services/user-services/notifications.service'; 22 | import { take, tap } from 'rxjs/operators'; 23 | 24 | @Injectable({ 25 | providedIn: 'root', 26 | }) 27 | export class ChatGuard implements CanActivate { 28 | constructor( 29 | private chat: ChatService, 30 | private dialog: DialogService, 31 | private notify: NotificationsService, 32 | private router: Router 33 | ) {} 34 | 35 | canActivate(route: ActivatedRouteSnapshot) { 36 | const canChat = this.chat.canChat(); 37 | 38 | if (canChat) { 39 | return true; 40 | } else { 41 | this.chat 42 | .getApiKeyDialog() 43 | .pipe( 44 | take(1), 45 | tap((result: boolean) => { 46 | if (result) { 47 | this.router.navigate([ 48 | 'app', 49 | route.url[0].path, 50 | route.url[1].path, 51 | ]); 52 | } 53 | }) 54 | ) 55 | .subscribe(); 56 | 57 | return false; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/ipc-services/browser-view-dialog.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { DialogService, DynamicDialogRef } from 'primeng/dynamicdialog'; 18 | import { Injectable } from '@angular/core'; 19 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 20 | import { 21 | KsPreviewComponent, 22 | KsPreviewInput, 23 | } from '@components/source-components/ks-preview.component'; 24 | 25 | export interface BrowserViewDialogConfig { 26 | ks: KnowledgeSource; 27 | } 28 | 29 | @Injectable({ 30 | providedIn: 'root', 31 | }) 32 | export class BrowserViewDialogService { 33 | constructor(public dialog: DialogService) {} 34 | 35 | open(options: BrowserViewDialogConfig): DynamicDialogRef | undefined { 36 | if (!this.validateURI(options.ks)) { 37 | return undefined; 38 | } 39 | 40 | const ksPreviewInput: KsPreviewInput = { 41 | ks: options.ks, 42 | }; 43 | 44 | return this.dialog.open(KsPreviewComponent, { 45 | width: '100vw', 46 | height: '100vh', 47 | contentStyle: { 'padding-left': 0, 'padding-right': 0 }, 48 | showHeader: false, 49 | data: ksPreviewInput, 50 | }); 51 | } 52 | 53 | validateURI(ks: KnowledgeSource) { 54 | if (ks.ingestType === 'file' && typeof ks.accessLink === 'string') { 55 | if (ks.accessLink.includes('#')) { 56 | return false; 57 | } 58 | } 59 | 60 | return true; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/ipc-services/startup.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Injectable } from '@angular/core'; 17 | import { ElectronIpcService } from './electron-ipc.service'; 18 | import { DialogService } from 'primeng/dynamicdialog'; 19 | 20 | @Injectable({ 21 | providedIn: 'root', 22 | }) 23 | export class StartupService { 24 | constructor(private dialog: DialogService, private ipc: ElectronIpcService) { 25 | this.ipc.version.subscribe((version) => { 26 | if (!version || version === '') { 27 | return; 28 | } 29 | 30 | let major, minor, patch; 31 | [major, minor, patch] = version.split('.'); 32 | 33 | // this.storage.getProjects().then((projects) => { 34 | // for (let project of projects) { 35 | // console.log('Analyzing project: ', project.name); 36 | // for (let ks of project.knowledgeSource) { 37 | // console.log('\t\tAnalyzing KS: ', ks.title); 38 | // 39 | // // First, check if KS exists in local storage. If it does, then we are done here. 40 | // const lookup = `ks-${ks.id.value}`; 41 | // const kstr = localStorage.getItem(lookup); 42 | // 43 | // // If it does not exist in local storage, save it 44 | // if (!kstr) { 45 | // const kson = JSON.stringify(ks); 46 | // if (kson) { 47 | // localStorage.setItem(lookup, kson); 48 | // } 49 | // } 50 | // 51 | // if (project.sources && !project.sources.find(k => k.value === ks.id.value)) { 52 | // project.sources.push(ks.id); 53 | // } else { 54 | // project.sources = [ks.id]; 55 | // } 56 | // } 57 | // 58 | // this.storage.saveProject(project); 59 | // } 60 | // }) 61 | }); 62 | 63 | this.ipc.getCurrentVersion(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/ipc-services/uuid.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Injectable } from '@angular/core'; 18 | import { ElectronIpcService } from './electron-ipc.service'; 19 | import { UUID } from '@shared/models/uuid.model'; 20 | 21 | declare global { 22 | interface Window { 23 | api?: any; 24 | } 25 | } 26 | 27 | @Injectable({ 28 | providedIn: 'root', 29 | }) 30 | export class UuidService { 31 | private uuidBuffer: UUID[] = []; 32 | 33 | constructor(private ipcService: ElectronIpcService) { 34 | this.asyncGenerate(); 35 | } 36 | 37 | generate(quantity: number): UUID[] { 38 | if (quantity < 1) { 39 | console.error('Requested less than 1 UUID.. which is invalid...'); 40 | return []; 41 | } 42 | 43 | const uuids: UUID[] = this.uuidBuffer.slice(0, quantity); 44 | this.uuidBuffer = this.uuidBuffer.slice(quantity); 45 | if (this.uuidBuffer.length <= 32) { 46 | this.asyncGenerate(); 47 | } 48 | return uuids; 49 | } 50 | 51 | private asyncGenerate() { 52 | this.ipcService.generateUuid(128).then((ids: UUID[]) => { 53 | if (ids) this.uuidBuffer = ids; 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/user-services/event.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { Injectable } from '@angular/core'; 17 | import { KcProject } from '@app/models/project.model'; 18 | import { KnowledgeSource } from '@app/models/knowledge.source.model'; 19 | import { ProjectCalendarEvent } from '@components/project-components/project-calendar.component'; 20 | 21 | @Injectable({ 22 | providedIn: 'root', 23 | }) 24 | export class EventService { 25 | fromProject(project: KcProject) { 26 | const projectColor = 'yellow'; 27 | const projectTextColor = 'black'; 28 | return [ 29 | { 30 | title: `"${project.name}" (Created)`, 31 | start: project.dateCreated, 32 | color: projectColor, 33 | textColor: projectTextColor, 34 | url: 'project', 35 | }, 36 | { 37 | title: `"${project.name}" (Modified)`, 38 | start: project.dateModified, 39 | color: projectColor, 40 | textColor: projectTextColor, 41 | url: 'project', 42 | }, 43 | { 44 | title: `"${project.name}" (Accessed)`, 45 | start: project.dateAccessed, 46 | color: projectColor, 47 | textColor: projectTextColor, 48 | url: 'project', 49 | }, 50 | ]; 51 | } 52 | 53 | fromSourceList(sources: KnowledgeSource[]) { 54 | const createdColor = 'var(--green-500)'; 55 | const modifiedColor = 'var(--yellow-500)'; 56 | const accessedColor = 'var(--blue-500)'; 57 | const events: ProjectCalendarEvent[] = []; 58 | for (const ks of sources) { 59 | events.push({ 60 | title: `${ks.title}`, 61 | start: ks.dateCreated, 62 | url: ks.id.value, 63 | color: createdColor, 64 | }); 65 | ks.dateModified.forEach((d) => { 66 | events.push({ 67 | title: `${ks.title}`, 68 | start: d, 69 | url: ks.id.value, 70 | color: modifiedColor, 71 | }); 72 | }); 73 | ks.dateAccessed.forEach((d) => { 74 | events.push({ 75 | title: `${ks.title}`, 76 | start: d, 77 | url: ks.id.value, 78 | color: accessedColor, 79 | }); 80 | }); 81 | if (ks.dateDue) { 82 | events.push({ 83 | title: `${ks.title}`, 84 | start: ks.dateDue, 85 | color: 'var(--pink-500)', 86 | url: ks.id.value, 87 | }); 88 | } 89 | } 90 | return events; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/services/user-services/icon.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Injectable } from '@angular/core'; 18 | import { PrimeIcons } from 'primeng/api'; 19 | 20 | @Injectable({ 21 | providedIn: 'root', 22 | }) 23 | export class IconService { 24 | iconValues = Object.values(PrimeIcons); 25 | 26 | constructor() { 27 | // Replace several broken icons with working ones 28 | this.iconValues[this.iconValues.indexOf('pi pi-sort-numeric-alt-up')] = 29 | 'pi pi-sort-numeric-up-alt'; 30 | 31 | this.iconValues[this.iconValues.indexOf('pi pi-sort-numeric-alt-down')] = 32 | 'pi pi-sort-numeric-down-alt'; 33 | 34 | this.iconValues[this.iconValues.indexOf('pi pi-sort-alpha-alt-down')] = 35 | 'pi pi-sort-alpha-down-alt'; 36 | 37 | this.iconValues[this.iconValues.indexOf('pi pi-sort-alpha-alt-up')] = 38 | 'pi pi-sort-alpha-up-alt'; 39 | 40 | this.iconValues[this.iconValues.indexOf('pi pi-sort-slash')] = 41 | 'pi pi-sort-alt-slash'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/workers/graph.worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /// 17 | 18 | import { KcProject } from '../models/project.model'; 19 | 20 | export function createGraph( 21 | projects: (KcProject & { level: number })[], 22 | root: string, 23 | showSources: boolean 24 | ): any[] { 25 | const data: any[] = []; 26 | 27 | for (const project of projects) { 28 | data.push({ 29 | group: 'nodes', 30 | data: { 31 | id: project.id.value, 32 | label: project.name, 33 | type: project.id.value === root ? 'root' : 'project', 34 | project: project, 35 | width: 64 / Math.pow(project.level, 1 / 2) + 4, 36 | height: 64 / Math.pow(project.level, 1 / 2), 37 | level: project.level, 38 | }, 39 | }); 40 | 41 | for (const sub of project.subprojects) { 42 | const edge = { 43 | group: 'edges', 44 | data: { 45 | id: `${project.id.value}-${sub}`, 46 | source: project.id.value, 47 | target: sub, 48 | }, 49 | }; 50 | data.push(edge); 51 | } 52 | 53 | if (showSources) { 54 | for (const ks of project.knowledgeSource) { 55 | data.push({ 56 | group: 'nodes', 57 | data: { 58 | id: ks.id.value, 59 | label: ks.title, 60 | type: 'ks', 61 | ks: ks, 62 | icon: ks.icon, 63 | }, 64 | }); 65 | 66 | data.push({ 67 | group: 'edges', 68 | data: { 69 | id: `${project.id.value}-${ks.id.value}`, 70 | source: project.id.value, 71 | target: ks.id.value, 72 | }, 73 | }); 74 | } 75 | } 76 | } 77 | return data; 78 | } 79 | 80 | addEventListener('message', (msg) => { 81 | if (!msg.data || !msg.data.projects || !msg.data.root) { 82 | return; 83 | } 84 | 85 | const projects: (KcProject & { level: number })[] = msg.data.projects; 86 | const root: string = msg.data.root; 87 | const showSources: boolean = msg.data.showSources; 88 | const data = createGraph(projects, root, showSources); 89 | postMessage(data); 90 | }); 91 | -------------------------------------------------------------------------------- /src/kc_angular/src/app/workers/tree.worker.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /// 17 | 18 | import { ProjectTreeNode } from '../models/project.tree.model'; 19 | import { TreeNode } from 'primeng/api'; 20 | 21 | export function constructTreeNodes( 22 | nodes: ProjectTreeNode[], 23 | collapsed: boolean, 24 | parent?: TreeNode 25 | ) { 26 | const treeNodes: TreeNode[] = []; 27 | for (const node of nodes) { 28 | const treeNode: TreeNode = { 29 | label: node.name, 30 | expanded: collapsed ? false : node.expanded, 31 | leaf: node.subprojects.length === 0, 32 | selectable: true, 33 | draggable: true, 34 | parent: parent, 35 | droppable: true, 36 | key: node.id, 37 | icon: node.icon, 38 | }; 39 | treeNode.children = 40 | node.subprojects.length > 0 41 | ? constructTreeNodes(node.subprojects, collapsed, treeNode) 42 | : []; 43 | treeNodes.push(treeNode); 44 | } 45 | return treeNodes; 46 | } 47 | 48 | addEventListener('message', (msg) => { 49 | if (!msg.data || !msg.data.nodes) { 50 | return; 51 | } 52 | 53 | const nodes = msg.data.nodes; 54 | const collapsed = msg.data.collapsed; 55 | const parent = msg.data.parent; 56 | const constructed = constructTreeNodes(nodes, collapsed, parent); 57 | postMessage(constructed); 58 | }); 59 | -------------------------------------------------------------------------------- /src/kc_angular/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/src/kc_angular/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/kc_angular/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/src/kc_angular/src/assets/favicon.ico -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/src/kc_angular/src/assets/img/default.png -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/icons/chrome_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/kc-icon-greyscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/src/kc_angular/src/assets/img/kc-icon-greyscale.png -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/kc-icon-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/src/kc_angular/src/assets/img/kc-icon-transparent.png -------------------------------------------------------------------------------- /src/kc_angular/src/assets/img/kc-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/src/kc_angular/src/assets/img/kc-icon.png -------------------------------------------------------------------------------- /src/kc_angular/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export const environment = { 18 | production: true, 19 | }; 20 | -------------------------------------------------------------------------------- /src/kc_angular/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This file can be replaced during build by using the `fileReplacements` array. 18 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 19 | // The list of file replacements can be found in `angular.json`. 20 | 21 | export const environment = { 22 | production: false, 23 | }; 24 | 25 | /* 26 | * For easier debugging in development mode, you can import the following file 27 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 28 | * 29 | * This import should be commented out in production mode because it will have a negative impact 30 | * on performance if an error is thrown. 31 | */ 32 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 33 | -------------------------------------------------------------------------------- /src/kc_angular/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunlight0102/chatgpt-typescript/088a2bb7e80b56d2bf25461bd317cb02751ae2cc/src/kc_angular/src/favicon.ico -------------------------------------------------------------------------------- /src/kc_angular/src/index.html: -------------------------------------------------------------------------------- 1 | 14 | 15 | 16 | 17 | 18 | 19 | Knowledge 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/kc_angular/src/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { enableProdMode } from '@angular/core'; 18 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 19 | 20 | import { AppModule } from '@app/app.module'; 21 | import { environment } from '@environments/environment'; 22 | 23 | if (environment.production) { 24 | enableProdMode(); 25 | } 26 | 27 | platformBrowserDynamic() 28 | .bootstrapModule(AppModule) 29 | .catch((err) => console.error(err)); 30 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/kc-styles.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | .knowledge-source-icon { 17 | min-width: 32px !important; 18 | min-height: 32px !important; 19 | max-width: 32px !important; 20 | max-height: 32px !important; 21 | border-radius: 50%; 22 | overflow: hidden; 23 | } 24 | 25 | .source-drag-handle { 26 | cursor: move; 27 | } 28 | 29 | .pulsate-fwd { 30 | animation: pulsate-fwd 3s ease-in-out infinite forwards; 31 | } 32 | 33 | @-webkit-keyframes pulsate-fwd { 34 | 0% { 35 | transform: scale(1); 36 | } 37 | 50% { 38 | transform: scale(1.1); 39 | } 40 | 100% { 41 | transform: scale(1); 42 | } 43 | } 44 | 45 | @keyframes pulsate-fwd { 46 | 0% { 47 | transform: scale(1); 48 | } 49 | 50% { 50 | transform: scale(1.1); 51 | } 52 | 100% { 53 | transform: scale(1); 54 | } 55 | } 56 | 57 | 58 | .project-receptor-in { 59 | animation: project-receptor-in 0.4s cubic-bezier(0.250, 0.460, 0.450, 0.560) both; 60 | } 61 | 62 | @keyframes project-receptor-in { 63 | 0% { 64 | transform: translateZ(0) translateX(0); 65 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); 66 | } 67 | 100% { 68 | transform: translateZ(50px) translateX(12px); 69 | box-shadow: -12px 0 20px -12px rgba(0, 0, 0, 0.35); 70 | } 71 | } 72 | 73 | .project-receptor-out { 74 | animation: project-receptor-out 0.4s cubic-bezier(0.250, 0.460, 0.450, 0.560) reverse both; 75 | } 76 | 77 | @keyframes project-receptor-out { 78 | 0% { 79 | transform: translateZ(0) translateX(0); 80 | box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); 81 | } 82 | 100% { 83 | transform: translateZ(50px) translateX(12px); 84 | box-shadow: -12px 0 20px -12px rgba(0, 0, 0, 0.35); 85 | } 86 | } 87 | 88 | .tracking-in-expand-fwd { 89 | animation: tracking-in-expand-fwd 0.8s cubic-bezier(0.175, 0.885, 0.320, 1.275) infinite alternate forwards; 90 | } 91 | 92 | @keyframes tracking-in-expand-fwd { 93 | 0% { 94 | letter-spacing: -0.5em; 95 | transform: translateZ(-700px); 96 | opacity: 0; 97 | } 98 | 40% { 99 | opacity: 0.6; 100 | } 101 | 100% { 102 | transform: translateZ(0); 103 | opacity: 1; 104 | } 105 | } 106 | 107 | .bg-pan-left { 108 | animation: bg-pan-left 3s infinite alternate both; 109 | } 110 | 111 | @keyframes bg-pan-left { 112 | 0% { 113 | background-position: 100% 50%; 114 | background: var(--surface-ground); 115 | } 116 | 100% { 117 | background-position: 0 50%; 118 | background: var(--surface-a); 119 | } 120 | } 121 | 122 | .kenburns-top { 123 | animation: kenburns-top 3s ease-out alternate-reverse both; 124 | } 125 | 126 | @keyframes kenburns-top { 127 | 0% { 128 | transform: scale(1) translateY(0); 129 | transform-origin: 50% 16%; 130 | } 131 | 100% { 132 | transform: scale(1.25) translateY(-15px); 133 | transform-origin: top; 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-green.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-green/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-orange.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-orange/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/arya-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/arya-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-indigo.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-indigo/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-dark-teal.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-dark-teal/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-indigo.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-indigo/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/lara-light-teal.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/lara-light-teal/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-green.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-green/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-orange.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-orange/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/saga-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/saga-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-light.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-blue.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-blue/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-green.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-green/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-orange.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-orange/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/src/styles/themes/vela-purple.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | @import "../../../../../node_modules/primeng/resources/themes/vela-purple/theme.css"; 18 | @import '../../../../../node_modules/highlight.js/styles/atom-one-dark.css'; 19 | -------------------------------------------------------------------------------- /src/kc_angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "allowSyntheticDefaultImports": true, 7 | "outDir": "./dist/out-tsc", 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "sourceMap": true, 13 | "declaration": false, 14 | "downlevelIteration": true, 15 | "experimentalDecorators": true, 16 | "moduleResolution": "node", 17 | "importHelpers": true, 18 | "target": "es2020", 19 | "module": "es2020", 20 | "lib": [ 21 | "es2018", 22 | "dom" 23 | ], 24 | "paths": { 25 | "@app/*": [ 26 | "src/app/*" 27 | ], 28 | "@assets/*": [ 29 | "src/assets/*" 30 | ], 31 | "@environments/*": [ 32 | "src/environments/*" 33 | ], 34 | "@styles/*": [ 35 | "src/styles/*" 36 | ], 37 | "@components/*": [ 38 | "src/app/components/*" 39 | ], 40 | "@pipes/*": [ 41 | "src/app/pipes/*" 42 | ], 43 | "@shared/*": [ 44 | "../kc_shared/*" 45 | ], 46 | "@services/*": [ 47 | "src/app/services/*" 48 | ] 49 | } 50 | }, 51 | "files": [ 52 | "src/main.ts", 53 | "src/polyfills.ts" 54 | ], 55 | "include": [ 56 | "src/**/*.d.ts" 57 | ], 58 | "angularCompilerOptions": { 59 | "enableI18nLegacyMessageIdFormat": false, 60 | "strictInjectionParameters": true, 61 | "strictInputAccessModifiers": true, 62 | "strictTemplates": true 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/kc_angular/tsconfig.worker.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/worker", 6 | "lib": [ 7 | "dom" 8 | ], 9 | "types": [] 10 | }, 11 | "include": [ 12 | "**/*.worker.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/kc_electron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kc_electron", 3 | "version": "0.8.1", 4 | "description": "This package contains the Electron portion of the Knowledge desktop application.", 5 | "main": "dist/main.js", 6 | "author": "Rob Royce (https://robroyce.dev)", 7 | "license": "Apache-2.0", 8 | "private": true, 9 | "scripts": { 10 | "build": "webpack --config webpack.prod.js", 11 | "build-dev": "webpack --config webpack.dev.js", 12 | "clean": "rm -rf dist", 13 | "purge": "rm -rf node_modules", 14 | "test": "echo \"Error: no test specified\" && exit 1", 15 | "watch-electron": "webpack --config webpack.prod.js --watch", 16 | "watch-electron-dev": "webpack --config webpack.dev.js --watch" 17 | }, 18 | "dependencies": { 19 | "@dqbd/tiktoken": "^1.0.6", 20 | "chokidar": "^3.5.3", 21 | "cors": "^2.8.5", 22 | "crypto-js": "^4.1.1", 23 | "dotenv": "^16.0.3", 24 | "electron": "^21.2.1", 25 | "electron-updater": "^5.3.0", 26 | "express-rate-limit": "^6.7.0", 27 | "lodash": "^4.17.21", 28 | "mime-types": "^2.1.35", 29 | "openai": "^3.2.1", 30 | "rxjs": "^7.5.7", 31 | "uuid": "^9.0.0" 32 | }, 33 | "devDependencies": { 34 | "@types/cors": "^2", 35 | "@types/crypto-js": "^4", 36 | "@types/lodash": "^4.14.187", 37 | "@types/mime-types": "^2.1.1", 38 | "electron-builder": "^23.6.0", 39 | "ts-loader": "^9.4.1", 40 | "typescript": "<4.9.0", 41 | "webpack": "^5.76.0", 42 | "webpack-cli": "^4.10.0", 43 | "webpack-merge": "^5.8.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/ipc/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const fileIpc = require("./ipc-files"); 18 | const browserIpc = require("./ipc-browser"); 19 | require("./ipc-misc"); 20 | const autoUpdateIpc = require("./ipc-auto-update"); 21 | 22 | module.exports = { 23 | autoUpdateIpc, 24 | fileIpc, 25 | browserIpc, 26 | }; 27 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/ipc/ipc-auto-update.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const share: any = (global as any).share; 18 | const ipcMain = share.ipcMain; 19 | const autoUpdater = share.autoUpdater; 20 | 21 | import { IpcMessage } from "../../../../kc_shared/models/electron.ipc.model"; 22 | 23 | const checkForUpdate = ipcMain.on("A2E:AutoUpdate:Check", (_: any) => { 24 | autoUpdater 25 | .checkForUpdates() 26 | .then((result: any) => { 27 | console.warn("Result from check for update: ", result); 28 | }) 29 | .catch((error: any) => { 30 | console.warn("Error from check for update: ", error); 31 | }); 32 | }); 33 | 34 | const getCurrentVersion = ipcMain.on("A2E:Version:Get", (_: any) => { 35 | const kcMainWindow: any = share.BrowserWindow.getAllWindows()[0]; 36 | const message: IpcMessage = { 37 | error: undefined, 38 | success: { 39 | data: autoUpdater.currentVersion.version, 40 | }, 41 | }; 42 | kcMainWindow.webContents.send("E2A:Version:Get", message); 43 | }); 44 | 45 | module.exports = { 46 | checkForUpdate, 47 | getCurrentVersion, 48 | }; 49 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/ipc/ipc-misc.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { 17 | IpcMessage, 18 | UuidRequest, 19 | } from "../../../../kc_shared/models/electron.ipc.model"; 20 | 21 | const share: any = (global as any).share; 22 | const ipcMain: any = share.ipcMain; 23 | const http: any = share.http; 24 | const uuid: any = share.uuid; 25 | 26 | let generateUuid; 27 | 28 | generateUuid = ipcMain.on("A2E:Uuid:Generate", (event: any, args: any) => { 29 | const kcMainWindow: any = share.BrowserWindow.getAllWindows()[0]; 30 | const response: IpcMessage = { 31 | error: undefined, 32 | success: undefined, 33 | }; 34 | if (!isKcUuidRequest(args)) { 35 | const message = `electron-generate-uuid argument does not conform to KcUuidRequest`; 36 | response.error = { 37 | code: 412, 38 | label: http.STATUS_CODES["412"], 39 | message: message, 40 | }; 41 | console.warn(response.error); 42 | kcMainWindow.webContents.send("E2A:BrowserView:Open", response); 43 | return; 44 | } 45 | let ids = []; 46 | for (let i = 0; i < args.quantity; i++) { 47 | const id = uuid.v4(); 48 | if (i === 0) ids = [id]; 49 | else ids.push(id); 50 | } 51 | response.success = { data: ids }; 52 | kcMainWindow.webContents.send("E2A:Uuid:Generate", response); 53 | }); 54 | 55 | function isKcUuidRequest(args: any): args is UuidRequest { 56 | const containsQuantity = args && args.quantity; 57 | const correctType = typeof args.quantity === "number"; 58 | const correctRange = 0 < args.quantity && args.quantity <= 128; 59 | return containsQuantity && correctType && correctRange; 60 | } 61 | 62 | module.exports = { generateUuid }; 63 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/services/auto.update.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const share: any = (global as any).share; 18 | const http: any = share.http; 19 | const autoUpdater = share.autoUpdater; 20 | 21 | import { IpcMessage } from "../../../../kc_shared/models/electron.ipc.model"; 22 | 23 | console.log( 24 | `AutoUpdate - Knowledge Version ${autoUpdater.currentVersion.version} - Initializing...` 25 | ); 26 | 27 | autoUpdater.on("checking-for-update", () => { 28 | const message: IpcMessage = { 29 | error: undefined, 30 | success: { 31 | data: "Auto updater checking for update...", 32 | }, 33 | }; 34 | console.log(message); 35 | }); 36 | 37 | autoUpdater.on("update-available", (info: any) => { 38 | const message: IpcMessage = { 39 | error: undefined, 40 | success: { 41 | data: info, 42 | message: "Auto updater found new update...", 43 | }, 44 | }; 45 | console.log(message); 46 | }); 47 | 48 | autoUpdater.on("update-not-available", (info: any) => { 49 | const message: IpcMessage = { 50 | error: undefined, 51 | success: { 52 | data: info, 53 | message: "No updates available...", 54 | }, 55 | }; 56 | console.log(message); 57 | }); 58 | 59 | autoUpdater.on("error", (err: any) => { 60 | const message: IpcMessage = { 61 | error: { 62 | code: 501, 63 | label: http.STATUS_CODES["501"], 64 | message: err, 65 | }, 66 | success: undefined, 67 | }; 68 | console.log(message); 69 | }); 70 | 71 | autoUpdater.on("download-progress", (progressObj: any) => { 72 | let log_message = "Download speed: " + progressObj.bytesPerSecond; 73 | log_message = log_message + " - Downloaded " + progressObj.percent + "%"; 74 | log_message = 75 | log_message + 76 | " (" + 77 | progressObj.transferred + 78 | "/" + 79 | progressObj.total + 80 | ")"; 81 | const message: IpcMessage = { 82 | error: undefined, 83 | success: { 84 | message: log_message, 85 | }, 86 | }; 87 | console.log(message); 88 | }); 89 | 90 | autoUpdater.on("update-downloaded", (info: any) => { 91 | const message: IpcMessage = { 92 | error: undefined, 93 | success: { 94 | data: info, 95 | message: "Update finished downloading...", 96 | }, 97 | }; 98 | console.log(message); 99 | }); 100 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/services/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | const autoscanService = require("./autoscan.service"); 17 | const extensionService = require("./extension.service"); 18 | const windowService = require("./window.service"); 19 | 20 | module.exports = { 21 | autoscan: autoscanService, 22 | extensions: extensionService, 23 | window: windowService, 24 | }; 25 | -------------------------------------------------------------------------------- /src/kc_electron/src/app/services/window.service.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const share: any = (global as any).share; 18 | 19 | class WindowService { 20 | constructor() { 21 | share.ipcMain.on("A2E:Window:Minimize", (_: any) => { 22 | // TODO: this method of finding the main window is definitely broken... 23 | // there is no gaurantee that the main window will be first in this array when a second window is open... 24 | // this is preventing us from opening the Knowledge Graph in its own window 25 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 26 | if (kcMainWindow) { 27 | kcMainWindow.minimize(); 28 | } else { 29 | console.log("Unable to get main window..."); 30 | } 31 | }); 32 | 33 | share.ipcMain.on("A2E:Window:Maximize", (_: any) => { 34 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 35 | if (kcMainWindow) { 36 | kcMainWindow.fullScreen = !kcMainWindow.fullScreen; 37 | } else { 38 | console.log("Unable to get main window..."); 39 | } 40 | }); 41 | 42 | share.ipcMain.on("A2E:Window:ZoomIn", (_: any, zoomLevel: number) => { 43 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 44 | if (kcMainWindow) { 45 | kcMainWindow.webContents.setZoomFactor(zoomLevel / 100); 46 | } else { 47 | console.log("Unable to get main window..."); 48 | } 49 | }); 50 | 51 | share.ipcMain.on("A2E:Window:ZoomOut", (_: any, zoomLevel: number) => { 52 | const kcMainWindow = share.BrowserWindow.getAllWindows()[0]; 53 | if (kcMainWindow) { 54 | kcMainWindow.webContents.setZoomFactor(zoomLevel / 100); 55 | } else { 56 | console.log("Unable to get main window..."); 57 | } 58 | }); 59 | } 60 | } 61 | 62 | const electronWindowService = new WindowService(); 63 | module.exports = electronWindowService; 64 | -------------------------------------------------------------------------------- /src/kc_electron/src/ipc/chat.ipc.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { IpcChannelInterface } from "../local/utils/ipc.utils"; 18 | import { IpcMainEvent } from "electron"; 19 | import { IpcRequest } from "../../../kc_shared/models/electron.ipc.model"; 20 | 21 | export class ChatPrinterIpc implements IpcChannelInterface { 22 | getName(): string { 23 | return "ChatPrinter"; 24 | } 25 | 26 | handle(event: IpcMainEvent, request: IpcRequest): void { 27 | console.log("Chat printer handler", event, request); 28 | } 29 | 30 | private async createContainer(height: number, width: number, doc: Document) { 31 | const container = doc.createElement("div"); 32 | container.style.display = "block"; 33 | container.style.height = `${height}px`; 34 | container.style.width = `${width}px`; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/autoscan.api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import * as chokidar from "chokidar"; 17 | import * as fs from "fs-extra"; 18 | import * as path from "path"; 19 | 20 | /** 21 | * TODO: Not implemented yet. 22 | */ 23 | export default class Autoscan { 24 | private sourceDirectory = "./source"; 25 | private pendingDirectory = "./pending"; 26 | private locationMapFile = "fileLocationMap.json"; 27 | private fileLocationMap = new Map(); 28 | 29 | async processFile(filePath: string) { 30 | // Implement your custom post-processing logic here 31 | console.log(`Processing ${filePath}`); 32 | } 33 | 34 | async moveFileToPending(filePath: string) { 35 | const fileName = path.basename(filePath); 36 | const pendingFilePath = path.join(this.pendingDirectory, fileName); 37 | 38 | try { 39 | await fs.move(filePath, pendingFilePath); 40 | this.fileLocationMap.set(fileName, pendingFilePath); 41 | console.log(`Moved ${filePath} to ${pendingFilePath}`); 42 | await this.saveFileLocationMap(); 43 | } catch (err) { 44 | console.error(`Failed to move ${filePath} to ${pendingFilePath}`, err); 45 | } 46 | } 47 | 48 | async handleNewFile(filePath: string) { 49 | await this.processFile(filePath); 50 | await this.moveFileToPending(filePath); 51 | } 52 | 53 | startWatching() { 54 | const watcher = chokidar.watch(this.sourceDirectory, { 55 | persistent: true, 56 | ignoreInitial: true, 57 | }); 58 | 59 | watcher.on("add", (filePath) => { 60 | console.log(`New file detected: ${filePath}`); 61 | this.handleNewFile(filePath); 62 | }); 63 | 64 | watcher.on("error", (error) => console.error(`Watcher error: ${error}`)); 65 | } 66 | 67 | async saveFileLocationMap() { 68 | const data = JSON.stringify(Array.from(this.fileLocationMap.entries())); 69 | await fs.writeFile(this.locationMapFile, data, "utf8"); 70 | console.log(`Saved file location map to ${this.locationMapFile}`); 71 | } 72 | 73 | async loadFileLocationMap() { 74 | if (await fs.pathExists(this.locationMapFile)) { 75 | const data = await fs.readFile(this.locationMapFile, "utf8"); 76 | const entries = JSON.parse(data) as [string, string][]; 77 | this.fileLocationMap.clear(); 78 | for (const [key, value] of entries) { 79 | this.fileLocationMap.set(key, value); 80 | } 81 | console.log(`Loaded file location map from ${this.locationMapFile}`); 82 | } 83 | } 84 | 85 | async init() { 86 | await fs.ensureDir(this.sourceDirectory); 87 | await fs.ensureDir(this.pendingDirectory); 88 | 89 | await this.loadFileLocationMap(); 90 | this.startWatching(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/browser.api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/chat.api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import express, { Express } from "express"; 18 | import cors from "cors"; 19 | import { ErrorHandler } from "./middleware/ErrorHandler"; 20 | 21 | import chatRoutes from "./routes/chat.routes"; 22 | import apiRoutes from "./routes/api.routes"; 23 | import sourceRoutes from "./routes/source.routes"; 24 | 25 | export default class ChatServer { 26 | private app: Express; 27 | 28 | constructor() { 29 | this.app = express(); 30 | this.setupMiddleware(); 31 | this.setupRoutes(); 32 | } 33 | 34 | start(port: number) { 35 | this.app.listen(port, () => { 36 | console.log(`Chat server listening on port ${port}`); 37 | }); 38 | } 39 | 40 | private setupMiddleware() { 41 | this.app.use(express.json({ limit: "50mb" })); // Parse JSON request bodies 42 | this.app.use(cors()); // Enable CORS 43 | } 44 | 45 | private setupRoutes() { 46 | this.app.use("/api", ErrorHandler.catchErrors(apiRoutes)); 47 | this.app.use("/sources", ErrorHandler.catchErrors(sourceRoutes)); 48 | this.app.use("/chat", ErrorHandler.catchErrors(chatRoutes)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/controllers/api.controller.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Request, Response } from "express"; 18 | import { Configuration, OpenAIApi } from "openai"; 19 | 20 | import fs from "fs"; 21 | import chatEncrypt from "../utils/encrypt.utils"; 22 | 23 | const settings = require("../../app/services/settings.service"); 24 | 25 | export class ApiKeyController { 26 | async checkApiKey(req: Request, res: Response): Promise { 27 | // Returns true if API key is set and works as expected, otherwise false 28 | const apiKey = await this.loadApiKey(); 29 | const apiKeyWorks = await this.testApiKey(apiKey); 30 | return res.json({ 31 | apiKeySet: apiKeyWorks, 32 | }); 33 | } 34 | 35 | async hasApiKey(req: Request, res: Response): Promise { 36 | // Returns true if API key is set, otherwise false 37 | try { 38 | const apiKey = await this.loadApiKey(); 39 | return res.json({ 40 | apiKeySet: apiKey && apiKey.length > 0, 41 | }); 42 | } catch { 43 | return res.json({ apiKeySet: false }); 44 | } 45 | } 46 | 47 | async deleteApiKey(req: Request, res: Response): Promise { 48 | const apiKeyPath = this.getApiKeyPath(); 49 | if (fs.existsSync(apiKeyPath)) { 50 | console.debug("Deleting API key at path: ", apiKeyPath); 51 | fs.unlinkSync(apiKeyPath); 52 | return res.json({ success: true }); 53 | } 54 | return res.json({ success: false }); 55 | } 56 | 57 | async setApiKey(req: Request, res: Response): Promise { 58 | const apiKeyWorks = await this.testApiKey(req.body.apiKey); 59 | if (!apiKeyWorks) { 60 | return res.status(400).json({ success: false }); 61 | } 62 | 63 | const saved = await this.saveApiKey(req.body.apiKey); 64 | return res.json({ success: saved }); 65 | } 66 | 67 | private getApiKeyPath(): string { 68 | const userDataPath = settings.getSettings().system.appPath; 69 | return `${userDataPath}/openai.encrypted`; 70 | } 71 | 72 | private async loadApiKey() { 73 | return chatEncrypt.readAndDecryptApiKey(this.getApiKeyPath(), "unsecured"); 74 | } 75 | 76 | private async saveApiKey(apiKey: string) { 77 | const encryptedApiKey = chatEncrypt.encryptApiKey(apiKey, "unsecured"); 78 | const filePath = this.getApiKeyPath(); 79 | fs.writeFileSync(filePath, encryptedApiKey); 80 | return true; 81 | } 82 | 83 | private async testApiKey(apiKey: string) { 84 | try { 85 | const config = new Configuration({ 86 | apiKey: apiKey, 87 | }); 88 | const openaiTest = new OpenAIApi(config); 89 | const models = await openaiTest.listModels(); 90 | return models.status === 200; 91 | } catch (e) { 92 | return false; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/controllers/project.controller.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Request, Response } from "express"; 18 | 19 | export default class ProjectChatController { 20 | async chat(req: Request, res: Response): Promise { 21 | // Load the entire source here 22 | return res.status(500).json({ message: "Not implemented" }); 23 | } 24 | 25 | async intro(req: Request, res: Response): Promise { 26 | // Load the entire source here 27 | console.log("Got request on sources/intro..."); 28 | return res.status(500).json({ message: "Not implemented" }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/middleware/ErrorHandler.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { NextFunction, Request, Response } from "express"; 18 | import { ResponseUtil } from "../utils/response.util"; 19 | 20 | export class ErrorHandler { 21 | static catchErrors(fn: any) { 22 | return (req: Request, res: Response, next: NextFunction) => { 23 | Promise.resolve(fn(req, res, next)).catch(next); 24 | }; 25 | } 26 | 27 | static handleErrors(err: any, req: Request, res: Response) { 28 | console.error(err); 29 | 30 | if (err.message === "Invalid file type") { 31 | return ResponseUtil.sendError(res, "Invalid file type", 422, null); 32 | } 33 | 34 | return res.status(500).send({ 35 | success: false, 36 | message: "Internal server error", 37 | }); 38 | } 39 | 40 | static formatErrors(error: any) { 41 | // Used in conjunction with class-validator to handle format errors 42 | const errors = {}; 43 | error.forEach((e: any) => { 44 | // @ts-ignore 45 | if (!errors[e.property]) { 46 | // @ts-ignore 47 | errors[e.property] = []; 48 | } 49 | // @ts-ignore 50 | errors[e.property].push(e.constraints[Object.keys(e.constraints)[0]]); 51 | }); 52 | return errors; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/routes/api.routes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import express from "express"; 18 | import { ApiKeyController } from "../controllers/api.controller"; 19 | 20 | const apiKeyController = new ApiKeyController(); 21 | 22 | const router = express.Router(); 23 | 24 | router.post("/key", apiKeyController.setApiKey.bind(apiKeyController)); 25 | router.get("/key", apiKeyController.hasApiKey.bind(apiKeyController)); 26 | router.delete("/key", apiKeyController.deleteApiKey.bind(apiKeyController)); 27 | 28 | export default router; 29 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/routes/chat.routes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import express from "express"; 18 | import ChatController from "../controllers/chat.controller"; 19 | 20 | const chatController = new ChatController(); 21 | 22 | const router = express.Router(); 23 | 24 | router.post("/", chatController.chat.bind(chatController)); 25 | router.post("/tokens", chatController.tokens.bind(chatController)); 26 | 27 | export default router; 28 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/routes/source.routes.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import express from "express"; 18 | import SourceChatController from "../controllers/source.controller"; 19 | 20 | const sourceController = new SourceChatController(); 21 | 22 | const router = express.Router(); 23 | 24 | router.post("/", sourceController.chat.bind(sourceController)); 25 | router.post("/intro", sourceController.intro.bind(sourceController)); 26 | // router.post("/pdf", sourceController.pdf.bind(sourceController)); 27 | 28 | export default router; 29 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/chat.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ChatCompletionRequestMessage } from "openai/api"; 18 | import tokenizerUtils from "./tokenizer.utils"; 19 | 20 | const settings = require("../../app/services/settings.service"); 21 | 22 | export default class ChatUtils { 23 | constructor() {} 24 | 25 | /** 26 | * Reduce the messages to a single message while retaining as much information as possible 27 | * @param messages 28 | */ 29 | async reduce(messages: ChatCompletionRequestMessage[]) {} 30 | 31 | async refine(messages: ChatCompletionRequestMessage[]) {} 32 | 33 | /** 34 | * Split the text into chunks and summarize each chunk 35 | * @param text 36 | */ 37 | async mapReduce(text: string) { 38 | const tokenizer = this.getTokenizer(); 39 | const tokenCount = tokenizer.countTokens(text); 40 | console.log("Token count: ", tokenCount); 41 | } 42 | 43 | private getTokenizer() { 44 | const model = settings.getSettings().app.chat.model.name; 45 | tokenizerUtils.setModel(model); 46 | return tokenizerUtils; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/encrypt.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import CryptoJS from "crypto-js"; 18 | import fs from "fs"; 19 | 20 | export class EncryptUtils { 21 | encryptApiKey(apiKey: string, secretKey: string): string { 22 | return CryptoJS.AES.encrypt(apiKey, secretKey).toString(); 23 | } 24 | 25 | decryptApiKey(encrypted: string, secret: string): string { 26 | const apiKey = CryptoJS.AES.decrypt(encrypted, secret); 27 | return apiKey.toString(CryptoJS.enc.Utf8); 28 | } 29 | 30 | async readAndDecryptApiKey(keyPath: string, secret: string): Promise { 31 | const filePath = keyPath; 32 | 33 | if (!fs.existsSync(filePath)) { 34 | return ""; 35 | } 36 | 37 | const encryptedApiKey = fs.readFileSync(filePath, "utf-8"); 38 | return this.decryptApiKey(encryptedApiKey, secret); 39 | } 40 | } 41 | 42 | const chatEncrypt = new EncryptUtils(); 43 | export default chatEncrypt; 44 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/ipc.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { ipcMain, IpcMainEvent } from "electron"; 18 | import { IpcRequest } from "../../../../kc_shared/models/electron.ipc.model"; 19 | import { ChatPrinterIpc } from "../../ipc/chat.ipc"; 20 | 21 | export interface IpcChannelInterface { 22 | getName(): string; 23 | 24 | handle(event: IpcMainEvent, request: IpcRequest): void; 25 | } 26 | 27 | export default class KnowledgeIpc { 28 | ipcChannels: IpcChannelInterface[] = [new ChatPrinterIpc()]; 29 | 30 | constructor() { 31 | this.registerIpcChannels(this.ipcChannels); 32 | } 33 | 34 | /** 35 | * Registers all IPC channels with the main process 36 | * @param ipcChannels 37 | */ 38 | private registerIpcChannels(ipcChannels: IpcChannelInterface[]) { 39 | ipcChannels.forEach((channel) => { 40 | console.log("Registering IPC Channel: " + channel.getName()); 41 | ipcMain.on(channel.getName(), (event, request) => { 42 | try { 43 | channel.handle(event, request); 44 | } catch (err) { 45 | console.log(err); 46 | } 47 | }); 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/response.util.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import { Response } from "express"; 18 | 19 | export class ResponseUtil { 20 | static sendResponse( 21 | res: Response, 22 | message: string, 23 | data: T, 24 | statusCode = 200, 25 | paginationInfo: any = null 26 | ): Response { 27 | return res.status(statusCode).json({ 28 | success: true, 29 | message, 30 | data, 31 | pagination: paginationInfo, 32 | status: statusCode, 33 | }); 34 | } 35 | 36 | static sendError( 37 | res: Response, 38 | message: string, 39 | statusCode = 500, 40 | error: T 41 | ): Response { 42 | return res.status(statusCode).json({ 43 | success: false, 44 | message, 45 | error, 46 | }); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/kc_electron/src/local/utils/text.utils.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export default class TextUtils { 18 | constructor() { 19 | throw new Error("TextUtils is a static class and cannot be instantiated"); 20 | } 21 | 22 | static isNullOrWhitespace(text: string): boolean { 23 | return text === null || text.match(/^ *$/) !== null; 24 | } 25 | 26 | static isNullOrEmpty(text: string): boolean { 27 | return text === null || text === ""; 28 | } 29 | 30 | static isNullOrWhitespaceOrEmpty(text: string): boolean { 31 | return TextUtils.isNullOrWhitespace(text) || TextUtils.isNullOrEmpty(text); 32 | } 33 | 34 | static convertToAscii(text: string): string { 35 | return text.replace(/[^\x00-\x7F]/g, ""); 36 | } 37 | 38 | static convertToBase64(text: string): string { 39 | return Buffer.from(text).toString("base64"); 40 | } 41 | 42 | static convertFromBase64(text: string): string { 43 | return Buffer.from(text, "base64").toString(); 44 | } 45 | 46 | static convertToBase64Url(text: string): string { 47 | return TextUtils.convertToBase64(text) 48 | .replace(/\+/g, "-") 49 | .replace(/\//g, "_") 50 | .replace(/=/g, ""); 51 | } 52 | 53 | static chunk(text: string, size: number): string[] { 54 | const chunks = []; 55 | for (let i = 0; i < text.length; i += size) { 56 | chunks.push(text.substring(i, i + size - 1)); 57 | } 58 | return chunks; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/autoscan.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/browser.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/chat.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/src/test/ipc.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /src/kc_electron/webpack.common.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const path = require("path"); 18 | 19 | let webpack_config = { 20 | entry: { 21 | main: path.join(__dirname, "src", "main.ts"), 22 | preload: path.join(__dirname, "src", "preload.js"), 23 | }, 24 | target: "electron-main", // Webpack knows about the electron main process specifically 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.ts$/, // This particular rule matches all .ts files 29 | use: [{ loader: "ts-loader" }], // Which loader to use when the rule matches 30 | }, 31 | ], 32 | }, 33 | output: { 34 | path: path.join(process.cwd(), "dist"), // all output files are placed here 35 | filename: "[name].js", // Primary output bundle 36 | }, 37 | externals: { 38 | // NOTE: this had to be added after manually installing Chokidar 3.5 39 | // NOTE: https://github.com/yan-foto/electron-reload/issues/71 40 | fsevents: "require('fsevents')", 41 | express: "require('express')", 42 | }, 43 | resolve: { 44 | extensions: [".ts", ".js", ".json"], 45 | }, 46 | plugins: [], 47 | }; 48 | 49 | module.exports = webpack_config; 50 | -------------------------------------------------------------------------------- /src/kc_electron/webpack.dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This file was generated following the guide provided at 18 | // https://www.sitepen.com/blog/getting-started-with-electron-typescript-react-and-webpack 19 | const { merge } = require("webpack-merge"); 20 | const common = require("./webpack.common"); 21 | 22 | module.exports = merge(common, { 23 | mode: "development", 24 | }); 25 | -------------------------------------------------------------------------------- /src/kc_electron/webpack.prod.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // This file was generated following the guide provided at 18 | // https://www.sitepen.com/blog/getting-started-with-electron-typescript-react-and-webpack 19 | const { merge } = require("webpack-merge"); 20 | const common = require("./webpack.common"); 21 | 22 | module.exports = merge(common, { 23 | mode: "production", 24 | }); 25 | -------------------------------------------------------------------------------- /src/kc_shared/models/author.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {UuidModel} from "./uuid.model"; 17 | 18 | export interface AuthorModel { 19 | firstName: string; 20 | lastName: string; 21 | id: UuidModel; 22 | } 23 | -------------------------------------------------------------------------------- /src/kc_shared/models/browser.view.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | export interface BrowserViewHeaderConfig { 17 | showOpenButton?: boolean; 18 | canClose?: boolean; 19 | canCopy?: boolean; 20 | canGoBack?: boolean; 21 | canGoForward?: boolean; 22 | canRefresh?: boolean; 23 | canSave?: boolean; 24 | displayText?: string; 25 | displayTextReadOnly?: boolean; 26 | backgroundColor?: string; 27 | showSaveButton?: boolean; 28 | showNavButtons?: boolean; 29 | showActionButtons?: boolean; 30 | showDisplayText?: boolean; 31 | showCloseButton?: boolean; 32 | showInvertButton?: boolean; 33 | } 34 | 35 | export interface BrowserViewHeaderEvent { 36 | backClicked?: boolean; 37 | forwardClicked?: boolean; 38 | refreshClicked?: boolean; 39 | closeClicked?: boolean; 40 | copyClicked?: boolean; 41 | saveClicked?: boolean; 42 | openClicked?: boolean; 43 | invertClicked?: boolean; 44 | } 45 | 46 | export interface FileViewConfig { 47 | filePath: string; 48 | isDialog?: true; 49 | } 50 | 51 | export type FileViewClickEvent = BrowserViewHeaderEvent; 52 | 53 | export interface BrowserViewConfig { 54 | url: URL; 55 | isDialog?: boolean; 56 | canSave?: boolean; 57 | } 58 | 59 | export interface BrowserViewNavEvent { 60 | urlChanged?: true; 61 | url?: URL; 62 | } 63 | 64 | export type BrowserViewClickEvent = BrowserViewHeaderEvent; 65 | -------------------------------------------------------------------------------- /src/kc_shared/models/electron.ipc.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { KnowledgeSource } from "./knowledge.source.model"; 17 | 18 | export interface IpcSuccess { 19 | message?: string; 20 | data?: any; 21 | } 22 | 23 | export interface IpcError { 24 | code: number; 25 | label: string; 26 | message: string; 27 | } 28 | 29 | export interface IpcMessage { 30 | error: IpcError | undefined; 31 | success: IpcSuccess | undefined; 32 | } 33 | 34 | export interface IpcRequest { 35 | responseChannel: string; 36 | data: any; 37 | } 38 | 39 | export interface UuidRequest { 40 | quantity: number; 41 | } 42 | 43 | export interface BrowserViewRequest { 44 | url: string; 45 | x: number; 46 | y: number; 47 | height: number; 48 | width: number; 49 | returnHtml?: boolean; 50 | } 51 | 52 | export interface BrowserViewResponse { 53 | html: string; 54 | backgroundColor: string; 55 | } 56 | 57 | export interface DialogRequest { 58 | ksList: KnowledgeSource[]; 59 | } 60 | 61 | export interface ThumbnailRequest { 62 | path: string; 63 | width?: number; 64 | height?: number; 65 | id?: string; 66 | } 67 | 68 | export interface PromptForDirectoryRequest { 69 | title?: string; // Dialog window title 70 | defaultPath?: string; // Path to point to when dialog loads 71 | buttonLabel?: string; // Custom label for the confirmation button, when left empty the default label will be used. 72 | filters?: FileFilter[]; // Filters for displaying certain file types 73 | properties?: PromptForDirectoryProperties[]; // Contains which features the dialog should use. 74 | message?: string; // [MacOS Only] Message to display above input boxes. 75 | securityScopedBookmarks?: boolean; // [MacOS Only] Create security scoped bookmarks when packaged for the Mac App Store 76 | } 77 | 78 | export type PromptForDirectoryProperties = 79 | | "openFile" // Allow files to be selected 80 | | "openDirectory" // Allow directories to be selected. 81 | | "multiSelections" // Allow multiple paths to be selected. 82 | | "showHiddenFiles" // Show hidden files in dialog. 83 | | "createDirectory" // [MacOS Only] Allow creating new directories from dialog. 84 | | "promptToCreate" // [Windows Only] Prompt for creation if the file path entered in the dialog does not exist. This does not actually create the file at the path but allows non-existent paths to be returned that should be created by the application. 85 | | "noResolveAliases" // [MacOS Only] Disable the automatic alias (symlink) path resolution. Selected aliases will now return the alias path instead of their target path. 86 | | "treatPackageAsDirectory" // [MacOS Only] Treat packages, such as .app folders, as a directory instead of a file. 87 | | "dontAddToRecent"; // [Windows Only] Do not add the item being opened to the recent documents list. 88 | 89 | export type FileFilter = { 90 | name: string; 91 | extensions: string[]; 92 | }; 93 | -------------------------------------------------------------------------------- /src/kc_shared/models/event.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export type EventType = 18 | | "create" 19 | | "read" 20 | | "update" 21 | | "delete" 22 | | "reminder" 23 | | "checkPoint" 24 | | "dueDate"; 25 | 26 | export interface EventModel { 27 | timestamp: string; 28 | type: EventType; 29 | description?: string; 30 | icon?: string; 31 | } 32 | 33 | export interface ProjectCalendar { 34 | events: EventModel[]; 35 | end: Date | string | null; 36 | start: Date | string | null; 37 | } 38 | -------------------------------------------------------------------------------- /src/kc_shared/models/file.source.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import { UuidModel } from "./uuid.model"; 17 | 18 | export interface FileSourceModel { 19 | filename: string; 20 | size: number; 21 | path: string; 22 | id: UuidModel; 23 | type: string; 24 | accessTime: string; 25 | modificationTime: string; 26 | creationTime: string; 27 | pages?: number; 28 | words?: number; 29 | } 30 | 31 | export interface FileWatcherUpdate { 32 | id: string; 33 | method: "add" | "remove" | "delay"; 34 | } 35 | 36 | export interface PendingFileTransfer { 37 | id: string; 38 | filename: string; 39 | oldPath: string; 40 | newPath: string; 41 | } 42 | -------------------------------------------------------------------------------- /src/kc_shared/models/graph.model.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Rob Royce 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | export interface ProjectGraphNode { 17 | name: string; 18 | id: string; 19 | type: string; 20 | expanded: boolean; 21 | subprojects: ProjectGraphNode[]; 22 | } 23 | 24 | export interface SourceGraphNode { 25 | name: string; 26 | id: string; 27 | icon: string; 28 | } 29 | -------------------------------------------------------------------------------- /src/kc_shared/models/hashable.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | export interface Hashable { 18 | hash: string 19 | } 20 | -------------------------------------------------------------------------------- /src/kc_shared/models/knowledge.source.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {WebSourceModel} from "./web.source.model"; 17 | import {FileSourceModel} from "./file.source.model"; 18 | import {UuidModel} from "./uuid.model"; 19 | import {EventModel} from "./event.model"; 20 | 21 | export interface KnowledgeSourceModel { 22 | title: string 23 | id: UuidModel 24 | type: 'file' | 'web' 25 | source: FileSourceModel | WebSourceModel 26 | associatedProjects?: UuidModel[] 27 | events?: EventModel[] 28 | icon?: UuidModel 29 | thumbnail?: UuidModel 30 | markup?: UuidModel[] 31 | topics?: UuidModel[] 32 | authors?: UuidModel[] 33 | flagged: boolean 34 | } 35 | 36 | export interface KnowledgeSource extends KnowledgeSourceModel { 37 | 38 | } 39 | 40 | export interface KnowledgeSourceImage { 41 | id: UuidModel 42 | data: string 43 | } 44 | 45 | export interface KnowledgeSourceIcon extends KnowledgeSourceImage { 46 | link?: string 47 | } 48 | 49 | export interface KnowledgeSourceThumbnail extends KnowledgeSourceImage { 50 | height: number 51 | width: number 52 | link?: string 53 | } 54 | 55 | export interface KnowledgeSourceIngestTask { 56 | method: ImportMethod 57 | callback: (method: 'add' | 'remove' | 'delay') => void 58 | id: string 59 | } 60 | 61 | export type ImportMethod = 'autoscan' | 'dnd' | 'extension' | 'manual' | 'example' | 'recommend'; 62 | -------------------------------------------------------------------------------- /src/kc_shared/models/markup.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {EventModel} from "./event.model"; 17 | 18 | export type MarkupType = 'note' | 'highlight' | 'underline' | 'sticker'; 19 | 20 | export interface KnowledgeSourceMarkup { 21 | type: MarkupType 22 | event: EventModel 23 | } 24 | 25 | export interface MarkupColor { 26 | color: string 27 | } 28 | 29 | export interface MarkupFont { 30 | weight: number 31 | } 32 | 33 | export interface MarkupData { 34 | data: string 35 | } 36 | 37 | export interface MarkupNote extends KnowledgeSourceMarkup { 38 | title?: string 39 | body: string 40 | } 41 | 42 | export interface MarkupSticker extends KnowledgeSourceMarkup, MarkupData { 43 | link?: string 44 | } 45 | 46 | export interface MarkupUnderline extends KnowledgeSourceMarkup, MarkupColor, MarkupFont, Partial { 47 | } 48 | 49 | export interface MarkupHighlight extends KnowledgeSourceMarkup, MarkupColor, MarkupFont, Partial { 50 | opacity: number 51 | } 52 | 53 | export interface FileSourceMarkup extends KnowledgeSourceMarkup { 54 | pos?: { x: Number, y: Number, width: Number, height: Number } 55 | } 56 | 57 | export interface WebSourceMarkup { 58 | notes?: MarkupNote[] 59 | highlights?: MarkupHighlight[] 60 | stickers?: MarkupSticker[] 61 | } 62 | -------------------------------------------------------------------------------- /src/kc_shared/models/project.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {KnowledgeSource} from "kc_angular/src/app/models/knowledge.source.model"; 17 | import {UUID} from "./uuid.model"; 18 | import {EventModel} from "./event.model"; 19 | 20 | export type KcProjectType = 'default' | 'school' | 'work' | 'hobby' | 'research'; 21 | 22 | export interface KcProjectModel { 23 | readonly id: UUID; 24 | name: string; 25 | type: KcProjectType; 26 | description: string; 27 | events?: EventModel[]; 28 | authors: string[]; 29 | parentId: UUID; 30 | subprojects: string[]; 31 | topics: string[]; 32 | sources: UUID[]; 33 | 34 | // TODO: this needs to be removed 35 | knowledgeSource: KnowledgeSource[]; 36 | } 37 | -------------------------------------------------------------------------------- /src/kc_shared/models/style.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | export class KcTheme { 18 | name: string = 'Lara Light Indigo'; 19 | code: string = 'lara-light-indigo'; 20 | isDark: boolean = false; 21 | isDual: boolean = true; 22 | items?: KcTheme[] 23 | } 24 | -------------------------------------------------------------------------------- /src/kc_shared/models/topic.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {UuidModel} from "./uuid.model"; 17 | 18 | export interface TopicModel { 19 | id: UuidModel 20 | label: string 21 | } 22 | -------------------------------------------------------------------------------- /src/kc_shared/models/uuid.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | export type UuidModel = { 18 | value: string 19 | } 20 | 21 | export interface UUID extends UuidModel {} 22 | -------------------------------------------------------------------------------- /src/kc_shared/models/web.source.model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2022 Rob Royce 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | import {WebSourceMarkup} from "./markup.model"; 17 | 18 | export interface WebSourceModel { 19 | accessLink: string, 20 | iconUrl?: string, 21 | topics?: string[], 22 | metadata?: WebsiteMetadataModel, 23 | markup?: WebSourceMarkup, 24 | flagged?: boolean, 25 | rawText?: string, 26 | thumbnail?: string, 27 | title?: string, 28 | description?: string 29 | } 30 | 31 | export interface WebsiteMetadataModel { 32 | title?: string, 33 | meta?: WebsiteMetaTagsModel[], 34 | icon?: any, 35 | article?: ArticleModel, 36 | code?: CodeModel[], 37 | links?: string[] 38 | } 39 | 40 | export interface WebsiteMetaTagsModel { 41 | key?: string | null, 42 | value?: string | null, 43 | property?: string | null 44 | } 45 | 46 | export interface WebsiteContentModel { 47 | title?: string, 48 | type?: string, 49 | text?: string, 50 | html?: string 51 | } 52 | 53 | export interface ArticleModel extends WebsiteContentModel { 54 | 55 | } 56 | 57 | export interface CodeModel extends WebsiteContentModel { 58 | 59 | } 60 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2020", 4 | "module": "commonjs", 5 | "strict": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "strictTemplates": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "angularCompilerOptions": { 14 | "strictTemplates": true 15 | }, 16 | "$schema": "https://json.schemastore.org/tsconfig", 17 | "display": "Recommended" 18 | } 19 | --------------------------------------------------------------------------------