├── .gitignore ├── .husky └── pre-commit ├── .vscode ├── extensions.json └── settings.json ├── CONTRIBUTING.md ├── COPYING ├── LICENSE ├── NOTICE ├── README.md ├── editorconfig ├── package.json ├── pnpm-lock.yaml ├── pnpm.yaml └── ui ├── lightning ├── index.html ├── package.json ├── pnpm-lock.yaml ├── public │ ├── assets │ │ ├── hero-mask-inverted.png │ │ ├── icons.png │ │ ├── icons_white.png │ │ ├── rt-popcorn.png │ │ ├── sidenav.png │ │ ├── solidWord.png │ │ ├── solidjs.png │ │ ├── spinner.gif │ │ ├── stars-full.png │ │ ├── stars.png │ │ └── tmdb.png │ └── fonts │ │ ├── NotoSans-Bold.ttf │ │ ├── NotoSans-Regular.ttf │ │ ├── Ubuntu-Bold.msdf.json │ │ ├── Ubuntu-Bold.msdf.png │ │ ├── Ubuntu-Regular.msdf.json │ │ └── Ubuntu-Regular.msdf.png ├── src │ ├── AppCoreExtensions.ts │ ├── api │ │ ├── formatters │ │ │ └── ItemFormatter.ts │ │ ├── index.ts │ │ └── providers │ │ │ ├── browse.ts │ │ │ ├── entity.js │ │ │ └── people.js │ ├── components │ │ ├── Background.tsx │ │ ├── ContentBlock.tsx │ │ ├── Icon.tsx │ │ ├── NavDrawer │ │ │ ├── NavDrawer.styles.ts │ │ │ └── NavDrawer.tsx │ │ ├── index.tsx │ │ └── pagination.ts │ ├── global.d.ts │ ├── index.tsx │ ├── material-theme.json │ ├── pages │ │ ├── App.tsx │ │ ├── Browse.tsx │ │ ├── Buttons.tsx │ │ ├── ButtonsMaterial.tsx │ │ ├── Create.tsx │ │ ├── Entity.tsx │ │ ├── Flex.tsx │ │ ├── FlexColumn.tsx │ │ ├── FlexColumnSize.tsx │ │ ├── FlexSize.tsx │ │ ├── Grid.tsx │ │ ├── NotFound.tsx │ │ ├── People.tsx │ │ ├── Portal.tsx │ │ ├── SuperFlex.tsx │ │ ├── Text.tsx │ │ ├── Viewport.tsx │ │ └── gridStyles.ts │ ├── state.ts │ ├── styles.ts │ ├── threadx-core-worker.ts │ └── video.js ├── styles.css ├── tsconfig.json └── vite.config.js └── web ├── .gitignore ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src ├── App.module.css ├── App.tsx ├── assets │ └── favicon.ico ├── index.css ├── index.tsx └── logo.svg ├── tsconfig.json └── vite.config.ts /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | dist/ 4 | ui/lightning/src/api/key.ts 5 | # This project uses `pnpm` for package management 6 | package-lock.json 7 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | pnpm exec lint-staged 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "editorconfig.editorconfig", 4 | "dbaeumer.vscode-eslint", 5 | "esbenp.prettier-vscode" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "editor.defaultFormatter": "esbenp.prettier-vscode", 4 | "editor.codeActionsOnSave": [ 5 | "source.formatDocument", 6 | "source.fixAll.eslint" 7 | ], 8 | "[typescript]": { 9 | "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" 10 | }, 11 | } 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | Thank you for considering helping out! 4 | 5 | First, please read the [code of conduct](https://github.com/Comcast/Comcast.github.io/blob/main/CODE_OF_CONDUCT.md). We take it very seriously! 6 | 7 | Next, if you want to help out, do the following: 8 | 9 | 1. Fork the project. 10 | 2. Make a feature branch with the name of your change. 11 | 3. Make a change. 12 | 4. Commit your code. 13 | 5. Issue a Pull Request. 14 | 15 | Once your PR is issued, we will review your work and decide on adding it to the project! 16 | 17 | For more details about contributing to GitHub projects see [How to use Github: Fork, Branch, Track, Squash and Pull Request](http://gun.io/blog/how-to-github-fork-branch-and-pull-request/) 18 | 19 | ## Contributor License Agreement 20 | 21 | Before Comcast merges your code into the project you must sign the [Comcast Contributor License Agreement (CLA)](https://gist.github.com/ComcastOSS/a7b8933dd8e368535378cda25c92d19a). 22 | 23 | If you haven't previously signed a Comcast CLA, you'll automatically be asked to when you open a pull request. Alternatively, we can send you a PDF that you can sign and scan back to us. Please create a new GitHub issue to request a PDF version of the CLA. 24 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | LICENSE -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | This component contains software that is Copyright (c) 2023 Comcast. 2 | The component is licensed to you under the Apache License, Version 2.0 (the "License"). 3 | You may not use the component except in compliance with the License. 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lightning Demo App with SolidJS 2 | 3 | ## Getting started 4 | 5 | Get an api key from [TMDB API](https://developers.themoviedb.org/3/getting-started/introduction) 6 | and put the key in `ui/lightning/api/key.js` with `export default 'KEY_VALUE'` 7 | 8 | ``` 9 | git clone https://github.com/lightning-js/solid-demo-app 10 | cd solid-demo-app 11 | pnpm i 12 | ``` 13 | 14 | To run the lightning app: 15 | 16 | ``` 17 | pnpm start:lightning 18 | ``` 19 | 20 | To run the web app: 21 | 22 | ``` 23 | pnpm start:web 24 | ``` 25 | -------------------------------------------------------------------------------- /editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | insert_final_newline = true 6 | end_of_line = lf 7 | indent_style = space 8 | indent_size = 2 9 | max_line_length = 80 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solid-demo-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "type": "module", 6 | "main": "index.js", 7 | "scripts": { 8 | "start": "pnpm start:lightning", 9 | "-------------------------[lightning]-----------------------": "", 10 | "start:lightning": "pnpm -F lightning start", 11 | "start:lightning-prod": "pnpm -F lightning start:prod", 12 | "build:lightning": "pnpm -F lightning build", 13 | "build:lightning-github": "pnpm -F lightning build:github", 14 | "build:lightning-analyze": "pnpm -F lightning build:analyze", 15 | "deploy:lightning": "pnpm -F lightning deploy", 16 | "preview:lightning": "pnpm -F lightning preview", 17 | "tsc:lightning": "pnpm -F lightning tsc", 18 | "-------------------------[web]------------------------------": "", 19 | "start:web": "pnpm -F web start", 20 | "start:web-prod": "pnpm -F web start:prod", 21 | "build:web": "pnpm -F web build", 22 | "build:github-web": "pnpm -F web build:github", 23 | "build:web-analyze": "pnpm -F web build:analyze", 24 | "deploy:web": "pnpm -F web deploy", 25 | "preview:web": "vite preview --open --port 8080", 26 | "tsc:web": "pnpm -F web tsc", 27 | "-------------------------[test]----------------------------": "", 28 | "lint:prettier": "prettier --check \"**/*.{ts,js,cjs,md,tsx}\"", 29 | "lint:fix:prettier": "prettier --write \"**/*.{ts,js,cjs,md,tsx}\"", 30 | "test": "echo \"Error: no test specified\" && exit 1" 31 | }, 32 | "author": "", 33 | "license": "ISC", 34 | "dependencies": { 35 | "@solid-primitives/scheduled": "^1.4.3", 36 | "@solidjs/router": "^0.13.2", 37 | "proxy-polyfill": "^0.3.2", 38 | "solid-js": "^1.8.17", 39 | "vite-plugin-babel": "^1.2.0" 40 | }, 41 | "devDependencies": { 42 | "@lightningjs/vite-plugin-import-chunk-url": "^0.3.1", 43 | "@vitejs/plugin-legacy": "^5.3.2", 44 | "gh-pages": "^6.1.1", 45 | "husky": "^9.0.11", 46 | "lint-staged": "^15.2.2", 47 | "prettier": "^3.2.5", 48 | "terser": "^5.30.4", 49 | "typescript": "^5.4.5", 50 | "vite": "^5.2.10", 51 | "vite-bundle-visualizer": "^1.1.0", 52 | "vite-plugin-cross-origin-isolation": "^0.1.6", 53 | "vite-plugin-solid": "^2.10.2" 54 | }, 55 | "lint-staged": { 56 | "*.{ts,tsx}": [ 57 | "prettier --write" 58 | ], 59 | "*.{js,cjs,md}": "prettier --write" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /pnpm.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'ui/*' 3 | -------------------------------------------------------------------------------- /ui/lightning/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Solid Demo 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 21 | 22 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /ui/lightning/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lightning", 3 | "version": "1.0.0", 4 | "description": "", 5 | "type": "module", 6 | "main": "index.js", 7 | "scripts": { 8 | "start": "vite --open --host --force", 9 | "start:prod": "vite --open --host --force --mode production", 10 | "build": "vite build --sourcemap=true", 11 | "build:github": "vite build --sourcemap=true --base=/solid-demo-app/", 12 | "build:github:dev": "NODE_ENV=development vite build --sourcemap=true --mode development --base=/solid-demo-app/", 13 | "build:analyze": "vite-bundle-visualizer", 14 | "deploy": "gh-pages -d dist", 15 | "preview": "vite preview --open --port 8080", 16 | "tsc": "tsc", 17 | "test": "echo \"Error: no test specified\" && exit 1" 18 | }, 19 | "author": "", 20 | "license": "ISC", 21 | "dependencies": { 22 | "@lightningjs/l3-ui-theme-base": "^0.3.2", 23 | "@lightningjs/renderer": "^0.8.4", 24 | "@lightningjs/solid": "^0.16.0", 25 | "@lightningjs/solid-primitives": "^0.6.6", 26 | "@lightningjs/solid-ui": "^0.13.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ui/lightning/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | '@lightningjs/l3-ui-theme-base': 9 | specifier: ^0.3.2 10 | version: 0.3.3 11 | '@lightningjs/renderer': 12 | specifier: ^0.8.4 13 | version: 0.8.4 14 | '@lightningjs/solid': 15 | specifier: ^0.16.0 16 | version: 0.16.0(@lightningjs/renderer@0.8.4)(solid-js@1.8.17) 17 | '@lightningjs/solid-primitives': 18 | specifier: ^0.6.6 19 | version: 0.6.6(@lightningjs/solid@0.16.0)(solid-js@1.8.17) 20 | '@lightningjs/solid-ui': 21 | specifier: ^0.13.1 22 | version: 0.13.1(@lightningjs/solid-primitives@0.6.6)(@lightningjs/solid@0.16.0)(solid-js@1.8.17) 23 | 24 | packages: 25 | 26 | /@lightningjs/l3-ui-theme-base@0.3.3: 27 | resolution: {integrity: sha512-lbEO8OChUokt6CcudGZt7SL2laEDDbfPmeN6ttgGaid8/n3CN1eFgPXngZSG2mNNOrruUadGh3j81thphgFUdg==} 28 | dev: false 29 | 30 | /@lightningjs/renderer@0.8.4: 31 | resolution: {integrity: sha512-ybFTlM7HzKM6lbbtpV01X25pKVBeXXyRwmKMT6E1RHN1hJBkjmkz+BboFReL3Wq/FrsAg5zPO15baPEIH6brqA==} 32 | engines: {node: '>= 20.9.0', npm: '>= 10.0.0', pnpm: '>= 8.9.2'} 33 | requiresBuild: true 34 | dependencies: 35 | '@lightningjs/threadx': 0.3.5 36 | '@protobufjs/eventemitter': 1.1.0 37 | memize: 2.1.0 38 | dev: false 39 | 40 | /@lightningjs/solid-primitives@0.6.6(@lightningjs/solid@0.16.0)(solid-js@1.8.17): 41 | resolution: {integrity: sha512-bowP29fXs7z4YJngxGqtM1z6ZMD0NcCI/BAbaU36TJDNVw6esfQ8DYiz7ThKmznG1CS9nYX1LX4XlJFOZMfOBQ==} 42 | peerDependencies: 43 | '@lightningjs/solid': '*' 44 | solid-js: '*' 45 | dependencies: 46 | '@lightningjs/solid': 0.16.0(@lightningjs/renderer@0.8.4)(solid-js@1.8.17) 47 | '@solid-primitives/keyboard': 1.2.8(solid-js@1.8.17) 48 | '@solid-primitives/scheduled': 1.4.3(solid-js@1.8.17) 49 | solid-js: 1.8.17 50 | dev: false 51 | 52 | /@lightningjs/solid-ui@0.13.1(@lightningjs/solid-primitives@0.6.6)(@lightningjs/solid@0.16.0)(solid-js@1.8.17): 53 | resolution: {integrity: sha512-+xpuIutmuD7fqwVJjELwOOEnRDdoZ5DpvfWkSVE2IRfiWNWn0vBUO/TLPu8hx2+iGnhjzj4vefwMEPxGjskI5w==} 54 | peerDependencies: 55 | '@lightningjs/solid': '*' 56 | '@lightningjs/solid-primitives': '*' 57 | solid-js: '*' 58 | dependencies: 59 | '@lightningjs/solid': 0.16.0(@lightningjs/renderer@0.8.4)(solid-js@1.8.17) 60 | '@lightningjs/solid-primitives': 0.6.6(@lightningjs/solid@0.16.0)(solid-js@1.8.17) 61 | '@solid-primitives/refs': 1.0.8(solid-js@1.8.17) 62 | solid-js: 1.8.17 63 | dev: false 64 | 65 | /@lightningjs/solid@0.16.0(@lightningjs/renderer@0.8.4)(solid-js@1.8.17): 66 | resolution: {integrity: sha512-QbOmkiPq7ctL8VtM7dJ9LxQrHlp0WnrWi2M54lurbDqL8bZLXUWg2idWn6S/kuZjrYrK+AuAW16UcZ6dhOVbVA==} 67 | peerDependencies: 68 | '@lightningjs/renderer': ^0.8.4 69 | solid-js: '*' 70 | dependencies: 71 | '@lightningjs/renderer': 0.8.4 72 | solid-js: 1.8.17 73 | dev: false 74 | 75 | /@lightningjs/threadx@0.3.5: 76 | resolution: {integrity: sha512-aUIUfP/d3S0Vg/Ror7CLbqQR6qu5AAdGRnQ5RQuSQz4t9X2p8TomKD7ShRxI1/FnRR7om2MwKIe1Dix/Axdgpg==} 77 | dev: false 78 | 79 | /@protobufjs/eventemitter@1.1.0: 80 | resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} 81 | dev: false 82 | 83 | /@solid-primitives/event-listener@2.3.3(solid-js@1.8.17): 84 | resolution: {integrity: sha512-DAJbl+F0wrFW2xmcV8dKMBhk9QLVLuBSW+TR4JmIfTaObxd13PuL7nqaXnaYKDWOYa6otB00qcCUIGbuIhSUgQ==} 85 | peerDependencies: 86 | solid-js: ^1.6.12 87 | dependencies: 88 | '@solid-primitives/utils': 6.2.3(solid-js@1.8.17) 89 | solid-js: 1.8.17 90 | dev: false 91 | 92 | /@solid-primitives/keyboard@1.2.8(solid-js@1.8.17): 93 | resolution: {integrity: sha512-pJtcbkjozS6L1xvTht9rPpyPpX55nAkfBzbFWdf3y0Suwh6qClTibvvObzKOf7uzQ+8aZRDH4LsoGmbTKXtJjQ==} 94 | peerDependencies: 95 | solid-js: ^1.6.12 96 | dependencies: 97 | '@solid-primitives/event-listener': 2.3.3(solid-js@1.8.17) 98 | '@solid-primitives/rootless': 1.4.5(solid-js@1.8.17) 99 | '@solid-primitives/utils': 6.2.3(solid-js@1.8.17) 100 | solid-js: 1.8.17 101 | dev: false 102 | 103 | /@solid-primitives/refs@1.0.8(solid-js@1.8.17): 104 | resolution: {integrity: sha512-+jIsWG8/nYvhaCoG2Vg6CJOLgTmPKFbaCrNQKWfChalgUf9WrVxWw0CdJb3yX15n5lUcQ0jBo6qYtuVVmBLpBw==} 105 | peerDependencies: 106 | solid-js: ^1.6.12 107 | dependencies: 108 | '@solid-primitives/utils': 6.2.3(solid-js@1.8.17) 109 | solid-js: 1.8.17 110 | dev: false 111 | 112 | /@solid-primitives/rootless@1.4.5(solid-js@1.8.17): 113 | resolution: {integrity: sha512-GFJE9GC3ojx0aUKqAUZmQPyU8fOVMtnVNrkdk2yS4kd17WqVSpXpoTmo9CnOwA+PG7FTzdIkogvfLQSLs4lrww==} 114 | peerDependencies: 115 | solid-js: ^1.6.12 116 | dependencies: 117 | '@solid-primitives/utils': 6.2.3(solid-js@1.8.17) 118 | solid-js: 1.8.17 119 | dev: false 120 | 121 | /@solid-primitives/scheduled@1.4.3(solid-js@1.8.17): 122 | resolution: {integrity: sha512-HfWN5w7b7FEc6VPLBKnnE302h90jsLMuR28Fcf7neRGGf8jBj6wm6/UFQ00VlKexHFMR6KQ2u4VBh5a1ZcqM8g==} 123 | peerDependencies: 124 | solid-js: ^1.6.12 125 | dependencies: 126 | solid-js: 1.8.17 127 | dev: false 128 | 129 | /@solid-primitives/utils@6.2.3(solid-js@1.8.17): 130 | resolution: {integrity: sha512-CqAwKb2T5Vi72+rhebSsqNZ9o67buYRdEJrIFzRXz3U59QqezuuxPsyzTSVCacwS5Pf109VRsgCJQoxKRoECZQ==} 131 | peerDependencies: 132 | solid-js: ^1.6.12 133 | dependencies: 134 | solid-js: 1.8.17 135 | dev: false 136 | 137 | /csstype@3.1.3: 138 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} 139 | dev: false 140 | 141 | /memize@2.1.0: 142 | resolution: {integrity: sha512-yywVJy8ctVlN5lNPxsep5urnZ6TTclwPEyigM9M3Bi8vseJBOfqNrGWN/r8NzuIt3PovM323W04blJfGQfQSVg==} 143 | dev: false 144 | 145 | /seroval-plugins@1.0.5(seroval@1.0.5): 146 | resolution: {integrity: sha512-8+pDC1vOedPXjKG7oz8o+iiHrtF2WswaMQJ7CKFpccvSYfrzmvKY9zOJWCg+881722wIHfwkdnRmiiDm9ym+zQ==} 147 | engines: {node: '>=10'} 148 | peerDependencies: 149 | seroval: ^1.0 150 | dependencies: 151 | seroval: 1.0.5 152 | dev: false 153 | 154 | /seroval@1.0.5: 155 | resolution: {integrity: sha512-TM+Z11tHHvQVQKeNlOUonOWnsNM+2IBwZ4vwoi4j3zKzIpc5IDw8WPwCfcc8F17wy6cBcJGbZbFOR0UCuTZHQA==} 156 | engines: {node: '>=10'} 157 | dev: false 158 | 159 | /solid-js@1.8.17: 160 | resolution: {integrity: sha512-E0FkUgv9sG/gEBWkHr/2XkBluHb1fkrHywUgA6o6XolPDCJ4g1HaLmQufcBBhiF36ee40q+HpG/vCZu7fLpI3Q==} 161 | dependencies: 162 | csstype: 3.1.3 163 | seroval: 1.0.5 164 | seroval-plugins: 1.0.5(seroval@1.0.5) 165 | dev: false 166 | -------------------------------------------------------------------------------- /ui/lightning/public/assets/hero-mask-inverted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/hero-mask-inverted.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/icons.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/icons_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/icons_white.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/rt-popcorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/rt-popcorn.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/sidenav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/sidenav.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/solidWord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/solidWord.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/solidjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/solidjs.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/spinner.gif -------------------------------------------------------------------------------- /ui/lightning/public/assets/stars-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/stars-full.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/stars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/stars.png -------------------------------------------------------------------------------- /ui/lightning/public/assets/tmdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/assets/tmdb.png -------------------------------------------------------------------------------- /ui/lightning/public/fonts/NotoSans-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/fonts/NotoSans-Bold.ttf -------------------------------------------------------------------------------- /ui/lightning/public/fonts/NotoSans-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/fonts/NotoSans-Regular.ttf -------------------------------------------------------------------------------- /ui/lightning/public/fonts/Ubuntu-Bold.msdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/fonts/Ubuntu-Bold.msdf.png -------------------------------------------------------------------------------- /ui/lightning/public/fonts/Ubuntu-Regular.msdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/lightning/public/fonts/Ubuntu-Regular.msdf.png -------------------------------------------------------------------------------- /ui/lightning/src/AppCoreExtensions.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * If not stated otherwise in this file or this component's LICENSE file the 3 | * following copyright and licenses apply: 4 | * 5 | * Copyright 2023 Comcast 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the License); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | import { 21 | CoreExtension, 22 | WebTrFontFace, 23 | SdfTrFontFace, 24 | type Stage, 25 | } from "@lightningjs/renderer/core"; 26 | 27 | const basePath = import.meta.env.BASE_URL; 28 | 29 | export default class AppCoreExtension extends CoreExtension { 30 | async run(stage: Stage) { 31 | // stage.fontManager.addFontFace( 32 | // new WebTrFontFace( 33 | // "NotoSans", 34 | // {}, 35 | // basePath + "fonts/NotoSans-Regular.ttf", 36 | // ), 37 | // ); 38 | stage.fontManager.addFontFace( 39 | new SdfTrFontFace( 40 | "Ubuntu", 41 | { weight: 700 }, 42 | "msdf", 43 | stage, 44 | basePath + "fonts/Ubuntu-Bold.msdf.png", 45 | basePath + "fonts/Ubuntu-Bold.msdf.json", 46 | ), 47 | ); 48 | stage.fontManager.addFontFace( 49 | new SdfTrFontFace( 50 | "Ubuntu", 51 | { weight: 400 }, 52 | "msdf", 53 | stage, 54 | basePath + "fonts/Ubuntu-Regular.msdf.png", 55 | basePath + "fonts/Ubuntu-Regular.msdf.json", 56 | ), 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ui/lightning/src/api/formatters/ItemFormatter.ts: -------------------------------------------------------------------------------- 1 | import { getImageUrl } from "../index"; 2 | 3 | function truncateString(str: string, maxLength: number): string { 4 | if (str.length > maxLength) { 5 | return str.substring(0, maxLength - 3) + "..."; 6 | } 7 | return str; 8 | } 9 | 10 | export function chunkArray(array: string[], size = 7) { 11 | let result: string[][] = []; 12 | for (let i = 0, j = array.length; i < j; i += size) { 13 | result.push(array.slice(i, i + size)); 14 | } 15 | return result; 16 | } 17 | 18 | export interface Tile { 19 | src: string; 20 | tileSrc: string; 21 | backdrop: string; 22 | href: string; 23 | shortTitle: string; 24 | title: string; 25 | data: unknown; 26 | entityInfo: { 27 | type: string; 28 | id: string; 29 | }; 30 | heroContent: { 31 | title: string; 32 | description: string; 33 | }; 34 | } 35 | 36 | // TODO: Remove `any` type 37 | export function convertItemsToTiles(items: any[] = []): Tile[] { 38 | return items.map((item) => ({ 39 | src: getImageUrl(item.poster_path || item.profile_path), 40 | tileSrc: getImageUrl(item.backdrop_path || item.profile_path, "w300"), 41 | backdrop: getImageUrl(item.backdrop_path, "w1280"), 42 | href: `/entity/${item.media_type || "people"}/${item.id}`, 43 | shortTitle: truncateString(item.title || item.name, 30), 44 | title: item.title || item.name, 45 | data: item, 46 | entityInfo: { 47 | type: item.media_type || "people", 48 | id: item.id, 49 | }, 50 | heroContent: { 51 | title: item.title || item.name, 52 | description: item.overview, 53 | }, 54 | })); 55 | } 56 | -------------------------------------------------------------------------------- /ui/lightning/src/api/index.ts: -------------------------------------------------------------------------------- 1 | import API_KEY_V4 from "./key"; 2 | const API_BASE = "https://api.themoviedb.org/3"; 3 | let tmdbConfig; 4 | let baseImageUrl; 5 | const basePosterSize = "w185"; 6 | 7 | const defaultFetchParams = { 8 | headers: { 9 | "Content-Type": "application/json", 10 | Authorization: "Bearer " + API_KEY_V4, 11 | }, 12 | }; 13 | 14 | export function getImageUrl(path: string, posterSize: string = basePosterSize) { 15 | return baseImageUrl + posterSize + path; 16 | } 17 | 18 | function get(path: string, params: RequestInit = {}) { 19 | if (tmdbConfig) { 20 | return _get(path, params); 21 | } else { 22 | return loadConfig().then(() => _get(path, params)); 23 | } 24 | } 25 | 26 | function _get(path: string, params: RequestInit = {}) { 27 | return fetch(API_BASE + path, { 28 | ...defaultFetchParams, 29 | ...params, 30 | }).then((r) => r.json()); 31 | } 32 | 33 | function loadConfig() { 34 | return _get("/configuration").then((data) => { 35 | tmdbConfig = data; 36 | baseImageUrl = data.images?.secure_base_url; 37 | return data; 38 | }); 39 | } 40 | 41 | export default { 42 | get, 43 | loadConfig, 44 | }; 45 | -------------------------------------------------------------------------------- /ui/lightning/src/api/providers/browse.ts: -------------------------------------------------------------------------------- 1 | import api from ".."; 2 | import { convertItemsToTiles, chunkArray } from "../formatters/ItemFormatter"; 3 | 4 | let cache = new Map(); 5 | const leftoverTiles = new Map(); 6 | 7 | export default function (filter: string) { 8 | return (pageIndex: number): Promise => { 9 | const url = `/trending/${filter}/week?page=${pageIndex}`; 10 | if (cache.has(url)) { 11 | return cache.get(url); 12 | } 13 | 14 | let result = api.get(url).then((trending) => { 15 | let results = trending.results.filter((r) => !r.adult); 16 | let tiles = ( 17 | leftoverTiles.has(filter) ? leftoverTiles.get(filter) : [] 18 | ).concat(convertItemsToTiles(results)); 19 | let chunks = chunkArray(tiles); 20 | if (chunks[chunks.length - 1].length < 7) { 21 | leftoverTiles.set(filter, chunks.pop()); 22 | } else { 23 | leftoverTiles.delete(filter); 24 | } 25 | return chunks; 26 | }); 27 | 28 | cache.set(url, result); 29 | return result; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /ui/lightning/src/api/providers/entity.js: -------------------------------------------------------------------------------- 1 | import api, { getImageUrl } from ".."; 2 | import { convertItemsToTiles } from "../formatters/ItemFormatter"; 3 | 4 | export function minutesToHMM(minutes) { 5 | const hours = Math.floor(minutes / 60); 6 | const remainingMinutes = minutes % 60; 7 | return ( 8 | hours + "h " + (remainingMinutes < 10 ? "0" : "") + remainingMinutes + "min" 9 | ); 10 | } 11 | 12 | function formatDate(dateString) { 13 | const parts = dateString.split("-"); 14 | return parts[1] + "/" + parts[2] + "/" + parts[0]; 15 | } 16 | 17 | function justYear(dateString) { 18 | const parts = dateString.split("-"); 19 | return parts[0]; 20 | } 21 | 22 | export function getRecommendations({ type, id }) { 23 | return api.get(`/${type}/${id}/recommendations`).then(({ results }) => { 24 | if (results.length) { 25 | return convertItemsToTiles(results.slice(0, 7)); 26 | } 27 | return api 28 | .get(`/trending/${type}/week?page=1`) 29 | .then(({ results }) => convertItemsToTiles(results.slice(0, 7))); 30 | }); 31 | } 32 | 33 | export function getCredits({ type, id }) { 34 | return api 35 | .get(`/${type}/${id}/credits`) 36 | .then(({ cast }) => convertItemsToTiles(cast.slice(0, 7))); 37 | } 38 | 39 | export function getInfo({ type, id }) { 40 | let rt = 41 | type === "movie" 42 | ? { 43 | rtCrit: 86, 44 | rtFan: 92, 45 | } 46 | : {}; 47 | 48 | return api.get(`/${type}/${id}`).then((data) => ({ 49 | backgroundImage: getImageUrl(data.backdrop_path, "w1280"), 50 | heroContent: { 51 | title: data.title || data.name, 52 | description: data.overview, 53 | badges: ["HD", "CC"], 54 | voteAverage: data.vote_average, 55 | voteCount: data.vote_count, 56 | metaText: 57 | type === "movie" 58 | ? minutesToHMM(data.runtime) + " " + formatDate(data.release_date) 59 | : `${justYear(data.first_air_date)} - ${justYear(data.last_air_date)}`, 60 | reviews: rt, 61 | }, 62 | ...data, 63 | })); 64 | } 65 | -------------------------------------------------------------------------------- /ui/lightning/src/api/providers/people.js: -------------------------------------------------------------------------------- 1 | import api, { getImageUrl } from ".."; 2 | import { convertItemsToTiles } from "../formatters/ItemFormatter"; 3 | 4 | export function minutesToHMM(minutes) { 5 | const hours = Math.floor(minutes / 60); 6 | const remainingMinutes = minutes % 60; 7 | return ( 8 | hours + "h " + (remainingMinutes < 10 ? "0" : "") + remainingMinutes + "m" 9 | ); 10 | } 11 | 12 | function justYear(dateString) { 13 | const parts = dateString.split("-"); 14 | return parts[0]; 15 | } 16 | 17 | export function getCredits({ id }) { 18 | return api 19 | .get(`/person/${id}/combined_credits`) 20 | .then(({ cast }) => convertItemsToTiles(cast.slice(0, 7))); 21 | } 22 | 23 | export function getInfo({ id }) { 24 | return api.get(`/person/${id}`).then((data) => ({ 25 | backgroundImage: getImageUrl(data.profile_path, "original"), 26 | heroContent: { 27 | title: data.title || data.name, 28 | description: data.biography, 29 | }, 30 | ...data, 31 | })); 32 | } 33 | -------------------------------------------------------------------------------- /ui/lightning/src/components/Background.tsx: -------------------------------------------------------------------------------- 1 | import { type AnimationSettings } from "@lightningjs/renderer"; 2 | import { globalBackground } from "../state.js"; 3 | import { 4 | type IntrinsicNodeStyleProps, 5 | View, 6 | Text, 7 | hexColor, 8 | } from "@lightningjs/solid"; 9 | import { createEffect, on } from "solid-js"; 10 | import theme from "theme"; 11 | 12 | export default function Background() { 13 | let bg1, bg2, heroMask; 14 | let active = 0; 15 | const alpha = 1; 16 | const animationSettings = { 17 | duration: 750, 18 | easing: "ease-in-out", 19 | } satisfies Partial; 20 | const bgStyles = { 21 | alpha, 22 | color: 0xffffffff, 23 | } satisfies IntrinsicNodeStyleProps; 24 | 25 | function changeBackgrounds(img: string) { 26 | if (img.startsWith("#")) { 27 | bg1.color = hexColor(img); 28 | bg1.src = ""; 29 | bg1.alpha = 1; 30 | active = 1; 31 | bg2.alpha = 0; 32 | heroMask.alpha = 0; 33 | return; 34 | } else { 35 | bg1.color = 0xffffffff; 36 | heroMask.alpha = 1; 37 | } 38 | 39 | if (active === 0) { 40 | bg1.src = img; 41 | active = 1; 42 | return; 43 | } 44 | 45 | if (active === 1) { 46 | bg2.src = img; 47 | active = 2; 48 | bg2.alpha = 0; 49 | bg2.animate({ alpha }, animationSettings).start(); 50 | bg1.animate({ alpha: 0 }, animationSettings).start(); 51 | return; 52 | } 53 | 54 | if (active === 2) { 55 | bg1.src = img; 56 | active = 1; 57 | bg1.alpha = 0; 58 | bg1.animate({ alpha }, animationSettings).start(); 59 | bg2.animate({ alpha: 0 }, animationSettings).start(); 60 | } 61 | } 62 | 63 | createEffect( 64 | on( 65 | globalBackground, 66 | (img: string) => { 67 | changeBackgrounds(img); 68 | }, 69 | { defer: true }, 70 | ), 71 | ); 72 | 73 | return ( 74 | <> 75 | 76 | 77 | 78 | 85 | 86 | 87 | ); 88 | } 89 | -------------------------------------------------------------------------------- /ui/lightning/src/components/ContentBlock.tsx: -------------------------------------------------------------------------------- 1 | import { View, Text } from "@lightningjs/solid"; 2 | import { For, Show } from "solid-js"; 3 | import { withPadding } from "@lightningjs/solid-primitives"; 4 | import theme from "theme"; 5 | withPadding; 6 | 7 | const blockWidth = 900; 8 | 9 | const ContentBlockStyle = { 10 | display: "flex", 11 | flexDirection: "column", 12 | flexBoundary: "fixed", 13 | width: blockWidth, 14 | height: 220, 15 | gap: 16, 16 | }; 17 | 18 | const HeadlineStyles = { 19 | ...theme.typography.display2, 20 | fontFamily: "Ubuntu", 21 | fontWeight: 700, 22 | maxLines: 1, 23 | width: blockWidth, 24 | contain: "width", 25 | }; 26 | const Headline = (props) => ; 27 | 28 | const DescriptionStyles = { 29 | ...theme.typography.body1, 30 | fontFamily: "Ubuntu", 31 | fontWeight: 400, 32 | lineHeight: 32, 33 | width: blockWidth, 34 | maxLines: 3, 35 | contain: "width", 36 | }; 37 | 38 | const BadgeStyle = { 39 | fontSize: 16, 40 | lineHeight: 20, 41 | }; 42 | 43 | const Description = (props) => ( 44 | 45 | {props.children} 46 | 47 | ); 48 | 49 | const Badge = (props) => { 50 | return ( 51 | 60 | {props.children} 61 | 62 | ); 63 | }; 64 | 65 | const MetaTextStyle = { 66 | ...theme.typography.body2, 67 | fontFamily: "Ubuntu", 68 | fontWeight: 400, 69 | }; 70 | 71 | const Metadata = (props) => ( 72 | 81 | 82 | 89 | 90 | 91 | {props.voteCount} reviews 92 | {props.metaText} 93 | {(item) => {item}} 94 | 95 | ); 96 | 97 | const ContentBlock = (props) => ( 98 | 99 | {props.content.title} 100 | {props.content.description} 101 | 102 | 108 | 109 | 110 | ); 111 | 112 | export default ContentBlock; 113 | -------------------------------------------------------------------------------- /ui/lightning/src/components/Icon.tsx: -------------------------------------------------------------------------------- 1 | import { For, IntrinsicNodeProps, View } from "@lightningjs/solid"; 2 | import { createSpriteMap } from "@lightningjs/solid-primitives"; 3 | // Icons from https://uxwing.com/ 4 | 5 | const basePath = import.meta.env.BASE_URL; 6 | 7 | const icons = [ 8 | { name: "experiment", width: 81, height: 100, x: 0, y: 0 }, 9 | { name: "trending", width: 100, height: 56, x: 81, y: 0 }, 10 | { name: "tv", width: 100, height: 68, x: 181, y: 0 }, 11 | { name: "movie", width: 94, height: 100, x: 282, y: 0 }, 12 | ]; 13 | 14 | interface IconProps extends IntrinsicNodeProps { 15 | name: string; 16 | } 17 | 18 | function Icon(props: IconProps) { 19 | const sprite = createSpriteMap(basePath + "assets/icons_white.png", icons); 20 | 21 | return ( 22 | 30 | ); 31 | } 32 | 33 | export default Icon; 34 | export function PreviewIcons() { 35 | return ( 36 | <> 37 | 43 | 44 | {(icon, i) => } 45 | 46 | 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /ui/lightning/src/components/NavDrawer/NavDrawer.styles.ts: -------------------------------------------------------------------------------- 1 | import { IntrinsicNodeStyleProps, hexColor } from "@lightningjs/solid"; 2 | import theme from "theme"; 3 | 4 | export default { 5 | Column: { 6 | flexDirection: "column", 7 | display: "flex", 8 | width: 140, 9 | height: 600, 10 | y: 360, 11 | gap: 20, 12 | zIndex: 101, 13 | transition: { 14 | x: { 15 | duration: 250, 16 | easing: "ease-in-out", 17 | }, 18 | }, 19 | x: 8, 20 | focus: { 21 | width: 500, 22 | x: theme.layout.marginX, 23 | }, 24 | } satisfies IntrinsicNodeStyleProps, 25 | Gradient: { 26 | zIndex: 99, 27 | color: hexColor("#000000"), 28 | src: "./assets/sidenav.png", 29 | alpha: 0, 30 | width: 1200, 31 | height: 1080, 32 | focus: { 33 | alpha: 1, 34 | }, 35 | transition: { alpha: true }, 36 | } satisfies IntrinsicNodeStyleProps, 37 | NavButton: { 38 | zIndex: 102, 39 | height: 70, 40 | width: 100, 41 | borderRadius: 8, 42 | focus: { 43 | color: hexColor("#424242"), 44 | }, 45 | active: { 46 | width: 328, 47 | height: 70, 48 | }, 49 | } satisfies IntrinsicNodeStyleProps, 50 | }; 51 | -------------------------------------------------------------------------------- /ui/lightning/src/components/NavDrawer/NavDrawer.tsx: -------------------------------------------------------------------------------- 1 | import { useMatch, useNavigate } from "@solidjs/router"; 2 | import { 3 | View, 4 | Text, 5 | IntrinsicNodeProps, 6 | ElementNode, 7 | } from "@lightningjs/solid"; 8 | import { Column } from "@lightningjs/solid-ui"; 9 | import styles from "./NavDrawer.styles"; 10 | import Icon from "../Icon"; 11 | import theme from "theme"; 12 | 13 | interface NavButtonProps extends IntrinsicNodeProps { 14 | icon: string; 15 | children: string; 16 | } 17 | 18 | function NavButton(props: NavButtonProps) { 19 | return ( 20 | 21 | 22 | 23 | 24 | 36 | {props.children} 37 | 38 | 39 | ); 40 | } 41 | 42 | export default function NavDrawer(props) { 43 | let backdrop; 44 | const navigate = useNavigate(); 45 | function onFocus(this: ElementNode) { 46 | backdrop.states.add("focus"); 47 | this.children.forEach((c) => c.states!.add("active")); 48 | this.children.selected!.setFocus(); 49 | } 50 | 51 | function onBlur(this: ElementNode) { 52 | backdrop.states.remove("focus"); 53 | this.selected = 0; 54 | this.children.forEach((c) => c.states!.remove("active")); 55 | } 56 | 57 | function handleNavigate(page: string) { 58 | const isOnPage = useMatch(() => page); 59 | if (isOnPage()) { 60 | return props.focusPage(); 61 | } 62 | 63 | navigate(page); 64 | } 65 | 66 | return ( 67 | <> 68 | 77 | 78 | Built With: 79 | 80 | 81 | 82 | 83 | 91 | This product uses the TMDB API but is not endorsed or certified by 92 | TMDB. 93 | 94 | 95 | 102 | handleNavigate("/browse/all")} 104 | icon="trending" 105 | > 106 | Trending 107 | 108 | handleNavigate("/browse/movie")}> 109 | Movies 110 | 111 | handleNavigate("/browse/tv")}> 112 | TV 113 | 114 | handleNavigate("/examples")} 117 | > 118 | Examples 119 | 120 | 121 | 122 | 123 | ); 124 | } 125 | -------------------------------------------------------------------------------- /ui/lightning/src/components/index.tsx: -------------------------------------------------------------------------------- 1 | import { IntrinsicNodeProps, View, Text } from "@lightningjs/solid"; 2 | import { Row } from "@lightningjs/solid-ui"; 3 | import { For, splitProps } from "solid-js"; 4 | import styles, { buttonStyles } from "../styles"; 5 | import { type Tile } from "../api/formatters/ItemFormatter"; 6 | 7 | export function Thumbnail(props: IntrinsicNodeProps) { 8 | return ; 9 | } 10 | 11 | export function FocusRing(props: IntrinsicNodeProps) { 12 | return ; 13 | } 14 | 15 | export interface TileRowProps extends IntrinsicNodeProps { 16 | items: Tile[]; 17 | } 18 | 19 | export function TileRow(props: TileRowProps) { 20 | const [local, others] = splitProps(props, ["items"]); 21 | 22 | return ( 23 | 24 | {(item) => } 25 | 26 | ); 27 | } 28 | 29 | export function Button(props) { 30 | return ( 31 | 32 | {props.children} 33 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /ui/lightning/src/components/pagination.ts: -------------------------------------------------------------------------------- 1 | import { createSignal, createComputed, batch, createResource } from "solid-js"; 2 | 3 | export function createInfiniteScroll(fetcher: (page: number) => Promise) { 4 | const [pages, setPages] = createSignal([]); 5 | const [page, setPage] = createSignal(1); 6 | const [end, setEnd] = createSignal(false); 7 | 8 | const [contents] = createResource(page, fetcher); 9 | 10 | createComputed(() => { 11 | const content = contents(); 12 | if (!content) return; 13 | batch(() => { 14 | if (content.length === 0) setEnd(true); 15 | setPages((p) => [...p, ...content]); 16 | }); 17 | }); 18 | 19 | return { 20 | pages, 21 | page, 22 | setPage, 23 | setPages, 24 | end, 25 | setEnd, 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /ui/lightning/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Window { 3 | APP: string; 4 | } 5 | } 6 | 7 | export {}; 8 | -------------------------------------------------------------------------------- /ui/lightning/src/index.tsx: -------------------------------------------------------------------------------- 1 | import { render, Config, hexColor } from "@lightningjs/solid"; 2 | import { HashRouter, Route } from "@solidjs/router"; 3 | import { lazy } from "solid-js"; 4 | import App from "./pages/App"; 5 | import Browse from "./pages/Browse"; 6 | import NotFound from "./pages/NotFound"; 7 | import coreExtensionModuleUrl from "./AppCoreExtensions.js?importChunkUrl"; 8 | 9 | const Grid = lazy(() => import("./pages/Grid")); 10 | const Portal = lazy(() => import("./pages/Portal")); 11 | const TextPage = lazy(() => import("./pages/Text")); 12 | const CreatePage = lazy(() => import("./pages/Create")); 13 | const ViewportPage = lazy(() => import("./pages/Viewport")); 14 | const ButtonsPage = lazy(() => import("./pages/Buttons")); 15 | const FlexPage = lazy(() => import("./pages/Flex")); 16 | const FlexSizePage = lazy(() => import("./pages/FlexSize")); 17 | const FlexColumnSizePage = lazy(() => import("./pages/FlexColumnSize")); 18 | const FlexColumnPage = lazy(() => import("./pages/FlexColumn")); 19 | const ButtonsMaterialPage = lazy(() => import("./pages/ButtonsMaterial")); 20 | const SuperFlexPage = lazy(() => import("./pages/SuperFlex")); 21 | const Entity = lazy(() => import("./pages/Entity")); 22 | const People = lazy(() => import("./pages/People")); 23 | 24 | const logFps = true; 25 | Config.debug = false; 26 | Config.animationsEnabled = true; 27 | Config.fontSettings.fontFamily = "Ubuntu"; 28 | Config.fontSettings.color = hexColor("#f6f6f6"); 29 | Config.fontSettings.fontSize = 32; 30 | Config.rendererOptions = { 31 | coreExtensionModule: coreExtensionModuleUrl, 32 | fpsUpdateInterval: logFps ? 200 : 0, 33 | enableInspector: true, 34 | // Set the resolution based on window height 35 | // 720p = 0.666667, 1080p = 1, 1440p = 1.5, 2160p = 2 36 | deviceLogicalPixelRatio: window.innerHeight / 1080, 37 | }; 38 | 39 | render(() => ( 40 | }> 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | )); 60 | -------------------------------------------------------------------------------- /ui/lightning/src/material-theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "flexRow": { 3 | "display": "flex", 4 | "flexDirection": "row", 5 | "justifyContent": "flexStart" 6 | }, 7 | "flexColumn": { 8 | "display": "flex", 9 | "flexDirection": "column", 10 | "justifyContent": "flexStart" 11 | }, 12 | "layout": { 13 | "screenW": 1920, 14 | "screenH": 1080, 15 | "marginX": 120, 16 | "marginY": 120, 17 | "gutterX": 24, 18 | "gutterY": 72, 19 | "focusScale": 1.1 20 | }, 21 | "color": { 22 | "primary": "#00315c", 23 | "focus": "#bdbdbd", 24 | "container": "#004882" 25 | }, 26 | "typography": { 27 | "display1": { 28 | "fontFamily": "Ubuntu", 29 | "fontSize": 72, 30 | "lineHeight": 88, 31 | "fontStyle": "600", 32 | "verticalAlign": "middle", 33 | "textBaseline": "bottom", 34 | "maxLineSuffix": "..." 35 | }, 36 | "display2": { 37 | "fontFamily": "Ubuntu", 38 | "fontSize": 56, 39 | "lineHeight": 72 40 | }, 41 | "headline1": { 42 | "fontFamily": "Ubuntu", 43 | "fontSize": 36, 44 | "fontStyle": "600", 45 | "lineHeight": 48, 46 | "verticalAlign": "middle", 47 | "textBaseline": "bottom", 48 | "maxLineSuffix": "..." 49 | }, 50 | "headline2": { 51 | "fontFamily": "Ubuntu", 52 | "fontSize": 32, 53 | "lineHeight": 44 54 | }, 55 | "headline3": { 56 | "fontFamily": "Ubuntu", 57 | "fontSize": 28, 58 | "lineHeight": 40 59 | }, 60 | "body1": { 61 | "fontFamily": "Ubuntu", 62 | "fontSize": 32, 63 | "lineHeight": 40 64 | }, 65 | "body2": { 66 | "fontFamily": "Ubuntu", 67 | "fontSize": 28, 68 | "lineHeight": 34 69 | }, 70 | "button1": { 71 | "fontFamily": "Ubuntu", 72 | "fontSize": 32, 73 | "lineHeight": 40 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/App.tsx: -------------------------------------------------------------------------------- 1 | import { useLocation, useNavigate } from "@solidjs/router"; 2 | import { View, activeElement, renderer } from "@lightningjs/solid"; 3 | import { useFocusManager, useAnnouncer } from "@lightningjs/solid-primitives"; 4 | import Background from "../components/Background"; 5 | import NavDrawer from "../components/NavDrawer/NavDrawer"; 6 | import { FPSCounter, setupFPS } from "@lightningjs/solid-ui"; 7 | import { createEffect, createSignal } from "solid-js"; 8 | 9 | declare module "@lightningjs/solid-primitives" { 10 | // Augment the FocusManager KeyMap interface with our custom keys 11 | interface KeyMap { 12 | Announcer: (string | number)[]; 13 | Menu: (string | number)[]; 14 | Escape: (string | number)[]; 15 | Backspace: (string | number)[]; 16 | } 17 | } 18 | 19 | declare module "@lightningjs/solid" { 20 | interface ElementNode { 21 | heroContent?: boolean; 22 | backdrop?: any; 23 | entityInfo?: any; 24 | href?: string; 25 | } 26 | } 27 | 28 | const App = (props) => { 29 | useFocusManager({ 30 | Announcer: ["a"], 31 | Menu: ["m"], 32 | Escape: ["Escape", 27], 33 | Backspace: ["Backspace", 8], 34 | Left: ["ArrowLeft", 37], 35 | Right: ["ArrowRight", 39], 36 | Up: ["ArrowUp", 38], 37 | Down: ["ArrowDown", 40], 38 | Enter: ["Enter", 13], 39 | }); 40 | const announcer = useAnnouncer(); 41 | announcer.enabled = false; 42 | const navigate = useNavigate(); 43 | 44 | let navDrawer, lastFocused; 45 | 46 | setupFPS({ renderer }); 47 | 48 | function focusNavDrawer() { 49 | if (navDrawer.states.has("focus")) { 50 | return false; 51 | } 52 | lastFocused = activeElement(); 53 | return navDrawer.setFocus(); 54 | } 55 | 56 | const [showWidgets, setShowWidgets] = createSignal(true); 57 | const location = useLocation(); 58 | const showOnPaths = ["/browse", "/entity"]; 59 | createEffect(() => { 60 | const currentPath = location.pathname; 61 | let matchesPartial = showOnPaths.some((path) => 62 | currentPath.startsWith(path) 63 | ); 64 | if (currentPath === "/") { 65 | matchesPartial = true; 66 | } 67 | setShowWidgets(matchesPartial); 68 | }); 69 | 70 | return ( 71 | (announcer.enabled = !announcer.enabled)} 74 | onLast={() => history.back()} 75 | onMenu={() => navigate("/")} 76 | style={{ width: 1920, height: 1080 }} 77 | onBackspace={focusNavDrawer} 78 | onLeft={focusNavDrawer} 79 | onRight={() => navDrawer.states.has("focus") && lastFocused.setFocus()} 80 | > 81 | 82 | 83 | 84 | {props.children} 85 | lastFocused.setFocus()} 88 | showWidgets={showWidgets()} 89 | /> 90 | 91 | ); 92 | }; 93 | 94 | export default App; 95 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Browse.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | createEffect, 3 | createMemo, 4 | on, 5 | createSignal, 6 | Show, 7 | createSelector, 8 | For, 9 | } from "solid-js"; 10 | import { ElementNode, View, activeElement } from "@lightningjs/solid"; 11 | import { Column } from "@lightningjs/solid-ui"; 12 | import { useNavigate, useParams } from "@solidjs/router"; 13 | import { TileRow } from "../components"; 14 | import styles from "../styles"; 15 | import { setGlobalBackground } from "../state"; 16 | import browseProvider from "../api/providers/browse"; 17 | import { createInfiniteScroll } from "../components/pagination"; 18 | import ContentBlock from "../components/ContentBlock"; 19 | import { assertTruthy } from "@lightningjs/renderer/utils"; 20 | import { debounce } from "@solid-primitives/scheduled"; 21 | 22 | const Browse = () => { 23 | const params = useParams(); 24 | const [columnY, setcolumnY] = createSignal(0); 25 | const [heroContent, setHeroContent] = createSignal({}); 26 | const navigate = useNavigate(); 27 | const isFirst = createSelector(() => { 28 | return 0; 29 | }); 30 | 31 | const provider = createMemo(() => { 32 | return createInfiniteScroll(browseProvider(params.filter || "all")); 33 | }); 34 | 35 | const delayedBackgrounds = debounce( 36 | (img: string) => setGlobalBackground(img), 37 | 400, 38 | ); 39 | const delayedHero = debounce( 40 | (content: {}) => setHeroContent(content || {}), 41 | 200, 42 | ); 43 | 44 | createEffect( 45 | on( 46 | activeElement, 47 | (elm) => { 48 | if (elm.backdrop) { 49 | delayedBackgrounds(elm.backdrop); 50 | } 51 | 52 | if (elm.heroContent) { 53 | delayedHero(elm.heroContent); 54 | } 55 | }, 56 | { defer: true }, 57 | ), 58 | ); 59 | 60 | function onRowFocus(this: ElementNode) { 61 | this.children.selected?.setFocus(); 62 | setcolumnY((this.y || 0) * -1 + 24); 63 | let numPages = provider().pages().length; 64 | this.parent!.selected = this.parent!.children.indexOf(this); 65 | 66 | if ( 67 | numPages === 0 || 68 | (this.parent.selected && this.parent.selected >= numPages - 2) 69 | ) { 70 | provider().setPage((p) => p + 1); 71 | } 72 | } 73 | 74 | function onEnter(this: ElementNode) { 75 | let entity = this.children.find((c) => c.states!.has("focus")); 76 | assertTruthy(entity && entity.href); 77 | navigate(entity.href); 78 | return true; 79 | } 80 | 81 | return ( 82 | 83 | 84 | 85 | 93 | 94 | {(items, i) => ( 95 | 102 | )} 103 | 104 | 105 | 106 | 107 | ); 108 | }; 109 | 110 | export default Browse; 111 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Buttons.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | View, 3 | Text, 4 | ElementNode, 5 | IntrinsicNodeProps, 6 | hexColor, 7 | IntrinsicNodeStyleProps, 8 | } from "@lightningjs/solid"; 9 | import { withPadding } from "@lightningjs/solid-primitives"; 10 | import { Row } from "@lightningjs/solid-ui"; 11 | import { buttonStyles } from "../styles"; 12 | withPadding; 13 | 14 | const ButtonsPage = () => { 15 | function onEnter(this: ElementNode, event, elm) { 16 | this.states.toggle("disabled"); 17 | } 18 | 19 | const RowStyles = { 20 | display: "flex", 21 | justifyContent: "flexStart", 22 | width: 1500, 23 | height: 300, 24 | color: hexColor("00000000"), 25 | gap: 26, 26 | y: 400, 27 | } satisfies IntrinsicNodeStyleProps; 28 | 29 | function Button(props) { 30 | return ( 31 | 32 | {props.children} 33 | 34 | ); 35 | } 36 | 37 | const Badge = (props: IntrinsicNodeProps) => { 38 | return ( 39 | 48 | 55 | {props.children as string} 56 | 57 | 58 | ); 59 | }; 60 | return ( 61 | <> 62 | 63 | HD 64 | PG13 65 | NC17 66 | I like bananas 67 | DOLBY 68 | 69 | 70 | 71 | 74 | 75 | 76 | 77 | 78 | 79 | ); 80 | }; 81 | 82 | export default ButtonsPage; 83 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/ButtonsMaterial.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ElementNode, 3 | IntrinsicNodeStyleProps, 4 | Text, 5 | View, 6 | hexColor, 7 | } from "@lightningjs/solid"; 8 | import { Row } from "@lightningjs/solid-ui"; 9 | 10 | import { MaterialButtonText } from "../styles"; 11 | 12 | const MaterialButtonsPage = () => { 13 | function onEnter(this: ElementNode, event, elm) { 14 | this.states.toggle("disabled"); 15 | } 16 | 17 | const RowStyles = { 18 | display: "flex", 19 | justifyContent: "flexStart", 20 | width: 1500, 21 | height: 300, 22 | color: hexColor("00000000"), 23 | gap: 26, 24 | y: 400, 25 | x: 100, 26 | } satisfies IntrinsicNodeStyleProps; 27 | 28 | const MaterialButton = { 29 | width: 386, 30 | height: 136, 31 | color: "0x715cabff", 32 | focus: { 33 | color: "0x5a39a2ff", 34 | }, 35 | disabled: { 36 | color: "0x291d43ff", 37 | }, 38 | }; 39 | const RoundedRectangle = ["RoundedRectangle", { radius: 65 }]; 40 | function Button(props) { 41 | return ( 42 | 48 | {props.children} 49 | 50 | ); 51 | } 52 | 53 | return ( 54 | 55 | 58 | 59 | 60 | 61 | ); 62 | }; 63 | 64 | export default MaterialButtonsPage; 65 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Create.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | IntrinsicNodeStyleProps, 3 | IntrinsicTextNodeStyleProps, 4 | Text, 5 | View, 6 | hexColor, 7 | } from "@lightningjs/solid"; 8 | import { Show, children, createSignal, onMount } from "solid-js"; 9 | import { setGlobalBackground } from "../state"; 10 | 11 | const CreatePage = () => { 12 | const OverviewContainer = { 13 | width: 900, 14 | height: 500, 15 | y: 50, 16 | x: 150, 17 | gap: 25, 18 | display: "flex", 19 | flexDirection: "column", 20 | justifyContent: "flexStart", 21 | color: hexColor("00000000"), 22 | } satisfies IntrinsicNodeStyleProps; 23 | 24 | const SublineContainer = { 25 | width: 900, 26 | height: 36, 27 | gap: 6, 28 | display: "flex", 29 | flexDirection: "row", 30 | justifyContent: "flexStart", 31 | color: hexColor("00000000"), 32 | } satisfies IntrinsicNodeStyleProps; 33 | 34 | const Title = { 35 | fontSize: 42, 36 | }; 37 | 38 | const Subline = { 39 | fontSize: 26, 40 | }; 41 | 42 | let myBox, childRef; 43 | onMount(() => { 44 | setGlobalBackground("#000000"); 45 | myBox.animate({ x: 100 }, { duration: 2000 }).start(); 46 | }); 47 | 48 | const [insertTest, setInsertTest] = createSignal(); 49 | const [emptyTest, setEmptyTest] = createSignal(); 50 | 51 | setTimeout(() => { 52 | setInsertTest("- Inserted -"); 53 | childRef 54 | .getChildById("child1") 55 | //.searchChildrenById('subChild') - more expensive version of getChildById 56 | ?.animate({ x: 600 }, { duration: 2000 }) 57 | .start(); 58 | }, 2000); 59 | 60 | const styleChild = { 61 | width: 400, 62 | height: 300, 63 | // Solid blue 64 | color: hexColor("#0000ff"), 65 | } as const; 66 | 67 | const someOtherStyle = { 68 | // pretty red 69 | color: hexColor("#f54242"), 70 | focus: { 71 | // pretty blue 72 | color: hexColor("#4287f5"), 73 | }, 74 | }; 75 | 76 | function ChildTest(props) { 77 | // This causes a parent not rendered error since we're rendering it twice in the template 78 | const resolved = children(() => props.children); 79 | return ( 80 | 81 | 88 | {resolved()} 89 | 96 | {props.title} 97 | 98 | 99 | {resolved()} 100 | 101 | 102 | ); 103 | } 104 | 105 | const borderStyles = { 106 | borderLeft: { 107 | width: 8, 108 | color: 0x05b2b626, 109 | }, 110 | borderTop: { 111 | width: 8, 112 | color: 0x25a2bd26, 113 | }, 114 | borderRight: { 115 | width: 8, 116 | color: 0x05b2b626, 117 | }, 118 | borderBottom: { 119 | width: 8, 120 | color: 0xc5b23626, 121 | }, 122 | } as const; 123 | 124 | const childTestPassedStyles = { 125 | // grey color 126 | color: hexColor("#cccccc"), 127 | focus: { 128 | // black 129 | color: hexColor("#000000"), 130 | }, 131 | }; 132 | 133 | const childTestPassedStyles2 = { 134 | // white color 135 | color: hexColor("#ffffff"), 136 | focus: { 137 | // white something... 138 | color: hexColor("#f6f6cc"), 139 | }, 140 | }; 141 | 142 | function hasFocus(elm) { 143 | // This doesnt work yet - need to make states reactive 144 | return elm.states.has("focus"); 145 | } 146 | 147 | return ( 148 | 149 | Title of the Page 150 | 151 | {emptyTest()} 152 | Sub {insertTest()} Text 153 | 154 | 155 | 156 | More Text 157 | 158 | 163 | Child Test 164 | 165 | 175 | 176 | ); 177 | }; 178 | 179 | export default CreatePage; 180 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Entity.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ElementNode, 3 | Text, 4 | View, 5 | Show, 6 | hexColor, 7 | setActiveElement, 8 | } from "@lightningjs/solid"; 9 | import { Column, Button, Row } from "@lightningjs/solid-ui"; 10 | import { useParams } from "@solidjs/router"; 11 | import { createEffect, createResource, on, createSignal } from "solid-js"; 12 | import { TileRow } from "../components"; 13 | import { setGlobalBackground } from "../state"; 14 | import ContentBlock from "../components/ContentBlock"; 15 | import { useNavigate } from "@solidjs/router"; 16 | import styles from "../styles"; 17 | import * as provider from "../api/providers/entity"; 18 | import { assertTruthy } from "@lightningjs/renderer/utils"; 19 | import type { Tile } from "../api/formatters/ItemFormatter"; 20 | import { playVideo, closeVideo } from "../video"; 21 | 22 | const Entity = () => { 23 | const params = useParams(); 24 | const navigate = useNavigate(); 25 | 26 | const [data] = createResource(() => ({ ...params }), provider.getInfo); 27 | const [credits] = createResource( 28 | () => ({ ...params }), 29 | provider.getCredits, 30 | ); 31 | const [recommendations] = createResource( 32 | () => ({ ...params }), 33 | provider.getRecommendations, 34 | ); 35 | const [backdropAlpha, setBackdropAlpha] = createSignal(0); 36 | 37 | createEffect( 38 | on( 39 | data, 40 | (data) => { 41 | setGlobalBackground(data.backgroundImage); 42 | }, 43 | { defer: true }, 44 | ), 45 | ); 46 | 47 | const columnY = 640; 48 | 49 | const Backdrop = { 50 | color: hexColor("#000000"), 51 | alpha: 0, 52 | width: 1900, 53 | height: 890, 54 | x: -160, 55 | y: columnY, 56 | borderRadius: 30, 57 | }; 58 | 59 | function onRowFocus(this: ElementNode) { 60 | this.children.selected?.setFocus(); 61 | columnRef.y = columnY; 62 | backdropRef.y = columnY; 63 | backdropRef.alpha = 0; 64 | } 65 | 66 | function onRowFocusAnimate(this: ElementNode) { 67 | this.children.selected?.setFocus(); 68 | columnRef.y = 200; 69 | backdropRef.y = 160; 70 | backdropRef.alpha = 0.9; 71 | } 72 | 73 | function onEnter(this: ElementNode) { 74 | let entity = this.children.find((c) => c.states!.has("focus")); 75 | assertTruthy(entity && entity.href); 76 | navigate(entity.href); 77 | } 78 | 79 | function onEscape() { 80 | closeVideo(); 81 | // Set focus back to lightning app 82 | document.getElementsByTagName("canvas")[0].focus(); 83 | entityActions.setFocus(); 84 | setBackdropAlpha(0); 85 | } 86 | 87 | function onEnterTrailer() { 88 | const video = playVideo(); 89 | setActiveElement(video); 90 | setBackdropAlpha(0.9); 91 | } 92 | 93 | let columnRef, backdropRef, entityActions; 94 | 95 | return ( 96 | 97 | entityActions.setFocus()} onEscape={onEscape}> 98 | 99 | columnRef.setFocus()} 107 | onEnter={onEnterTrailer} 108 | > 109 | 112 | 113 | 114 | 115 | 124 | 125 | 126 | Recommendations 127 | 128 | 134 | 135 | Cast and Crew 136 | 137 | 143 | 144 | 145 | 150 | 151 | 158 | 159 | ); 160 | }; 161 | 162 | export default Entity; 163 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Flex.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ElementNode, 3 | IntrinsicNodeStyleProps, 4 | Text, 5 | View, 6 | hexColor, 7 | } from "@lightningjs/solid"; 8 | import { Column, Row } from "@lightningjs/solid-ui"; 9 | import { createSignal, onMount } from "solid-js"; 10 | import styles from "../styles"; 11 | import { setGlobalBackground } from "../state"; 12 | 13 | const FlexPage = () => { 14 | const RowStyles = { 15 | display: "flex", 16 | justifyContent: "flexStart", 17 | width: 1600, 18 | height: 110, 19 | color: hexColor("#4dabf5"), 20 | } satisfies IntrinsicNodeStyleProps; 21 | 22 | const rowTitle = { 23 | fontSize: 44, 24 | marginTop: 25, 25 | marginBottom: -20, 26 | skipFocus: true, 27 | }; 28 | 29 | function Block(props) { 30 | const styles = { 31 | width: 200, 32 | height: 100, 33 | y: 5, 34 | color: 0x1769aaff, 35 | }; 36 | 37 | return ; 38 | } 39 | 40 | const [columnY, setColumnY] = createSignal(50); 41 | function onFocus(this: ElementNode) { 42 | this.children.selected?.setFocus(); 43 | setColumnY(150 + (this.y || 0) * -1); 44 | } 45 | 46 | onMount(() => { 47 | setGlobalBackground("#333333"); 48 | }); 49 | 50 | const gap = 50; 51 | 52 | return ( 53 | <> 54 | 62 | Flex Start 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Flex Start - Margin Left 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | Flex End 79 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Flex End - Margin Right 93 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | Center - No Margin Support 107 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | Space Between - No Margin Support 121 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | Space Evenly - No Margin Support 135 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | ); 150 | }; 151 | 152 | export default FlexPage; 153 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/FlexColumn.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ElementNode, 3 | IntrinsicNodeStyleProps, 4 | Text, 5 | View, 6 | hexColor, 7 | } from "@lightningjs/solid"; 8 | import { Column, Row } from "@lightningjs/solid-ui"; 9 | import { createSignal, onMount } from "solid-js"; 10 | import { setGlobalBackground } from "../state"; 11 | 12 | const FlexColumnPage = () => { 13 | const RowStyles = { 14 | display: "flex", 15 | justifyContent: "spaceEvenly", 16 | width: 1920, 17 | y: 100, 18 | height: 880, 19 | color: hexColor("00000000"), 20 | } satisfies IntrinsicNodeStyleProps; 21 | 22 | const ColumnStyles = { 23 | display: "flex", 24 | flexDirection: "column", 25 | justifyContent: "flexStart", 26 | color: hexColor("#4dabf5"), 27 | height: 850, 28 | width: 60, 29 | } satisfies IntrinsicNodeStyleProps; 30 | 31 | const rowTitle = { 32 | fontSize: 44, 33 | y: 20, 34 | x: 150, 35 | }; 36 | 37 | function Block(props) { 38 | const styles = { 39 | width: 50, 40 | height: 80, 41 | x: 5, 42 | color: hexColor("#1769aa"), 43 | }; 44 | 45 | return ; 46 | } 47 | 48 | const [columnY, setColumnY] = createSignal(50); 49 | function onFocus(this: ElementNode) { 50 | this.children.selected?.setFocus(); 51 | setColumnY(150 + (this.y || 0) * -1); 52 | } 53 | 54 | onMount(() => { 55 | setGlobalBackground("#333333"); 56 | }); 57 | 58 | const gap = 50; 59 | 60 | return ( 61 | <> 62 | 63 | Start, MarginTop, End, MarginBottom, Center, Between, Evenly 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | ); 149 | }; 150 | 151 | export default FlexColumnPage; 152 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/FlexColumnSize.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ElementNode, 3 | IntrinsicNodeStyleProps, 4 | Text, 5 | View, 6 | hexColor, 7 | } from "@lightningjs/solid"; 8 | import { Column, Row } from "@lightningjs/solid-ui"; 9 | import { createSignal, onMount } from "solid-js"; 10 | import { setGlobalBackground } from "../state"; 11 | 12 | const FlexColumnPage = () => { 13 | const RowStyles = { 14 | display: "flex", 15 | justifyContent: "spaceEvenly", 16 | width: 1920, 17 | y: 100, 18 | height: 880, 19 | color: hexColor("00000000"), 20 | } satisfies IntrinsicNodeStyleProps; 21 | 22 | const ColumnStyles = { 23 | display: "flex", 24 | flexDirection: "column", 25 | justifyContent: "flexStart", 26 | color: hexColor("#4dabf5"), 27 | height: 850, 28 | width: 80, 29 | } satisfies IntrinsicNodeStyleProps; 30 | 31 | const rowTitle = { 32 | fontSize: 44, 33 | y: 20, 34 | x: 150, 35 | }; 36 | 37 | function Block(props) { 38 | const styles = { 39 | width: randSize(), 40 | height: 80, 41 | x: 5, 42 | color: hexColor("#1769aa"), 43 | }; 44 | 45 | return ; 46 | } 47 | 48 | function randSize() { 49 | // size 10 to 70 50 | return Math.floor(Math.random() * 61) + 10; 51 | } 52 | 53 | const [columnY, setColumnY] = createSignal(50); 54 | function onFocus(this: ElementNode) { 55 | this.children.selected?.setFocus(); 56 | setColumnY(150 + (this.y || 0) * -1); 57 | } 58 | 59 | onMount(() => { 60 | setGlobalBackground("#333333"); 61 | }); 62 | 63 | const gap = 50; 64 | 65 | return ( 66 | <> 67 | 68 | Start, MarginTop, End, MarginBottom, Center, Between, Evenly 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | ); 160 | }; 161 | 162 | export default FlexColumnPage; 163 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/FlexSize.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ElementNode, 3 | IntrinsicNodeStyleProps, 4 | Text, 5 | View, 6 | hexColor, 7 | } from "@lightningjs/solid"; 8 | import { Column, Row } from "@lightningjs/solid-ui"; 9 | import { createSignal, onMount } from "solid-js"; 10 | import styles from "../styles"; 11 | import { setGlobalBackground } from "../state"; 12 | 13 | const FlexSizePage = () => { 14 | const RowStyles = { 15 | display: "flex", 16 | justifyContent: "flexStart", 17 | width: 1600, 18 | height: 110, 19 | color: hexColor("#4dabf5"), 20 | } satisfies IntrinsicNodeStyleProps; 21 | 22 | const rowTitle = { 23 | fontSize: 44, 24 | marginTop: 25, 25 | marginBottom: -20, 26 | skipFocus: true, 27 | }; 28 | 29 | function Block(props) { 30 | const styles = { 31 | width: 200, 32 | height: 100, 33 | y: 5, 34 | color: 0x1769aaff, 35 | }; 36 | 37 | return ; 38 | } 39 | 40 | function randSize() { 41 | // size 21 to 100 42 | return Math.floor(Math.random() * 91) + 10; 43 | } 44 | 45 | const [columnY, setColumnY] = createSignal(50); 46 | function onFocus(this: ElementNode) { 47 | this.children.selected?.setFocus(); 48 | setColumnY(150 + (this.y || 0) * -1); 49 | } 50 | 51 | onMount(() => { 52 | setGlobalBackground("#333333"); 53 | }); 54 | 55 | const gap = 50; 56 | 57 | return ( 58 | <> 59 | 67 | Flex Start - AlignItems: center 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Flex Start - Margin Left - AlignItems: flexStart 77 | 78 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Flex End - AlignItems: flexEnd 91 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | Flex End - Margin Right 106 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | Center - No Margin Support 120 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | Space Between - No Margin Support 134 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | Space Evenly - No Margin Support 148 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | ); 163 | }; 164 | 165 | export default FlexSizePage; 166 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Grid.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | createEffect, 3 | on, 4 | createSignal, 5 | createSelector, 6 | Index, 7 | onMount, 8 | } from "solid-js"; 9 | import { type ElementNode, View, Text } from "@lightningjs/solid"; 10 | import { Column, Row } from "@lightningjs/solid-ui"; 11 | import styles from "./gridStyles"; 12 | import { setGlobalBackground } from "../state"; 13 | import { createInfiniteItems } from "@lightningjs/solid-primitives"; 14 | 15 | interface ProductsResponse { 16 | limit: number; 17 | products: any[]; // You can replace 'any' with the actual type of your products 18 | skip: number; 19 | total: number; 20 | } 21 | 22 | interface Product { 23 | brand: string; 24 | category: string; 25 | description: string; 26 | discountPercentage: number; 27 | id: number; 28 | images: string[]; 29 | price: number; 30 | rating: number; 31 | stock: number; 32 | thumbnail: string; 33 | title: string; 34 | } 35 | 36 | function ProductRow(props) { 37 | return ( 38 | 44 | {props.item.id} 45 | {props.item.title} 46 | {props.item.price} 47 | 48 | ); 49 | } 50 | 51 | const Grid = () => { 52 | let totalProducts = 100; 53 | const [columnY, setcolumnY] = createSignal(0); 54 | const isFirst = createSelector(() => 0); 55 | const [rowIndex, setRowIndex] = createSignal(0); 56 | const [items, setItems] = createSignal([]); 57 | const [products, { setPage }] = createInfiniteItems((page) => { 58 | return fetch(`https://dummyjson.com/products?limit=20&skip=${20 * page}`) 59 | .then((res) => res.json()) 60 | .then((data: ProductsResponse) => { 61 | totalProducts = data.total; 62 | return data.products; 63 | }); 64 | }); 65 | 66 | const EXTRA = 8; 67 | // When rowIndex changes we create a sub array for the UI 68 | createEffect( 69 | on( 70 | [products, rowIndex], 71 | ([products, index]) => { 72 | if (items().length - EXTRA > index) return; 73 | 74 | setItems(products.slice(0, index + EXTRA)); 75 | if (index > products.length - 5) { 76 | // Load more products 77 | setPage((p) => p + 1); 78 | } 79 | }, 80 | { defer: true }, 81 | ), 82 | ); 83 | 84 | onMount(() => { 85 | setGlobalBackground("#000000"); 86 | }); 87 | 88 | function changeRow(elm, active, selectedIndex, lastSelectedIndex) { 89 | setcolumnY((active.y || 0) * -1 + 50); 90 | setRowIndex(selectedIndex); 91 | } 92 | 93 | return ( 94 | 95 | 96 | 97 | {(item, i) => ( 98 | 99 | )} 100 | 101 | 102 | 103 | ); 104 | }; 105 | 106 | export default Grid; 107 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/NotFound.tsx: -------------------------------------------------------------------------------- 1 | const NotFound = () => { 2 | return ; 3 | }; 4 | 5 | export default NotFound; 6 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/People.tsx: -------------------------------------------------------------------------------- 1 | import { ElementNode, Text, View, Show, hexColor } from "@lightningjs/solid"; 2 | import { Column } from "@lightningjs/solid-ui"; 3 | import { useParams } from "@solidjs/router"; 4 | import { createResource, onMount } from "solid-js"; 5 | import { TileRow } from "../components"; 6 | import { setGlobalBackground } from "../state"; 7 | import { useNavigate } from "@solidjs/router"; 8 | import theme from "theme"; 9 | import styles from "../styles"; 10 | import * as provider from "../api/providers/people"; 11 | import { assertTruthy } from "@lightningjs/renderer/utils"; 12 | 13 | const People = () => { 14 | const params = useParams(); 15 | const navigate = useNavigate(); 16 | 17 | const [data] = createResource(() => ({ ...params }), provider.getInfo); 18 | const [credits] = createResource(() => ({ ...params }), provider.getCredits); 19 | 20 | const Backdrop = { 21 | color: hexColor("#000000"), 22 | alpha: 0.8, 23 | width: 800, 24 | height: 440, 25 | x: 130, 26 | y: 180, 27 | borderRadius: 30, 28 | }; 29 | 30 | function onEnter(this: ElementNode) { 31 | let entity = this.children.selected; 32 | assertTruthy(entity && entity.href); 33 | navigate(entity.href); 34 | } 35 | 36 | onMount(() => { 37 | setGlobalBackground("#333333"); 38 | }); 39 | 40 | return ( 41 | 42 | 50 | 58 | 63 | {data().name} 64 | 65 | 66 | {data().biography} 67 | 68 | 69 | 70 | 71 | 72 | 73 | Credits 74 | 75 | 76 | 77 | 78 | 79 | ); 80 | }; 81 | 82 | export default People; 83 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Portal.tsx: -------------------------------------------------------------------------------- 1 | import { createSignal, createSelector, For } from "solid-js"; 2 | import { ElementNode, View, Text } from "@lightningjs/solid"; 3 | import { Column, Row } from "@lightningjs/solid-ui"; 4 | import { useNavigate } from "@solidjs/router"; 5 | import styles from "../styles"; 6 | import { assertTruthy } from "@lightningjs/renderer/utils"; 7 | 8 | const Portal = () => { 9 | const navigate = useNavigate(); 10 | const isFirst = createSelector(() => { 11 | return 0; 12 | }); 13 | 14 | function onEnter(this: ElementNode) { 15 | let entity = this.children.selected; 16 | assertTruthy(entity && entity.id); 17 | navigate("/" + entity.id); 18 | } 19 | 20 | const flexDemos = [ 21 | { 22 | title: "Flex Row", 23 | id: "flex", 24 | description: "Flex Row Implementation", 25 | }, 26 | { 27 | title: "Flex Column", 28 | id: "flexcolumn", 29 | description: "Flex Column Implementation", 30 | }, 31 | { 32 | title: "Flex Row Vertical Align", 33 | id: "flexsize", 34 | description: "Flex Row Vertical Align Implementation", 35 | }, 36 | { 37 | title: "Flex Column Vertical Align", 38 | id: "flexcolumnsize", 39 | description: "Flex Column Vertical Align Implementation", 40 | }, 41 | { 42 | title: "Flex Layout Tests", 43 | id: "superflex", 44 | description: "Complicated flex layouts", 45 | }, 46 | ]; 47 | 48 | const demos = [ 49 | { 50 | title: "Grid", 51 | id: "grid", 52 | description: "Infinite Scroll Grid", 53 | }, 54 | { 55 | title: "Buttons", 56 | id: "buttons", 57 | description: "Demo a few buttons", 58 | }, 59 | { 60 | title: "Text", 61 | id: "text", 62 | description: "Text layout with flexbox", 63 | }, 64 | { 65 | title: "Create Elements", 66 | id: "create", 67 | description: "Testing Show + children + inserting text", 68 | }, 69 | { 70 | title: "Viewport", 71 | id: "viewport", 72 | description: "Events going in and out of viewport", 73 | }, 74 | ]; 75 | 76 | function DemoTile(props) { 77 | const Container = { 78 | width: 370, 79 | height: 320, 80 | borderRadius: 6, 81 | scale: 1, 82 | color: 0x182b44ff, 83 | transition: { color: true, scale: true }, 84 | focus: { 85 | scale: 1.1, 86 | color: 0xffffffff, 87 | }, 88 | }; 89 | const [color, setColor] = createSignal(0xffffffff); 90 | 91 | return ( 92 | setColor(0x000000ff)} 95 | onBlur={() => setColor(0xffffffff)} 96 | style={Container} 97 | > 98 | 99 | 100 | {props.index} 101 | 102 | 110 | {props.title} 111 | 112 | 119 | {props.description} 120 | 121 | 122 | 123 | ); 124 | } 125 | 126 | return ( 127 | 128 | 129 | 130 | 131 | Examples 132 | 133 | 134 | 135 | 136 | 142 | 143 | {(demo, i) => ( 144 | 145 | )} 146 | 147 | 148 | 149 | 155 | 156 | {(demo, i) => } 157 | 158 | 159 | 160 | 161 | ); 162 | }; 163 | 164 | export default Portal; 165 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/SuperFlex.tsx: -------------------------------------------------------------------------------- 1 | import { View, Text, For } from "@lightningjs/solid"; 2 | import { Column, Row } from "@lightningjs/solid-ui"; 3 | import { Show, createSignal } from "solid-js"; 4 | 5 | const Items = [ 6 | "Mary", 7 | "had", 8 | "a", 9 | "little", 10 | "lamb", 11 | "her", 12 | "fleece", 13 | "was", 14 | "white", 15 | "as", 16 | "snow", 17 | ]; 18 | export const styles = { 19 | PageContainer: { 20 | width: 1920, 21 | height: 1080, 22 | display: "flex", 23 | flexDirection: "column", 24 | justifyContent: "center", 25 | alignItems: "center", 26 | zIndex: 99, 27 | }, 28 | } as const; 29 | 30 | export default () => { 31 | const [lazyShow, setLazyShow] = createSignal(false); 32 | let PageLoader; 33 | 34 | setTimeout(() => { 35 | setLazyShow(true); 36 | PageLoader.alpha = 0; 37 | }, 2000); 38 | 39 | return ( 40 | <> 41 | 42 | Center - gif doesnt animate 43 | 44 | Spinner 45 | 46 | 55 | 56 | {(item, index) => ( 57 | 62 | )} 63 | 64 | 65 | 66 | 67 | 76 | 77 | {(item, index) => ( 78 | 83 | )} 84 | 85 | 86 | 87 | 88 | 89 | 97 | 98 | {(item, index) => {item}} 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | {(item, index) => {item}} 107 | 108 | 109 | 110 | 111 | ); 112 | }; 113 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Text.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | IntrinsicNodeStyleProps, 3 | IntrinsicTextNodeStyleProps, 4 | Text, 5 | View, 6 | hexColor, 7 | } from "@lightningjs/solid"; 8 | import { onMount } from "solid-js"; 9 | import { setGlobalBackground } from "../state"; 10 | 11 | const TextPage = () => { 12 | const OverviewContainer = { 13 | width: 900, 14 | height: 500, 15 | y: 350, 16 | x: 150, 17 | gap: 25, 18 | display: "flex", 19 | flexDirection: "column", 20 | justifyContent: "flexStart", 21 | color: hexColor("00000000"), 22 | } satisfies IntrinsicNodeStyleProps; 23 | 24 | const SublineContainer = { 25 | width: 900, 26 | height: 36, 27 | gap: 6, 28 | display: "flex", 29 | flexDirection: "row", 30 | justifyContent: "flexStart", 31 | color: hexColor("00000000"), 32 | } satisfies IntrinsicNodeStyleProps; 33 | 34 | const Title = { 35 | fontSize: 42, 36 | }; 37 | 38 | const Overview = { 39 | width: OverviewContainer.width, 40 | fontSize: 26, 41 | contain: "width", 42 | } satisfies IntrinsicTextNodeStyleProps; 43 | 44 | const Subline = { 45 | fontSize: 26, 46 | }; 47 | 48 | onMount(() => { 49 | setGlobalBackground("#000000"); 50 | }); 51 | 52 | return ( 53 | 54 | Title of the Page 55 | 56 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vel 57 | tempor tellus. Sed eu leo purus. Vestibulum sollicitudin eget tellus a 58 | varius. Phasellus est turpis, volutpat sed blandit sit amet, rutrum sit 59 | amet mauris. In dignissim elit orci, a sollicitudin ipsum faucibus et. 60 | Quisque vel quam rutrum, faucibus augue sed, scelerisque nunc. 61 | 62 | 63 | Subline Text 64 | 65 | More Text 66 | 67 | 68 | ); 69 | }; 70 | 71 | export default TextPage; 72 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/Viewport.tsx: -------------------------------------------------------------------------------- 1 | import { Text, View, hexColor } from "@lightningjs/solid"; 2 | import { onMount, onCleanup, createSignal } from "solid-js"; 3 | import { setGlobalBackground } from "../state"; 4 | 5 | export default () => { 6 | let ball, invervalTimer; 7 | 8 | const [ballStatus, setBallStatus] = createSignal([]); 9 | 10 | const styleBall = { 11 | width: 100, 12 | height: 100, 13 | x: -400, 14 | y: -400, 15 | rotation: 0, 16 | borderRadius: 50, 17 | color: hexColor("#4287f5"), 18 | transition: { 19 | x: { duration: 1250, easing: "linear" }, 20 | y: { duration: 1250, easing: "linear" }, 21 | rotation: { duration: 1400, easing: "ease-in-out" }, 22 | }, 23 | } as const; 24 | 25 | const Title = { 26 | fontSize: 32, 27 | x: 960, 28 | y: 540, 29 | mount: 0.5, 30 | lineheight: 52, 31 | }; 32 | 33 | const randomIntBetween = (from, to) => 34 | Math.floor(Math.random() * (to - from + 1) + from); 35 | 36 | onMount(() => { 37 | setGlobalBackground("#000000"); 38 | 39 | ball.x = (1920 - 100) / 2; 40 | ball.y = (1080 - 100) / 2; 41 | invervalTimer = setInterval(() => { 42 | ball.rotation = randomIntBetween(-90, 90); 43 | ball.x = randomIntBetween(-300, 2220); 44 | ball.y = randomIntBetween(-300, 1380); 45 | }, 2500); 46 | }); 47 | 48 | function logEvent(name, elm) { 49 | setBallStatus((prev) => { 50 | return [...prev, name].slice(-4); 51 | }); 52 | console.log(name); 53 | } 54 | 55 | onCleanup(() => { 56 | clearInterval(invervalTimer); 57 | }); 58 | 59 | return ( 60 | 61 | {ballStatus().join("\n")} 62 | logEvent("inBounds", elm)], 68 | ["outOfBounds", (elm) => logEvent("outOfBounds", elm)], 69 | ["inViewport", (elm) => logEvent("inViewport", elm)], 70 | ["outOfViewport", (elm) => logEvent("outOfViewport", elm)], 71 | ]} 72 | /> 73 | 74 | ); 75 | }; 76 | -------------------------------------------------------------------------------- /ui/lightning/src/pages/gridStyles.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IntrinsicNodeStyleProps, 3 | IntrinsicTextNodeStyleProps, 4 | hexColor, 5 | } from "@lightningjs/solid"; 6 | import theme from "theme"; 7 | 8 | const ROW_HEIGHT = 50; 9 | export default { 10 | ProductRow: { 11 | width: 500, 12 | display: "flex", 13 | flexDirection: "row", 14 | gap: 40, 15 | height: ROW_HEIGHT, 16 | borderRadius: 16, 17 | color: 0xffffff0d, 18 | border: { color: 0x008085ff, width: 0 }, 19 | active: { 20 | color: 0x39393cff, 21 | }, 22 | focus: { 23 | color: 0xf6f6f9ff, 24 | border: { color: 0x008085ff, width: 6 }, 25 | }, 26 | transition: { 27 | // leave easing blank to use default linear 28 | x: { duration: 300 }, 29 | width: { duration: 300 }, 30 | alpha: { duration: 300 }, 31 | }, 32 | }, 33 | ProductText: { 34 | fontSize: 20, 35 | fontWeight: 600, 36 | lineHeight: 24, 37 | color: hexColor("#f6f6f6"), 38 | focus: { 39 | color: 0x141417ff, 40 | }, 41 | }, 42 | itemsContainer: { 43 | width: theme.layout.screenW, 44 | height: 600, 45 | y: 180, 46 | x: 180, 47 | zIndex: 2, 48 | }, 49 | } as const; 50 | -------------------------------------------------------------------------------- /ui/lightning/src/state.ts: -------------------------------------------------------------------------------- 1 | import { createSignal } from "solid-js"; 2 | export const [globalBackground, setGlobalBackground] = createSignal(""); 3 | -------------------------------------------------------------------------------- /ui/lightning/src/styles.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IntrinsicNodeStyleProps, 3 | IntrinsicTextNodeStyleProps, 4 | hexColor, 5 | } from "@lightningjs/solid"; 6 | import theme from "theme"; 7 | 8 | // Augment existing intrinsic style prop interfaces to include our own 9 | // app-specific states 10 | declare module "@lightningjs/solid" { 11 | interface IntrinsicNodeStyleProps { 12 | // TODO: Refactor states to use a $ prefix 13 | active?: IntrinsicNodeStyleProps; 14 | disabled?: IntrinsicNodeStyleProps; 15 | } 16 | 17 | interface IntrinsicTextNodeStyleProps { 18 | // TODO: Refactor states to use a $ prefix 19 | active?: IntrinsicTextNodeStyleProps; 20 | disabled?: IntrinsicTextNodeStyleProps; 21 | } 22 | } 23 | 24 | export default { 25 | Page: { 26 | width: 1920, 27 | height: 1080, 28 | }, 29 | headlineText: { 30 | width: 1200, 31 | height: 240, 32 | x: 360, 33 | // lineHeight: 170, // TODO: Add back when lineHeight is supported 34 | y: 455, 35 | contain: "both", 36 | fontSize: 66, 37 | textAlign: "center", 38 | } satisfies IntrinsicTextNodeStyleProps, 39 | headlineSubText: { 40 | width: 960, 41 | height: 170, 42 | // lineHeight: 170, // TODO: Add back when lineHeight is supported 43 | x: 530, 44 | y: 655, 45 | contain: "both", 46 | fontSize: 48, 47 | textAlign: "center", 48 | } satisfies IntrinsicTextNodeStyleProps, 49 | itemsContainer: { 50 | width: theme.layout.screenW, 51 | height: 800, 52 | y: 560, 53 | x: 0, 54 | zIndex: 2, 55 | }, 56 | Thumbnail: { 57 | borderRadius: 16, 58 | width: 185, 59 | height: 278, 60 | scale: 1, 61 | zIndex: 2, 62 | transition: { scale: { duration: 250, easing: "ease-in-out" } }, 63 | border: { width: 0, color: 0x00000000 }, 64 | focus: { scale: 1.1, border: { color: 0xffffff66, width: 8 } }, 65 | }, 66 | FocusRing: { 67 | borderRadius: 16, 68 | width: 194, 69 | height: 286, 70 | y: -5, 71 | x: -5, 72 | zIndex: -1, 73 | }, 74 | FPS: { 75 | color: 0x000000ff, 76 | height: 42, 77 | width: 140, 78 | x: 20, 79 | y: 20, 80 | zIndex: 100, 81 | } as const, 82 | FPSLabel: { 83 | x: 10, 84 | y: 0, 85 | fontSize: 36, 86 | textColor: hexColor("#ffffff"), 87 | }, 88 | FPSValue: { 89 | x: 90, 90 | y: 0, 91 | fontSize: 36, 92 | textColor: hexColor("#ffffff"), 93 | }, 94 | showHeadline: { x: 70, y: 20 }, 95 | headlineBlur: { 96 | width: 1920, 97 | height: 150, 98 | x: 0, 99 | y: 0, 100 | zIndex: 14, 101 | alpha: 0.9, 102 | color: hexColor("#000000"), 103 | }, 104 | RowTitle: { 105 | height: 60, 106 | width: 300, 107 | marginBottom: -40, 108 | fontSize: 36, 109 | color: hexColor("#f0f0f0"), 110 | zIndex: 2, 111 | } satisfies IntrinsicTextNodeStyleProps, 112 | Row: { 113 | display: "flex", 114 | justifyContent: "spaceBetween", 115 | height: 300, 116 | }, 117 | Column: { 118 | display: "flex", 119 | flexDirection: "column", 120 | justifyContent: "flexStart", 121 | flexBoundary: "contain", 122 | gap: 64, 123 | width: theme.layout.screenW - 2 * theme.layout.marginX, 124 | x: theme.layout.marginX + theme.layout.gutterX, 125 | y: 48, 126 | transition: { y: { duration: 250, easing: "ease-in-out" } }, 127 | zIndex: 2, 128 | }, 129 | Rect: { 130 | width: 250, 131 | height: 100, 132 | y: 10, 133 | x: 300, 134 | color: hexColor("#0000ff"), 135 | }, 136 | peopleBio: { 137 | ...theme.typography.body1, 138 | fontFamily: "Ubuntu", 139 | fontWeight: "normal", 140 | contain: "both", 141 | width: 780, 142 | height: 340, 143 | } satisfies IntrinsicTextNodeStyleProps, 144 | } as const; 145 | 146 | const Button = { 147 | width: 120, 148 | height: 40, 149 | mount: 0.5, 150 | color: 0x000000b3, 151 | borderRadius: 8, 152 | borderBottom: { width: 2, color: 0xff00faff }, 153 | border: { width: 2, color: 0xfafafa33 }, 154 | focus: { 155 | color: 0xfafafaff, 156 | borderRadius: 20, 157 | borderBottom: { width: 0, color: 0x00000000 }, 158 | }, 159 | } satisfies IntrinsicNodeStyleProps; 160 | 161 | const TopBar = { 162 | color: hexColor("#00A699"), 163 | height: 8, 164 | y: 2, 165 | x: -4, 166 | width: Button.width + 8, 167 | } satisfies IntrinsicNodeStyleProps; 168 | 169 | const ButtonText = { 170 | fontSize: 12, 171 | y: 12, 172 | // lineHeight: Button.height, // TODO: Add back when lineHeight is supported 173 | contain: "width", 174 | textAlign: "center", 175 | color: hexColor("#F6F6F9"), 176 | height: Button.height, 177 | width: Button.width, 178 | } satisfies IntrinsicTextNodeStyleProps; 179 | 180 | export const buttonStyles = { 181 | container: Button, 182 | topBar: TopBar, 183 | text: ButtonText, 184 | } satisfies Record; 185 | 186 | export const MaterialButton = { 187 | width: 386, 188 | height: 136, 189 | color: hexColor("#715cab"), 190 | focus: { 191 | color: hexColor("#5a39a2"), 192 | }, 193 | disabled: { 194 | color: hexColor("#291d43"), 195 | }, 196 | } satisfies IntrinsicNodeStyleProps; 197 | 198 | export const MaterialButtonText = { 199 | fontSize: 32, 200 | contain: "width", 201 | textAlign: "center", 202 | mountY: -0.35, 203 | color: hexColor("#FFFFFF"), 204 | height: MaterialButton.height, 205 | width: MaterialButton.width, 206 | // lineHeight: MaterialButton.height, // TODO: Add back when lineHeight is supported 207 | focus: { 208 | fontSize: 40, 209 | }, 210 | disabled: { 211 | color: hexColor("#909090"), 212 | }, 213 | } satisfies IntrinsicTextNodeStyleProps; 214 | -------------------------------------------------------------------------------- /ui/lightning/src/threadx-core-worker.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is needed to properly import the ThreadX renderer worker via 3 | * the vite-plugin-import-chunk-url plugin. 4 | */ 5 | import "@lightningjs/renderer/workers/renderer"; 6 | -------------------------------------------------------------------------------- /ui/lightning/src/video.js: -------------------------------------------------------------------------------- 1 | // Documentation from Shaka player: 2 | // https://shaka-player-demo.appspot.com/docs/api/tutorial-basic-usage.html 3 | 4 | const manifestUri = 5 | "https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd"; 6 | 7 | function initApp() { 8 | // Install built-in polyfills to patch browser incompatibilities. 9 | shaka.polyfill.installAll(); 10 | 11 | // Check to see if the browser supports the basic APIs Shaka needs. 12 | if (shaka.Player.isBrowserSupported()) { 13 | // Everything looks good! 14 | initPlayer(); 15 | } else { 16 | // This browser does not have the minimum set of APIs we need. 17 | console.error("Browser not supported!"); 18 | } 19 | } 20 | 21 | async function initPlayer() { 22 | // Create a Player instance. 23 | const video = document.getElementById("video"); 24 | const player = new shaka.Player(); 25 | await player.attach(video); 26 | 27 | // Attach player to the window to make it easy to access in the JS console. 28 | window.player = player; 29 | 30 | // Listen for error events. 31 | player.addEventListener("error", onErrorEvent); 32 | 33 | // Try to load a manifest. 34 | // This is an asynchronous process. 35 | try { 36 | await player.load(manifestUri); 37 | // This runs if the asynchronous load is successful. 38 | console.log("The video has now been loaded!"); 39 | } catch (e) { 40 | // onError is executed if the asynchronous load fails. 41 | onError(e); 42 | } 43 | } 44 | 45 | function onErrorEvent(event) { 46 | // Extract the shaka.util.Error object from the event. 47 | onError(event.detail); 48 | } 49 | 50 | function onError(error) { 51 | // Log the error. 52 | console.error("Error code", error.code, "object", error); 53 | } 54 | 55 | export function playVideo() { 56 | const video = document.getElementById("video"); 57 | video.hidden = false; 58 | // Needs delay from hidden to play in Chrome 59 | setTimeout(() => video.play(), 50); 60 | video.focus(); 61 | return video; 62 | } 63 | 64 | export function closeVideo() { 65 | const video = document.getElementById("video"); 66 | video.hidden = true; 67 | video.pause(); 68 | return video; 69 | } 70 | 71 | //document.addEventListener("DOMContentLoaded", initApp); 72 | -------------------------------------------------------------------------------- /ui/lightning/styles.css: -------------------------------------------------------------------------------- 1 | html, body, * { padding: 0; margin: 0 } 2 | video { position: absolute; top: 0; left: 0; z-index: 2; outline: none; } 3 | .center-element { 4 | position: absolute; 5 | top: 50%; 6 | left: 50%; 7 | transform: translate(-50%, -50%); 8 | } -------------------------------------------------------------------------------- /ui/lightning/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ES2019", 5 | "module": "esnext", 6 | "moduleResolution": "Bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "jsxImportSource": "solid-js", 11 | "types": [ 12 | "vite/client", 13 | "@lightningjs/vite-plugin-import-chunk-url/client" 14 | ], 15 | "noEmit": true, 16 | "isolatedModules": true, 17 | "noImplicitAny": false, 18 | "paths": { 19 | "theme": ["./node_modules/@lightningjs/l3-ui-theme-base"] 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ui/lightning/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import solidPlugin from "vite-plugin-solid"; 3 | import { importChunkUrl } from "@lightningjs/vite-plugin-import-chunk-url"; 4 | import legacy from "@vitejs/plugin-legacy"; 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | importChunkUrl(), 9 | solidPlugin({ 10 | solid: { 11 | moduleName: "@lightningjs/solid", 12 | generate: "universal", 13 | }, 14 | }), 15 | legacy({ 16 | targets: ["defaults", "Chrome >= 49"], 17 | // additionalLegacyPolyfills: ["whatwg-fetch", "es6-proxy-polyfill"], 18 | }), 19 | ], 20 | resolve: { 21 | alias: { 22 | theme: "@lightningjs/l3-ui-theme-base", 23 | }, 24 | dedupe: [ 25 | "solid-js", 26 | "@lightningjs/solid", 27 | "@lightningjs/solid-ui", 28 | "@lightningjs/solid-primitives", 29 | "@lightningjs/renderer", 30 | ], 31 | }, 32 | // Close to removing this - SolidUI is the only thing that needs it (renaming _ElementNode for some reason) 33 | optimizeDeps: { 34 | include: [], 35 | exclude: [ 36 | "@lightningjs/solid", 37 | "@lightningjs/solid-ui", 38 | "@lightningjs/solid-primitives", 39 | "@lightningjs/renderer", 40 | "@lightningjs/renderer/core", 41 | "@lightningjs/renderer/workers/renderer", 42 | ], 43 | }, 44 | server: { 45 | port: 5174, 46 | hmr: true, 47 | headers: { 48 | "Cross-Origin-Opener-Policy": "same-origin", 49 | "Cross-Origin-Embedder-Policy": "require-corp", 50 | }, 51 | }, 52 | }); 53 | -------------------------------------------------------------------------------- /ui/web/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /ui/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Solid App 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ui/web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "version": "1.0.0", 4 | "description": "", 5 | "type": "module", 6 | "scripts": { 7 | "start": "vite --open --host --force", 8 | "start:prod": "vite --open --host --force --mode production", 9 | "build": "vite build --sourcemap=true", 10 | "build:github": "vite build --sourcemap=true --base=/solid-demo-app/", 11 | "build:analyze": "vite-bundle-visualizer", 12 | "deploy": "gh-pages -d dist", 13 | "preview": "vite preview --open --port 8080", 14 | "tsc": "tsc" 15 | }, 16 | "author": "", 17 | "license": "ISC" 18 | } 19 | -------------------------------------------------------------------------------- /ui/web/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | solid-js: 9 | specifier: ^1.8.11 10 | version: 1.8.11 11 | 12 | devDependencies: 13 | solid-devtools: 14 | specifier: ^0.29.2 15 | version: 0.29.2(solid-js@1.8.11)(vite@5.0.11) 16 | typescript: 17 | specifier: ^5.3.3 18 | version: 5.3.3 19 | vite: 20 | specifier: ^5.0.11 21 | version: 5.0.11 22 | vite-plugin-solid: 23 | specifier: ^2.8.2 24 | version: 2.8.2(solid-js@1.8.11)(vite@5.0.11) 25 | 26 | packages: 27 | 28 | /@ampproject/remapping@2.2.1: 29 | resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} 30 | engines: {node: '>=6.0.0'} 31 | dependencies: 32 | '@jridgewell/gen-mapping': 0.3.3 33 | '@jridgewell/trace-mapping': 0.3.18 34 | dev: true 35 | 36 | /@babel/code-frame@7.23.5: 37 | resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} 38 | engines: {node: '>=6.9.0'} 39 | dependencies: 40 | '@babel/highlight': 7.23.4 41 | chalk: 2.4.2 42 | dev: true 43 | 44 | /@babel/compat-data@7.23.5: 45 | resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} 46 | engines: {node: '>=6.9.0'} 47 | dev: true 48 | 49 | /@babel/core@7.23.7: 50 | resolution: {integrity: sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==} 51 | engines: {node: '>=6.9.0'} 52 | dependencies: 53 | '@ampproject/remapping': 2.2.1 54 | '@babel/code-frame': 7.23.5 55 | '@babel/generator': 7.23.6 56 | '@babel/helper-compilation-targets': 7.23.6 57 | '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) 58 | '@babel/helpers': 7.23.8 59 | '@babel/parser': 7.23.6 60 | '@babel/template': 7.22.15 61 | '@babel/traverse': 7.23.7 62 | '@babel/types': 7.23.6 63 | convert-source-map: 2.0.0 64 | debug: 4.3.4 65 | gensync: 1.0.0-beta.2 66 | json5: 2.2.3 67 | semver: 6.3.1 68 | transitivePeerDependencies: 69 | - supports-color 70 | dev: true 71 | 72 | /@babel/generator@7.23.6: 73 | resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} 74 | engines: {node: '>=6.9.0'} 75 | dependencies: 76 | '@babel/types': 7.23.6 77 | '@jridgewell/gen-mapping': 0.3.3 78 | '@jridgewell/trace-mapping': 0.3.18 79 | jsesc: 2.5.2 80 | dev: true 81 | 82 | /@babel/helper-annotate-as-pure@7.22.5: 83 | resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} 84 | engines: {node: '>=6.9.0'} 85 | dependencies: 86 | '@babel/types': 7.22.5 87 | dev: true 88 | 89 | /@babel/helper-compilation-targets@7.23.6: 90 | resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} 91 | engines: {node: '>=6.9.0'} 92 | dependencies: 93 | '@babel/compat-data': 7.23.5 94 | '@babel/helper-validator-option': 7.23.5 95 | browserslist: 4.22.2 96 | lru-cache: 5.1.1 97 | semver: 6.3.1 98 | dev: true 99 | 100 | /@babel/helper-create-class-features-plugin@7.23.7(@babel/core@7.23.7): 101 | resolution: {integrity: sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==} 102 | engines: {node: '>=6.9.0'} 103 | peerDependencies: 104 | '@babel/core': ^7.0.0 105 | dependencies: 106 | '@babel/core': 7.23.7 107 | '@babel/helper-annotate-as-pure': 7.22.5 108 | '@babel/helper-environment-visitor': 7.22.20 109 | '@babel/helper-function-name': 7.23.0 110 | '@babel/helper-member-expression-to-functions': 7.23.0 111 | '@babel/helper-optimise-call-expression': 7.22.5 112 | '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.7) 113 | '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 114 | '@babel/helper-split-export-declaration': 7.22.6 115 | semver: 6.3.1 116 | dev: true 117 | 118 | /@babel/helper-environment-visitor@7.22.20: 119 | resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} 120 | engines: {node: '>=6.9.0'} 121 | dev: true 122 | 123 | /@babel/helper-function-name@7.23.0: 124 | resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} 125 | engines: {node: '>=6.9.0'} 126 | dependencies: 127 | '@babel/template': 7.22.15 128 | '@babel/types': 7.23.6 129 | dev: true 130 | 131 | /@babel/helper-hoist-variables@7.22.5: 132 | resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} 133 | engines: {node: '>=6.9.0'} 134 | dependencies: 135 | '@babel/types': 7.23.6 136 | dev: true 137 | 138 | /@babel/helper-member-expression-to-functions@7.23.0: 139 | resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} 140 | engines: {node: '>=6.9.0'} 141 | dependencies: 142 | '@babel/types': 7.23.6 143 | dev: true 144 | 145 | /@babel/helper-module-imports@7.18.6: 146 | resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} 147 | engines: {node: '>=6.9.0'} 148 | dependencies: 149 | '@babel/types': 7.22.5 150 | dev: true 151 | 152 | /@babel/helper-module-imports@7.22.15: 153 | resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} 154 | engines: {node: '>=6.9.0'} 155 | dependencies: 156 | '@babel/types': 7.23.6 157 | dev: true 158 | 159 | /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.7): 160 | resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} 161 | engines: {node: '>=6.9.0'} 162 | peerDependencies: 163 | '@babel/core': ^7.0.0 164 | dependencies: 165 | '@babel/core': 7.23.7 166 | '@babel/helper-environment-visitor': 7.22.20 167 | '@babel/helper-module-imports': 7.22.15 168 | '@babel/helper-simple-access': 7.22.5 169 | '@babel/helper-split-export-declaration': 7.22.6 170 | '@babel/helper-validator-identifier': 7.22.20 171 | dev: true 172 | 173 | /@babel/helper-optimise-call-expression@7.22.5: 174 | resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} 175 | engines: {node: '>=6.9.0'} 176 | dependencies: 177 | '@babel/types': 7.22.5 178 | dev: true 179 | 180 | /@babel/helper-plugin-utils@7.22.5: 181 | resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} 182 | engines: {node: '>=6.9.0'} 183 | dev: true 184 | 185 | /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.7): 186 | resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} 187 | engines: {node: '>=6.9.0'} 188 | peerDependencies: 189 | '@babel/core': ^7.0.0 190 | dependencies: 191 | '@babel/core': 7.23.7 192 | '@babel/helper-environment-visitor': 7.22.20 193 | '@babel/helper-member-expression-to-functions': 7.23.0 194 | '@babel/helper-optimise-call-expression': 7.22.5 195 | dev: true 196 | 197 | /@babel/helper-simple-access@7.22.5: 198 | resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} 199 | engines: {node: '>=6.9.0'} 200 | dependencies: 201 | '@babel/types': 7.22.5 202 | dev: true 203 | 204 | /@babel/helper-skip-transparent-expression-wrappers@7.22.5: 205 | resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} 206 | engines: {node: '>=6.9.0'} 207 | dependencies: 208 | '@babel/types': 7.22.5 209 | dev: true 210 | 211 | /@babel/helper-split-export-declaration@7.22.6: 212 | resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} 213 | engines: {node: '>=6.9.0'} 214 | dependencies: 215 | '@babel/types': 7.22.5 216 | dev: true 217 | 218 | /@babel/helper-string-parser@7.22.5: 219 | resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} 220 | engines: {node: '>=6.9.0'} 221 | dev: true 222 | 223 | /@babel/helper-string-parser@7.23.4: 224 | resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} 225 | engines: {node: '>=6.9.0'} 226 | dev: true 227 | 228 | /@babel/helper-validator-identifier@7.22.20: 229 | resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} 230 | engines: {node: '>=6.9.0'} 231 | dev: true 232 | 233 | /@babel/helper-validator-identifier@7.22.5: 234 | resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} 235 | engines: {node: '>=6.9.0'} 236 | dev: true 237 | 238 | /@babel/helper-validator-option@7.23.5: 239 | resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} 240 | engines: {node: '>=6.9.0'} 241 | dev: true 242 | 243 | /@babel/helpers@7.23.8: 244 | resolution: {integrity: sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==} 245 | engines: {node: '>=6.9.0'} 246 | dependencies: 247 | '@babel/template': 7.22.15 248 | '@babel/traverse': 7.23.7 249 | '@babel/types': 7.23.6 250 | transitivePeerDependencies: 251 | - supports-color 252 | dev: true 253 | 254 | /@babel/highlight@7.23.4: 255 | resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} 256 | engines: {node: '>=6.9.0'} 257 | dependencies: 258 | '@babel/helper-validator-identifier': 7.22.20 259 | chalk: 2.4.2 260 | js-tokens: 4.0.0 261 | dev: true 262 | 263 | /@babel/parser@7.22.5: 264 | resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==} 265 | engines: {node: '>=6.0.0'} 266 | hasBin: true 267 | dependencies: 268 | '@babel/types': 7.22.5 269 | dev: true 270 | 271 | /@babel/parser@7.23.6: 272 | resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} 273 | engines: {node: '>=6.0.0'} 274 | hasBin: true 275 | dependencies: 276 | '@babel/types': 7.23.6 277 | dev: true 278 | 279 | /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.7): 280 | resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} 281 | engines: {node: '>=6.9.0'} 282 | peerDependencies: 283 | '@babel/core': ^7.0.0-0 284 | dependencies: 285 | '@babel/core': 7.23.7 286 | '@babel/helper-plugin-utils': 7.22.5 287 | dev: true 288 | 289 | /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.7): 290 | resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} 291 | engines: {node: '>=6.9.0'} 292 | peerDependencies: 293 | '@babel/core': ^7.0.0-0 294 | dependencies: 295 | '@babel/core': 7.23.7 296 | '@babel/helper-plugin-utils': 7.22.5 297 | dev: true 298 | 299 | /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.7): 300 | resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} 301 | engines: {node: '>=6.9.0'} 302 | peerDependencies: 303 | '@babel/core': ^7.0.0-0 304 | dependencies: 305 | '@babel/core': 7.23.7 306 | '@babel/helper-plugin-utils': 7.22.5 307 | dev: true 308 | 309 | /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.7): 310 | resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} 311 | engines: {node: '>=6.9.0'} 312 | peerDependencies: 313 | '@babel/core': ^7.0.0-0 314 | dependencies: 315 | '@babel/core': 7.23.7 316 | '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) 317 | '@babel/helper-plugin-utils': 7.22.5 318 | '@babel/helper-simple-access': 7.22.5 319 | dev: true 320 | 321 | /@babel/plugin-transform-typescript@7.23.6(@babel/core@7.23.7): 322 | resolution: {integrity: sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==} 323 | engines: {node: '>=6.9.0'} 324 | peerDependencies: 325 | '@babel/core': ^7.0.0-0 326 | dependencies: 327 | '@babel/core': 7.23.7 328 | '@babel/helper-annotate-as-pure': 7.22.5 329 | '@babel/helper-create-class-features-plugin': 7.23.7(@babel/core@7.23.7) 330 | '@babel/helper-plugin-utils': 7.22.5 331 | '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.7) 332 | dev: true 333 | 334 | /@babel/preset-typescript@7.23.3(@babel/core@7.23.7): 335 | resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==} 336 | engines: {node: '>=6.9.0'} 337 | peerDependencies: 338 | '@babel/core': ^7.0.0-0 339 | dependencies: 340 | '@babel/core': 7.23.7 341 | '@babel/helper-plugin-utils': 7.22.5 342 | '@babel/helper-validator-option': 7.23.5 343 | '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.7) 344 | '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.7) 345 | '@babel/plugin-transform-typescript': 7.23.6(@babel/core@7.23.7) 346 | dev: true 347 | 348 | /@babel/template@7.22.15: 349 | resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} 350 | engines: {node: '>=6.9.0'} 351 | dependencies: 352 | '@babel/code-frame': 7.23.5 353 | '@babel/parser': 7.23.6 354 | '@babel/types': 7.23.6 355 | dev: true 356 | 357 | /@babel/traverse@7.23.7: 358 | resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} 359 | engines: {node: '>=6.9.0'} 360 | dependencies: 361 | '@babel/code-frame': 7.23.5 362 | '@babel/generator': 7.23.6 363 | '@babel/helper-environment-visitor': 7.22.20 364 | '@babel/helper-function-name': 7.23.0 365 | '@babel/helper-hoist-variables': 7.22.5 366 | '@babel/helper-split-export-declaration': 7.22.6 367 | '@babel/parser': 7.23.6 368 | '@babel/types': 7.23.6 369 | debug: 4.3.4 370 | globals: 11.12.0 371 | transitivePeerDependencies: 372 | - supports-color 373 | dev: true 374 | 375 | /@babel/types@7.22.5: 376 | resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} 377 | engines: {node: '>=6.9.0'} 378 | dependencies: 379 | '@babel/helper-string-parser': 7.22.5 380 | '@babel/helper-validator-identifier': 7.22.5 381 | to-fast-properties: 2.0.0 382 | dev: true 383 | 384 | /@babel/types@7.23.6: 385 | resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} 386 | engines: {node: '>=6.9.0'} 387 | dependencies: 388 | '@babel/helper-string-parser': 7.23.4 389 | '@babel/helper-validator-identifier': 7.22.20 390 | to-fast-properties: 2.0.0 391 | dev: true 392 | 393 | /@esbuild/aix-ppc64@0.19.11: 394 | resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} 395 | engines: {node: '>=12'} 396 | cpu: [ppc64] 397 | os: [aix] 398 | requiresBuild: true 399 | dev: true 400 | optional: true 401 | 402 | /@esbuild/android-arm64@0.19.11: 403 | resolution: {integrity: sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==} 404 | engines: {node: '>=12'} 405 | cpu: [arm64] 406 | os: [android] 407 | requiresBuild: true 408 | dev: true 409 | optional: true 410 | 411 | /@esbuild/android-arm@0.19.11: 412 | resolution: {integrity: sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==} 413 | engines: {node: '>=12'} 414 | cpu: [arm] 415 | os: [android] 416 | requiresBuild: true 417 | dev: true 418 | optional: true 419 | 420 | /@esbuild/android-x64@0.19.11: 421 | resolution: {integrity: sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==} 422 | engines: {node: '>=12'} 423 | cpu: [x64] 424 | os: [android] 425 | requiresBuild: true 426 | dev: true 427 | optional: true 428 | 429 | /@esbuild/darwin-arm64@0.19.11: 430 | resolution: {integrity: sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==} 431 | engines: {node: '>=12'} 432 | cpu: [arm64] 433 | os: [darwin] 434 | requiresBuild: true 435 | dev: true 436 | optional: true 437 | 438 | /@esbuild/darwin-x64@0.19.11: 439 | resolution: {integrity: sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==} 440 | engines: {node: '>=12'} 441 | cpu: [x64] 442 | os: [darwin] 443 | requiresBuild: true 444 | dev: true 445 | optional: true 446 | 447 | /@esbuild/freebsd-arm64@0.19.11: 448 | resolution: {integrity: sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==} 449 | engines: {node: '>=12'} 450 | cpu: [arm64] 451 | os: [freebsd] 452 | requiresBuild: true 453 | dev: true 454 | optional: true 455 | 456 | /@esbuild/freebsd-x64@0.19.11: 457 | resolution: {integrity: sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==} 458 | engines: {node: '>=12'} 459 | cpu: [x64] 460 | os: [freebsd] 461 | requiresBuild: true 462 | dev: true 463 | optional: true 464 | 465 | /@esbuild/linux-arm64@0.19.11: 466 | resolution: {integrity: sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==} 467 | engines: {node: '>=12'} 468 | cpu: [arm64] 469 | os: [linux] 470 | requiresBuild: true 471 | dev: true 472 | optional: true 473 | 474 | /@esbuild/linux-arm@0.19.11: 475 | resolution: {integrity: sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==} 476 | engines: {node: '>=12'} 477 | cpu: [arm] 478 | os: [linux] 479 | requiresBuild: true 480 | dev: true 481 | optional: true 482 | 483 | /@esbuild/linux-ia32@0.19.11: 484 | resolution: {integrity: sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==} 485 | engines: {node: '>=12'} 486 | cpu: [ia32] 487 | os: [linux] 488 | requiresBuild: true 489 | dev: true 490 | optional: true 491 | 492 | /@esbuild/linux-loong64@0.19.11: 493 | resolution: {integrity: sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==} 494 | engines: {node: '>=12'} 495 | cpu: [loong64] 496 | os: [linux] 497 | requiresBuild: true 498 | dev: true 499 | optional: true 500 | 501 | /@esbuild/linux-mips64el@0.19.11: 502 | resolution: {integrity: sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==} 503 | engines: {node: '>=12'} 504 | cpu: [mips64el] 505 | os: [linux] 506 | requiresBuild: true 507 | dev: true 508 | optional: true 509 | 510 | /@esbuild/linux-ppc64@0.19.11: 511 | resolution: {integrity: sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==} 512 | engines: {node: '>=12'} 513 | cpu: [ppc64] 514 | os: [linux] 515 | requiresBuild: true 516 | dev: true 517 | optional: true 518 | 519 | /@esbuild/linux-riscv64@0.19.11: 520 | resolution: {integrity: sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==} 521 | engines: {node: '>=12'} 522 | cpu: [riscv64] 523 | os: [linux] 524 | requiresBuild: true 525 | dev: true 526 | optional: true 527 | 528 | /@esbuild/linux-s390x@0.19.11: 529 | resolution: {integrity: sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==} 530 | engines: {node: '>=12'} 531 | cpu: [s390x] 532 | os: [linux] 533 | requiresBuild: true 534 | dev: true 535 | optional: true 536 | 537 | /@esbuild/linux-x64@0.19.11: 538 | resolution: {integrity: sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==} 539 | engines: {node: '>=12'} 540 | cpu: [x64] 541 | os: [linux] 542 | requiresBuild: true 543 | dev: true 544 | optional: true 545 | 546 | /@esbuild/netbsd-x64@0.19.11: 547 | resolution: {integrity: sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==} 548 | engines: {node: '>=12'} 549 | cpu: [x64] 550 | os: [netbsd] 551 | requiresBuild: true 552 | dev: true 553 | optional: true 554 | 555 | /@esbuild/openbsd-x64@0.19.11: 556 | resolution: {integrity: sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==} 557 | engines: {node: '>=12'} 558 | cpu: [x64] 559 | os: [openbsd] 560 | requiresBuild: true 561 | dev: true 562 | optional: true 563 | 564 | /@esbuild/sunos-x64@0.19.11: 565 | resolution: {integrity: sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==} 566 | engines: {node: '>=12'} 567 | cpu: [x64] 568 | os: [sunos] 569 | requiresBuild: true 570 | dev: true 571 | optional: true 572 | 573 | /@esbuild/win32-arm64@0.19.11: 574 | resolution: {integrity: sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==} 575 | engines: {node: '>=12'} 576 | cpu: [arm64] 577 | os: [win32] 578 | requiresBuild: true 579 | dev: true 580 | optional: true 581 | 582 | /@esbuild/win32-ia32@0.19.11: 583 | resolution: {integrity: sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==} 584 | engines: {node: '>=12'} 585 | cpu: [ia32] 586 | os: [win32] 587 | requiresBuild: true 588 | dev: true 589 | optional: true 590 | 591 | /@esbuild/win32-x64@0.19.11: 592 | resolution: {integrity: sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==} 593 | engines: {node: '>=12'} 594 | cpu: [x64] 595 | os: [win32] 596 | requiresBuild: true 597 | dev: true 598 | optional: true 599 | 600 | /@jridgewell/gen-mapping@0.3.3: 601 | resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} 602 | engines: {node: '>=6.0.0'} 603 | dependencies: 604 | '@jridgewell/set-array': 1.1.2 605 | '@jridgewell/sourcemap-codec': 1.4.15 606 | '@jridgewell/trace-mapping': 0.3.18 607 | dev: true 608 | 609 | /@jridgewell/resolve-uri@3.1.0: 610 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 611 | engines: {node: '>=6.0.0'} 612 | dev: true 613 | 614 | /@jridgewell/set-array@1.1.2: 615 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} 616 | engines: {node: '>=6.0.0'} 617 | dev: true 618 | 619 | /@jridgewell/sourcemap-codec@1.4.14: 620 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 621 | dev: true 622 | 623 | /@jridgewell/sourcemap-codec@1.4.15: 624 | resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} 625 | dev: true 626 | 627 | /@jridgewell/trace-mapping@0.3.18: 628 | resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} 629 | dependencies: 630 | '@jridgewell/resolve-uri': 3.1.0 631 | '@jridgewell/sourcemap-codec': 1.4.14 632 | dev: true 633 | 634 | /@nothing-but/utils@0.12.1: 635 | resolution: {integrity: sha512-1qZU1Q5El0IjE7JT/ucvJNzdr2hL3W8Rm27xNf1p6gb3Nw8pGnZmxp6/GEW9h+I1k1cICxXNq25hBwknTQ7yhg==} 636 | dev: true 637 | 638 | /@rollup/rollup-android-arm-eabi@4.9.5: 639 | resolution: {integrity: sha512-idWaG8xeSRCfRq9KpRysDHJ/rEHBEXcHuJ82XY0yYFIWnLMjZv9vF/7DOq8djQ2n3Lk6+3qfSH8AqlmHlmi1MA==} 640 | cpu: [arm] 641 | os: [android] 642 | requiresBuild: true 643 | dev: true 644 | optional: true 645 | 646 | /@rollup/rollup-android-arm64@4.9.5: 647 | resolution: {integrity: sha512-f14d7uhAMtsCGjAYwZGv6TwuS3IFaM4ZnGMUn3aCBgkcHAYErhV1Ad97WzBvS2o0aaDv4mVz+syiN0ElMyfBPg==} 648 | cpu: [arm64] 649 | os: [android] 650 | requiresBuild: true 651 | dev: true 652 | optional: true 653 | 654 | /@rollup/rollup-darwin-arm64@4.9.5: 655 | resolution: {integrity: sha512-ndoXeLx455FffL68OIUrVr89Xu1WLzAG4n65R8roDlCoYiQcGGg6MALvs2Ap9zs7AHg8mpHtMpwC8jBBjZrT/w==} 656 | cpu: [arm64] 657 | os: [darwin] 658 | requiresBuild: true 659 | dev: true 660 | optional: true 661 | 662 | /@rollup/rollup-darwin-x64@4.9.5: 663 | resolution: {integrity: sha512-UmElV1OY2m/1KEEqTlIjieKfVwRg0Zwg4PLgNf0s3glAHXBN99KLpw5A5lrSYCa1Kp63czTpVll2MAqbZYIHoA==} 664 | cpu: [x64] 665 | os: [darwin] 666 | requiresBuild: true 667 | dev: true 668 | optional: true 669 | 670 | /@rollup/rollup-linux-arm-gnueabihf@4.9.5: 671 | resolution: {integrity: sha512-Q0LcU61v92tQB6ae+udZvOyZ0wfpGojtAKrrpAaIqmJ7+psq4cMIhT/9lfV6UQIpeItnq/2QDROhNLo00lOD1g==} 672 | cpu: [arm] 673 | os: [linux] 674 | requiresBuild: true 675 | dev: true 676 | optional: true 677 | 678 | /@rollup/rollup-linux-arm64-gnu@4.9.5: 679 | resolution: {integrity: sha512-dkRscpM+RrR2Ee3eOQmRWFjmV/payHEOrjyq1VZegRUa5OrZJ2MAxBNs05bZuY0YCtpqETDy1Ix4i/hRqX98cA==} 680 | cpu: [arm64] 681 | os: [linux] 682 | requiresBuild: true 683 | dev: true 684 | optional: true 685 | 686 | /@rollup/rollup-linux-arm64-musl@4.9.5: 687 | resolution: {integrity: sha512-QaKFVOzzST2xzY4MAmiDmURagWLFh+zZtttuEnuNn19AiZ0T3fhPyjPPGwLNdiDT82ZE91hnfJsUiDwF9DClIQ==} 688 | cpu: [arm64] 689 | os: [linux] 690 | requiresBuild: true 691 | dev: true 692 | optional: true 693 | 694 | /@rollup/rollup-linux-riscv64-gnu@4.9.5: 695 | resolution: {integrity: sha512-HeGqmRJuyVg6/X6MpE2ur7GbymBPS8Np0S/vQFHDmocfORT+Zt76qu+69NUoxXzGqVP1pzaY6QIi0FJWLC3OPA==} 696 | cpu: [riscv64] 697 | os: [linux] 698 | requiresBuild: true 699 | dev: true 700 | optional: true 701 | 702 | /@rollup/rollup-linux-x64-gnu@4.9.5: 703 | resolution: {integrity: sha512-Dq1bqBdLaZ1Gb/l2e5/+o3B18+8TI9ANlA1SkejZqDgdU/jK/ThYaMPMJpVMMXy2uRHvGKbkz9vheVGdq3cJfA==} 704 | cpu: [x64] 705 | os: [linux] 706 | requiresBuild: true 707 | dev: true 708 | optional: true 709 | 710 | /@rollup/rollup-linux-x64-musl@4.9.5: 711 | resolution: {integrity: sha512-ezyFUOwldYpj7AbkwyW9AJ203peub81CaAIVvckdkyH8EvhEIoKzaMFJj0G4qYJ5sw3BpqhFrsCc30t54HV8vg==} 712 | cpu: [x64] 713 | os: [linux] 714 | requiresBuild: true 715 | dev: true 716 | optional: true 717 | 718 | /@rollup/rollup-win32-arm64-msvc@4.9.5: 719 | resolution: {integrity: sha512-aHSsMnUw+0UETB0Hlv7B/ZHOGY5bQdwMKJSzGfDfvyhnpmVxLMGnQPGNE9wgqkLUs3+gbG1Qx02S2LLfJ5GaRQ==} 720 | cpu: [arm64] 721 | os: [win32] 722 | requiresBuild: true 723 | dev: true 724 | optional: true 725 | 726 | /@rollup/rollup-win32-ia32-msvc@4.9.5: 727 | resolution: {integrity: sha512-AiqiLkb9KSf7Lj/o1U3SEP9Zn+5NuVKgFdRIZkvd4N0+bYrTOovVd0+LmYCPQGbocT4kvFyK+LXCDiXPBF3fyA==} 728 | cpu: [ia32] 729 | os: [win32] 730 | requiresBuild: true 731 | dev: true 732 | optional: true 733 | 734 | /@rollup/rollup-win32-x64-msvc@4.9.5: 735 | resolution: {integrity: sha512-1q+mykKE3Vot1kaFJIDoUFv5TuW+QQVaf2FmTT9krg86pQrGStOSJJ0Zil7CFagyxDuouTepzt5Y5TVzyajOdQ==} 736 | cpu: [x64] 737 | os: [win32] 738 | requiresBuild: true 739 | dev: true 740 | optional: true 741 | 742 | /@solid-devtools/debugger@0.23.3(solid-js@1.8.11): 743 | resolution: {integrity: sha512-VrgswTjb2FyHxQJp5y5u7OaJ2k1R14LYlAOX/1rDZrGHWKdGYCaWHGzxI7C8AExtMP+LS+WOxy0uXMPQpoAD2g==} 744 | peerDependencies: 745 | solid-js: ^1.8.0 746 | dependencies: 747 | '@nothing-but/utils': 0.12.1 748 | '@solid-devtools/shared': 0.13.1(solid-js@1.8.11) 749 | '@solid-primitives/bounds': 0.0.118(solid-js@1.8.11) 750 | '@solid-primitives/cursor': 0.0.112(solid-js@1.8.11) 751 | '@solid-primitives/event-bus': 1.0.9(solid-js@1.8.11) 752 | '@solid-primitives/event-listener': 2.3.1(solid-js@1.8.11) 753 | '@solid-primitives/keyboard': 1.2.6(solid-js@1.8.11) 754 | '@solid-primitives/platform': 0.1.1(solid-js@1.8.11) 755 | '@solid-primitives/rootless': 1.4.3(solid-js@1.8.11) 756 | '@solid-primitives/scheduled': 1.4.2(solid-js@1.8.11) 757 | '@solid-primitives/static-store': 0.0.5(solid-js@1.8.11) 758 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 759 | solid-js: 1.8.11 760 | dev: true 761 | 762 | /@solid-devtools/shared@0.13.1(solid-js@1.8.11): 763 | resolution: {integrity: sha512-qaAcZF47FFr4alVQSy5ooLy7mMt4MMDxSHw52heY1oCut8yfXDrnLcYDONabfoin2WYIwsQpjYhryHgjtB0uDg==} 764 | peerDependencies: 765 | solid-js: ^1.8.0 766 | dependencies: 767 | '@solid-primitives/event-bus': 1.0.9(solid-js@1.8.11) 768 | '@solid-primitives/event-listener': 2.3.1(solid-js@1.8.11) 769 | '@solid-primitives/media': 2.2.6(solid-js@1.8.11) 770 | '@solid-primitives/refs': 1.0.6(solid-js@1.8.11) 771 | '@solid-primitives/rootless': 1.4.3(solid-js@1.8.11) 772 | '@solid-primitives/scheduled': 1.4.2(solid-js@1.8.11) 773 | '@solid-primitives/static-store': 0.0.5(solid-js@1.8.11) 774 | '@solid-primitives/styles': 0.0.111(solid-js@1.8.11) 775 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 776 | solid-js: 1.8.11 777 | dev: true 778 | 779 | /@solid-primitives/bounds@0.0.118(solid-js@1.8.11): 780 | resolution: {integrity: sha512-Qj42w8LlnhJ3r/t+t0c0vrdwIvvQMPgjEFGmLiwREaA85ojLbgL9lSBq2tKvljeLCvRVkgj10KEUf+vc99VCIg==} 781 | peerDependencies: 782 | solid-js: ^1.6.12 783 | dependencies: 784 | '@solid-primitives/event-listener': 2.3.1(solid-js@1.8.11) 785 | '@solid-primitives/resize-observer': 2.0.23(solid-js@1.8.11) 786 | '@solid-primitives/static-store': 0.0.5(solid-js@1.8.11) 787 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 788 | solid-js: 1.8.11 789 | dev: true 790 | 791 | /@solid-primitives/cursor@0.0.112(solid-js@1.8.11): 792 | resolution: {integrity: sha512-TAtU7qD7ipSLSXHnq8FhhosAPVX+dnOCb/ITcGcLlj8e/C9YKcxDhgBHJ3R/d1xDRb5/vO/szJtEz6fnQD311Q==} 793 | peerDependencies: 794 | solid-js: ^1.6.12 795 | dependencies: 796 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 797 | solid-js: 1.8.11 798 | dev: true 799 | 800 | /@solid-primitives/event-bus@1.0.9(solid-js@1.8.11): 801 | resolution: {integrity: sha512-BI9dla3GQzINsufEzr/CV3B/9e0D1pyk7Ig6kPI6s4geUkiVgFadY5V8R95PEeHH1NagOny7AHpw+RaRIuBpkA==} 802 | peerDependencies: 803 | solid-js: ^1.6.12 804 | dependencies: 805 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 806 | solid-js: 1.8.11 807 | dev: true 808 | 809 | /@solid-primitives/event-listener@2.3.1(solid-js@1.8.11): 810 | resolution: {integrity: sha512-S1AfFYatOJ3g/ZUbGDoKplSGLTTfarQ3Mfd3F/fXb9SnzGtROtd+Y6yLkPVzK4AVw83r2wUSaS0GS6dg8izTEQ==} 811 | peerDependencies: 812 | solid-js: ^1.6.12 813 | dependencies: 814 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 815 | solid-js: 1.8.11 816 | dev: true 817 | 818 | /@solid-primitives/keyboard@1.2.6(solid-js@1.8.11): 819 | resolution: {integrity: sha512-ZbXkzAwFs+6hyaZ2hT9uQ38iPZzGTjV6kWvVvJ3BDfKASg0dDDuhEZRKmpkmpLfnqOabV58BUkASJWMAA4dZCg==} 820 | peerDependencies: 821 | solid-js: ^1.6.12 822 | dependencies: 823 | '@solid-primitives/event-listener': 2.3.1(solid-js@1.8.11) 824 | '@solid-primitives/rootless': 1.4.3(solid-js@1.8.11) 825 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 826 | solid-js: 1.8.11 827 | dev: true 828 | 829 | /@solid-primitives/media@2.2.6(solid-js@1.8.11): 830 | resolution: {integrity: sha512-VopOSqoUZgmSFY4SNnwBzHYaoGG+7gQYcwX+RJ/qQtuZJgzOiC+PejZEwNJh+aBZ383HPwrypyd3zrYVm7EnpQ==} 831 | peerDependencies: 832 | solid-js: ^1.6.12 833 | dependencies: 834 | '@solid-primitives/event-listener': 2.3.1(solid-js@1.8.11) 835 | '@solid-primitives/rootless': 1.4.3(solid-js@1.8.11) 836 | '@solid-primitives/static-store': 0.0.6(solid-js@1.8.11) 837 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 838 | solid-js: 1.8.11 839 | dev: true 840 | 841 | /@solid-primitives/platform@0.1.1(solid-js@1.8.11): 842 | resolution: {integrity: sha512-Ln7dzHFjNDpjmhnKiMAUWBjObRZ01FQtj4ABkSmE51VjLI0i9JW54lbZhJImYjpCyoBjtxBEGWsCgYi9JyRXrA==} 843 | peerDependencies: 844 | solid-js: ^1.6.12 845 | dependencies: 846 | solid-js: 1.8.11 847 | dev: true 848 | 849 | /@solid-primitives/refs@1.0.6(solid-js@1.8.11): 850 | resolution: {integrity: sha512-ruh4YdVMxThEVnvqbpeLXKojW442vpFU8q7dSKtElGOTa31aKOAkRb9BTbdaTwVjN4BEq79fiiYIXozJNl4dSw==} 851 | peerDependencies: 852 | solid-js: ^1.6.12 853 | dependencies: 854 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 855 | solid-js: 1.8.11 856 | dev: true 857 | 858 | /@solid-primitives/resize-observer@2.0.23(solid-js@1.8.11): 859 | resolution: {integrity: sha512-SgKRzRfy1oFbPSapmtF5H9VQcN66foQaQK3QTyzh4cihIG2k/UiVNjbC+el1nEDnSeAP7zTO4Xsf2UW8dc+aBw==} 860 | peerDependencies: 861 | solid-js: ^1.6.12 862 | dependencies: 863 | '@solid-primitives/event-listener': 2.3.1(solid-js@1.8.11) 864 | '@solid-primitives/rootless': 1.4.3(solid-js@1.8.11) 865 | '@solid-primitives/static-store': 0.0.6(solid-js@1.8.11) 866 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 867 | solid-js: 1.8.11 868 | dev: true 869 | 870 | /@solid-primitives/rootless@1.4.3(solid-js@1.8.11): 871 | resolution: {integrity: sha512-IPsfUhKsqQOxLtRMQWK2EZAYbL9RKJMLBelLwpaXl9+oa1tl5aNvA6GHgrNrK+85oUhiYh7/OuogO18AuHepqQ==} 872 | peerDependencies: 873 | solid-js: ^1.6.12 874 | dependencies: 875 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 876 | solid-js: 1.8.11 877 | dev: true 878 | 879 | /@solid-primitives/scheduled@1.4.2(solid-js@1.8.11): 880 | resolution: {integrity: sha512-duKaugDQtPk0v6MnkBuEalWk66/vA2G7zzoimQEvmUdh2+K2o8t908HIfI2NdBfwakQMQBV4epE3TFeN2Vsveg==} 881 | peerDependencies: 882 | solid-js: ^1.6.12 883 | dependencies: 884 | solid-js: 1.8.11 885 | dev: true 886 | 887 | /@solid-primitives/static-store@0.0.5(solid-js@1.8.11): 888 | resolution: {integrity: sha512-ssQ+s/wrlFAEE4Zw8GV499yBfvWx7SMm+ZVc11wvao4T5xg9VfXCL9Oa+x4h+vPMvSV/Knv5LrsLiUa+wlJUXQ==} 889 | peerDependencies: 890 | solid-js: ^1.6.12 891 | dependencies: 892 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 893 | solid-js: 1.8.11 894 | dev: true 895 | 896 | /@solid-primitives/static-store@0.0.6(solid-js@1.8.11): 897 | resolution: {integrity: sha512-PtvkbbucbjT+9p95pksOciG9gOnCtJz4IUyAKX1Ld7YwI+QgtPTo0Wuxs8gNbNtLtoDv5PNv5t4YRzUyl0fwdg==} 898 | peerDependencies: 899 | solid-js: ^1.6.12 900 | dependencies: 901 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 902 | solid-js: 1.8.11 903 | dev: true 904 | 905 | /@solid-primitives/styles@0.0.111(solid-js@1.8.11): 906 | resolution: {integrity: sha512-1mBxOGAPXmfD5oYCvqjKBDN7SuNjz2qz7RdH7KtsuNLQh6lpuSKadtHnLvru0Y8Vz1InqTJisBIy/6P5kyDmPw==} 907 | peerDependencies: 908 | solid-js: ^1.6.12 909 | dependencies: 910 | '@solid-primitives/rootless': 1.4.3(solid-js@1.8.11) 911 | '@solid-primitives/utils': 6.2.2(solid-js@1.8.11) 912 | solid-js: 1.8.11 913 | dev: true 914 | 915 | /@solid-primitives/utils@6.2.2(solid-js@1.8.11): 916 | resolution: {integrity: sha512-11ypVbp987XxETeRqY5Y3OmmTpm8/jZqJXRvo6AyqBthzkvvjEdReuUMU2yVb+pwWGxfZpWHZ6EUCcGXUMhfwg==} 917 | peerDependencies: 918 | solid-js: ^1.6.12 919 | dependencies: 920 | solid-js: 1.8.11 921 | dev: true 922 | 923 | /@types/babel__core@7.20.5: 924 | resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} 925 | dependencies: 926 | '@babel/parser': 7.22.5 927 | '@babel/types': 7.22.5 928 | '@types/babel__generator': 7.6.4 929 | '@types/babel__template': 7.4.1 930 | '@types/babel__traverse': 7.20.1 931 | dev: true 932 | 933 | /@types/babel__generator@7.6.4: 934 | resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} 935 | dependencies: 936 | '@babel/types': 7.22.5 937 | dev: true 938 | 939 | /@types/babel__template@7.4.1: 940 | resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} 941 | dependencies: 942 | '@babel/parser': 7.22.5 943 | '@babel/types': 7.22.5 944 | dev: true 945 | 946 | /@types/babel__traverse@7.20.1: 947 | resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==} 948 | dependencies: 949 | '@babel/types': 7.22.5 950 | dev: true 951 | 952 | /@types/estree@1.0.5: 953 | resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} 954 | dev: true 955 | 956 | /ansi-styles@3.2.1: 957 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 958 | engines: {node: '>=4'} 959 | dependencies: 960 | color-convert: 1.9.3 961 | dev: true 962 | 963 | /babel-plugin-jsx-dom-expressions@0.37.13(@babel/core@7.23.7): 964 | resolution: {integrity: sha512-oAEMMIgU0h1DmHn4ZDaBBFc08nsVJciLq9pF7g0ZdpeIDKfY4zXjXr8+/oBjKhXG8nyomhnTodPjeG+/ZXcWXQ==} 965 | peerDependencies: 966 | '@babel/core': ^7.20.12 967 | dependencies: 968 | '@babel/core': 7.23.7 969 | '@babel/helper-module-imports': 7.18.6 970 | '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.7) 971 | '@babel/types': 7.22.5 972 | html-entities: 2.3.3 973 | validate-html-nesting: 1.2.2 974 | dev: true 975 | 976 | /babel-preset-solid@1.8.9(@babel/core@7.23.7): 977 | resolution: {integrity: sha512-1awR1QCoryXtAdnjsrx/eVBTYz+tpHUDOdBXqG9oVV7S0ojf2MV/woR0+8BG+LMXVzIr60oKYzCZ9UZGafxmpg==} 978 | peerDependencies: 979 | '@babel/core': ^7.0.0 980 | dependencies: 981 | '@babel/core': 7.23.7 982 | babel-plugin-jsx-dom-expressions: 0.37.13(@babel/core@7.23.7) 983 | dev: true 984 | 985 | /browserslist@4.22.2: 986 | resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} 987 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 988 | hasBin: true 989 | dependencies: 990 | caniuse-lite: 1.0.30001579 991 | electron-to-chromium: 1.4.639 992 | node-releases: 2.0.14 993 | update-browserslist-db: 1.0.13(browserslist@4.22.2) 994 | dev: true 995 | 996 | /caniuse-lite@1.0.30001579: 997 | resolution: {integrity: sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==} 998 | dev: true 999 | 1000 | /chalk@2.4.2: 1001 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 1002 | engines: {node: '>=4'} 1003 | dependencies: 1004 | ansi-styles: 3.2.1 1005 | escape-string-regexp: 1.0.5 1006 | supports-color: 5.5.0 1007 | dev: true 1008 | 1009 | /color-convert@1.9.3: 1010 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 1011 | dependencies: 1012 | color-name: 1.1.3 1013 | dev: true 1014 | 1015 | /color-name@1.1.3: 1016 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 1017 | dev: true 1018 | 1019 | /convert-source-map@2.0.0: 1020 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} 1021 | dev: true 1022 | 1023 | /csstype@3.1.2: 1024 | resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} 1025 | 1026 | /debug@4.3.4: 1027 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 1028 | engines: {node: '>=6.0'} 1029 | peerDependencies: 1030 | supports-color: '*' 1031 | peerDependenciesMeta: 1032 | supports-color: 1033 | optional: true 1034 | dependencies: 1035 | ms: 2.1.2 1036 | dev: true 1037 | 1038 | /electron-to-chromium@1.4.639: 1039 | resolution: {integrity: sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==} 1040 | dev: true 1041 | 1042 | /esbuild@0.19.11: 1043 | resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==} 1044 | engines: {node: '>=12'} 1045 | hasBin: true 1046 | requiresBuild: true 1047 | optionalDependencies: 1048 | '@esbuild/aix-ppc64': 0.19.11 1049 | '@esbuild/android-arm': 0.19.11 1050 | '@esbuild/android-arm64': 0.19.11 1051 | '@esbuild/android-x64': 0.19.11 1052 | '@esbuild/darwin-arm64': 0.19.11 1053 | '@esbuild/darwin-x64': 0.19.11 1054 | '@esbuild/freebsd-arm64': 0.19.11 1055 | '@esbuild/freebsd-x64': 0.19.11 1056 | '@esbuild/linux-arm': 0.19.11 1057 | '@esbuild/linux-arm64': 0.19.11 1058 | '@esbuild/linux-ia32': 0.19.11 1059 | '@esbuild/linux-loong64': 0.19.11 1060 | '@esbuild/linux-mips64el': 0.19.11 1061 | '@esbuild/linux-ppc64': 0.19.11 1062 | '@esbuild/linux-riscv64': 0.19.11 1063 | '@esbuild/linux-s390x': 0.19.11 1064 | '@esbuild/linux-x64': 0.19.11 1065 | '@esbuild/netbsd-x64': 0.19.11 1066 | '@esbuild/openbsd-x64': 0.19.11 1067 | '@esbuild/sunos-x64': 0.19.11 1068 | '@esbuild/win32-arm64': 0.19.11 1069 | '@esbuild/win32-ia32': 0.19.11 1070 | '@esbuild/win32-x64': 0.19.11 1071 | dev: true 1072 | 1073 | /escalade@3.1.1: 1074 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 1075 | engines: {node: '>=6'} 1076 | dev: true 1077 | 1078 | /escape-string-regexp@1.0.5: 1079 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 1080 | engines: {node: '>=0.8.0'} 1081 | dev: true 1082 | 1083 | /fsevents@2.3.3: 1084 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 1085 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1086 | os: [darwin] 1087 | requiresBuild: true 1088 | dev: true 1089 | optional: true 1090 | 1091 | /gensync@1.0.0-beta.2: 1092 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 1093 | engines: {node: '>=6.9.0'} 1094 | dev: true 1095 | 1096 | /globals@11.12.0: 1097 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 1098 | engines: {node: '>=4'} 1099 | dev: true 1100 | 1101 | /has-flag@3.0.0: 1102 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 1103 | engines: {node: '>=4'} 1104 | dev: true 1105 | 1106 | /html-entities@2.3.3: 1107 | resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} 1108 | dev: true 1109 | 1110 | /is-what@4.1.15: 1111 | resolution: {integrity: sha512-uKua1wfy3Yt+YqsD6mTUEa2zSi3G1oPlqTflgaPJ7z63vUGN5pxFpnQfeSLMFnJDEsdvOtkp1rUWkYjB4YfhgA==} 1112 | engines: {node: '>=12.13'} 1113 | dev: true 1114 | 1115 | /js-tokens@4.0.0: 1116 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1117 | dev: true 1118 | 1119 | /jsesc@2.5.2: 1120 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} 1121 | engines: {node: '>=4'} 1122 | hasBin: true 1123 | dev: true 1124 | 1125 | /json5@2.2.3: 1126 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} 1127 | engines: {node: '>=6'} 1128 | hasBin: true 1129 | dev: true 1130 | 1131 | /lru-cache@5.1.1: 1132 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} 1133 | dependencies: 1134 | yallist: 3.1.1 1135 | dev: true 1136 | 1137 | /merge-anything@5.1.7: 1138 | resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} 1139 | engines: {node: '>=12.13'} 1140 | dependencies: 1141 | is-what: 4.1.15 1142 | dev: true 1143 | 1144 | /ms@2.1.2: 1145 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1146 | dev: true 1147 | 1148 | /nanoid@3.3.7: 1149 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 1150 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1151 | hasBin: true 1152 | dev: true 1153 | 1154 | /node-releases@2.0.14: 1155 | resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} 1156 | dev: true 1157 | 1158 | /picocolors@1.0.0: 1159 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 1160 | dev: true 1161 | 1162 | /postcss@8.4.33: 1163 | resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} 1164 | engines: {node: ^10 || ^12 || >=14} 1165 | dependencies: 1166 | nanoid: 3.3.7 1167 | picocolors: 1.0.0 1168 | source-map-js: 1.0.2 1169 | dev: true 1170 | 1171 | /rollup@4.9.5: 1172 | resolution: {integrity: sha512-E4vQW0H/mbNMw2yLSqJyjtkHY9dslf/p0zuT1xehNRqUTBOFMqEjguDvqhXr7N7r/4ttb2jr4T41d3dncmIgbQ==} 1173 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1174 | hasBin: true 1175 | dependencies: 1176 | '@types/estree': 1.0.5 1177 | optionalDependencies: 1178 | '@rollup/rollup-android-arm-eabi': 4.9.5 1179 | '@rollup/rollup-android-arm64': 4.9.5 1180 | '@rollup/rollup-darwin-arm64': 4.9.5 1181 | '@rollup/rollup-darwin-x64': 4.9.5 1182 | '@rollup/rollup-linux-arm-gnueabihf': 4.9.5 1183 | '@rollup/rollup-linux-arm64-gnu': 4.9.5 1184 | '@rollup/rollup-linux-arm64-musl': 4.9.5 1185 | '@rollup/rollup-linux-riscv64-gnu': 4.9.5 1186 | '@rollup/rollup-linux-x64-gnu': 4.9.5 1187 | '@rollup/rollup-linux-x64-musl': 4.9.5 1188 | '@rollup/rollup-win32-arm64-msvc': 4.9.5 1189 | '@rollup/rollup-win32-ia32-msvc': 4.9.5 1190 | '@rollup/rollup-win32-x64-msvc': 4.9.5 1191 | fsevents: 2.3.3 1192 | dev: true 1193 | 1194 | /semver@6.3.1: 1195 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} 1196 | hasBin: true 1197 | dev: true 1198 | 1199 | /seroval-plugins@1.0.4(seroval@1.0.4): 1200 | resolution: {integrity: sha512-DQ2IK6oQVvy8k+c2V5x5YCtUa/GGGsUwUBNN9UqohrZ0rWdUapBFpNMYP1bCyRHoxOJjdKGl+dieacFIpU/i1A==} 1201 | engines: {node: '>=10'} 1202 | peerDependencies: 1203 | seroval: ^1.0 1204 | dependencies: 1205 | seroval: 1.0.4 1206 | 1207 | /seroval@1.0.4: 1208 | resolution: {integrity: sha512-qQs/N+KfJu83rmszFQaTxcoJoPn6KNUruX4KmnmyD0oZkUoiNvJ1rpdYKDf4YHM05k+HOgCxa3yvf15QbVijGg==} 1209 | engines: {node: '>=10'} 1210 | 1211 | /solid-devtools@0.29.2(solid-js@1.8.11)(vite@5.0.11): 1212 | resolution: {integrity: sha512-sfGLBSIQ3E5dFha5UCE5wKnz+War99JNAOggfBbwhltXL8lbIG1PnKKB9N2pvloZuFzMtT/u1Qbb/ubqXnw2Sg==} 1213 | peerDependencies: 1214 | solid-js: ^1.8.0 1215 | solid-start: ^0.3.0 1216 | vite: ^2.2.3 || ^3.0.0 || ^4.0.0 1217 | peerDependenciesMeta: 1218 | solid-start: 1219 | optional: true 1220 | vite: 1221 | optional: true 1222 | dependencies: 1223 | '@babel/core': 7.23.7 1224 | '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.7) 1225 | '@babel/types': 7.23.6 1226 | '@solid-devtools/debugger': 0.23.3(solid-js@1.8.11) 1227 | '@solid-devtools/shared': 0.13.1(solid-js@1.8.11) 1228 | solid-js: 1.8.11 1229 | vite: 5.0.11 1230 | transitivePeerDependencies: 1231 | - supports-color 1232 | dev: true 1233 | 1234 | /solid-js@1.8.11: 1235 | resolution: {integrity: sha512-WdwmER+TwBJiN4rVQTVBxocg+9pKlOs41KzPYntrC86xO5sek8TzBYozPEZPL1IRWDouf2lMrvSbIs3CanlPvQ==} 1236 | dependencies: 1237 | csstype: 3.1.2 1238 | seroval: 1.0.4 1239 | seroval-plugins: 1.0.4(seroval@1.0.4) 1240 | 1241 | /solid-refresh@0.6.3(solid-js@1.8.11): 1242 | resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} 1243 | peerDependencies: 1244 | solid-js: ^1.3 1245 | dependencies: 1246 | '@babel/generator': 7.23.6 1247 | '@babel/helper-module-imports': 7.22.15 1248 | '@babel/types': 7.23.6 1249 | solid-js: 1.8.11 1250 | dev: true 1251 | 1252 | /source-map-js@1.0.2: 1253 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 1254 | engines: {node: '>=0.10.0'} 1255 | dev: true 1256 | 1257 | /supports-color@5.5.0: 1258 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 1259 | engines: {node: '>=4'} 1260 | dependencies: 1261 | has-flag: 3.0.0 1262 | dev: true 1263 | 1264 | /to-fast-properties@2.0.0: 1265 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 1266 | engines: {node: '>=4'} 1267 | dev: true 1268 | 1269 | /typescript@5.3.3: 1270 | resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} 1271 | engines: {node: '>=14.17'} 1272 | hasBin: true 1273 | dev: true 1274 | 1275 | /update-browserslist-db@1.0.13(browserslist@4.22.2): 1276 | resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} 1277 | hasBin: true 1278 | peerDependencies: 1279 | browserslist: '>= 4.21.0' 1280 | dependencies: 1281 | browserslist: 4.22.2 1282 | escalade: 3.1.1 1283 | picocolors: 1.0.0 1284 | dev: true 1285 | 1286 | /validate-html-nesting@1.2.2: 1287 | resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==} 1288 | dev: true 1289 | 1290 | /vite-plugin-solid@2.8.2(solid-js@1.8.11)(vite@5.0.11): 1291 | resolution: {integrity: sha512-HcvMs6DTxBaO4kE3psnirPQBCUUdYeQkCNKuB2TpEkJsxb6BGP6/7qkbbCSMxn25PyNdjvzVi1WXi0ou8KPgHw==} 1292 | peerDependencies: 1293 | solid-js: ^1.7.2 1294 | vite: ^3.0.0 || ^4.0.0 || ^5.0.0 1295 | dependencies: 1296 | '@babel/core': 7.23.7 1297 | '@babel/preset-typescript': 7.23.3(@babel/core@7.23.7) 1298 | '@types/babel__core': 7.20.5 1299 | babel-preset-solid: 1.8.9(@babel/core@7.23.7) 1300 | merge-anything: 5.1.7 1301 | solid-js: 1.8.11 1302 | solid-refresh: 0.6.3(solid-js@1.8.11) 1303 | vite: 5.0.11 1304 | vitefu: 0.2.5(vite@5.0.11) 1305 | transitivePeerDependencies: 1306 | - supports-color 1307 | dev: true 1308 | 1309 | /vite@5.0.11: 1310 | resolution: {integrity: sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==} 1311 | engines: {node: ^18.0.0 || >=20.0.0} 1312 | hasBin: true 1313 | peerDependencies: 1314 | '@types/node': ^18.0.0 || >=20.0.0 1315 | less: '*' 1316 | lightningcss: ^1.21.0 1317 | sass: '*' 1318 | stylus: '*' 1319 | sugarss: '*' 1320 | terser: ^5.4.0 1321 | peerDependenciesMeta: 1322 | '@types/node': 1323 | optional: true 1324 | less: 1325 | optional: true 1326 | lightningcss: 1327 | optional: true 1328 | sass: 1329 | optional: true 1330 | stylus: 1331 | optional: true 1332 | sugarss: 1333 | optional: true 1334 | terser: 1335 | optional: true 1336 | dependencies: 1337 | esbuild: 0.19.11 1338 | postcss: 8.4.33 1339 | rollup: 4.9.5 1340 | optionalDependencies: 1341 | fsevents: 2.3.3 1342 | dev: true 1343 | 1344 | /vitefu@0.2.5(vite@5.0.11): 1345 | resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} 1346 | peerDependencies: 1347 | vite: ^3.0.0 || ^4.0.0 || ^5.0.0 1348 | peerDependenciesMeta: 1349 | vite: 1350 | optional: true 1351 | dependencies: 1352 | vite: 5.0.11 1353 | dev: true 1354 | 1355 | /yallist@3.1.1: 1356 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} 1357 | dev: true 1358 | -------------------------------------------------------------------------------- /ui/web/src/App.module.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .logo { 6 | animation: logo-spin infinite 20s linear; 7 | height: 40vmin; 8 | pointer-events: none; 9 | } 10 | 11 | .header { 12 | background-color: #282c34; 13 | min-height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-size: calc(10px + 2vmin); 19 | color: white; 20 | } 21 | 22 | .link { 23 | color: #b318f0; 24 | } 25 | 26 | @keyframes logo-spin { 27 | from { 28 | transform: rotate(0deg); 29 | } 30 | to { 31 | transform: rotate(360deg); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ui/web/src/App.tsx: -------------------------------------------------------------------------------- 1 | import type { Component } from "solid-js"; 2 | 3 | import logo from "./logo.svg"; 4 | import styles from "./App.module.css"; 5 | 6 | const App: Component = () => { 7 | return ( 8 |
9 |
10 | logo 11 |

12 | Edit src/App.tsx and save to reload. 13 |

14 | 20 | Learn Solid 21 | 22 |
23 |
24 | ); 25 | }; 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /ui/web/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lightning-js/solid-demo-app/8a0dc4f40eeb4adaa1bb159a700aff15638434b1/ui/web/src/assets/favicon.ico -------------------------------------------------------------------------------- /ui/web/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /ui/web/src/index.tsx: -------------------------------------------------------------------------------- 1 | /* @refresh reload */ 2 | import { render } from "solid-js/web"; 3 | 4 | import "./index.css"; 5 | import App from "./App"; 6 | 7 | const root = document.getElementById("root"); 8 | 9 | if (import.meta.env.DEV && !(root instanceof HTMLElement)) { 10 | throw new Error( 11 | "Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?", 12 | ); 13 | } 14 | 15 | render(() => , root!); 16 | -------------------------------------------------------------------------------- /ui/web/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ui/web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "jsxImportSource": "solid-js", 11 | "types": ["vite/client"], 12 | "noEmit": true, 13 | "isolatedModules": true, 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /ui/web/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import solidPlugin from "vite-plugin-solid"; 3 | import legacy from "@vitejs/plugin-legacy"; 4 | 5 | export default defineConfig({ 6 | plugins: [ 7 | solidPlugin(), 8 | legacy({ 9 | targets: ["defaults", "not IE 11"], 10 | }), 11 | ], 12 | server: { 13 | port: 5173, 14 | hmr: false, 15 | headers: { 16 | "Cross-Origin-Opener-Policy": "same-origin", 17 | "Cross-Origin-Embedder-Policy": "require-corp", 18 | }, 19 | }, 20 | }); 21 | --------------------------------------------------------------------------------