├── .editorconfig ├── .gitignore ├── .node-version ├── .prettierrc ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── angular ├── .browserslistrc ├── .gitignore ├── README.md ├── angular.json ├── package.json ├── src │ ├── app │ │ ├── app.component.css │ │ ├── app.component.html │ │ ├── app.component.ts │ │ ├── app.module.ts │ │ └── components │ │ │ ├── item │ │ │ ├── item.component.css │ │ │ ├── item.component.html │ │ │ └── item.component.ts │ │ │ └── search-box │ │ │ ├── search-box.component.css │ │ │ ├── search-box.component.html │ │ │ └── search-box.component.ts │ ├── assets │ │ └── .gitkeep │ ├── data │ ├── environments │ │ ├── environment.prod.ts │ │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ └── test.ts ├── tsconfig.app.json ├── tsconfig.json └── tsconfig.spec.json ├── bench.js ├── build.sh ├── data ├── a.sh ├── item.json ├── items.ts ├── location.json ├── move.json ├── pokemon.json └── raw.json ├── index.html ├── package.json ├── preact ├── .gitignore ├── index.html ├── package.json ├── src │ ├── App.module.css │ ├── App.tsx │ ├── components │ │ ├── Item │ │ │ ├── Item.module.css │ │ │ └── index.tsx │ │ └── SearchBox │ │ │ ├── SearchBox.module.css │ │ │ └── index.tsx │ ├── data │ ├── favicon.svg │ ├── index.css │ ├── logo.tsx │ ├── main.tsx │ ├── preact.d.ts │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── react ├── .gitignore ├── index.html ├── package.json ├── src │ ├── App.module.css │ ├── App.tsx │ ├── components │ │ ├── Item │ │ │ ├── Item.module.css │ │ │ └── index.tsx │ │ └── SearchBox │ │ │ ├── SearchBox.module.css │ │ │ └── index.tsx │ ├── data │ ├── index.css │ ├── main.tsx │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── solidjs ├── .gitignore ├── README.md ├── index.html ├── package.json ├── pnpm-lock.yaml ├── src │ ├── App.module.css │ ├── App.tsx │ ├── assets │ │ └── favicon.ico │ ├── components │ │ ├── Item │ │ │ ├── Item.module.css │ │ │ └── index.tsx │ │ └── SearchBox │ │ │ ├── SearchBox.module.css │ │ │ └── index.tsx │ ├── data │ ├── index.css │ └── index.tsx ├── tsconfig.json └── vite.config.ts ├── svelte ├── .gitignore ├── README.md ├── index.html ├── package.json ├── public │ └── favicon.ico ├── src │ ├── App.svelte │ ├── components │ │ ├── Item.svelte │ │ └── SearchBox.svelte │ ├── data │ ├── index.css │ ├── main.ts │ └── vite-env.d.ts ├── svelte.config.js ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── vue ├── .gitignore ├── README.md ├── index.html ├── package.json ├── public │ └── favicon.ico ├── src │ ├── App.vue │ ├── components │ │ ├── Item.vue │ │ └── SearchBox.vue │ ├── data │ ├── env.d.ts │ ├── index.css │ └── main.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /dist 3 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 16.14.0 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Vue.volar", 4 | "svelte.svelte-vscode", 5 | "angular.ng-template" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 uhyo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UI Library Benchmark 2 | 3 | A UI library benchmark suite. 4 | 5 | Article: https://qiita.com/uhyo/items/35cb243557df5e1a87fc 6 | -------------------------------------------------------------------------------- /angular/.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | -------------------------------------------------------------------------------- /angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /angular/README.md: -------------------------------------------------------------------------------- 1 | # Angular 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.0.5. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. 28 | -------------------------------------------------------------------------------- /angular/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "angular": { 7 | "projectType": "application", 8 | "schematics": {}, 9 | "root": "", 10 | "sourceRoot": "src", 11 | "prefix": "app", 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "dist/angular", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": "src/polyfills.ts", 20 | "tsConfig": "tsconfig.app.json", 21 | "assets": [ 22 | "src/favicon.ico", 23 | "src/assets" 24 | ], 25 | "styles": [ 26 | "src/styles.css" 27 | ], 28 | "scripts": [] 29 | }, 30 | "configurations": { 31 | "production": { 32 | "budgets": [ 33 | { 34 | "type": "initial", 35 | "maximumWarning": "500kb", 36 | "maximumError": "1mb" 37 | }, 38 | { 39 | "type": "anyComponentStyle", 40 | "maximumWarning": "2kb", 41 | "maximumError": "4kb" 42 | } 43 | ], 44 | "fileReplacements": [ 45 | { 46 | "replace": "src/environments/environment.ts", 47 | "with": "src/environments/environment.prod.ts" 48 | } 49 | ], 50 | "outputHashing": "all" 51 | }, 52 | "development": { 53 | "buildOptimizer": false, 54 | "optimization": false, 55 | "vendorChunk": true, 56 | "extractLicenses": false, 57 | "sourceMap": true, 58 | "namedChunks": true 59 | } 60 | }, 61 | "defaultConfiguration": "production" 62 | }, 63 | "serve": { 64 | "builder": "@angular-devkit/build-angular:dev-server", 65 | "configurations": { 66 | "production": { 67 | "browserTarget": "angular:build:production" 68 | }, 69 | "development": { 70 | "browserTarget": "angular:build:development" 71 | } 72 | }, 73 | "defaultConfiguration": "development" 74 | }, 75 | "extract-i18n": { 76 | "builder": "@angular-devkit/build-angular:extract-i18n", 77 | "options": { 78 | "browserTarget": "angular:build" 79 | } 80 | }, 81 | "test": { 82 | "builder": "@angular-devkit/build-angular:karma", 83 | "options": { 84 | "main": "src/test.ts", 85 | "polyfills": "src/polyfills.ts", 86 | "tsConfig": "tsconfig.spec.json", 87 | "karmaConfig": "karma.conf.js", 88 | "assets": [ 89 | "src/favicon.ico", 90 | "src/assets" 91 | ], 92 | "styles": [ 93 | "src/styles.css" 94 | ], 95 | "scripts": [] 96 | } 97 | } 98 | } 99 | } 100 | }, 101 | "cli": { 102 | "analytics": "818953c4-e16f-41aa-9e75-486d49498a22" 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^14.0.0", 14 | "@angular/common": "^14.0.0", 15 | "@angular/compiler": "^14.0.0", 16 | "@angular/core": "^14.0.0", 17 | "@angular/forms": "^14.0.0", 18 | "@angular/platform-browser": "^14.0.0", 19 | "@angular/platform-browser-dynamic": "^14.0.0", 20 | "@angular/router": "^14.0.0", 21 | "rxjs": "~7.5.0", 22 | "tslib": "^2.3.0", 23 | "zone.js": "~0.11.4" 24 | }, 25 | "devDependencies": { 26 | "@angular-devkit/build-angular": "^14.0.5", 27 | "@angular/cli": "~14.0.5", 28 | "@angular/compiler-cli": "^14.0.0", 29 | "@types/jasmine": "~4.0.0", 30 | "jasmine-core": "~4.1.0", 31 | "typescript": "~4.7.2" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /angular/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .pokemonList { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); 4 | grid-gap: 20px; 5 | margin: 20px; 6 | } 7 | 8 | .searchBox { 9 | position: fixed; 10 | top: 50vh; 11 | left: 50vw; 12 | transform: translate(-50%, -50%); 13 | } 14 | 15 | footer { 16 | text-align: center; 17 | } 18 | -------------------------------------------------------------------------------- /angular/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 | 7 |
8 | 15 | 18 | -------------------------------------------------------------------------------- /angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from "@angular/core"; 2 | import { itemMap } from "../data/items"; 3 | 4 | @Component({ 5 | selector: "app-root", 6 | templateUrl: "./app.component.html", 7 | styleUrls: ["./app.component.css"], 8 | }) 9 | export class AppComponent { 10 | input = ""; 11 | searchQuery = ""; 12 | 13 | itemIds = Array.from(itemMap.keys()); 14 | 15 | onInput(value: string) { 16 | this.input = value; 17 | this.searchQuery = value.toLowerCase(); 18 | } 19 | 20 | /** 21 | * Tell how to track changes of the collection to Angular. 22 | * @see https://angular.jp/guide/built-in-directives#tracking-items-with-ngfor-trackby 23 | */ 24 | trackById(index: number, itemId: string) { 25 | return itemId; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /angular/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from "@angular/core"; 2 | import { FormsModule } from "@angular/forms"; 3 | import { BrowserModule } from "@angular/platform-browser"; 4 | 5 | import { AppComponent } from "./app.component"; 6 | import { SearchBoxComponent } from "./components/search-box/search-box.component"; 7 | import { ItemComponent } from './components/item/item.component'; 8 | 9 | @NgModule({ 10 | declarations: [AppComponent, SearchBoxComponent, ItemComponent], 11 | imports: [BrowserModule, FormsModule], 12 | providers: [], 13 | bootstrap: [AppComponent], 14 | }) 15 | export class AppModule {} 16 | -------------------------------------------------------------------------------- /angular/src/app/components/item/item.component.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | background-color: var(--bg-sub-color); 3 | } 4 | 5 | .id { 6 | color: var(--text-sub-color); 7 | } 8 | 9 | .name > mark { 10 | font-weight: bold; 11 | } 12 | 13 | .unmatchedName { 14 | color: var(--text-sub-color); 15 | } 16 | -------------------------------------------------------------------------------- /angular/src/app/components/item/item.component.html: -------------------------------------------------------------------------------- 1 |
2 |
{{ id }}
3 |
4 | 5 | {{ nameMarked.prefix 6 | }}{{ nameMarked.mark }}{{ nameMarked.suffix }} 8 | 9 |
10 |
{{ item.ja }}
11 |
12 | -------------------------------------------------------------------------------- /angular/src/app/components/item/item.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from "@angular/core"; 2 | import { itemMap } from "../../../data/items"; 3 | 4 | @Component({ 5 | selector: "app-item", 6 | templateUrl: "./item.component.html", 7 | styleUrls: ["./item.component.css"], 8 | }) 9 | export class ItemComponent { 10 | @Input() id!: string; 11 | @Input() searchQuery!: string; 12 | 13 | get item() { 14 | return itemMap.get(this.id); 15 | } 16 | 17 | get nameMarked() { 18 | if (!this.item) { 19 | return undefined; 20 | } 21 | if (!this.searchQuery) { 22 | return { 23 | unmatched: false, 24 | prefix: this.item.en, 25 | mark: "", 26 | suffix: "", 27 | }; 28 | } 29 | const en = this.item.en; 30 | const name = en.toLowerCase(); 31 | const searchIndex = name.indexOf(this.searchQuery); 32 | if (searchIndex === -1) { 33 | return { 34 | unmatched: true, 35 | prefix: en, 36 | mark: "", 37 | suffix: "", 38 | }; 39 | } 40 | return { 41 | unmatched: false, 42 | prefix: en.substring(0, searchIndex), 43 | mark: en.substring(searchIndex, searchIndex + this.searchQuery.length), 44 | suffix: en.substring(searchIndex + this.searchQuery.length), 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /angular/src/app/components/search-box/search-box.component.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: grid; 3 | grid-template-columns: 3rem auto 3rem; 4 | grid-template-rows: 3rem auto 3rem; 5 | 6 | border: 1px solid var(--text-color); 7 | background-color: var(--bg-sub-color); 8 | background-repeat: repeat; 9 | } 10 | 11 | .input { 12 | grid-area: 2 / 2; 13 | font-size: 2.5rem; 14 | padding: 0.5rem; 15 | } 16 | -------------------------------------------------------------------------------- /angular/src/app/components/search-box/search-box.component.html: -------------------------------------------------------------------------------- 1 |
2 | 8 |
9 | -------------------------------------------------------------------------------- /angular/src/app/components/search-box/search-box.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "search-box", 5 | templateUrl: "./search-box.component.html", 6 | styleUrls: ["./search-box.component.css"], 7 | }) 8 | export class SearchBoxComponent { 9 | @Input() value: string = ""; 10 | @Output() valueChange = new EventEmitter(); 11 | 12 | constructor() {} 13 | } 14 | -------------------------------------------------------------------------------- /angular/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uhyo/ui-library-benchmark/ec661339b4cb440fb94344631cdf045bd72a3511/angular/src/assets/.gitkeep -------------------------------------------------------------------------------- /angular/src/data: -------------------------------------------------------------------------------- 1 | ../../data -------------------------------------------------------------------------------- /angular/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /angular/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /angular/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uhyo/ui-library-benchmark/ec661339b4cb440fb94344631cdf045bd72a3511/angular/src/favicon.ico -------------------------------------------------------------------------------- /angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /angular/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including 12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** 22 | * By default, zone.js will patch all possible macroTask and DomEvents 23 | * user can disable parts of macroTask/DomEvents patch by setting following flags 24 | * because those flags need to be set before `zone.js` being loaded, and webpack 25 | * will put import in the top of bundle, so user need to create a separate file 26 | * in this directory (for example: zone-flags.ts), and put the following flags 27 | * into that file, and then add the following code before importing zone.js. 28 | * import './zone-flags'; 29 | * 30 | * The flags allowed in zone-flags.ts are listed here. 31 | * 32 | * The following flags will work for all browsers. 33 | * 34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 37 | * 38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 40 | * 41 | * (window as any).__Zone_enable_cross_context_check = true; 42 | * 43 | */ 44 | 45 | /*************************************************************************************************** 46 | * Zone JS is required by default for Angular itself. 47 | */ 48 | import 'zone.js'; // Included with Angular CLI. 49 | 50 | 51 | /*************************************************************************************************** 52 | * APPLICATION IMPORTS 53 | */ 54 | -------------------------------------------------------------------------------- /angular/src/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", 4 | "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", 5 | "Helvetica Neue", sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | 9 | background-color: var(--bg-color); 10 | color: var(--text-color); 11 | 12 | color-scheme: light dark; 13 | 14 | --bg-color: white; 15 | --text-color: black; 16 | --bg-sub-color: #fafafa; 17 | --text-sub-color: #666666; 18 | } 19 | 20 | @media (prefers-color-scheme: dark) { 21 | body { 22 | --bg-color: #1a1a1a; 23 | --text-color: white; 24 | --bg-sub-color: #333333; 25 | --text-sub-color: #999999; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /angular/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | (id: string): T; 13 | keys(): string[]; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting(), 21 | ); 22 | 23 | // Then we find all the tests. 24 | const context = require.context('./', true, /\.spec\.ts$/); 25 | // And load the modules. 26 | context.keys().forEach(context); 27 | -------------------------------------------------------------------------------- /angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": ["src/main.ts", "src/polyfills.ts", "../data/items.ts"], 9 | "include": ["src/**/*.d.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noUncheckedIndexedAccess": true, 11 | "noPropertyAccessFromIndexSignature": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "sourceMap": true, 15 | "declaration": false, 16 | "downlevelIteration": true, 17 | "experimentalDecorators": true, 18 | "esModuleInterop": true, 19 | "resolveJsonModule": true, 20 | "moduleResolution": "node", 21 | "importHelpers": true, 22 | "target": "es2020", 23 | "module": "es2020", 24 | "lib": ["es2020", "dom"] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /bench.js: -------------------------------------------------------------------------------- 1 | async function benchmark() { 2 | const input = document.querySelector("input"); 3 | // https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-onchange-event-in-react-js 4 | const nativeInputValueSetter = Object.getOwnPropertyDescriptor( 5 | HTMLInputElement.prototype, 6 | "value" 7 | ).set; 8 | 9 | const results = []; 10 | for (const _ of Array.from(range(0, 101))) { 11 | results.push(await runOnce()); 12 | } 13 | results.sort((a, b) => a - b); 14 | const median = results[50]; 15 | console.log("median:", median); 16 | console.log(results); 17 | 18 | async function runOnce() { 19 | inputClear(); 20 | await waitForIdle(); 21 | const start = performance.now(); 22 | await runTasks(100, [ 23 | inputChar("b"), 24 | inputChar("a"), 25 | inputChar("l"), 26 | inputChar("l"), 27 | // removeChar, 28 | // removeChar, 29 | // removeChar, 30 | // removeChar, 31 | ]); 32 | const end = performance.now(); 33 | await waitForIdle(); 34 | return end - start; 35 | } 36 | 37 | function runTasks(interval, _tasks) { 38 | const tasks = [..._tasks]; 39 | let end; 40 | const timerId = setInterval(() => { 41 | const task = tasks.shift(); 42 | if (task) { 43 | task(); 44 | return; 45 | } 46 | clearInterval(timerId); 47 | end(); 48 | }, interval); 49 | return new Promise((resolve) => (end = resolve)); 50 | } 51 | 52 | function inputChar(char) { 53 | return () => { 54 | nativeInputValueSetter.call(input, input.value + char); 55 | input.dispatchEvent( 56 | new InputEvent("input", { 57 | bubbles: true, 58 | }) 59 | ); 60 | }; 61 | } 62 | function removeChar() { 63 | nativeInputValueSetter.call(input, input.value.slice(0, -1)); 64 | input.dispatchEvent( 65 | new InputEvent("input", { 66 | bubbles: true, 67 | }) 68 | ); 69 | } 70 | function inputClear() { 71 | nativeInputValueSetter.call(input, ""); 72 | input.dispatchEvent( 73 | new InputEvent("input", { 74 | bubbles: true, 75 | }) 76 | ); 77 | } 78 | 79 | function waitForIdle() { 80 | return new Promise((resolve) => { 81 | requestIdleCallback(resolve); 82 | }); 83 | } 84 | 85 | function* range(start, end) { 86 | for (let i = start; i < end; i++) { 87 | yield i; 88 | } 89 | } 90 | } 91 | benchmark(); 92 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | set -e 3 | 4 | rm -r dist || true 5 | mkdir -p dist 6 | 7 | cd angular 8 | yarn build 9 | cp -r dist/angular ../dist/angular 10 | cd .. 11 | 12 | cd react 13 | yarn build 14 | cp -r dist ../dist/react 15 | cd .. 16 | 17 | cd solidjs 18 | yarn build 19 | cp -r dist ../dist/solidjs 20 | cd .. 21 | 22 | cd svelte 23 | yarn build 24 | cp -r dist ../dist/svelte 25 | cd .. 26 | 27 | cd vue 28 | yarn build 29 | cp -r dist ../dist/vue 30 | cd .. 31 | 32 | cd preact 33 | yarn build 34 | cp -r dist ../dist/preact 35 | cd .. 36 | 37 | cp index.html dist/ 38 | -------------------------------------------------------------------------------- /data/a.sh: -------------------------------------------------------------------------------- 1 | cat raw.json | jq '.data.pokemon_v2_location | map({ 2 | id: .id, 3 | en: .pokemon_v2_locationnames | .[] | select(.language_id == 9) | .name, 4 | ja: .pokemon_v2_locationnames | .[] | select(.language_id == 1) | .name 5 | })' > location.json 6 | -------------------------------------------------------------------------------- /data/items.ts: -------------------------------------------------------------------------------- 1 | import pokemon from "./pokemon.json"; 2 | import move from "./move.json"; 3 | import item from "./item.json"; 4 | import location from "./location.json"; 5 | 6 | export type Item = { 7 | id: number; 8 | en: string; 9 | ja: string; 10 | }; 11 | 12 | export const itemMap = new Map([ 13 | ...sortById( 14 | Object.values(pokemon).map((pokemon) => [`p${pokemon.id}`, pokemon]) 15 | ), 16 | ...sortById(Object.values(move).map((move) => [`m${move.id}`, move])), 17 | ...sortById(Object.values(item).map((item) => [`i${item.id}`, item])), 18 | ...sortById(Object.values(location).map((item) => [`l${item.id}`, item])), 19 | ]); 20 | 21 | function sortById( 22 | arr: (readonly [string, Item])[] 23 | ): (readonly [string, Item])[] { 24 | return arr.sort((a, b) => { 25 | return a[1].id - b[1].id; 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /data/location.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 344, 4 | "en": "Mystery Zone", 5 | "ja": "なぞの場所" 6 | }, 7 | { 8 | "id": 345, 9 | "en": "Faraway place", 10 | "ja": "遠い場所" 11 | }, 12 | { 13 | "id": 346, 14 | "en": "Nuvema Town", 15 | "ja": "カノコタウン" 16 | }, 17 | { 18 | "id": 347, 19 | "en": "Accumula Town", 20 | "ja": "カラクサタウン" 21 | }, 22 | { 23 | "id": 348, 24 | "en": "Striaton City", 25 | "ja": "サンヨウシティ" 26 | }, 27 | { 28 | "id": 349, 29 | "en": "Nacrene City", 30 | "ja": "シッポウシティ" 31 | }, 32 | { 33 | "id": 350, 34 | "en": "Castelia City", 35 | "ja": "ヒウンシティ" 36 | }, 37 | { 38 | "id": 351, 39 | "en": "Nimbasa City", 40 | "ja": "ライモンシティ" 41 | }, 42 | { 43 | "id": 352, 44 | "en": "Driftveil City", 45 | "ja": "ホドモエシティ" 46 | }, 47 | { 48 | "id": 353, 49 | "en": "Mistralton City", 50 | "ja": "フキヨセシティ" 51 | }, 52 | { 53 | "id": 354, 54 | "en": "Icirrus City", 55 | "ja": "セッカシティ" 56 | }, 57 | { 58 | "id": 355, 59 | "en": "Opelucid City", 60 | "ja": "ソウリュウシティ" 61 | }, 62 | { 63 | "id": 356, 64 | "en": "Route 1", 65 | "ja": "1番道路" 66 | }, 67 | { 68 | "id": 357, 69 | "en": "Route 2", 70 | "ja": "2番道路" 71 | }, 72 | { 73 | "id": 358, 74 | "en": "Route 3", 75 | "ja": "3番道路" 76 | }, 77 | { 78 | "id": 359, 79 | "en": "Route 4", 80 | "ja": "4番道路" 81 | }, 82 | { 83 | "id": 360, 84 | "en": "Route 5", 85 | "ja": "5番道路" 86 | }, 87 | { 88 | "id": 361, 89 | "en": "Route 6", 90 | "ja": "6番道路" 91 | }, 92 | { 93 | "id": 362, 94 | "en": "Route 7", 95 | "ja": "7番道路" 96 | }, 97 | { 98 | "id": 363, 99 | "en": "Route 8", 100 | "ja": "8番道路" 101 | }, 102 | { 103 | "id": 364, 104 | "en": "Route 9", 105 | "ja": "9番道路" 106 | }, 107 | { 108 | "id": 365, 109 | "en": "Route 10", 110 | "ja": "10番道路" 111 | }, 112 | { 113 | "id": 366, 114 | "en": "Route 11", 115 | "ja": "11番道路" 116 | }, 117 | { 118 | "id": 367, 119 | "en": "Route 12", 120 | "ja": "12番道路" 121 | }, 122 | { 123 | "id": 368, 124 | "en": "Route 13", 125 | "ja": "13番道路" 126 | }, 127 | { 128 | "id": 369, 129 | "en": "Route 14", 130 | "ja": "14番道路" 131 | }, 132 | { 133 | "id": 370, 134 | "en": "Route 15", 135 | "ja": "15番道路" 136 | }, 137 | { 138 | "id": 371, 139 | "en": "Route 16", 140 | "ja": "16番道路" 141 | }, 142 | { 143 | "id": 372, 144 | "en": "Route 17", 145 | "ja": "17番水道" 146 | }, 147 | { 148 | "id": 373, 149 | "en": "Route 18", 150 | "ja": "18番道路" 151 | }, 152 | { 153 | "id": 374, 154 | "en": "Dreamyard", 155 | "ja": "夢の跡地" 156 | }, 157 | { 158 | "id": 375, 159 | "en": "Pinwheel Forest", 160 | "ja": "ヤグルマの森" 161 | }, 162 | { 163 | "id": 376, 164 | "en": "Desert Resort", 165 | "ja": "リゾートデザート" 166 | }, 167 | { 168 | "id": 377, 169 | "en": "Relic Castle", 170 | "ja": "古代の城" 171 | }, 172 | { 173 | "id": 378, 174 | "en": "Cold Storage", 175 | "ja": "冷凍コンテナ" 176 | }, 177 | { 178 | "id": 379, 179 | "en": "Chargestone Cave", 180 | "ja": "電気石の洞穴" 181 | }, 182 | { 183 | "id": 380, 184 | "en": "Twist Mountain", 185 | "ja": "ネジ山" 186 | }, 187 | { 188 | "id": 381, 189 | "en": "Dragonspiral Tower", 190 | "ja": "リュウラセンの塔" 191 | }, 192 | { 193 | "id": 382, 194 | "en": "Victory Road", 195 | "ja": "チャンピオンロード" 196 | }, 197 | { 198 | "id": 383, 199 | "en": "Lacunosa Town", 200 | "ja": "カゴメタウン" 201 | }, 202 | { 203 | "id": 384, 204 | "en": "Undella Town", 205 | "ja": "サザナミタウン" 206 | }, 207 | { 208 | "id": 385, 209 | "en": "Anville Town", 210 | "ja": "カナワタウン" 211 | }, 212 | { 213 | "id": 386, 214 | "en": "Pokémon League", 215 | "ja": "ポケモンリーグ" 216 | }, 217 | { 218 | "id": 387, 219 | "en": "N's Castle", 220 | "ja": "Nの城" 221 | }, 222 | { 223 | "id": 388, 224 | "en": "Royal Unova", 225 | "ja": "ロイヤルイッシュ号" 226 | }, 227 | { 228 | "id": 389, 229 | "en": "Gear Station", 230 | "ja": "ギアステーション" 231 | }, 232 | { 233 | "id": 390, 234 | "en": "Battle Subway", 235 | "ja": "バトルサブウェイ" 236 | }, 237 | { 238 | "id": 391, 239 | "en": "Musical Theater", 240 | "ja": "ミュージカルホール" 241 | }, 242 | { 243 | "id": 392, 244 | "en": "Black City", 245 | "ja": "ブラックシティ" 246 | }, 247 | { 248 | "id": 393, 249 | "en": "White Forest", 250 | "ja": "ホワイトフォレスト" 251 | }, 252 | { 253 | "id": 394, 254 | "en": "Unity Tower", 255 | "ja": "ユナイテッドタワー" 256 | }, 257 | { 258 | "id": 395, 259 | "en": "Wellspring Cave", 260 | "ja": "地下水脈の穴" 261 | }, 262 | { 263 | "id": 396, 264 | "en": "Mistralton Cave", 265 | "ja": "フキヨセの洞穴" 266 | }, 267 | { 268 | "id": 397, 269 | "en": "Rumination Field", 270 | "ja": "思索の原" 271 | }, 272 | { 273 | "id": 398, 274 | "en": "Celestial Tower", 275 | "ja": "タワーオブヘブン" 276 | }, 277 | { 278 | "id": 399, 279 | "en": "Moor of Icirrus", 280 | "ja": "セッカの湿原" 281 | }, 282 | { 283 | "id": 400, 284 | "en": "Shopping Mall", 285 | "ja": "ショッピングモール" 286 | }, 287 | { 288 | "id": 401, 289 | "en": "Challenger's Cave", 290 | "ja": "修行の岩屋" 291 | }, 292 | { 293 | "id": 402, 294 | "en": "Poké Transfer Lab", 295 | "ja": "シフトファクトリー" 296 | }, 297 | { 298 | "id": 403, 299 | "en": "Giant Chasm", 300 | "ja": "ジャイアントホール" 301 | }, 302 | { 303 | "id": 404, 304 | "en": "Liberty Garden", 305 | "ja": "リバティガーデン島" 306 | }, 307 | { 308 | "id": 405, 309 | "en": "P2 Laboratory", 310 | "ja": "P2ラボ" 311 | }, 312 | { 313 | "id": 406, 314 | "en": "Skyarrow Bridge", 315 | "ja": "スカイアローブリッジ" 316 | }, 317 | { 318 | "id": 407, 319 | "en": "Driftveil Drawbridge", 320 | "ja": "ホドモエの跳ね橋" 321 | }, 322 | { 323 | "id": 408, 324 | "en": "Tubeline Bridge", 325 | "ja": "シリンダーブリッジ" 326 | }, 327 | { 328 | "id": 409, 329 | "en": "Village Bridge", 330 | "ja": "ビレッジブリッジ" 331 | }, 332 | { 333 | "id": 410, 334 | "en": "Marvelous Bridge", 335 | "ja": "ワンダーブリッジ" 336 | }, 337 | { 338 | "id": 411, 339 | "en": "Entralink", 340 | "ja": "ハイリンク" 341 | }, 342 | { 343 | "id": 412, 344 | "en": "Abundant Shrine", 345 | "ja": "ほうじょうの社" 346 | }, 347 | { 348 | "id": 413, 349 | "en": "Undella Bay", 350 | "ja": "サザナミ湾" 351 | }, 352 | { 353 | "id": 414, 354 | "en": "Lostlorn Forest", 355 | "ja": "迷いの森" 356 | }, 357 | { 358 | "id": 415, 359 | "en": "Trial Chamber", 360 | "ja": "試練の室" 361 | }, 362 | { 363 | "id": 416, 364 | "en": "Guidance Chamber", 365 | "ja": "導の間" 366 | }, 367 | { 368 | "id": 417, 369 | "en": "Entree Forest", 370 | "ja": "ハイリンクの森" 371 | }, 372 | { 373 | "id": 418, 374 | "en": "Accumula Gate", 375 | "ja": "カラクサゲート" 376 | }, 377 | { 378 | "id": 419, 379 | "en": "Undella Gate", 380 | "ja": "サザナミゲート" 381 | }, 382 | { 383 | "id": 420, 384 | "en": "Nacrene Gate", 385 | "ja": "シッポウゲート" 386 | }, 387 | { 388 | "id": 421, 389 | "en": "Castelia Gate", 390 | "ja": "ヒウンゲート" 391 | }, 392 | { 393 | "id": 422, 394 | "en": "Nimbasa Gate", 395 | "ja": "ライモンゲート" 396 | }, 397 | { 398 | "id": 423, 399 | "en": "Opelucid Gate", 400 | "ja": "ソウリュウゲート" 401 | }, 402 | { 403 | "id": 424, 404 | "en": "Black Gate", 405 | "ja": "ブラックゲート" 406 | }, 407 | { 408 | "id": 425, 409 | "en": "White Gate", 410 | "ja": "ホワイトゲート" 411 | }, 412 | { 413 | "id": 426, 414 | "en": "Bridge Gate", 415 | "ja": "ブリッジゲート" 416 | }, 417 | { 418 | "id": 427, 419 | "en": "Route Gate", 420 | "ja": "ロードゲート" 421 | }, 422 | { 423 | "id": 428, 424 | "en": "Abyssal Ruins", 425 | "ja": "海底遺跡" 426 | }, 427 | { 428 | "id": 429, 429 | "en": "Petalburg City", 430 | "ja": "トウカシティ" 431 | }, 432 | { 433 | "id": 430, 434 | "en": "Slateport City", 435 | "ja": "カイナシティ" 436 | }, 437 | { 438 | "id": 431, 439 | "en": "Lilycove City", 440 | "ja": "ミナモシティ" 441 | }, 442 | { 443 | "id": 432, 444 | "en": "Mossdeep City", 445 | "ja": "トクサネシティ" 446 | }, 447 | { 448 | "id": 433, 449 | "en": "Sootopolis City", 450 | "ja": "ルネシティ" 451 | }, 452 | { 453 | "id": 434, 454 | "en": "Ever Grande City", 455 | "ja": "サイユウシティ" 456 | }, 457 | { 458 | "id": 435, 459 | "en": "Meteor Falls", 460 | "ja": "りゅうせいのたき" 461 | }, 462 | { 463 | "id": 436, 464 | "en": "Rusturf Tunnel", 465 | "ja": "カナシダトンネル" 466 | }, 467 | { 468 | "id": 437, 469 | "en": "Granite Cave", 470 | "ja": "いしのどうくつ" 471 | }, 472 | { 473 | "id": 438, 474 | "en": "Petalburg Woods", 475 | "ja": "トウカのもり" 476 | }, 477 | { 478 | "id": 439, 479 | "en": "Jagged Pass", 480 | "ja": "デコボコさんどう" 481 | }, 482 | { 483 | "id": 440, 484 | "en": "Fiery Path", 485 | "ja": "ほのおのぬけみち" 486 | }, 487 | { 488 | "id": 441, 489 | "en": "Mt. Pyre", 490 | "ja": "おくりびやま" 491 | }, 492 | { 493 | "id": 442, 494 | "en": "Seafloor Cavern", 495 | "ja": "かいていどうくつ" 496 | }, 497 | { 498 | "id": 443, 499 | "en": "Cave of Origin", 500 | "ja": "めざめのほこら" 501 | }, 502 | { 503 | "id": 444, 504 | "en": "Victory Road", 505 | "ja": "チャンピオンロード" 506 | }, 507 | { 508 | "id": 445, 509 | "en": "Shoal Cave", 510 | "ja": "あさせのほらあな" 511 | }, 512 | { 513 | "id": 446, 514 | "en": "New Mauville", 515 | "ja": "ニューキンセツ" 516 | }, 517 | { 518 | "id": 448, 519 | "en": "Sky Pillar", 520 | "ja": "そらのはしら" 521 | }, 522 | { 523 | "id": 449, 524 | "en": "Route 101", 525 | "ja": "101ばんどうろ" 526 | }, 527 | { 528 | "id": 450, 529 | "en": "Route 102", 530 | "ja": "102ばんどうろ" 531 | }, 532 | { 533 | "id": 451, 534 | "en": "Route 103", 535 | "ja": "103ばんどうろ" 536 | }, 537 | { 538 | "id": 452, 539 | "en": "Route 104", 540 | "ja": "104ばんどうろ" 541 | }, 542 | { 543 | "id": 453, 544 | "en": "Route 105", 545 | "ja": "105ばんすいどう" 546 | }, 547 | { 548 | "id": 454, 549 | "en": "Route 106", 550 | "ja": "106ばんすいどう" 551 | }, 552 | { 553 | "id": 455, 554 | "en": "Route 107", 555 | "ja": "107ばんすいどう" 556 | }, 557 | { 558 | "id": 456, 559 | "en": "Route 108", 560 | "ja": "108ばんすいどう" 561 | }, 562 | { 563 | "id": 457, 564 | "en": "Route 109", 565 | "ja": "109ばんすいどう" 566 | }, 567 | { 568 | "id": 458, 569 | "en": "Route 110", 570 | "ja": "110ばんどうろ" 571 | }, 572 | { 573 | "id": 459, 574 | "en": "Route 111", 575 | "ja": "111ばんどうろ" 576 | }, 577 | { 578 | "id": 460, 579 | "en": "Route 112", 580 | "ja": "112ばんどうろ" 581 | }, 582 | { 583 | "id": 461, 584 | "en": "Route 113", 585 | "ja": "113ばんどうろ" 586 | }, 587 | { 588 | "id": 462, 589 | "en": "Route 114", 590 | "ja": "114ばんどうろ" 591 | }, 592 | { 593 | "id": 463, 594 | "en": "Route 115", 595 | "ja": "115ばんどうろ" 596 | }, 597 | { 598 | "id": 464, 599 | "en": "Route 116", 600 | "ja": "116ばんどうろ" 601 | }, 602 | { 603 | "id": 465, 604 | "en": "Route 117", 605 | "ja": "117ばんどうろ" 606 | }, 607 | { 608 | "id": 466, 609 | "en": "Route 118", 610 | "ja": "118ばんどうろ" 611 | }, 612 | { 613 | "id": 467, 614 | "en": "Route 119", 615 | "ja": "119ばんどうろ" 616 | }, 617 | { 618 | "id": 468, 619 | "en": "Route 120", 620 | "ja": "120ばんどうろ" 621 | }, 622 | { 623 | "id": 469, 624 | "en": "Route 121", 625 | "ja": "121ばんどうろ" 626 | }, 627 | { 628 | "id": 470, 629 | "en": "Route 122", 630 | "ja": "122ばんすいどう" 631 | }, 632 | { 633 | "id": 471, 634 | "en": "Route 123", 635 | "ja": "123ばんどうろ" 636 | }, 637 | { 638 | "id": 472, 639 | "en": "Route 124", 640 | "ja": "124ばんすいどう" 641 | }, 642 | { 643 | "id": 473, 644 | "en": "Route 125", 645 | "ja": "125ばんすいどう" 646 | }, 647 | { 648 | "id": 474, 649 | "en": "Route 126", 650 | "ja": "126ばんすいどう" 651 | }, 652 | { 653 | "id": 475, 654 | "en": "Route 127", 655 | "ja": "127ばんすいどう" 656 | }, 657 | { 658 | "id": 476, 659 | "en": "Route 128", 660 | "ja": "128ばんすいどう" 661 | }, 662 | { 663 | "id": 477, 664 | "en": "Route 129", 665 | "ja": "129ばんすいどう" 666 | }, 667 | { 668 | "id": 478, 669 | "en": "Route 130", 670 | "ja": "130ばんすいどう" 671 | }, 672 | { 673 | "id": 479, 674 | "en": "Route 131", 675 | "ja": "131ばんすいどう" 676 | }, 677 | { 678 | "id": 480, 679 | "en": "Route 132", 680 | "ja": "132ばんすいどう" 681 | }, 682 | { 683 | "id": 481, 684 | "en": "Route 133", 685 | "ja": "133ばんすいどう" 686 | }, 687 | { 688 | "id": 482, 689 | "en": "Route 134", 690 | "ja": "134ばんすいどう" 691 | }, 692 | { 693 | "id": 483, 694 | "en": "Safari Zone", 695 | "ja": "サファリゾーン" 696 | }, 697 | { 698 | "id": 484, 699 | "en": "Dewford Town", 700 | "ja": "ムロタウン" 701 | }, 702 | { 703 | "id": 485, 704 | "en": "Pacifidlog Town", 705 | "ja": "キナギタウン" 706 | }, 707 | { 708 | "id": 531, 709 | "en": "Aspertia City", 710 | "ja": "ヒオウギシティ" 711 | }, 712 | { 713 | "id": 532, 714 | "en": "Virbank City", 715 | "ja": "タチワキシティ" 716 | }, 717 | { 718 | "id": 533, 719 | "en": "Humilau City", 720 | "ja": "セイガイハシティ" 721 | }, 722 | { 723 | "id": 534, 724 | "en": "PokéStar Studios", 725 | "ja": "ポケウッド" 726 | }, 727 | { 728 | "id": 535, 729 | "en": "Join Avenue", 730 | "ja": "ジョインアベニュー" 731 | }, 732 | { 733 | "id": 536, 734 | "en": "Floccesy Town", 735 | "ja": "サンギタウン" 736 | }, 737 | { 738 | "id": 537, 739 | "en": "Lentimas Town", 740 | "ja": "ヤマジタウン" 741 | }, 742 | { 743 | "id": 538, 744 | "en": "Route 19", 745 | "ja": "19番道路" 746 | }, 747 | { 748 | "id": 539, 749 | "en": "Route 20", 750 | "ja": "20番道路" 751 | }, 752 | { 753 | "id": 540, 754 | "en": "Route 21", 755 | "ja": "21番水道" 756 | }, 757 | { 758 | "id": 541, 759 | "en": "Route 22", 760 | "ja": "22番道路" 761 | }, 762 | { 763 | "id": 542, 764 | "en": "Route 23", 765 | "ja": "23番道路" 766 | }, 767 | { 768 | "id": 543, 769 | "en": "Castelia Sewers", 770 | "ja": "ヒウン下水道" 771 | }, 772 | { 773 | "id": 544, 774 | "en": "Floccesy Ranch", 775 | "ja": "サンギ牧場" 776 | }, 777 | { 778 | "id": 545, 779 | "en": "Virbank Complex", 780 | "ja": "タチワキコンビナート" 781 | }, 782 | { 783 | "id": 546, 784 | "en": "Reversal Mountain", 785 | "ja": "リバースマウンテン" 786 | }, 787 | { 788 | "id": 547, 789 | "en": "Strange House", 790 | "ja": "ストレンジャーハウス" 791 | }, 792 | { 793 | "id": 548, 794 | "en": "Victory Road", 795 | "ja": "チャンピオンロード" 796 | }, 797 | { 798 | "id": 549, 799 | "en": "Plasma Frigate", 800 | "ja": "プラズマフリゲート" 801 | }, 802 | { 803 | "id": 550, 804 | "en": "Relic Passage", 805 | "ja": "古代の抜け道" 806 | }, 807 | { 808 | "id": 551, 809 | "en": "Clay Tunnel", 810 | "ja": "ヤーコンロード" 811 | }, 812 | { 813 | "id": 552, 814 | "en": "White Treehollow", 815 | "ja": "白の樹洞" 816 | }, 817 | { 818 | "id": 553, 819 | "en": "Black Tower", 820 | "ja": "黒の摩天楼" 821 | }, 822 | { 823 | "id": 554, 824 | "en": "Seaside Cave", 825 | "ja": "海辺の洞穴" 826 | }, 827 | { 828 | "id": 555, 829 | "en": "Cave of Being", 830 | "ja": "心の空洞" 831 | }, 832 | { 833 | "id": 556, 834 | "en": "Hidden Grotto", 835 | "ja": "隠し穴" 836 | }, 837 | { 838 | "id": 557, 839 | "en": "Marine Tube", 840 | "ja": "マリンチューブ" 841 | }, 842 | { 843 | "id": 558, 844 | "en": "Virbank Gate", 845 | "ja": "タチワキゲート" 846 | }, 847 | { 848 | "id": 559, 849 | "en": "Aspertia Gate", 850 | "ja": "ヒオウギゲート" 851 | }, 852 | { 853 | "id": 560, 854 | "en": "Nature Sanctuary", 855 | "ja": "自然保護区" 856 | }, 857 | { 858 | "id": 561, 859 | "en": "Medal Secretariat", 860 | "ja": "メダル事務局" 861 | }, 862 | { 863 | "id": 562, 864 | "en": "Underground Ruins", 865 | "ja": "地底遺跡" 866 | }, 867 | { 868 | "id": 563, 869 | "en": "Rocky Mountain Room", 870 | "ja": "岩山の間" 871 | }, 872 | { 873 | "id": 564, 874 | "en": "Glacier Room", 875 | "ja": "氷山の間" 876 | }, 877 | { 878 | "id": 565, 879 | "en": "Iron Room", 880 | "ja": "鉄の間" 881 | }, 882 | { 883 | "id": 566, 884 | "en": "Pledge Grove", 885 | "ja": "誓いの林" 886 | }, 887 | { 888 | "id": 567, 889 | "en": "Littleroot Town", 890 | "ja": "ミシロタウン" 891 | }, 892 | { 893 | "id": 568, 894 | "en": "Oldale Town", 895 | "ja": "コトキタウン" 896 | }, 897 | { 898 | "id": 569, 899 | "en": "Lavaridge Town", 900 | "ja": "フエンタウン" 901 | }, 902 | { 903 | "id": 570, 904 | "en": "Fallarbor Town", 905 | "ja": "ハジツゲタウン" 906 | }, 907 | { 908 | "id": 571, 909 | "en": "Verdanturf Town", 910 | "ja": "シダケタウン" 911 | }, 912 | { 913 | "id": 572, 914 | "en": "Mauville City", 915 | "ja": "キンセツシティ" 916 | }, 917 | { 918 | "id": 573, 919 | "en": "Rustboro City", 920 | "ja": "カナズミシティ" 921 | }, 922 | { 923 | "id": 574, 924 | "en": "Fortree City", 925 | "ja": "ヒワマキシティ" 926 | }, 927 | { 928 | "id": 576, 929 | "en": "Mt. Chimney", 930 | "ja": "えんとつやま" 931 | }, 932 | { 933 | "id": 577, 934 | "en": "Mirage Island", 935 | "ja": "マボロシじま" 936 | }, 937 | { 938 | "id": 578, 939 | "en": "Southern Island", 940 | "ja": "みなみのことう" 941 | }, 942 | { 943 | "id": 579, 944 | "en": "Sealed Chamber", 945 | "ja": "おふれのせきしつ" 946 | }, 947 | { 948 | "id": 580, 949 | "en": "Scorched Slab", 950 | "ja": "ひでりのいわと" 951 | }, 952 | { 953 | "id": 581, 954 | "en": "Island Cave", 955 | "ja": "こじまのよこあな" 956 | }, 957 | { 958 | "id": 582, 959 | "en": "Desert Ruins", 960 | "ja": "さばくいせき" 961 | }, 962 | { 963 | "id": 583, 964 | "en": "Ancient Tomb", 965 | "ja": "こだいづか" 966 | }, 967 | { 968 | "id": 584, 969 | "en": "???", 970 | "ja": "???" 971 | }, 972 | { 973 | "id": 585, 974 | "en": "Secret Base", 975 | "ja": "ひみつきち" 976 | }, 977 | { 978 | "id": 587, 979 | "en": "Vaniville Town", 980 | "ja": "アサメタウン" 981 | }, 982 | { 983 | "id": 588, 984 | "en": "Route 1", 985 | "ja": "1ばんどうろ" 986 | }, 987 | { 988 | "id": 589, 989 | "en": "Vaniville Pathway", 990 | "ja": "アサメのこみち" 991 | }, 992 | { 993 | "id": 590, 994 | "en": "Aquacorde Town", 995 | "ja": "メイスイタウン" 996 | }, 997 | { 998 | "id": 591, 999 | "en": "Route 2", 1000 | "ja": "2ばんどうろ" 1001 | }, 1002 | { 1003 | "id": 592, 1004 | "en": "Avance Trail", 1005 | "ja": "アバンセどおり" 1006 | }, 1007 | { 1008 | "id": 593, 1009 | "en": "Santalune Forest", 1010 | "ja": "ハクダンのもり" 1011 | }, 1012 | { 1013 | "id": 594, 1014 | "en": "Route 3", 1015 | "ja": "3ばんどうろ" 1016 | }, 1017 | { 1018 | "id": 595, 1019 | "en": "Ouvert Way", 1020 | "ja": "ウベールどおり" 1021 | }, 1022 | { 1023 | "id": 596, 1024 | "en": "Santalune City", 1025 | "ja": "ハクダンシティ" 1026 | }, 1027 | { 1028 | "id": 597, 1029 | "en": "Route 4", 1030 | "ja": "4ばんどうろ" 1031 | }, 1032 | { 1033 | "id": 598, 1034 | "en": "Parterre Way", 1035 | "ja": "パルテールかいどう" 1036 | }, 1037 | { 1038 | "id": 599, 1039 | "en": "Lumiose City", 1040 | "ja": "ミアレシティ" 1041 | }, 1042 | { 1043 | "id": 600, 1044 | "en": "Prism Tower", 1045 | "ja": "プリズムタワー" 1046 | }, 1047 | { 1048 | "id": 601, 1049 | "en": "Lysandre Labs", 1050 | "ja": "フラダリラボ" 1051 | }, 1052 | { 1053 | "id": 602, 1054 | "en": "Route 5", 1055 | "ja": "5ばんどうろ" 1056 | }, 1057 | { 1058 | "id": 603, 1059 | "en": "Versant Road", 1060 | "ja": "ベルサンどおり" 1061 | }, 1062 | { 1063 | "id": 604, 1064 | "en": "Camphrier Town", 1065 | "ja": "コボクタウン" 1066 | }, 1067 | { 1068 | "id": 605, 1069 | "en": "Shabboneau Castle", 1070 | "ja": "ショボンヌじょう" 1071 | }, 1072 | { 1073 | "id": 606, 1074 | "en": "Route 6", 1075 | "ja": "6ばんどうろ" 1076 | }, 1077 | { 1078 | "id": 607, 1079 | "en": "Palais Lane", 1080 | "ja": "パレのなみきみち" 1081 | }, 1082 | { 1083 | "id": 608, 1084 | "en": "Parfum Palace", 1085 | "ja": "パルファムきゅうでん" 1086 | }, 1087 | { 1088 | "id": 609, 1089 | "en": "Route 7", 1090 | "ja": "7ばんどうろ" 1091 | }, 1092 | { 1093 | "id": 610, 1094 | "en": "Rivière Walk", 1095 | "ja": "リビエールライン" 1096 | }, 1097 | { 1098 | "id": 611, 1099 | "en": "Cyllage City", 1100 | "ja": "ショウヨウシティ" 1101 | }, 1102 | { 1103 | "id": 612, 1104 | "en": "Route 8", 1105 | "ja": "8ばんどうろ" 1106 | }, 1107 | { 1108 | "id": 613, 1109 | "en": "Muraille Coast", 1110 | "ja": "ミュライユかいがん" 1111 | }, 1112 | { 1113 | "id": 614, 1114 | "en": "Ambrette Town", 1115 | "ja": "コウジンタウン" 1116 | }, 1117 | { 1118 | "id": 615, 1119 | "en": "Route 9", 1120 | "ja": "9ばんどうろ" 1121 | }, 1122 | { 1123 | "id": 616, 1124 | "en": "Spikes Passage", 1125 | "ja": "トゲトゲさんどう" 1126 | }, 1127 | { 1128 | "id": 617, 1129 | "en": "Battle Chateau", 1130 | "ja": "バトルシャトー" 1131 | }, 1132 | { 1133 | "id": 618, 1134 | "en": "Route 10", 1135 | "ja": "10ばんどうろ" 1136 | }, 1137 | { 1138 | "id": 619, 1139 | "en": "Menhir Trail", 1140 | "ja": "メンヒルロード" 1141 | }, 1142 | { 1143 | "id": 620, 1144 | "en": "Geosenge Town", 1145 | "ja": "セキタイタウン" 1146 | }, 1147 | { 1148 | "id": 621, 1149 | "en": "Route 11", 1150 | "ja": "11ばんどうろ" 1151 | }, 1152 | { 1153 | "id": 622, 1154 | "en": "Miroir Way", 1155 | "ja": "ミロワールどおり" 1156 | }, 1157 | { 1158 | "id": 623, 1159 | "en": "Reflection Cave", 1160 | "ja": "うつしみのどうくつ" 1161 | }, 1162 | { 1163 | "id": 624, 1164 | "en": "Shalour City", 1165 | "ja": "シャラシティ" 1166 | }, 1167 | { 1168 | "id": 625, 1169 | "en": "Tower of Mastery", 1170 | "ja": "マスタータワー" 1171 | }, 1172 | { 1173 | "id": 626, 1174 | "en": "Route 12", 1175 | "ja": "12ばんどうろ" 1176 | }, 1177 | { 1178 | "id": 627, 1179 | "en": "Fourrage Road", 1180 | "ja": "フラージュどおり" 1181 | }, 1182 | { 1183 | "id": 628, 1184 | "en": "Coumarine City", 1185 | "ja": "ヒヨクシティ" 1186 | }, 1187 | { 1188 | "id": 629, 1189 | "en": "Route 13", 1190 | "ja": "13ばんどうろ" 1191 | }, 1192 | { 1193 | "id": 630, 1194 | "en": "Lumiose Badlands", 1195 | "ja": "ミアレのこうや" 1196 | }, 1197 | { 1198 | "id": 631, 1199 | "en": "Route 14", 1200 | "ja": "14ばんどうろ" 1201 | }, 1202 | { 1203 | "id": 632, 1204 | "en": "Laverre Nature Trail", 1205 | "ja": "クノエのりんどう" 1206 | }, 1207 | { 1208 | "id": 633, 1209 | "en": "Laverre City", 1210 | "ja": "クノエシティ" 1211 | }, 1212 | { 1213 | "id": 634, 1214 | "en": "Poké Ball Factory", 1215 | "ja": "ボールこうじょう" 1216 | }, 1217 | { 1218 | "id": 635, 1219 | "en": "Route 15", 1220 | "ja": "15ばんどうろ" 1221 | }, 1222 | { 1223 | "id": 636, 1224 | "en": "Brun Way", 1225 | "ja": "ブランどおり" 1226 | }, 1227 | { 1228 | "id": 637, 1229 | "en": "Dendemille Town", 1230 | "ja": "フウジョタウン" 1231 | }, 1232 | { 1233 | "id": 638, 1234 | "en": "Route 16", 1235 | "ja": "16ばんどうろ" 1236 | }, 1237 | { 1238 | "id": 639, 1239 | "en": "Mélancolie Path", 1240 | "ja": "トリストどおり" 1241 | }, 1242 | { 1243 | "id": 640, 1244 | "en": "Frost Cavern", 1245 | "ja": "フロストケイブ" 1246 | }, 1247 | { 1248 | "id": 641, 1249 | "en": "Route 17", 1250 | "ja": "17ばんどうろ" 1251 | }, 1252 | { 1253 | "id": 642, 1254 | "en": "Mamoswine Road", 1255 | "ja": "マンムーロード" 1256 | }, 1257 | { 1258 | "id": 643, 1259 | "en": "Anistar City", 1260 | "ja": "ヒャッコクシティ" 1261 | }, 1262 | { 1263 | "id": 644, 1264 | "en": "Route 18", 1265 | "ja": "18ばんどうろ" 1266 | }, 1267 | { 1268 | "id": 645, 1269 | "en": "Vallée Étroite Way", 1270 | "ja": "エトロワ・バレどおり" 1271 | }, 1272 | { 1273 | "id": 646, 1274 | "en": "Couriway Town", 1275 | "ja": "レンリタウン" 1276 | }, 1277 | { 1278 | "id": 647, 1279 | "en": "Route 19", 1280 | "ja": "19ばんどうろ" 1281 | }, 1282 | { 1283 | "id": 648, 1284 | "en": "Grande Vallée Way", 1285 | "ja": "ラルジュ・バレどおり" 1286 | }, 1287 | { 1288 | "id": 649, 1289 | "en": "Snowbelle City", 1290 | "ja": "エイセツシティ" 1291 | }, 1292 | { 1293 | "id": 650, 1294 | "en": "Route 20", 1295 | "ja": "20ばんどうろ" 1296 | }, 1297 | { 1298 | "id": 651, 1299 | "en": "Winding Woods", 1300 | "ja": "まよいのもり" 1301 | }, 1302 | { 1303 | "id": 652, 1304 | "en": "Pokémon Village", 1305 | "ja": "ポケモンのむら" 1306 | }, 1307 | { 1308 | "id": 653, 1309 | "en": "Route 21", 1310 | "ja": "21ばんどうろ" 1311 | }, 1312 | { 1313 | "id": 654, 1314 | "en": "Dernière Way", 1315 | "ja": "デルニエどおり" 1316 | }, 1317 | { 1318 | "id": 655, 1319 | "en": "Route 22", 1320 | "ja": "22ばんどうろ" 1321 | }, 1322 | { 1323 | "id": 656, 1324 | "en": "Détourner Way", 1325 | "ja": "デトルネどおり" 1326 | }, 1327 | { 1328 | "id": 657, 1329 | "en": "Victory Road", 1330 | "ja": "チャンピオンロード" 1331 | }, 1332 | { 1333 | "id": 658, 1334 | "en": "Pokémon League", 1335 | "ja": "ポケモンリーグ" 1336 | }, 1337 | { 1338 | "id": 659, 1339 | "en": "Kiloude City", 1340 | "ja": "キナンシティ" 1341 | }, 1342 | { 1343 | "id": 660, 1344 | "en": "Battle Maison", 1345 | "ja": "バトルハウス" 1346 | }, 1347 | { 1348 | "id": 661, 1349 | "en": "Azure Bay", 1350 | "ja": "アズールわん" 1351 | }, 1352 | { 1353 | "id": 662, 1354 | "en": "Dendemille Gate", 1355 | "ja": "フウジョゲート" 1356 | }, 1357 | { 1358 | "id": 663, 1359 | "en": "Couriway Gate", 1360 | "ja": "レンリゲート" 1361 | }, 1362 | { 1363 | "id": 664, 1364 | "en": "Ambrette Gate", 1365 | "ja": "コウジンゲート" 1366 | }, 1367 | { 1368 | "id": 665, 1369 | "en": "Lumiose Gate", 1370 | "ja": "ミアレゲート" 1371 | }, 1372 | { 1373 | "id": 666, 1374 | "en": "Shalour Gate", 1375 | "ja": "シャラゲート" 1376 | }, 1377 | { 1378 | "id": 667, 1379 | "en": "Coumarine Gate", 1380 | "ja": "ヒヨクゲート" 1381 | }, 1382 | { 1383 | "id": 668, 1384 | "en": "Laverre Gate", 1385 | "ja": "クノエゲート" 1386 | }, 1387 | { 1388 | "id": 669, 1389 | "en": "Anistar Gate", 1390 | "ja": "ヒャッコクゲート" 1391 | }, 1392 | { 1393 | "id": 670, 1394 | "en": "Snowbelle Gate", 1395 | "ja": "エイセツゲート" 1396 | }, 1397 | { 1398 | "id": 671, 1399 | "en": "Glittering Cave", 1400 | "ja": "かがやきのどうくつ" 1401 | }, 1402 | { 1403 | "id": 672, 1404 | "en": "Connecting Cave", 1405 | "ja": "じつなぎのどうけつ" 1406 | }, 1407 | { 1408 | "id": 673, 1409 | "en": "Zubat Roost", 1410 | "ja": "ズバットたちのすみか" 1411 | }, 1412 | { 1413 | "id": 674, 1414 | "en": "Kalos Power Plant", 1415 | "ja": "カロスはつでんしょ" 1416 | }, 1417 | { 1418 | "id": 675, 1419 | "en": "Team Flare Secret HQ", 1420 | "ja": "フレアだんひみつきち" 1421 | }, 1422 | { 1423 | "id": 676, 1424 | "en": "Terminus Cave", 1425 | "ja": "ついのどうくつ" 1426 | }, 1427 | { 1428 | "id": 677, 1429 | "en": "Lost Hotel", 1430 | "ja": "あれはてホテル" 1431 | }, 1432 | { 1433 | "id": 678, 1434 | "en": "Chamber of Emptiness", 1435 | "ja": "うつろのま" 1436 | }, 1437 | { 1438 | "id": 679, 1439 | "en": "Sea Spirit’s Den", 1440 | "ja": "わだつみのあな" 1441 | }, 1442 | { 1443 | "id": 680, 1444 | "en": "Friend Safari", 1445 | "ja": "フレンドサファリ" 1446 | }, 1447 | { 1448 | "id": 681, 1449 | "en": "Blazing Chamber", 1450 | "ja": "かえんのま" 1451 | }, 1452 | { 1453 | "id": 682, 1454 | "en": "Flood Chamber", 1455 | "ja": "すいもんのま" 1456 | }, 1457 | { 1458 | "id": 683, 1459 | "en": "Ironworks Chamber", 1460 | "ja": "こうてつのま" 1461 | }, 1462 | { 1463 | "id": 684, 1464 | "en": "Dragonmark Chamber", 1465 | "ja": "りゅうしょうのま" 1466 | }, 1467 | { 1468 | "id": 685, 1469 | "en": "Radiant Chamber", 1470 | "ja": "ひかりのま" 1471 | }, 1472 | { 1473 | "id": 686, 1474 | "en": "Pokémon League Gate", 1475 | "ja": "ポケモンリーグゲート" 1476 | }, 1477 | { 1478 | "id": 687, 1479 | "en": "Lumiose Station", 1480 | "ja": "ミアレステーション" 1481 | }, 1482 | { 1483 | "id": 688, 1484 | "en": "Kiloude Station", 1485 | "ja": "キナンステーション" 1486 | }, 1487 | { 1488 | "id": 689, 1489 | "en": "Ambrette Aquarium", 1490 | "ja": "コウジンすいぞくかん" 1491 | }, 1492 | { 1493 | "id": 690, 1494 | "en": "Unknown Dungeon", 1495 | "ja": "ななしのどうくつ" 1496 | }, 1497 | { 1498 | "id": 691, 1499 | "en": "Pokémon League", 1500 | "ja": "ポケモンリーグ" 1501 | }, 1502 | { 1503 | "id": 692, 1504 | "en": "Team Aqua Hideout", 1505 | "ja": "アクアだんアジト" 1506 | }, 1507 | { 1508 | "id": 693, 1509 | "en": "Sea Mauville", 1510 | "ja": "シーキンセツ" 1511 | }, 1512 | { 1513 | "id": 694, 1514 | "en": "Team Magma Hideout", 1515 | "ja": "マグマだんアジト" 1516 | }, 1517 | { 1518 | "id": 695, 1519 | "en": "Battle Resort", 1520 | "ja": "バトルリゾート" 1521 | }, 1522 | { 1523 | "id": 696, 1524 | "en": "S.S. Tidal", 1525 | "ja": "タイドリップごう" 1526 | }, 1527 | { 1528 | "id": 697, 1529 | "en": "Mirage Forest", 1530 | "ja": "マボロシもり" 1531 | }, 1532 | { 1533 | "id": 698, 1534 | "en": "Mirage Cave", 1535 | "ja": "マボロシどうくつ" 1536 | }, 1537 | { 1538 | "id": 699, 1539 | "en": "Mirage Mountain", 1540 | "ja": "マボロシやま" 1541 | }, 1542 | { 1543 | "id": 700, 1544 | "en": "Trackless Forest", 1545 | "ja": "みかいのもり" 1546 | }, 1547 | { 1548 | "id": 701, 1549 | "en": "Pathless Plain", 1550 | "ja": "なもなきへいげん" 1551 | }, 1552 | { 1553 | "id": 702, 1554 | "en": "Nameless Cavern", 1555 | "ja": "みちのどうくつ" 1556 | }, 1557 | { 1558 | "id": 703, 1559 | "en": "Fabled Cave", 1560 | "ja": "おぼろのどうくつ" 1561 | }, 1562 | { 1563 | "id": 704, 1564 | "en": "Gnarled Den", 1565 | "ja": "いびつなあな" 1566 | }, 1567 | { 1568 | "id": 705, 1569 | "en": "Crescent Isle", 1570 | "ja": "ゆみなりのしま" 1571 | }, 1572 | { 1573 | "id": 706, 1574 | "en": "Secret Islet", 1575 | "ja": "ひみつのこじま" 1576 | }, 1577 | { 1578 | "id": 707, 1579 | "en": "Soaring in the sky", 1580 | "ja": "おおぞら" 1581 | }, 1582 | { 1583 | "id": 708, 1584 | "en": "Secret Shore", 1585 | "ja": "ひみつのいそべ" 1586 | }, 1587 | { 1588 | "id": 709, 1589 | "en": "Secret Meadow", 1590 | "ja": "ひみつのはなばたけ" 1591 | }, 1592 | { 1593 | "id": 710, 1594 | "en": "Route 1", 1595 | "ja": "1ばんどうろ" 1596 | }, 1597 | { 1598 | "id": 711, 1599 | "en": "Route 1", 1600 | "ja": "1ばんどうろ" 1601 | }, 1602 | { 1603 | "id": 712, 1604 | "en": "Route 3", 1605 | "ja": "3ばんどうろ" 1606 | }, 1607 | { 1608 | "id": 713, 1609 | "en": "Route 2", 1610 | "ja": "2ばんどうろ" 1611 | }, 1612 | { 1613 | "id": 714, 1614 | "en": "Kala’e Bay", 1615 | "ja": "カーラエわん" 1616 | }, 1617 | { 1618 | "id": 715, 1619 | "en": "Melemele Sea", 1620 | "ja": "メレメレかい" 1621 | }, 1622 | { 1623 | "id": 716, 1624 | "en": "Hau’oli City", 1625 | "ja": "ハウオリシティ" 1626 | }, 1627 | { 1628 | "id": 717, 1629 | "en": "Hau’oli City", 1630 | "ja": "ハウオリシティ" 1631 | }, 1632 | { 1633 | "id": 718, 1634 | "en": "Hau’oli City", 1635 | "ja": "ハウオリシティ" 1636 | }, 1637 | { 1638 | "id": 719, 1639 | "en": "Iki Town", 1640 | "ja": "リリィタウン" 1641 | }, 1642 | { 1643 | "id": 720, 1644 | "en": "Mahalo Trail", 1645 | "ja": "マハロさんどう" 1646 | }, 1647 | { 1648 | "id": 721, 1649 | "en": "Mahalo Trail", 1650 | "ja": "マハロさんどう" 1651 | }, 1652 | { 1653 | "id": 722, 1654 | "en": "Ruins of Conflict", 1655 | "ja": "いくさのいせき" 1656 | }, 1657 | { 1658 | "id": 723, 1659 | "en": "Ten Carat Hill", 1660 | "ja": "テンカラットヒル" 1661 | }, 1662 | { 1663 | "id": 724, 1664 | "en": "Ten Carat Hill", 1665 | "ja": "テンカラットヒル" 1666 | }, 1667 | { 1668 | "id": 725, 1669 | "en": "Hau’oli Cemetery", 1670 | "ja": "ハウオリれいえん" 1671 | }, 1672 | { 1673 | "id": 726, 1674 | "en": "Melemele Meadow", 1675 | "ja": "メレメレのはなぞの" 1676 | }, 1677 | { 1678 | "id": 727, 1679 | "en": "Seaward Cave", 1680 | "ja": "うみつなぎのどうけつ" 1681 | }, 1682 | { 1683 | "id": 728, 1684 | "en": "Berry Fields", 1685 | "ja": "きのみばたけ" 1686 | }, 1687 | { 1688 | "id": 729, 1689 | "en": "Verdant Cavern", 1690 | "ja": "しげみのどうくつ" 1691 | }, 1692 | { 1693 | "id": 730, 1694 | "en": "Verdant Cavern", 1695 | "ja": "しげみのどうくつ" 1696 | }, 1697 | { 1698 | "id": 731, 1699 | "en": "Route 4", 1700 | "ja": "4ばんどうろ" 1701 | }, 1702 | { 1703 | "id": 732, 1704 | "en": "Route 5", 1705 | "ja": "5ばんどうろ" 1706 | }, 1707 | { 1708 | "id": 733, 1709 | "en": "Route 6", 1710 | "ja": "6ばんどうろ" 1711 | }, 1712 | { 1713 | "id": 734, 1714 | "en": "Route 7", 1715 | "ja": "7ばんどうろ" 1716 | }, 1717 | { 1718 | "id": 735, 1719 | "en": "Route 8", 1720 | "ja": "8ばんどうろ" 1721 | }, 1722 | { 1723 | "id": 736, 1724 | "en": "Route 9", 1725 | "ja": "9ばんどうろ" 1726 | }, 1727 | { 1728 | "id": 737, 1729 | "en": "Hano Grand Resort", 1730 | "ja": "ハノハノリゾート" 1731 | }, 1732 | { 1733 | "id": 738, 1734 | "en": "Hano Beach", 1735 | "ja": "ハノハノビーチ" 1736 | }, 1737 | { 1738 | "id": 739, 1739 | "en": "Akala Meadow", 1740 | "ja": "アーカラのはなぞの" 1741 | }, 1742 | { 1743 | "id": 740, 1744 | "en": "Paniola Town", 1745 | "ja": "オハナタウン" 1746 | }, 1747 | { 1748 | "id": 741, 1749 | "en": "Heahea City", 1750 | "ja": "カンタイシティ" 1751 | }, 1752 | { 1753 | "id": 742, 1754 | "en": "Konikoni City", 1755 | "ja": "コニコシティ" 1756 | }, 1757 | { 1758 | "id": 743, 1759 | "en": "Royal Avenue", 1760 | "ja": "ロイヤルアベニュー" 1761 | }, 1762 | { 1763 | "id": 744, 1764 | "en": "Memorial Hill", 1765 | "ja": "メモリアルヒル" 1766 | }, 1767 | { 1768 | "id": 745, 1769 | "en": "Paniola Ranch", 1770 | "ja": "オハナぼくじょう" 1771 | }, 1772 | { 1773 | "id": 746, 1774 | "en": "Wela Volcano Park", 1775 | "ja": "ヴェラかざんこうえん" 1776 | }, 1777 | { 1778 | "id": 747, 1779 | "en": "Wela Volcano Park", 1780 | "ja": "ヴェラかざんこうえん" 1781 | }, 1782 | { 1783 | "id": 748, 1784 | "en": "Brooklet Hill", 1785 | "ja": "せせらぎのおか" 1786 | }, 1787 | { 1788 | "id": 749, 1789 | "en": "Brooklet Hill", 1790 | "ja": "せせらぎのおか" 1791 | }, 1792 | { 1793 | "id": 750, 1794 | "en": "Lush Jungle", 1795 | "ja": "シェードジャングル" 1796 | }, 1797 | { 1798 | "id": 751, 1799 | "en": "Ruins of Life", 1800 | "ja": "いのちのいせき" 1801 | }, 1802 | { 1803 | "id": 752, 1804 | "en": "Akala Outskirts", 1805 | "ja": "アーカラじまはずれ" 1806 | }, 1807 | { 1808 | "id": 753, 1809 | "en": "Diglett’s Tunnel", 1810 | "ja": "ディグダトンネル" 1811 | }, 1812 | { 1813 | "id": 754, 1814 | "en": "Battle Royal Dome", 1815 | "ja": "ロイヤルドーム" 1816 | }, 1817 | { 1818 | "id": 755, 1819 | "en": "Route 10", 1820 | "ja": "10ばんどうろ" 1821 | }, 1822 | { 1823 | "id": 756, 1824 | "en": "Route 11", 1825 | "ja": "11ばんどうろ" 1826 | }, 1827 | { 1828 | "id": 757, 1829 | "en": "Secluded Shore", 1830 | "ja": "ウラウラうらかいがん" 1831 | }, 1832 | { 1833 | "id": 758, 1834 | "en": "Route 13", 1835 | "ja": "13ばんどうろ" 1836 | }, 1837 | { 1838 | "id": 759, 1839 | "en": "Tapu Village", 1840 | "ja": "カプのむら" 1841 | }, 1842 | { 1843 | "id": 760, 1844 | "en": "Route 15", 1845 | "ja": "15ばんすいどう" 1846 | }, 1847 | { 1848 | "id": 761, 1849 | "en": "Route 16", 1850 | "ja": "16ばんどうろ" 1851 | }, 1852 | { 1853 | "id": 762, 1854 | "en": "Route 17", 1855 | "ja": "17ばんどうろ" 1856 | }, 1857 | { 1858 | "id": 763, 1859 | "en": "Route 12", 1860 | "ja": "12ばんどうろ" 1861 | }, 1862 | { 1863 | "id": 764, 1864 | "en": "Haina Desert", 1865 | "ja": "ハイナさばく" 1866 | }, 1867 | { 1868 | "id": 765, 1869 | "en": "Route 14", 1870 | "ja": "14ばんどうろ" 1871 | }, 1872 | { 1873 | "id": 766, 1874 | "en": "Ula’ula Meadow", 1875 | "ja": "ウラウラのはなぞの" 1876 | }, 1877 | { 1878 | "id": 767, 1879 | "en": "Po Town", 1880 | "ja": "ポータウン" 1881 | }, 1882 | { 1883 | "id": 768, 1884 | "en": "Malie City", 1885 | "ja": "マリエシティ" 1886 | }, 1887 | { 1888 | "id": 769, 1889 | "en": "Malie Garden", 1890 | "ja": "マリエていえん" 1891 | }, 1892 | { 1893 | "id": 770, 1894 | "en": "Mount Hokulani", 1895 | "ja": "ホクラニだけ" 1896 | }, 1897 | { 1898 | "id": 771, 1899 | "en": "Blush Mountain", 1900 | "ja": "ホテリやま" 1901 | }, 1902 | { 1903 | "id": 772, 1904 | "en": "Ruins of Abundance", 1905 | "ja": "みのりのいせき" 1906 | }, 1907 | { 1908 | "id": 773, 1909 | "en": "Lake of the Sunne", 1910 | "ja": "にちりんのみずうみ" 1911 | }, 1912 | { 1913 | "id": 774, 1914 | "en": "Lake of the Moone", 1915 | "ja": "がちりんのみずうみ" 1916 | }, 1917 | { 1918 | "id": 775, 1919 | "en": "Mount Lanakila", 1920 | "ja": "ラナキラマウンテン" 1921 | }, 1922 | { 1923 | "id": 776, 1924 | "en": "Shady House", 1925 | "ja": "いかがわしきやしき" 1926 | }, 1927 | { 1928 | "id": 777, 1929 | "en": "Thrifty Megamart", 1930 | "ja": "スーパー・メガやす" 1931 | }, 1932 | { 1933 | "id": 778, 1934 | "en": "Hokulani Observatory", 1935 | "ja": "ホクラニてんもんだい" 1936 | }, 1937 | { 1938 | "id": 779, 1939 | "en": "Pokémon League", 1940 | "ja": "ポケモンリーグ" 1941 | }, 1942 | { 1943 | "id": 780, 1944 | "en": "Poni Meadow", 1945 | "ja": "ポニのはなぞの" 1946 | }, 1947 | { 1948 | "id": 781, 1949 | "en": "Poni Wilds", 1950 | "ja": "ポニのげんや" 1951 | }, 1952 | { 1953 | "id": 782, 1954 | "en": "Ancient Poni Path", 1955 | "ja": "ポニのこどう" 1956 | }, 1957 | { 1958 | "id": 783, 1959 | "en": "Poni Breaker Coast", 1960 | "ja": "ポニのあらいそ" 1961 | }, 1962 | { 1963 | "id": 784, 1964 | "en": "Poni Grove", 1965 | "ja": "ポニのじゅりん" 1966 | }, 1967 | { 1968 | "id": 785, 1969 | "en": "Poni Plains", 1970 | "ja": "ポニのこうや" 1971 | }, 1972 | { 1973 | "id": 786, 1974 | "en": "Poni Coast", 1975 | "ja": "ポニのかいがん" 1976 | }, 1977 | { 1978 | "id": 787, 1979 | "en": "Poni Gauntlet", 1980 | "ja": "ポニのけんろ" 1981 | }, 1982 | { 1983 | "id": 788, 1984 | "en": "Seafolk Village", 1985 | "ja": "うみのたみのむら" 1986 | }, 1987 | { 1988 | "id": 789, 1989 | "en": "Vast Poni Canyon", 1990 | "ja": "ポニのだいきょうこく" 1991 | }, 1992 | { 1993 | "id": 790, 1994 | "en": "Altar of the Sunne", 1995 | "ja": "にちりんのさいだん" 1996 | }, 1997 | { 1998 | "id": 791, 1999 | "en": "Altar of the Moone", 2000 | "ja": "がちりんのさいだん" 2001 | }, 2002 | { 2003 | "id": 792, 2004 | "en": "Ruins of Hope", 2005 | "ja": "ひがんのいせき" 2006 | }, 2007 | { 2008 | "id": 793, 2009 | "en": "Resolution Cave", 2010 | "ja": "エンドケイブ" 2011 | }, 2012 | { 2013 | "id": 794, 2014 | "en": "Exeggutor Island", 2015 | "ja": "ナッシー・アイランド" 2016 | }, 2017 | { 2018 | "id": 795, 2019 | "en": "Battle Tree", 2020 | "ja": "バトルツリー" 2021 | }, 2022 | { 2023 | "id": 796, 2024 | "en": "Aether Paradise", 2025 | "ja": "エーテルパラダイス" 2026 | }, 2027 | { 2028 | "id": 797, 2029 | "en": "Ultra Space", 2030 | "ja": "ウルトラスペース" 2031 | }, 2032 | { 2033 | "id": 798, 2034 | "en": "Malie City", 2035 | "ja": "マリエシティ" 2036 | } 2037 | ] 2038 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | UI Library Benchmarks 10 | 11 | 12 |

UI Library Benchmarks

13 | 21 |
22 |

23 | 24 | GitHub 25 | 26 |

27 | 28 | 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ui-library-benchmark", 3 | "version": "0.0.0", 4 | "main": "index.js", 5 | "repository": "https://github.com/uhyo/ui-library-benchmark.git", 6 | "author": "uhyo ", 7 | "license": "MIT", 8 | "scripts": { 9 | "build": "./build.sh", 10 | "serve": "http-server ./dist" 11 | }, 12 | "private": true, 13 | "workspaces": [ 14 | "angular", 15 | "preact", 16 | "react", 17 | "solidjs", 18 | "svelte", 19 | "vue" 20 | ], 21 | "dependencies": { 22 | "http-server": "^14.1.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /preact/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /preact/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Preact 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /preact/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "preact", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build --base=/preact/", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "preact": "^10.5.15" 12 | }, 13 | "devDependencies": { 14 | "@preact/preset-vite": "^2.1.5", 15 | "typescript": "^4.5.4", 16 | "vite": "^2.9.9" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /preact/src/App.module.css: -------------------------------------------------------------------------------- 1 | .pokemonList { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); 4 | grid-gap: 20px; 5 | margin: 20px; 6 | } 7 | 8 | .searchBox { 9 | position: fixed; 10 | top: 50vh; 11 | left: 50vw; 12 | transform: translate(-50%, -50%); 13 | } 14 | 15 | .footer { 16 | text-align: center; 17 | } -------------------------------------------------------------------------------- /preact/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback, useState } from "preact/hooks"; 2 | import classes from "./App.module.css"; 3 | import { Item } from "./components/Item"; 4 | import { SearchBox } from "./components/SearchBox"; 5 | import { itemMap } from "./data/items"; 6 | 7 | export function App() { 8 | const [input, setInput] = useState(""); 9 | const [searchQuery, setSearchQuery] = useState(""); 10 | const onChange = useCallback((input: string) => { 11 | setInput(input); 12 | setSearchQuery(input.toLowerCase()); 13 | }, []); 14 | 15 | return ( 16 | <> 17 |
18 | {Array.from(itemMap.keys()).map((id) => { 19 | return ; 20 | })} 21 |
22 | 31 |
32 | 33 |
34 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /preact/src/components/Item/Item.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | background-color: var(--bg-sub-color); 3 | } 4 | 5 | .id { 6 | color: var(--text-sub-color) 7 | } 8 | 9 | .name > mark { 10 | font-weight: bold; 11 | } 12 | 13 | .unmatchedName { 14 | color: var(--text-sub-color); 15 | } -------------------------------------------------------------------------------- /preact/src/components/Item/index.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "preact/hooks"; 2 | import { itemMap } from "../../data/items"; 3 | import classes from "./Item.module.css"; 4 | 5 | type Props = { 6 | /** 7 | * ID of Item 8 | */ 9 | id: string; 10 | /** 11 | * Search query, in lowercase 12 | */ 13 | searchQuery: string; 14 | }; 15 | 16 | export const Item: preact.FunctionComponent = ({ id, searchQuery }) => { 17 | const item = itemMap.get(id); 18 | if (!item) { 19 | return null; 20 | } 21 | 22 | const name = item.en.toLowerCase(); 23 | const { nameMarked } = useMemo(() => { 24 | if (!searchQuery) { 25 | return { 26 | nameMarked: {item.en}, 27 | }; 28 | } 29 | const searchIndex = name.indexOf(searchQuery); 30 | if (searchIndex === -1) { 31 | return { 32 | nameMarked: ( 33 | 34 | {item.en} 35 | 36 | ), 37 | }; 38 | } 39 | return { 40 | nameMarked: ( 41 | 42 | {item.en.substring(0, searchIndex)} 43 | 44 | {item.en.substring(searchIndex, searchIndex + searchQuery.length)} 45 | 46 | {item.en.substring(searchIndex + searchQuery.length)} 47 | 48 | ), 49 | }; 50 | }, [name, item.en, searchQuery]); 51 | 52 | return ( 53 |
54 |
{item.id}
55 |
{nameMarked}
56 |
{item.ja}
57 |
58 | ); 59 | }; 60 | -------------------------------------------------------------------------------- /preact/src/components/SearchBox/SearchBox.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: grid; 3 | grid-template-columns: 3rem auto 3rem; 4 | grid-template-rows: 3rem auto 3rem; 5 | 6 | border: 1px solid var(--text-color); 7 | background-color: var(--bg-sub-color); 8 | background-repeat: repeat; 9 | } 10 | 11 | .input { 12 | grid-area: 2 / 2; 13 | font-size: 2.5rem; 14 | padding: 0.5rem; 15 | } -------------------------------------------------------------------------------- /preact/src/components/SearchBox/index.tsx: -------------------------------------------------------------------------------- 1 | import classes from "./SearchBox.module.css"; 2 | type Props = { 3 | /** 4 | * current input 5 | */ 6 | input: string; 7 | /** 8 | * onChange handler 9 | */ 10 | onChange: (input: string) => void; 11 | }; 12 | 13 | export const SearchBox: preact.FunctionComponent = ({ 14 | input, 15 | onChange, 16 | }) => { 17 | return ( 18 |
19 | onChange(e.currentTarget.value)} 23 | /> 24 |
25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /preact/src/data: -------------------------------------------------------------------------------- 1 | ../../data -------------------------------------------------------------------------------- /preact/src/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /preact/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 | background-color: var(--bg-color); 10 | color: var(--text-color); 11 | 12 | color-scheme: light dark; 13 | 14 | --bg-color: white; 15 | --text-color: black; 16 | --bg-sub-color: #fafafa; 17 | --text-sub-color: #666666; 18 | } 19 | 20 | @media (prefers-color-scheme: dark) { 21 | body { 22 | --bg-color: #1a1a1a; 23 | --text-color: white; 24 | --bg-sub-color: #333333; 25 | --text-sub-color: #999999; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /preact/src/logo.tsx: -------------------------------------------------------------------------------- 1 | export const Logo = () => ( 2 | 47 | ) 48 | -------------------------------------------------------------------------------- /preact/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { render } from "preact"; 2 | import { App } from "./App"; 3 | 4 | render(, document.getElementById("app")!); 5 | -------------------------------------------------------------------------------- /preact/src/preact.d.ts: -------------------------------------------------------------------------------- 1 | import JSX = preact.JSX 2 | -------------------------------------------------------------------------------- /preact/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /preact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "noUncheckedIndexedAccess": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "module": "ESNext", 14 | "moduleResolution": "Node", 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "noEmit": true, 18 | "jsx": "preserve", 19 | "jsxFactory": "h", 20 | "jsxFragmentFactory": "Fragment" 21 | }, 22 | "include": ["src"], 23 | "references": [{ "path": "./tsconfig.node.json" }] 24 | } 25 | -------------------------------------------------------------------------------- /preact/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /preact/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import preact from '@preact/preset-vite' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [preact()] 7 | }) 8 | -------------------------------------------------------------------------------- /react/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build --base=/react/", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "react": "^18.0.0", 12 | "react-dom": "^18.0.0" 13 | }, 14 | "devDependencies": { 15 | "@types/react": "^18.0.0", 16 | "@types/react-dom": "^18.0.0", 17 | "@vitejs/plugin-react": "^1.3.0", 18 | "typescript": "^4.6.3", 19 | "vite": "^2.9.9" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /react/src/App.module.css: -------------------------------------------------------------------------------- 1 | .pokemonList { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); 4 | grid-gap: 20px; 5 | margin: 20px; 6 | } 7 | 8 | .searchBox { 9 | position: fixed; 10 | top: 50vh; 11 | left: 50vw; 12 | transform: translate(-50%, -50%); 13 | } 14 | 15 | .footer { 16 | text-align: center; 17 | } -------------------------------------------------------------------------------- /react/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback, useState, useTransition } from "react"; 2 | import classes from "./App.module.css"; 3 | import { Item } from "./components/Item"; 4 | import { SearchBox } from "./components/SearchBox"; 5 | import { itemMap } from "./data/items"; 6 | 7 | function App() { 8 | const [input, setInput] = useState(""); 9 | const [searchQuery, setSearchQuery] = useState(""); 10 | const [, startTransition] = useTransition(); 11 | const onChange = useCallback((input: string) => { 12 | setInput(input); 13 | startTransition(() => { 14 | setSearchQuery(input.toLowerCase()); 15 | }); 16 | }, []); 17 | 18 | return ( 19 | <> 20 |
21 | {Array.from(itemMap.keys()).map((id) => { 22 | return ; 23 | })} 24 |
25 | 34 |
35 | 36 |
37 | 38 | ); 39 | } 40 | 41 | export default App; 42 | -------------------------------------------------------------------------------- /react/src/components/Item/Item.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | background-color: var(--bg-sub-color); 3 | } 4 | 5 | .id { 6 | color: var(--text-sub-color) 7 | } 8 | 9 | .name > mark { 10 | font-weight: bold; 11 | } 12 | 13 | .unmatchedName { 14 | color: var(--text-sub-color); 15 | } -------------------------------------------------------------------------------- /react/src/components/Item/index.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { itemMap } from "../../data/items"; 3 | import classes from "./Item.module.css"; 4 | 5 | type Props = { 6 | /** 7 | * ID of Item 8 | */ 9 | id: string; 10 | /** 11 | * Search query, in lowercase 12 | */ 13 | searchQuery: string; 14 | }; 15 | 16 | export const Item: React.FC = ({ id, searchQuery }) => { 17 | const item = itemMap.get(id); 18 | if (!item) { 19 | return null; 20 | } 21 | 22 | const name = item.en.toLowerCase(); 23 | const { nameMarked } = useMemo(() => { 24 | if (!searchQuery) { 25 | return { 26 | nameMarked: {item.en}, 27 | }; 28 | } 29 | const searchIndex = name.indexOf(searchQuery); 30 | if (searchIndex === -1) { 31 | return { 32 | nameMarked: ( 33 | 34 | {item.en} 35 | 36 | ), 37 | }; 38 | } 39 | return { 40 | nameMarked: ( 41 | 42 | {item.en.substring(0, searchIndex)} 43 | 44 | {item.en.substring(searchIndex, searchIndex + searchQuery.length)} 45 | 46 | {item.en.substring(searchIndex + searchQuery.length)} 47 | 48 | ), 49 | }; 50 | }, [name, item.en, searchQuery]); 51 | 52 | return ( 53 |
54 |
{item.id}
55 |
{nameMarked}
56 |
{item.ja}
57 |
58 | ); 59 | }; 60 | -------------------------------------------------------------------------------- /react/src/components/SearchBox/SearchBox.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: grid; 3 | grid-template-columns: 3rem auto 3rem; 4 | grid-template-rows: 3rem auto 3rem; 5 | 6 | border: 1px solid var(--text-color); 7 | background-color: var(--bg-sub-color); 8 | background-repeat: repeat; 9 | } 10 | 11 | .input { 12 | grid-area: 2 / 2; 13 | font-size: 2.5rem; 14 | padding: 0.5rem; 15 | } -------------------------------------------------------------------------------- /react/src/components/SearchBox/index.tsx: -------------------------------------------------------------------------------- 1 | import classes from "./SearchBox.module.css"; 2 | type Props = { 3 | /** 4 | * current input 5 | */ 6 | input: string; 7 | /** 8 | * onChange handler 9 | */ 10 | onChange: (input: string) => void; 11 | }; 12 | 13 | export const SearchBox: React.FC = ({ input, onChange }) => { 14 | return ( 15 |
16 | onChange(e.target.value)} 20 | /> 21 |
22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /react/src/data: -------------------------------------------------------------------------------- 1 | ../../data -------------------------------------------------------------------------------- /react/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 | background-color: var(--bg-color); 10 | color: var(--text-color); 11 | 12 | color-scheme: light dark; 13 | 14 | --bg-color: white; 15 | --text-color: black; 16 | --bg-sub-color: #fafafa; 17 | --text-sub-color: #666666; 18 | } 19 | 20 | @media (prefers-color-scheme: dark) { 21 | body { 22 | --bg-color: #1a1a1a; 23 | --text-color: white; 24 | --bg-sub-color: #333333; 25 | --text-sub-color: #999999; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /react/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | 10 | ) 11 | -------------------------------------------------------------------------------- /react/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /react/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()] 7 | }) 8 | -------------------------------------------------------------------------------- /solidjs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist -------------------------------------------------------------------------------- /solidjs/README.md: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | Those templates dependencies are maintained via [pnpm](https://pnpm.io) via `pnpm up -Lri`. 4 | 5 | This is the reason you see a `pnpm-lock.yaml`. That being said, any package manager will work. This file can be safely be removed once you clone a template. 6 | 7 | ```bash 8 | $ npm install # or pnpm install or yarn install 9 | ``` 10 | 11 | ### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs) 12 | 13 | ## Available Scripts 14 | 15 | In the project directory, you can run: 16 | 17 | ### `npm dev` or `npm start` 18 | 19 | Runs the app in the development mode.
20 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 21 | 22 | The page will reload if you make edits.
23 | 24 | ### `npm run build` 25 | 26 | Builds the app for production to the `dist` folder.
27 | It correctly bundles Solid in production mode and optimizes the build for the best performance. 28 | 29 | The build is minified and the filenames include the hashes.
30 | Your app is ready to be deployed! 31 | 32 | ## Deployment 33 | 34 | You can deploy the `dist` folder to any static host provider (netlify, surge, now, etc.) 35 | -------------------------------------------------------------------------------- /solidjs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Solid 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /solidjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-template-solid", 3 | "version": "0.0.0", 4 | "description": "", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build --base=/solidjs/", 8 | "serve": "vite preview" 9 | }, 10 | "license": "MIT", 11 | "devDependencies": { 12 | "typescript": "^4.6.4", 13 | "vite": "^2.9.9", 14 | "vite-plugin-solid": "^2.2.6" 15 | }, 16 | "dependencies": { 17 | "solid-js": "^1.4.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /solidjs/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | solid-js: ^1.4.2 5 | typescript: ^4.6.4 6 | vite: ^2.9.9 7 | vite-plugin-solid: ^2.2.6 8 | 9 | dependencies: 10 | solid-js: 1.4.2 11 | 12 | devDependencies: 13 | typescript: 4.6.4 14 | vite: 2.9.9 15 | vite-plugin-solid: 2.2.6 16 | 17 | packages: 18 | 19 | /@ampproject/remapping/2.1.2: 20 | resolution: {integrity: sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==} 21 | engines: {node: '>=6.0.0'} 22 | dependencies: 23 | '@jridgewell/trace-mapping': 0.3.4 24 | dev: true 25 | 26 | /@babel/code-frame/7.16.7: 27 | resolution: {integrity: sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==} 28 | engines: {node: '>=6.9.0'} 29 | dependencies: 30 | '@babel/highlight': 7.16.10 31 | dev: true 32 | 33 | /@babel/compat-data/7.17.7: 34 | resolution: {integrity: sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==} 35 | engines: {node: '>=6.9.0'} 36 | dev: true 37 | 38 | /@babel/core/7.17.8: 39 | resolution: {integrity: sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==} 40 | engines: {node: '>=6.9.0'} 41 | dependencies: 42 | '@ampproject/remapping': 2.1.2 43 | '@babel/code-frame': 7.16.7 44 | '@babel/generator': 7.17.7 45 | '@babel/helper-compilation-targets': 7.17.7_@babel+core@7.17.8 46 | '@babel/helper-module-transforms': 7.17.7 47 | '@babel/helpers': 7.17.8 48 | '@babel/parser': 7.17.8 49 | '@babel/template': 7.16.7 50 | '@babel/traverse': 7.17.3 51 | '@babel/types': 7.17.0 52 | convert-source-map: 1.8.0 53 | debug: 4.3.4 54 | gensync: 1.0.0-beta.2 55 | json5: 2.2.1 56 | semver: 6.3.0 57 | transitivePeerDependencies: 58 | - supports-color 59 | dev: true 60 | 61 | /@babel/generator/7.17.7: 62 | resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==} 63 | engines: {node: '>=6.9.0'} 64 | dependencies: 65 | '@babel/types': 7.17.0 66 | jsesc: 2.5.2 67 | source-map: 0.5.7 68 | dev: true 69 | 70 | /@babel/helper-annotate-as-pure/7.16.7: 71 | resolution: {integrity: sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==} 72 | engines: {node: '>=6.9.0'} 73 | dependencies: 74 | '@babel/types': 7.18.0 75 | dev: true 76 | 77 | /@babel/helper-compilation-targets/7.17.7_@babel+core@7.17.8: 78 | resolution: {integrity: sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==} 79 | engines: {node: '>=6.9.0'} 80 | peerDependencies: 81 | '@babel/core': ^7.0.0 82 | dependencies: 83 | '@babel/compat-data': 7.17.7 84 | '@babel/core': 7.17.8 85 | '@babel/helper-validator-option': 7.16.7 86 | browserslist: 4.20.2 87 | semver: 6.3.0 88 | dev: true 89 | 90 | /@babel/helper-create-class-features-plugin/7.17.6_@babel+core@7.17.8: 91 | resolution: {integrity: sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==} 92 | engines: {node: '>=6.9.0'} 93 | peerDependencies: 94 | '@babel/core': ^7.0.0 95 | dependencies: 96 | '@babel/core': 7.17.8 97 | '@babel/helper-annotate-as-pure': 7.16.7 98 | '@babel/helper-environment-visitor': 7.16.7 99 | '@babel/helper-function-name': 7.16.7 100 | '@babel/helper-member-expression-to-functions': 7.17.7 101 | '@babel/helper-optimise-call-expression': 7.16.7 102 | '@babel/helper-replace-supers': 7.16.7 103 | '@babel/helper-split-export-declaration': 7.16.7 104 | transitivePeerDependencies: 105 | - supports-color 106 | dev: true 107 | 108 | /@babel/helper-environment-visitor/7.16.7: 109 | resolution: {integrity: sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==} 110 | engines: {node: '>=6.9.0'} 111 | dependencies: 112 | '@babel/types': 7.17.0 113 | dev: true 114 | 115 | /@babel/helper-function-name/7.16.7: 116 | resolution: {integrity: sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==} 117 | engines: {node: '>=6.9.0'} 118 | dependencies: 119 | '@babel/helper-get-function-arity': 7.16.7 120 | '@babel/template': 7.16.7 121 | '@babel/types': 7.17.0 122 | dev: true 123 | 124 | /@babel/helper-get-function-arity/7.16.7: 125 | resolution: {integrity: sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==} 126 | engines: {node: '>=6.9.0'} 127 | dependencies: 128 | '@babel/types': 7.17.0 129 | dev: true 130 | 131 | /@babel/helper-hoist-variables/7.16.7: 132 | resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} 133 | engines: {node: '>=6.9.0'} 134 | dependencies: 135 | '@babel/types': 7.17.0 136 | dev: true 137 | 138 | /@babel/helper-member-expression-to-functions/7.17.7: 139 | resolution: {integrity: sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw==} 140 | engines: {node: '>=6.9.0'} 141 | dependencies: 142 | '@babel/types': 7.18.0 143 | dev: true 144 | 145 | /@babel/helper-module-imports/7.16.0: 146 | resolution: {integrity: sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==} 147 | engines: {node: '>=6.9.0'} 148 | dependencies: 149 | '@babel/types': 7.17.0 150 | dev: true 151 | 152 | /@babel/helper-module-imports/7.16.7: 153 | resolution: {integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==} 154 | engines: {node: '>=6.9.0'} 155 | dependencies: 156 | '@babel/types': 7.17.0 157 | dev: true 158 | 159 | /@babel/helper-module-transforms/7.17.7: 160 | resolution: {integrity: sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==} 161 | engines: {node: '>=6.9.0'} 162 | dependencies: 163 | '@babel/helper-environment-visitor': 7.16.7 164 | '@babel/helper-module-imports': 7.16.7 165 | '@babel/helper-simple-access': 7.17.7 166 | '@babel/helper-split-export-declaration': 7.16.7 167 | '@babel/helper-validator-identifier': 7.16.7 168 | '@babel/template': 7.16.7 169 | '@babel/traverse': 7.17.3 170 | '@babel/types': 7.17.0 171 | transitivePeerDependencies: 172 | - supports-color 173 | dev: true 174 | 175 | /@babel/helper-optimise-call-expression/7.16.7: 176 | resolution: {integrity: sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==} 177 | engines: {node: '>=6.9.0'} 178 | dependencies: 179 | '@babel/types': 7.18.0 180 | dev: true 181 | 182 | /@babel/helper-plugin-utils/7.16.7: 183 | resolution: {integrity: sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==} 184 | engines: {node: '>=6.9.0'} 185 | dev: true 186 | 187 | /@babel/helper-replace-supers/7.16.7: 188 | resolution: {integrity: sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==} 189 | engines: {node: '>=6.9.0'} 190 | dependencies: 191 | '@babel/helper-environment-visitor': 7.16.7 192 | '@babel/helper-member-expression-to-functions': 7.17.7 193 | '@babel/helper-optimise-call-expression': 7.16.7 194 | '@babel/traverse': 7.17.3 195 | '@babel/types': 7.18.0 196 | transitivePeerDependencies: 197 | - supports-color 198 | dev: true 199 | 200 | /@babel/helper-simple-access/7.17.7: 201 | resolution: {integrity: sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==} 202 | engines: {node: '>=6.9.0'} 203 | dependencies: 204 | '@babel/types': 7.17.0 205 | dev: true 206 | 207 | /@babel/helper-split-export-declaration/7.16.7: 208 | resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==} 209 | engines: {node: '>=6.9.0'} 210 | dependencies: 211 | '@babel/types': 7.17.0 212 | dev: true 213 | 214 | /@babel/helper-validator-identifier/7.16.7: 215 | resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} 216 | engines: {node: '>=6.9.0'} 217 | dev: true 218 | 219 | /@babel/helper-validator-option/7.16.7: 220 | resolution: {integrity: sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==} 221 | engines: {node: '>=6.9.0'} 222 | dev: true 223 | 224 | /@babel/helpers/7.17.8: 225 | resolution: {integrity: sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==} 226 | engines: {node: '>=6.9.0'} 227 | dependencies: 228 | '@babel/template': 7.16.7 229 | '@babel/traverse': 7.17.3 230 | '@babel/types': 7.17.0 231 | transitivePeerDependencies: 232 | - supports-color 233 | dev: true 234 | 235 | /@babel/highlight/7.16.10: 236 | resolution: {integrity: sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==} 237 | engines: {node: '>=6.9.0'} 238 | dependencies: 239 | '@babel/helper-validator-identifier': 7.16.7 240 | chalk: 2.4.2 241 | js-tokens: 4.0.0 242 | dev: true 243 | 244 | /@babel/parser/7.17.8: 245 | resolution: {integrity: sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==} 246 | engines: {node: '>=6.0.0'} 247 | hasBin: true 248 | dependencies: 249 | '@babel/types': 7.17.0 250 | dev: true 251 | 252 | /@babel/plugin-syntax-jsx/7.16.7_@babel+core@7.17.8: 253 | resolution: {integrity: sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==} 254 | engines: {node: '>=6.9.0'} 255 | peerDependencies: 256 | '@babel/core': ^7.0.0-0 257 | dependencies: 258 | '@babel/core': 7.17.8 259 | '@babel/helper-plugin-utils': 7.16.7 260 | dev: true 261 | 262 | /@babel/plugin-syntax-typescript/7.16.7_@babel+core@7.17.8: 263 | resolution: {integrity: sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==} 264 | engines: {node: '>=6.9.0'} 265 | peerDependencies: 266 | '@babel/core': ^7.0.0-0 267 | dependencies: 268 | '@babel/core': 7.17.8 269 | '@babel/helper-plugin-utils': 7.16.7 270 | dev: true 271 | 272 | /@babel/plugin-transform-typescript/7.16.8_@babel+core@7.17.8: 273 | resolution: {integrity: sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==} 274 | engines: {node: '>=6.9.0'} 275 | peerDependencies: 276 | '@babel/core': ^7.0.0-0 277 | dependencies: 278 | '@babel/core': 7.17.8 279 | '@babel/helper-create-class-features-plugin': 7.17.6_@babel+core@7.17.8 280 | '@babel/helper-plugin-utils': 7.16.7 281 | '@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.17.8 282 | transitivePeerDependencies: 283 | - supports-color 284 | dev: true 285 | 286 | /@babel/preset-typescript/7.16.7_@babel+core@7.17.8: 287 | resolution: {integrity: sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==} 288 | engines: {node: '>=6.9.0'} 289 | peerDependencies: 290 | '@babel/core': ^7.0.0-0 291 | dependencies: 292 | '@babel/core': 7.17.8 293 | '@babel/helper-plugin-utils': 7.16.7 294 | '@babel/helper-validator-option': 7.16.7 295 | '@babel/plugin-transform-typescript': 7.16.8_@babel+core@7.17.8 296 | transitivePeerDependencies: 297 | - supports-color 298 | dev: true 299 | 300 | /@babel/template/7.16.7: 301 | resolution: {integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==} 302 | engines: {node: '>=6.9.0'} 303 | dependencies: 304 | '@babel/code-frame': 7.16.7 305 | '@babel/parser': 7.17.8 306 | '@babel/types': 7.17.0 307 | dev: true 308 | 309 | /@babel/traverse/7.17.3: 310 | resolution: {integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==} 311 | engines: {node: '>=6.9.0'} 312 | dependencies: 313 | '@babel/code-frame': 7.16.7 314 | '@babel/generator': 7.17.7 315 | '@babel/helper-environment-visitor': 7.16.7 316 | '@babel/helper-function-name': 7.16.7 317 | '@babel/helper-hoist-variables': 7.16.7 318 | '@babel/helper-split-export-declaration': 7.16.7 319 | '@babel/parser': 7.17.8 320 | '@babel/types': 7.17.0 321 | debug: 4.3.4 322 | globals: 11.12.0 323 | transitivePeerDependencies: 324 | - supports-color 325 | dev: true 326 | 327 | /@babel/types/7.17.0: 328 | resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} 329 | engines: {node: '>=6.9.0'} 330 | dependencies: 331 | '@babel/helper-validator-identifier': 7.16.7 332 | to-fast-properties: 2.0.0 333 | dev: true 334 | 335 | /@babel/types/7.18.0: 336 | resolution: {integrity: sha512-vhAmLPAiC8j9K2GnsnLPCIH5wCrPpYIVBCWRBFDCB7Y/BXLqi/O+1RSTTM2bsmg6U/551+FCf9PNPxjABmxHTw==} 337 | engines: {node: '>=6.9.0'} 338 | dependencies: 339 | '@babel/helper-validator-identifier': 7.16.7 340 | to-fast-properties: 2.0.0 341 | dev: true 342 | 343 | /@jridgewell/resolve-uri/3.0.5: 344 | resolution: {integrity: sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==} 345 | engines: {node: '>=6.0.0'} 346 | dev: true 347 | 348 | /@jridgewell/sourcemap-codec/1.4.11: 349 | resolution: {integrity: sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==} 350 | dev: true 351 | 352 | /@jridgewell/trace-mapping/0.3.4: 353 | resolution: {integrity: sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==} 354 | dependencies: 355 | '@jridgewell/resolve-uri': 3.0.5 356 | '@jridgewell/sourcemap-codec': 1.4.11 357 | dev: true 358 | 359 | /ansi-styles/3.2.1: 360 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 361 | engines: {node: '>=4'} 362 | dependencies: 363 | color-convert: 1.9.3 364 | dev: true 365 | 366 | /babel-plugin-jsx-dom-expressions/0.32.11_@babel+core@7.17.8: 367 | resolution: {integrity: sha512-hytqY33SGW6B3obSLt8K5X510UwtNkTktCCWgwba+QOOV0CowDFiqeL+0ru895FLacFaYANHFTu1y76dg3GVtw==} 368 | dependencies: 369 | '@babel/helper-module-imports': 7.16.0 370 | '@babel/plugin-syntax-jsx': 7.16.7_@babel+core@7.17.8 371 | '@babel/types': 7.17.0 372 | html-entities: 2.3.2 373 | transitivePeerDependencies: 374 | - '@babel/core' 375 | dev: true 376 | 377 | /babel-preset-solid/1.3.13_@babel+core@7.17.8: 378 | resolution: {integrity: sha512-MZnmsceI9yiHlwwFCSALTJhadk2eea/+2UP4ec4jkPZFR+XRKTLoIwRkrBh7uLtvHF+3lHGyUaXtZukOmmUwhA==} 379 | dependencies: 380 | babel-plugin-jsx-dom-expressions: 0.32.11_@babel+core@7.17.8 381 | transitivePeerDependencies: 382 | - '@babel/core' 383 | dev: true 384 | 385 | /browserslist/4.20.2: 386 | resolution: {integrity: sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==} 387 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 388 | hasBin: true 389 | dependencies: 390 | caniuse-lite: 1.0.30001320 391 | electron-to-chromium: 1.4.93 392 | escalade: 3.1.1 393 | node-releases: 2.0.2 394 | picocolors: 1.0.0 395 | dev: true 396 | 397 | /caniuse-lite/1.0.30001320: 398 | resolution: {integrity: sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==} 399 | dev: true 400 | 401 | /chalk/2.4.2: 402 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 403 | engines: {node: '>=4'} 404 | dependencies: 405 | ansi-styles: 3.2.1 406 | escape-string-regexp: 1.0.5 407 | supports-color: 5.5.0 408 | dev: true 409 | 410 | /color-convert/1.9.3: 411 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 412 | dependencies: 413 | color-name: 1.1.3 414 | dev: true 415 | 416 | /color-name/1.1.3: 417 | resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} 418 | dev: true 419 | 420 | /convert-source-map/1.8.0: 421 | resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} 422 | dependencies: 423 | safe-buffer: 5.1.2 424 | dev: true 425 | 426 | /debug/4.3.4: 427 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 428 | engines: {node: '>=6.0'} 429 | peerDependencies: 430 | supports-color: '*' 431 | peerDependenciesMeta: 432 | supports-color: 433 | optional: true 434 | dependencies: 435 | ms: 2.1.2 436 | dev: true 437 | 438 | /electron-to-chromium/1.4.93: 439 | resolution: {integrity: sha512-ywq9Pc5Gwwpv7NG767CtoU8xF3aAUQJjH9//Wy3MBCg4w5JSLbJUq2L8IsCdzPMjvSgxuue9WcVaTOyyxCL0aQ==} 440 | dev: true 441 | 442 | /esbuild-android-64/0.14.39: 443 | resolution: {integrity: sha512-EJOu04p9WgZk0UoKTqLId9VnIsotmI/Z98EXrKURGb3LPNunkeffqQIkjS2cAvidh+OK5uVrXaIP229zK6GvhQ==} 444 | engines: {node: '>=12'} 445 | cpu: [x64] 446 | os: [android] 447 | requiresBuild: true 448 | dev: true 449 | optional: true 450 | 451 | /esbuild-android-arm64/0.14.39: 452 | resolution: {integrity: sha512-+twajJqO7n3MrCz9e+2lVOnFplRsaGRwsq1KL/uOy7xK7QdRSprRQcObGDeDZUZsacD5gUkk6OiHiYp6RzU3CA==} 453 | engines: {node: '>=12'} 454 | cpu: [arm64] 455 | os: [android] 456 | requiresBuild: true 457 | dev: true 458 | optional: true 459 | 460 | /esbuild-darwin-64/0.14.39: 461 | resolution: {integrity: sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==} 462 | engines: {node: '>=12'} 463 | cpu: [x64] 464 | os: [darwin] 465 | requiresBuild: true 466 | dev: true 467 | optional: true 468 | 469 | /esbuild-darwin-arm64/0.14.39: 470 | resolution: {integrity: sha512-/fcQ5UhE05OiT+bW5v7/up1bDsnvaRZPJxXwzXsMRrr7rZqPa85vayrD723oWMT64dhrgWeA3FIneF8yER0XTw==} 471 | engines: {node: '>=12'} 472 | cpu: [arm64] 473 | os: [darwin] 474 | requiresBuild: true 475 | dev: true 476 | optional: true 477 | 478 | /esbuild-freebsd-64/0.14.39: 479 | resolution: {integrity: sha512-oMNH8lJI4wtgN5oxuFP7BQ22vgB/e3Tl5Woehcd6i2r6F3TszpCnNl8wo2d/KvyQ4zvLvCWAlRciumhQg88+kQ==} 480 | engines: {node: '>=12'} 481 | cpu: [x64] 482 | os: [freebsd] 483 | requiresBuild: true 484 | dev: true 485 | optional: true 486 | 487 | /esbuild-freebsd-arm64/0.14.39: 488 | resolution: {integrity: sha512-1GHK7kwk57ukY2yI4ILWKJXaxfr+8HcM/r/JKCGCPziIVlL+Wi7RbJ2OzMcTKZ1HpvEqCTBT/J6cO4ZEwW4Ypg==} 489 | engines: {node: '>=12'} 490 | cpu: [arm64] 491 | os: [freebsd] 492 | requiresBuild: true 493 | dev: true 494 | optional: true 495 | 496 | /esbuild-linux-32/0.14.39: 497 | resolution: {integrity: sha512-g97Sbb6g4zfRLIxHgW2pc393DjnkTRMeq3N1rmjDUABxpx8SjocK4jLen+/mq55G46eE2TA0MkJ4R3SpKMu7dg==} 498 | engines: {node: '>=12'} 499 | cpu: [ia32] 500 | os: [linux] 501 | requiresBuild: true 502 | dev: true 503 | optional: true 504 | 505 | /esbuild-linux-64/0.14.39: 506 | resolution: {integrity: sha512-4tcgFDYWdI+UbNMGlua9u1Zhu0N5R6u9tl5WOM8aVnNX143JZoBZLpCuUr5lCKhnD0SCO+5gUyMfupGrHtfggQ==} 507 | engines: {node: '>=12'} 508 | cpu: [x64] 509 | os: [linux] 510 | requiresBuild: true 511 | dev: true 512 | optional: true 513 | 514 | /esbuild-linux-arm/0.14.39: 515 | resolution: {integrity: sha512-t0Hn1kWVx5UpCzAJkKRfHeYOLyFnXwYynIkK54/h3tbMweGI7dj400D1k0Vvtj2u1P+JTRT9tx3AjtLEMmfVBQ==} 516 | engines: {node: '>=12'} 517 | cpu: [arm] 518 | os: [linux] 519 | requiresBuild: true 520 | dev: true 521 | optional: true 522 | 523 | /esbuild-linux-arm64/0.14.39: 524 | resolution: {integrity: sha512-23pc8MlD2D6Px1mV8GMglZlKgwgNKAO8gsgsLLcXWSs9lQsCYkIlMo/2Ycfo5JrDIbLdwgP8D2vpfH2KcBqrDQ==} 525 | engines: {node: '>=12'} 526 | cpu: [arm64] 527 | os: [linux] 528 | requiresBuild: true 529 | dev: true 530 | optional: true 531 | 532 | /esbuild-linux-mips64le/0.14.39: 533 | resolution: {integrity: sha512-epwlYgVdbmkuRr5n4es3B+yDI0I2e/nxhKejT9H0OLxFAlMkeQZxSpxATpDc9m8NqRci6Kwyb/SfmD1koG2Zuw==} 534 | engines: {node: '>=12'} 535 | cpu: [mips64el] 536 | os: [linux] 537 | requiresBuild: true 538 | dev: true 539 | optional: true 540 | 541 | /esbuild-linux-ppc64le/0.14.39: 542 | resolution: {integrity: sha512-W/5ezaq+rQiQBThIjLMNjsuhPHg+ApVAdTz2LvcuesZFMsJoQAW2hutoyg47XxpWi7aEjJGrkS26qCJKhRn3QQ==} 543 | engines: {node: '>=12'} 544 | cpu: [ppc64] 545 | os: [linux] 546 | requiresBuild: true 547 | dev: true 548 | optional: true 549 | 550 | /esbuild-linux-riscv64/0.14.39: 551 | resolution: {integrity: sha512-IS48xeokcCTKeQIOke2O0t9t14HPvwnZcy+5baG13Z1wxs9ZrC5ig5ypEQQh4QMKxURD5TpCLHw2W42CLuVZaA==} 552 | engines: {node: '>=12'} 553 | cpu: [riscv64] 554 | os: [linux] 555 | requiresBuild: true 556 | dev: true 557 | optional: true 558 | 559 | /esbuild-linux-s390x/0.14.39: 560 | resolution: {integrity: sha512-zEfunpqR8sMomqXhNTFEKDs+ik7HC01m3M60MsEjZOqaywHu5e5682fMsqOlZbesEAAaO9aAtRBsU7CHnSZWyA==} 561 | engines: {node: '>=12'} 562 | cpu: [s390x] 563 | os: [linux] 564 | requiresBuild: true 565 | dev: true 566 | optional: true 567 | 568 | /esbuild-netbsd-64/0.14.39: 569 | resolution: {integrity: sha512-Uo2suJBSIlrZCe4E0k75VDIFJWfZy+bOV6ih3T4MVMRJh1lHJ2UyGoaX4bOxomYN3t+IakHPyEoln1+qJ1qYaA==} 570 | engines: {node: '>=12'} 571 | cpu: [x64] 572 | os: [netbsd] 573 | requiresBuild: true 574 | dev: true 575 | optional: true 576 | 577 | /esbuild-openbsd-64/0.14.39: 578 | resolution: {integrity: sha512-secQU+EpgUPpYjJe3OecoeGKVvRMLeKUxSMGHnK+aK5uQM3n1FPXNJzyz1LHFOo0WOyw+uoCxBYdM4O10oaCAA==} 579 | engines: {node: '>=12'} 580 | cpu: [x64] 581 | os: [openbsd] 582 | requiresBuild: true 583 | dev: true 584 | optional: true 585 | 586 | /esbuild-sunos-64/0.14.39: 587 | resolution: {integrity: sha512-qHq0t5gePEDm2nqZLb+35p/qkaXVS7oIe32R0ECh2HOdiXXkj/1uQI9IRogGqKkK+QjDG+DhwiUw7QoHur/Rwg==} 588 | engines: {node: '>=12'} 589 | cpu: [x64] 590 | os: [sunos] 591 | requiresBuild: true 592 | dev: true 593 | optional: true 594 | 595 | /esbuild-windows-32/0.14.39: 596 | resolution: {integrity: sha512-XPjwp2OgtEX0JnOlTgT6E5txbRp6Uw54Isorm3CwOtloJazeIWXuiwK0ONJBVb/CGbiCpS7iP2UahGgd2p1x+Q==} 597 | engines: {node: '>=12'} 598 | cpu: [ia32] 599 | os: [win32] 600 | requiresBuild: true 601 | dev: true 602 | optional: true 603 | 604 | /esbuild-windows-64/0.14.39: 605 | resolution: {integrity: sha512-E2wm+5FwCcLpKsBHRw28bSYQw0Ikxb7zIMxw3OPAkiaQhLVr3dnVO8DofmbWhhf6b97bWzg37iSZ45ZDpLw7Ow==} 606 | engines: {node: '>=12'} 607 | cpu: [x64] 608 | os: [win32] 609 | requiresBuild: true 610 | dev: true 611 | optional: true 612 | 613 | /esbuild-windows-arm64/0.14.39: 614 | resolution: {integrity: sha512-sBZQz5D+Gd0EQ09tZRnz/PpVdLwvp/ufMtJ1iDFYddDaPpZXKqPyaxfYBLs3ueiaksQ26GGa7sci0OqFzNs7KA==} 615 | engines: {node: '>=12'} 616 | cpu: [arm64] 617 | os: [win32] 618 | requiresBuild: true 619 | dev: true 620 | optional: true 621 | 622 | /esbuild/0.14.39: 623 | resolution: {integrity: sha512-2kKujuzvRWYtwvNjYDY444LQIA3TyJhJIX3Yo4+qkFlDDtGlSicWgeHVJqMUP/2sSfH10PGwfsj+O2ro1m10xQ==} 624 | engines: {node: '>=12'} 625 | hasBin: true 626 | requiresBuild: true 627 | optionalDependencies: 628 | esbuild-android-64: 0.14.39 629 | esbuild-android-arm64: 0.14.39 630 | esbuild-darwin-64: 0.14.39 631 | esbuild-darwin-arm64: 0.14.39 632 | esbuild-freebsd-64: 0.14.39 633 | esbuild-freebsd-arm64: 0.14.39 634 | esbuild-linux-32: 0.14.39 635 | esbuild-linux-64: 0.14.39 636 | esbuild-linux-arm: 0.14.39 637 | esbuild-linux-arm64: 0.14.39 638 | esbuild-linux-mips64le: 0.14.39 639 | esbuild-linux-ppc64le: 0.14.39 640 | esbuild-linux-riscv64: 0.14.39 641 | esbuild-linux-s390x: 0.14.39 642 | esbuild-netbsd-64: 0.14.39 643 | esbuild-openbsd-64: 0.14.39 644 | esbuild-sunos-64: 0.14.39 645 | esbuild-windows-32: 0.14.39 646 | esbuild-windows-64: 0.14.39 647 | esbuild-windows-arm64: 0.14.39 648 | dev: true 649 | 650 | /escalade/3.1.1: 651 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 652 | engines: {node: '>=6'} 653 | dev: true 654 | 655 | /escape-string-regexp/1.0.5: 656 | resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} 657 | engines: {node: '>=0.8.0'} 658 | dev: true 659 | 660 | /fsevents/2.3.2: 661 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 662 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 663 | os: [darwin] 664 | requiresBuild: true 665 | dev: true 666 | optional: true 667 | 668 | /function-bind/1.1.1: 669 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 670 | dev: true 671 | 672 | /gensync/1.0.0-beta.2: 673 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 674 | engines: {node: '>=6.9.0'} 675 | dev: true 676 | 677 | /globals/11.12.0: 678 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 679 | engines: {node: '>=4'} 680 | dev: true 681 | 682 | /has-flag/3.0.0: 683 | resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} 684 | engines: {node: '>=4'} 685 | dev: true 686 | 687 | /has/1.0.3: 688 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 689 | engines: {node: '>= 0.4.0'} 690 | dependencies: 691 | function-bind: 1.1.1 692 | dev: true 693 | 694 | /html-entities/2.3.2: 695 | resolution: {integrity: sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==} 696 | dev: true 697 | 698 | /is-core-module/2.9.0: 699 | resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} 700 | dependencies: 701 | has: 1.0.3 702 | dev: true 703 | 704 | /is-what/4.1.7: 705 | resolution: {integrity: sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==} 706 | engines: {node: '>=12.13'} 707 | dev: true 708 | 709 | /js-tokens/4.0.0: 710 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 711 | dev: true 712 | 713 | /jsesc/2.5.2: 714 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} 715 | engines: {node: '>=4'} 716 | hasBin: true 717 | dev: true 718 | 719 | /json5/2.2.1: 720 | resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} 721 | engines: {node: '>=6'} 722 | hasBin: true 723 | dev: true 724 | 725 | /merge-anything/5.0.2: 726 | resolution: {integrity: sha512-POPQBWkBC0vxdgzRJ2Mkj4+2NTKbvkHo93ih+jGDhNMLzIw+rYKjO7949hOQM2X7DxMHH1uoUkwWFLIzImw7gA==} 727 | engines: {node: '>=12.13'} 728 | dependencies: 729 | is-what: 4.1.7 730 | ts-toolbelt: 9.6.0 731 | dev: true 732 | 733 | /ms/2.1.2: 734 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 735 | dev: true 736 | 737 | /nanoid/3.3.4: 738 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 739 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 740 | hasBin: true 741 | dev: true 742 | 743 | /node-releases/2.0.2: 744 | resolution: {integrity: sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==} 745 | dev: true 746 | 747 | /path-parse/1.0.7: 748 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 749 | dev: true 750 | 751 | /picocolors/1.0.0: 752 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 753 | dev: true 754 | 755 | /postcss/8.4.14: 756 | resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} 757 | engines: {node: ^10 || ^12 || >=14} 758 | dependencies: 759 | nanoid: 3.3.4 760 | picocolors: 1.0.0 761 | source-map-js: 1.0.2 762 | dev: true 763 | 764 | /resolve/1.22.0: 765 | resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} 766 | hasBin: true 767 | dependencies: 768 | is-core-module: 2.9.0 769 | path-parse: 1.0.7 770 | supports-preserve-symlinks-flag: 1.0.0 771 | dev: true 772 | 773 | /rollup/2.74.1: 774 | resolution: {integrity: sha512-K2zW7kV8Voua5eGkbnBtWYfMIhYhT9Pel2uhBk2WO5eMee161nPze/XRfvEQPFYz7KgrCCnmh2Wy0AMFLGGmMA==} 775 | engines: {node: '>=10.0.0'} 776 | hasBin: true 777 | optionalDependencies: 778 | fsevents: 2.3.2 779 | dev: true 780 | 781 | /safe-buffer/5.1.2: 782 | resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} 783 | dev: true 784 | 785 | /semver/6.3.0: 786 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} 787 | hasBin: true 788 | dev: true 789 | 790 | /solid-js/1.4.2: 791 | resolution: {integrity: sha512-IU5yKuT8P/n5F5g8j1rTXqxUdPYmoZDk/074TG94AEYf/nyXAeG82BSge4/lLIbCfUcnGUJ6DRdebIjujOAYyg==} 792 | 793 | /solid-refresh/0.4.0_solid-js@1.4.2: 794 | resolution: {integrity: sha512-5XCUz845n/sHPzKK2i2G2EeV61tAmzv6SqzqhXcPaYhrgzVy7nKTQaBpKK8InKrriq9Z2JFF/mguIU00t/73xw==} 795 | peerDependencies: 796 | solid-js: ^1.3.0 797 | dependencies: 798 | '@babel/generator': 7.17.7 799 | '@babel/helper-module-imports': 7.16.7 800 | '@babel/types': 7.17.0 801 | solid-js: 1.4.2 802 | dev: true 803 | 804 | /source-map-js/1.0.2: 805 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 806 | engines: {node: '>=0.10.0'} 807 | dev: true 808 | 809 | /source-map/0.5.7: 810 | resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=} 811 | engines: {node: '>=0.10.0'} 812 | dev: true 813 | 814 | /supports-color/5.5.0: 815 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 816 | engines: {node: '>=4'} 817 | dependencies: 818 | has-flag: 3.0.0 819 | dev: true 820 | 821 | /supports-preserve-symlinks-flag/1.0.0: 822 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 823 | engines: {node: '>= 0.4'} 824 | dev: true 825 | 826 | /to-fast-properties/2.0.0: 827 | resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} 828 | engines: {node: '>=4'} 829 | dev: true 830 | 831 | /ts-toolbelt/9.6.0: 832 | resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} 833 | dev: true 834 | 835 | /typescript/4.6.4: 836 | resolution: {integrity: sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==} 837 | engines: {node: '>=4.2.0'} 838 | hasBin: true 839 | dev: true 840 | 841 | /vite-plugin-solid/2.2.6: 842 | resolution: {integrity: sha512-J1RnmqkZZJSNYDW7vZj0giKKHLWGr9tS/gxR70WDSTYfhyXrgukbZdIfSEFbtrsg8ZiQ2t2zXcvkWoeefenqKw==} 843 | dependencies: 844 | '@babel/core': 7.17.8 845 | '@babel/preset-typescript': 7.16.7_@babel+core@7.17.8 846 | babel-preset-solid: 1.3.13_@babel+core@7.17.8 847 | merge-anything: 5.0.2 848 | solid-js: 1.4.2 849 | solid-refresh: 0.4.0_solid-js@1.4.2 850 | vite: 2.9.9 851 | transitivePeerDependencies: 852 | - less 853 | - sass 854 | - stylus 855 | - supports-color 856 | dev: true 857 | 858 | /vite/2.9.9: 859 | resolution: {integrity: sha512-ffaam+NgHfbEmfw/Vuh6BHKKlI/XIAhxE5QSS7gFLIngxg171mg1P3a4LSRME0z2ZU1ScxoKzphkipcYwSD5Ew==} 860 | engines: {node: '>=12.2.0'} 861 | hasBin: true 862 | peerDependencies: 863 | less: '*' 864 | sass: '*' 865 | stylus: '*' 866 | peerDependenciesMeta: 867 | less: 868 | optional: true 869 | sass: 870 | optional: true 871 | stylus: 872 | optional: true 873 | dependencies: 874 | esbuild: 0.14.39 875 | postcss: 8.4.14 876 | resolve: 1.22.0 877 | rollup: 2.74.1 878 | optionalDependencies: 879 | fsevents: 2.3.2 880 | dev: true 881 | -------------------------------------------------------------------------------- /solidjs/src/App.module.css: -------------------------------------------------------------------------------- 1 | .pokemonList { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); 4 | grid-gap: 20px; 5 | margin: 20px; 6 | } 7 | 8 | .searchBox { 9 | position: fixed; 10 | top: 50vh; 11 | left: 50vw; 12 | transform: translate(-50%, -50%); 13 | } 14 | 15 | .footer { 16 | text-align: center; 17 | } -------------------------------------------------------------------------------- /solidjs/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Component, createSignal, Index, useTransition } from "solid-js"; 2 | import classes from "./App.module.css"; 3 | import { Item } from "./components/Item"; 4 | import { SearchBox } from "./components/SearchBox"; 5 | import { itemMap } from "./data/items"; 6 | 7 | const App: Component = () => { 8 | const [input, setInput] = createSignal(""); 9 | const [searchQuery, setSearchQuery] = createSignal(""); 10 | const [, startTransition] = useTransition(); 11 | 12 | const onChange = (input: string) => { 13 | setInput(input); 14 | startTransition(() => { 15 | setSearchQuery(input.toLowerCase()); 16 | }); 17 | }; 18 | 19 | return ( 20 | <> 21 |
22 | 23 | {(id) => } 24 | 25 |
26 | 35 |
36 | 37 |
38 | 39 | ); 40 | }; 41 | 42 | export default App; 43 | -------------------------------------------------------------------------------- /solidjs/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uhyo/ui-library-benchmark/ec661339b4cb440fb94344631cdf045bd72a3511/solidjs/src/assets/favicon.ico -------------------------------------------------------------------------------- /solidjs/src/components/Item/Item.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | background-color: var(--bg-sub-color); 3 | } 4 | 5 | .id { 6 | color: var(--text-sub-color) 7 | } 8 | 9 | .name > mark { 10 | font-weight: bold; 11 | } 12 | 13 | .unmatchedName { 14 | color: var(--text-sub-color); 15 | } -------------------------------------------------------------------------------- /solidjs/src/components/Item/index.tsx: -------------------------------------------------------------------------------- 1 | import { Component, createMemo, Show, Switch } from "solid-js"; 2 | import { itemMap } from "../../data/items"; 3 | import classes from "./Item.module.css"; 4 | 5 | type Props = { 6 | /** 7 | * ID of Item 8 | */ 9 | id: string; 10 | /** 11 | * Search query, in lowercase 12 | */ 13 | searchQuery: string; 14 | }; 15 | 16 | export const Item: Component = (props) => { 17 | const item = () => itemMap.get(props.id); 18 | 19 | const nameMarked = createMemo(() => { 20 | const i = item(); 21 | if (!i) { 22 | return undefined; 23 | } 24 | if (!props.searchQuery) { 25 | return { 26 | unmatched: false, 27 | prefix: i.en, 28 | mark: "", 29 | suffix: "", 30 | }; 31 | } 32 | const name = i.en.toLowerCase(); 33 | const searchIndex = name.indexOf(props.searchQuery); 34 | if (searchIndex === -1) { 35 | return { 36 | unmatched: true, 37 | prefix: i.en, 38 | mark: "", 39 | suffix: "", 40 | }; 41 | } 42 | return { 43 | unmatched: false, 44 | prefix: i.en.substring(0, searchIndex), 45 | mark: i.en.substring(searchIndex, searchIndex + props.searchQuery.length), 46 | suffix: i.en.substring(searchIndex + props.searchQuery.length), 47 | }; 48 | }); 49 | 50 | return ( 51 | 52 |
53 |
{item()!.id}
54 |
55 | 61 | {nameMarked()!.prefix} 62 | 63 | {nameMarked()!.mark} 64 | 65 | {nameMarked()!.suffix} 66 | 67 |
68 |
{item()!.ja}
69 |
70 |
71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /solidjs/src/components/SearchBox/SearchBox.module.css: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | display: grid; 3 | grid-template-columns: 3rem auto 3rem; 4 | grid-template-rows: 3rem auto 3rem; 5 | 6 | border: 1px solid var(--text-color); 7 | background-color: var(--bg-sub-color); 8 | background-repeat: repeat; 9 | } 10 | 11 | .input { 12 | grid-area: 2 / 2; 13 | font-size: 2.5rem; 14 | padding: 0.5rem; 15 | } -------------------------------------------------------------------------------- /solidjs/src/components/SearchBox/index.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "solid-js"; 2 | import classes from "./SearchBox.module.css"; 3 | 4 | type Props = { 5 | /** 6 | * current input 7 | */ 8 | input: string; 9 | /** 10 | * onChange handler 11 | */ 12 | onChange: (input: string) => void; 13 | }; 14 | 15 | export const SearchBox: Component = (props) => { 16 | return ( 17 |
18 | 22 | props.onChange((e.currentTarget as HTMLInputElement).value) 23 | } 24 | /> 25 |
26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /solidjs/src/data: -------------------------------------------------------------------------------- 1 | ../../data -------------------------------------------------------------------------------- /solidjs/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 | background-color: var(--bg-color); 10 | color: var(--text-color); 11 | 12 | color-scheme: light dark; 13 | 14 | --bg-color: white; 15 | --text-color: black; 16 | --bg-sub-color: #fafafa; 17 | --text-sub-color: #666666; 18 | } 19 | 20 | @media (prefers-color-scheme: dark) { 21 | body { 22 | --bg-color: #1a1a1a; 23 | --text-color: white; 24 | --bg-sub-color: #333333; 25 | --text-sub-color: #999999; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /solidjs/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 | render(() => , document.getElementById('root') as HTMLElement); 8 | -------------------------------------------------------------------------------- /solidjs/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 | -------------------------------------------------------------------------------- /solidjs/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import solidPlugin from 'vite-plugin-solid'; 3 | 4 | export default defineConfig({ 5 | plugins: [solidPlugin()], 6 | build: { 7 | target: 'esnext', 8 | polyfillDynamicImport: false, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /svelte/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /svelte/README.md: -------------------------------------------------------------------------------- 1 | # Svelte + TS + Vite 2 | 3 | This template should help get you started developing with Svelte and TypeScript in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). 8 | 9 | ## Need an official Svelte framework? 10 | 11 | Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. 12 | 13 | ## Technical considerations 14 | 15 | **Why use this over SvelteKit?** 16 | 17 | - It brings its own routing solution which might not be preferable for some users. 18 | - It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. 19 | `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. 20 | 21 | This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. 22 | 23 | Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. 24 | 25 | **Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** 26 | 27 | Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. 28 | 29 | **Why include `.vscode/extensions.json`?** 30 | 31 | Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. 32 | 33 | **Why enable `allowJs` in the TS template?** 34 | 35 | While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. 36 | 37 | **Why is HMR not preserving my local component state?** 38 | 39 | HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). 40 | 41 | If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. 42 | 43 | ```ts 44 | // store.ts 45 | // An extremely simple external store 46 | import { writable } from 'svelte/store' 47 | export default writable(0) 48 | ``` 49 | -------------------------------------------------------------------------------- /svelte/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Svelte 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build --base=/svelte/", 9 | "preview": "vite preview", 10 | "check": "svelte-check --tsconfig ./tsconfig.json" 11 | }, 12 | "devDependencies": { 13 | "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30", 14 | "@tsconfig/svelte": "^2.0.1", 15 | "svelte": "^3.44.0", 16 | "svelte-check": "^2.2.7", 17 | "svelte-preprocess": "^4.9.8", 18 | "tslib": "^2.3.1", 19 | "typescript": "^4.5.4", 20 | "vite": "^2.9.9" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /svelte/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uhyo/ui-library-benchmark/ec661339b4cb440fb94344631cdf045bd72a3511/svelte/public/favicon.ico -------------------------------------------------------------------------------- /svelte/src/App.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 | {#each itemIds as id} 12 | 13 | {/each} 14 |
15 | 16 |
17 |

18 | Data is obtained from PokéAPI. 21 |

22 |
23 | 24 | 27 | 28 | 47 | -------------------------------------------------------------------------------- /svelte/src/components/Item.svelte: -------------------------------------------------------------------------------- 1 | 50 | 51 | {#if item && nameMarked} 52 |
53 |
{id}
54 |
55 | 56 | {nameMarked.prefix}{#if nameMarked.mark}{nameMarked.mark}{/if}{nameMarked.suffix} 58 | 59 |
60 |
{item.ja}
61 |
62 | {/if} 63 | 64 | 81 | -------------------------------------------------------------------------------- /svelte/src/components/SearchBox.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 7 |
8 | 9 | 26 | -------------------------------------------------------------------------------- /svelte/src/data: -------------------------------------------------------------------------------- 1 | ../../data -------------------------------------------------------------------------------- /svelte/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 | background-color: var(--bg-color); 10 | color: var(--text-color); 11 | 12 | color-scheme: light dark; 13 | 14 | --bg-color: white; 15 | --text-color: black; 16 | --bg-sub-color: #fafafa; 17 | --text-sub-color: #666666; 18 | } 19 | 20 | @media (prefers-color-scheme: dark) { 21 | body { 22 | --bg-color: #1a1a1a; 23 | --text-color: white; 24 | --bg-sub-color: #333333; 25 | --text-sub-color: #999999; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /svelte/src/main.ts: -------------------------------------------------------------------------------- 1 | import App from "./App.svelte"; 2 | 3 | const app = new App({ 4 | target: document.getElementById("app")!, 5 | }); 6 | 7 | export default app; 8 | -------------------------------------------------------------------------------- /svelte/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from 'svelte-preprocess' 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess() 7 | } 8 | -------------------------------------------------------------------------------- /svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "resolveJsonModule": true, 8 | "baseUrl": ".", 9 | "strict": true, 10 | "noUncheckedIndexedAccess": true, 11 | /** 12 | * Typecheck JS in `.svelte` and `.js` files by default. 13 | * Disable checkJs if you'd like to use dynamic types in JS. 14 | * Note that setting allowJs false does not prevent the use 15 | * of JS in `.svelte` files. 16 | */ 17 | "allowJs": true, 18 | "checkJs": true, 19 | "isolatedModules": true 20 | }, 21 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], 22 | "references": [{ "path": "./tsconfig.node.json" }] 23 | } 24 | -------------------------------------------------------------------------------- /svelte/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /svelte/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import { svelte } from '@sveltejs/vite-plugin-svelte' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [svelte()] 7 | }) 8 | -------------------------------------------------------------------------------- /vue/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /vue/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + TypeScript + Vite 2 | 3 | This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` 13 | 14 | 15 | -------------------------------------------------------------------------------- /vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue", 3 | "private": true, 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vue-tsc --noEmit && vite build --base=/vue/", 8 | "preview": "vite preview" 9 | }, 10 | "dependencies": { 11 | "vue": "^3.2.25" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-vue": "^2.3.3", 15 | "typescript": "^4.5.4", 16 | "vite": "^2.9.9", 17 | "vue-tsc": "^0.34.7" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /vue/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uhyo/ui-library-benchmark/ec661339b4cb440fb94344631cdf045bd72a3511/vue/public/favicon.ico -------------------------------------------------------------------------------- /vue/src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 29 | 30 | 49 | -------------------------------------------------------------------------------- /vue/src/components/Item.vue: -------------------------------------------------------------------------------- 1 | 49 | 60 | -------------------------------------------------------------------------------- /vue/src/components/SearchBox.vue: -------------------------------------------------------------------------------- 1 | 19 | 29 | -------------------------------------------------------------------------------- /vue/src/data: -------------------------------------------------------------------------------- 1 | ../../data -------------------------------------------------------------------------------- /vue/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 6 | const component: DefineComponent<{}, {}, any> 7 | export default component 8 | } 9 | -------------------------------------------------------------------------------- /vue/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 | background-color: var(--bg-color); 10 | color: var(--text-color); 11 | 12 | color-scheme: light dark; 13 | 14 | --bg-color: white; 15 | --text-color: black; 16 | --bg-sub-color: #fafafa; 17 | --text-sub-color: #666666; 18 | } 19 | 20 | @media (prefers-color-scheme: dark) { 21 | body { 22 | --bg-color: #1a1a1a; 23 | --text-color: white; 24 | --bg-sub-color: #333333; 25 | --text-sub-color: #999999; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /vue/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | createApp(App).mount('#app') 5 | -------------------------------------------------------------------------------- /vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "noUncheckedIndexedAccess": true, 9 | "jsx": "preserve", 10 | "sourceMap": true, 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "esModuleInterop": true, 14 | "lib": ["esnext", "dom"], 15 | "types": [], 16 | "skipLibCheck": true 17 | }, 18 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], 19 | "references": [{ "path": "./tsconfig.node.json" }] 20 | } 21 | -------------------------------------------------------------------------------- /vue/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node" 6 | }, 7 | "include": ["vite.config.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [vue()] 7 | }) 8 | --------------------------------------------------------------------------------