mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2025-12-11 05:16:16 +00:00
initial commit
This commit is contained in:
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
.idea
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
13
.prettierignore
Normal file
13
.prettierignore
Normal file
@@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
9
.prettierrc
Normal file
9
.prettierrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"useTabs": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"printWidth": 100,
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"pluginSearchDirs": ["."],
|
||||
"overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]
|
||||
}
|
||||
17
.stylelintrc.json
Normal file
17
.stylelintrc.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard-scss",
|
||||
"stylelint-config-recommended-scss",
|
||||
"stylelint-config-html/svelte",
|
||||
"stylelint-config-clean-order",
|
||||
"stylelint-config-prettier-scss"
|
||||
],
|
||||
"rules": {
|
||||
"selector-pseudo-class-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignorePseudoClasses": ["global"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
38
README.md
Normal file
38
README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# dot i/o V2
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```bash
|
||||
# create a new project in the current directory
|
||||
npm create svelte@latest
|
||||
|
||||
# create a new project in my-app
|
||||
npm create svelte@latest my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
||||
13
jsconfig.json
Normal file
13
jsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
7224
package-lock.json
generated
Normal file
7224
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
39
package.json
Normal file
39
package.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "cccs",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
||||
"lint": "prettier --plugin-search-dir . --check .",
|
||||
"format": "prettier --plugin-search-dir . --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theaninova/prettier-config": "^1.0.0",
|
||||
"@types/w3c-web-serial": "^1.0.3",
|
||||
"@vite-pwa/sveltekit": "^0.2.5",
|
||||
"stylelint": "^15.9.0",
|
||||
"stylelint-config-standard-scss": "^10.0.0",
|
||||
"stylelint-config-prettier-scss": "^1.0.0",
|
||||
"stylelint-config-html": "^1.1.0",
|
||||
"stylelint-config-recommended-scss": "^12.0.0",
|
||||
"stylelint-config-clean-order": "^5.0.1",
|
||||
"@sveltejs/adapter-static": "^2.0.2",
|
||||
"@sveltejs/kit": "^1.20.4",
|
||||
"@material/material-color-utilities": "^0.2.7",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.10.1",
|
||||
"svelte": "^4.0.0",
|
||||
"svelte-check": "^3.4.3",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^4.3.6",
|
||||
"vite-plugin-pwa": "^0.16.4",
|
||||
"svelte-preprocess": "^5.0.4",
|
||||
"sass": "^1.63.6"
|
||||
},
|
||||
"type": "module",
|
||||
"prettier": "@theaninova/prettier-config"
|
||||
}
|
||||
12
src/app.d.ts
vendored
Normal file
12
src/app.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
12
src/app.html
Normal file
12
src/app.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
497
src/lib/assets/CC1_Default_Chord_Library.csv
Normal file
497
src/lib/assets/CC1_Default_Chord_Library.csv
Normal file
@@ -0,0 +1,497 @@
|
||||
s + Dup,say
|
||||
y + b,by
|
||||
y + Dup,why
|
||||
n + Dup,no
|
||||
n + f,find
|
||||
l + f,life
|
||||
l + p,people
|
||||
l + s + p,spell
|
||||
l + n,line
|
||||
l + n + p,plant
|
||||
t + h,that
|
||||
t + n + h,than
|
||||
t + n + p,plant
|
||||
t + l + f,left
|
||||
a + f,after
|
||||
a + d,add
|
||||
a + d + f,had
|
||||
a + h,has
|
||||
a + s,as
|
||||
a + s + h,has
|
||||
a + y + d,day
|
||||
a + y + s,say
|
||||
a + n,an
|
||||
a + n + d,and
|
||||
a + n + d + f,hand
|
||||
a + n + h,hand
|
||||
a + n + y,any
|
||||
a + l,all
|
||||
a + l + d,land
|
||||
a + l + p,plant
|
||||
a + l + s,last
|
||||
a + l + y + p,play
|
||||
a + l + n + d,land
|
||||
a + t,at
|
||||
a + t + h,that
|
||||
a + t + n + h,than
|
||||
a + t + l + s,last
|
||||
a + t + l + n + p,plant
|
||||
- + ?,question
|
||||
w + h,who
|
||||
w + s,saw
|
||||
w + y + h,why
|
||||
w + t,without
|
||||
w + t + h,watch
|
||||
w + t + n,went
|
||||
w + a,was
|
||||
w + a + h,what
|
||||
w + a + s,saw
|
||||
w + a + y,way
|
||||
w + a + y + Dup,away
|
||||
w + a + n,want
|
||||
w + a + l + f,walk
|
||||
w + a + l + y,always
|
||||
w + a + l + y + s,always
|
||||
w + a + t,watch
|
||||
w + a + t + h,watch
|
||||
w + a + t + n,want
|
||||
g + b,begin
|
||||
g + Dup,question
|
||||
g + h,here
|
||||
g + p,page
|
||||
g + l + n,long
|
||||
g + t,get
|
||||
k + q,quick
|
||||
k + f,and
|
||||
k + l + y + q,quickly
|
||||
k + t + l,talk
|
||||
k + a + b,back
|
||||
k + a + s,ask
|
||||
k + a + t + l,talk
|
||||
k + w + a + l,walk
|
||||
m + f,form
|
||||
m + y,my
|
||||
m + t + Dup,mountain
|
||||
m + a + f,family
|
||||
m + a + s,small
|
||||
m + a + y,may
|
||||
m + a + n,man
|
||||
m + a + n + y,many
|
||||
m + a + l,almost
|
||||
m + a + l + s,small
|
||||
m + a + l + s + Dup,small
|
||||
c + b,because
|
||||
c + Dup,sea
|
||||
c + h,head
|
||||
c + a + n,can
|
||||
c + a + n + h,change
|
||||
c + a + l,call
|
||||
c + a + l + p,place
|
||||
c + k + a + b,back
|
||||
u + p,us
|
||||
u + y,you
|
||||
u + j,just
|
||||
u + j + s,just
|
||||
u + t + b,but
|
||||
u + t + p,put
|
||||
u + t + s + d,study
|
||||
u + t + n,until
|
||||
u + t + j + s,just
|
||||
u + a + l,last
|
||||
u + k + q,quick
|
||||
u + k + l + y + q,quickly
|
||||
u + m + h,much
|
||||
u + m + n,number
|
||||
u + m + t + s,must
|
||||
u + m + c + h,much
|
||||
u + c + s + h,such
|
||||
u + c + t,cut
|
||||
u + c + t + n,country
|
||||
' + a + s,say
|
||||
' + a + n,any
|
||||
' + m + a + n,many
|
||||
o + Dup,off
|
||||
o + f,of
|
||||
o + f + f,food
|
||||
o + d,do
|
||||
o + s,so
|
||||
o + y + b,boy
|
||||
o + n,on
|
||||
o + n + s + Dup,soon
|
||||
o + l,line
|
||||
o + l + Dup,oil
|
||||
o + l + d,old
|
||||
o + l + y,only
|
||||
o + l + n + y,only
|
||||
o + t,to
|
||||
o + t + b,both
|
||||
o + t + Dup,too
|
||||
o + t + s,stop
|
||||
o + t + s + p,stop
|
||||
o + t + n,not
|
||||
o + t + n + f,often
|
||||
o + t + n + d,don't
|
||||
o + t + n + p,point
|
||||
o + a + n + h,another
|
||||
o + a + l,also
|
||||
o + a + l + s,also
|
||||
o + w,own
|
||||
o + w + h,how
|
||||
o + w + s + h,show
|
||||
o + w + n,now
|
||||
o + w + n + d,down
|
||||
o + w + l + f,follow
|
||||
o + w + t,two
|
||||
o + g,go
|
||||
o + g + Dup,good
|
||||
o + g + n + s,song
|
||||
o + g + l + n,long
|
||||
o + g + t,got
|
||||
o + g + a + l,along
|
||||
o + g + a + l + n,along
|
||||
o + k + b,book
|
||||
o + k + n,know
|
||||
o + k + l,look
|
||||
o + k + t,took
|
||||
o + k + t + Dup,took
|
||||
o + k + w + n,know
|
||||
o + v + a + b,above
|
||||
o + v + k,move
|
||||
o + m + s,some
|
||||
o + m + t + s,most
|
||||
o + m + a + l,almost
|
||||
o + m + a + l + s,almost
|
||||
o + m + a + t + l + s,almost
|
||||
o + c + f,food
|
||||
o + c + l + s + h,school
|
||||
o + u,our
|
||||
o + u + f,four
|
||||
o + u + s + h,should
|
||||
o + u + y,you
|
||||
o + u + n + f,found
|
||||
o + u + n + f + f,found
|
||||
o + u + n + s,sound
|
||||
o + u + n + s + d,sound
|
||||
o + u + l + s + d + f,should
|
||||
o + u + l + s + h,should
|
||||
o + u + t,out
|
||||
o + u + a + b,about
|
||||
o + u + a + t + b,about
|
||||
o + u + w + l + d,would
|
||||
o + u + g + n + y,young
|
||||
o + u + g + t + h,thought
|
||||
o + u + m + t + n,mountain
|
||||
o + u + m + t + n + Dup,mountain
|
||||
o + u + c + l + d,could
|
||||
o + ' + t + n + d,don't
|
||||
o + o + l,oil
|
||||
o + o + t + n,into
|
||||
o + o + t + n + p,point
|
||||
o + o + u + w + t + h,without
|
||||
o + o + u + m + a + t + n,mountain
|
||||
i + f,if
|
||||
i + f + f,different
|
||||
i + d,did
|
||||
i + RH_Thumb_1_Center,different
|
||||
i + s,is
|
||||
i + s + d,side
|
||||
i + s + h,his
|
||||
i + n,in
|
||||
i + n + f + f,find
|
||||
i + l,list
|
||||
i + l + n,line
|
||||
i + t,it
|
||||
i + t + s + Dup,still
|
||||
i + t + s + h,this
|
||||
i + t + n,into
|
||||
i + t + l + s,list
|
||||
i + t + l + s + Dup,still
|
||||
i + a + s,said
|
||||
i + a + s + d,said
|
||||
i + a + n,animal
|
||||
i + w + h,which
|
||||
i + w + h + Dup,which
|
||||
i + w + l,will
|
||||
i + w + l + Dup,will
|
||||
i + w + l + h,while
|
||||
i + w + t + h,with
|
||||
i + g,give
|
||||
i + g + b,big
|
||||
i + g + h,high
|
||||
i + g + n + h,night
|
||||
i + g + l + h,light
|
||||
i + g + t + n + h,thing
|
||||
i + g + t + l + h,light
|
||||
i + g + a + n,again
|
||||
i + g + a + n + Dup,again
|
||||
i + k + n + d,kind
|
||||
i + k + l,like
|
||||
i + k + t + n + h,think
|
||||
i + v + l,live
|
||||
i + m + h,him
|
||||
i + m + p,important
|
||||
i + m + s,miss
|
||||
i + m + s + Dup,miss
|
||||
i + m + l,mile
|
||||
i + m + t,time
|
||||
i + m + t + h,might
|
||||
i + m + a + n,animal
|
||||
i + m + a + n + Dup,animal
|
||||
i + m + a + l + n,another
|
||||
i + m + g + t + h,might
|
||||
i + c + p,picture
|
||||
i + c + t + y,city
|
||||
i + u + t + l + n,until
|
||||
i + u + w + t + h,without
|
||||
i + u + k + q,quick
|
||||
i + u + k + l + y + q,quickly
|
||||
i + u + c + k + q,quick
|
||||
i + u + c + k + l + y + q,quickly
|
||||
i + ' + t,it's
|
||||
i + ' + t + s,it's
|
||||
e + b,be
|
||||
e + Dup,earth
|
||||
e + x,example
|
||||
e + f + b,before
|
||||
e + h,he
|
||||
e + h + Dup,here
|
||||
e + s,state
|
||||
e + s + Dup,see
|
||||
e + s + h,she
|
||||
e + y + Dup,eye
|
||||
e + n,name
|
||||
e + n + b,been
|
||||
e + n + Dup,need
|
||||
e + n + d,end
|
||||
e + l + h,help
|
||||
e + l + h + f,help
|
||||
e + l + s + p,spell
|
||||
e + t,the
|
||||
e + t + Dup,eat
|
||||
e + t + f,feet
|
||||
e + t + h,there
|
||||
e + t + s,set
|
||||
e + t + s + h,these
|
||||
e + t + y + h,they
|
||||
e + t + n + x,next
|
||||
e + t + n + h,then
|
||||
e + t + l,let
|
||||
e + t + l + Dup,tell
|
||||
e + t + l + f,left
|
||||
e + a,at
|
||||
e + a + f,father
|
||||
e + a + d + f,head
|
||||
e + a + h,hear
|
||||
e + a + p,paper
|
||||
e + a + s,sea
|
||||
e + a + y,year
|
||||
e + a + n,name
|
||||
e + a + t,eat
|
||||
e + a + t + s + Dup,state
|
||||
e + w,we
|
||||
e + w + f,few
|
||||
e + w + n,new
|
||||
e + w + n + h,when
|
||||
e + w + l,well
|
||||
e + w + l + Dup,well
|
||||
e + w + t + b,between
|
||||
e + w + t + n,went
|
||||
e + w + t + n + b,between
|
||||
e + g + h,here
|
||||
e + g + t,get
|
||||
e + g + a + p,page
|
||||
e + g + a + n + b,began
|
||||
e + k,keep
|
||||
e + k + p,keep
|
||||
e + k + t,take
|
||||
e + k + a + t,take
|
||||
e + v + y,every
|
||||
e + v + n,even
|
||||
e + v + a + h,have
|
||||
e + v + a + l,leave
|
||||
e + v + a + l + Dup,leave
|
||||
e + m,me
|
||||
e + m + s,seem
|
||||
e + m + s + Dup,seem
|
||||
e + m + n,men
|
||||
e + m + t + h,them
|
||||
e + m + a,make
|
||||
e + m + a + d,made
|
||||
e + m + a + s,same
|
||||
e + m + a + n,mean
|
||||
e + m + a + l + p + x,example
|
||||
e + m + c + a,came
|
||||
e + c + s,second
|
||||
e + c + t + n + s,sentence
|
||||
e + c + a,came
|
||||
e + c + a + f,face
|
||||
e + c + a + h,each
|
||||
e + c + a + l + p,place
|
||||
e + LH_Thumb_1_Center + a,make
|
||||
e + u + s,use
|
||||
e + u + s + q,question
|
||||
e + u + n + d,under
|
||||
e + u + t + q,quite
|
||||
e + u + c + a + s + b,because
|
||||
e + o + p,open
|
||||
e + o + s + d,does
|
||||
e + o + n,one
|
||||
e + o + n + p,open
|
||||
e + o + l + b,below
|
||||
e + o + l + h,hello
|
||||
e + o + l + h + Dup,hello
|
||||
e + o + l + p,people
|
||||
e + o + t + f,often
|
||||
e + o + t + h,other
|
||||
e + o + t + s + h,those
|
||||
e + o + t + n + f,often
|
||||
e + o + w + l + b,below
|
||||
e + o + g + t + h,together
|
||||
e + o + v,over
|
||||
e + o + v + a + b,above
|
||||
e + o + v + k,move
|
||||
e + o + m,move
|
||||
e + o + m + h,home
|
||||
e + o + m + s,some
|
||||
e + o + m + t + s,sometime
|
||||
e + o + m + t + s + h,something
|
||||
e + o + m + g + t + n + s + h,something
|
||||
e + o + m + c,come
|
||||
e + o + c,come
|
||||
e + o + c + n,once
|
||||
e + o + c + n + s + d,second
|
||||
e + o + c + l + s,close
|
||||
e + o + u + s + h,house
|
||||
e + o + u + n,enough
|
||||
e + o + u + g + n + h,enough
|
||||
e + i + s + d,side
|
||||
e + i + l + f,life
|
||||
e + i + l + n,line
|
||||
e + i + t + q,quite
|
||||
e + i + t + l,little
|
||||
e + i + t + l + Dup,little
|
||||
e + i + a + d,idea
|
||||
e + i + w + l + h,while
|
||||
e + i + w + t + h,white
|
||||
e + i + g,give
|
||||
e + i + g + p,give
|
||||
e + i + g + n + b,begin
|
||||
e + i + k + l,like
|
||||
e + i + v + l,live
|
||||
e + i + m + l,mile
|
||||
e + i + m + t,time
|
||||
e + i + u + t + q,quite
|
||||
e + i + u + u + t + n + s + q,question
|
||||
r + e + h,her
|
||||
r + e + t + Dup,tree
|
||||
r + e + t + h,there
|
||||
r + e + t + h + Dup,three
|
||||
r + e + t + l,letter
|
||||
r + e + a,are
|
||||
r + e + a + d,read
|
||||
r + e + a + h,hear
|
||||
r + e + a + p,paper
|
||||
r + e + a + n,near
|
||||
r + e + a + l + y,really
|
||||
r + e + a + l + y + Dup,really
|
||||
r + e + a + t + f,after
|
||||
r + e + a + t + h,earth
|
||||
r + e + a + t + RH_Thumb_1_Center,father
|
||||
r + e + a + t + l,learn
|
||||
r + e + w,were
|
||||
r + e + w + Dup,were
|
||||
r + e + w + h,where
|
||||
r + e + w + a + n + s,answer
|
||||
r + e + w + a + t,water
|
||||
r + e + g + h,here
|
||||
r + e + g + a + l,large
|
||||
r + e + g + a + t,great
|
||||
r + e + v + y,very
|
||||
r + e + v + y + Dup,every
|
||||
r + e + v + n,never
|
||||
r + e + u + n + d,under
|
||||
r + e + u + m + n + b,number
|
||||
r + e + o + f + b,before
|
||||
r + e + o + t + h,other
|
||||
r + e + o + g + t + h,together
|
||||
r + e + o + v,over
|
||||
r + e + o + m,more
|
||||
r + e + o + m + t + h,mother
|
||||
r + e + i + t + h,their
|
||||
r + e + i + t + n + f + f,different
|
||||
r + e + i + v,river
|
||||
r + e + i + c + l + d + f,children
|
||||
r + e + i + u + c + t + p,picture
|
||||
r + f,for
|
||||
r + h,her
|
||||
r + y,your
|
||||
r + n,near
|
||||
r + l,learn
|
||||
r + t + Dup,tree
|
||||
r + t + f,father
|
||||
r + t + s + Dup,start
|
||||
r + t + y,try
|
||||
r + t + l,letter
|
||||
r + t + l + Dup,letter
|
||||
r + a,are
|
||||
r + a + f,far
|
||||
r + a + d,read
|
||||
r + a + d + f,hard
|
||||
r + a + h,hard
|
||||
r + a + p,part
|
||||
r + a + l + y,really
|
||||
r + a + l + y + Dup,really
|
||||
r + a + t + p,part
|
||||
r + a + t + s + Dup,start
|
||||
r + w,were
|
||||
r + w + h,where
|
||||
r + w + t,water
|
||||
r + w + a + n + s,answer
|
||||
r + g + t,great
|
||||
r + g + a + l,large
|
||||
r + v + y,very
|
||||
r + v + n,never
|
||||
r + v + l,later
|
||||
r + m + f,form
|
||||
r + c + a,car
|
||||
r + c + a + y,carry
|
||||
r + c + a + y + Dup,carry
|
||||
r + u + n,run
|
||||
r + u + t + h,through
|
||||
r + u + t + n,turn
|
||||
r + ' + t + s,story
|
||||
r + o,or
|
||||
r + o + f,for
|
||||
r + o + t + y + s,story
|
||||
r + o + a + n + h,another
|
||||
r + o + w,work
|
||||
r + o + w + d,word
|
||||
r + o + w + l + d,world
|
||||
r + o + g,grow
|
||||
r + o + LeftDoubleClick,grow
|
||||
r + o + k + w,work
|
||||
r + o + m,more
|
||||
r + o + m + f,from
|
||||
r + o + m + t + h,mother
|
||||
r + o + u,our
|
||||
r + o + u + f,four
|
||||
r + o + u + y,your
|
||||
r + o + u + a,around
|
||||
r + o + u + a + n,around
|
||||
r + o + u + a + n + d,around
|
||||
r + o + u + g,group
|
||||
r + o + u + g + p,group
|
||||
r + o + u + g + t + h,through
|
||||
r + o + u + c + t + n,country
|
||||
r + o + u + c + t + n + y,country
|
||||
r + i + t + h,their
|
||||
r + i + t + s + f,first
|
||||
r + i + a,air
|
||||
r + i + w + t,write
|
||||
r + i + g + h,right
|
||||
r + i + g + l,girl
|
||||
r + i + g + t + h,right
|
||||
r + i + v,river
|
||||
r + i + v + Dup,river
|
||||
r + i + m + t + n + p,important
|
||||
r + i + c + l + h,children
|
||||
|
3
src/lib/assets/key-symbols.json
Normal file
3
src/lib/assets/key-symbols.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
" ": "␣"
|
||||
}
|
||||
114
src/lib/components/Navigation.svelte
Normal file
114
src/lib/components/Navigation.svelte
Normal file
@@ -0,0 +1,114 @@
|
||||
<script>
|
||||
import {serialPort} from "$lib/serial/connection.js"
|
||||
import {browser} from "$app/environment"
|
||||
</script>
|
||||
|
||||
<nav>
|
||||
<h1>dot i/o</h1>
|
||||
|
||||
<div class="steps">
|
||||
<a href="/train/cpm" title="CPM - characters per minute" class="icon train cpm">music_note</a>
|
||||
<a href="/train/chm" title="ChM - chords mastered" class="icon train chords">piano</a>
|
||||
<a href="/train/avg-wpm" title="aWPM - average words per minute" class="icon test avg">avg_pace</a>
|
||||
<a href="/train/stm" title="StM - sentences mastered" class="icon train sentences">lyrics</a>
|
||||
<a href="/train/top-wpm" title="tWPM - top words per minute" class="icon test top">speed</a>
|
||||
<a href="/train/cm" title="CM - concepts mastered" class="icon train concepts">cognition</a>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
{#if browser && !("serial" in navigator)}
|
||||
<abbr
|
||||
title="Your browser does not support serial connections. Try using Chrome instead."
|
||||
class="icon error"
|
||||
>
|
||||
warning
|
||||
</abbr>
|
||||
{/if}
|
||||
<a
|
||||
href="/device-manager"
|
||||
title="Device Manager"
|
||||
class="icon connect"
|
||||
class:error={$serialPort === undefined}>cable</a
|
||||
>
|
||||
<a href="/" title="Statistics" class="icon account">person</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<style lang="scss">
|
||||
nav {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-block: 0;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
|
||||
aspect-ratio: 1;
|
||||
padding: 4px;
|
||||
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
|
||||
&.error {
|
||||
color: var(--md-sys-color-on-error);
|
||||
background: var(--md-sys-color-error);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--md-sys-color-on-primary);
|
||||
background: var(--md-sys-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.steps {
|
||||
display: flex;
|
||||
|
||||
> a.icon {
|
||||
aspect-ratio: unset;
|
||||
margin-inline: -4px;
|
||||
padding-inline: 16px;
|
||||
|
||||
font-size: 24px;
|
||||
color: var(--md-sys-on-surface-variant);
|
||||
|
||||
background: var(--md-sys-color-surface-variant);
|
||||
clip-path: polygon(25% 50%, 0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%);
|
||||
border-radius: 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--md-sys-color-on-tertiary);
|
||||
background: var(--md-sys-color-tertiary);
|
||||
|
||||
&,
|
||||
~ * {
|
||||
translate: 8px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.icon.account {
|
||||
font-size: 32px;
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
background: var(--md-sys-color-secondary-container);
|
||||
}
|
||||
</style>
|
||||
5
src/lib/components/StickCap.svelte
Normal file
5
src/lib/components/StickCap.svelte
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg>
|
||||
<defs />
|
||||
|
||||
<circle cx="16" cy="16" r="16" color="black" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 75 B |
158
src/lib/components/Terminal.svelte
Normal file
158
src/lib/components/Terminal.svelte
Normal file
@@ -0,0 +1,158 @@
|
||||
<script>
|
||||
import {serialLog, serialPort} from "$lib/serial/connection.js"
|
||||
import {slide} from "svelte/transition"
|
||||
|
||||
/**
|
||||
* @param event {KeyboardEvent}
|
||||
*/
|
||||
function keypress(event) {
|
||||
if (event.code === "Enter") {
|
||||
event.preventDefault()
|
||||
const command = prompt.textContent.trim()
|
||||
prompt.textContent = ""
|
||||
$serialPort.send(command)
|
||||
io.scrollTo({top: io.scrollHeight})
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {HTMLSpanElement} */
|
||||
let prompt
|
||||
|
||||
/** @type {HTMLDivElement} */
|
||||
let io
|
||||
</script>
|
||||
|
||||
<div class="terminal" tabindex="0" on:focus={() => prompt.focus()}>
|
||||
<div bind:this={io} class="io">
|
||||
{#each $serialLog as { type, value }}
|
||||
<p class={type} transition:slide>{value}</p>
|
||||
{/each}
|
||||
<div class="anchor" />
|
||||
</div>
|
||||
<div class="prompt">
|
||||
<b>$</b><span on:keypress={keypress} bind:this={prompt} contenteditable class="prompt" />
|
||||
<div class="resize-me" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.terminal {
|
||||
resize: both;
|
||||
|
||||
position: relative;
|
||||
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: calc(min(100%, 16.5cm));
|
||||
height: 8cm;
|
||||
|
||||
font-family: "Noto Sans Mono", monospace;
|
||||
font-size: 0.75rem;
|
||||
color: var(--md-sys-color-on-secondary);
|
||||
|
||||
background: var(--md-sys-color-secondary);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
background: transparent;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--md-sys-color-on-secondary);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-resizer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.io {
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
|
||||
padding: 12px;
|
||||
|
||||
color: var(--md-sys-color-on-secondary-container);
|
||||
|
||||
background: var(--md-sys-color-secondary-container);
|
||||
border-radius: 0 0 16px 16px;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.prompt {
|
||||
position: relative;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
.resize-me {
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
bottom: 0;
|
||||
rotate: -45deg;
|
||||
|
||||
width: 10px;
|
||||
height: 5px;
|
||||
|
||||
background: var(--md-sys-color-on-secondary);
|
||||
clip-path: polygon(0 0, 100% 0, 50% 100%);
|
||||
}
|
||||
|
||||
.anchor {
|
||||
overflow-anchor: auto;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
p {
|
||||
overflow-anchor: none;
|
||||
margin-block: 0.15rem;
|
||||
}
|
||||
|
||||
p.input {
|
||||
margin-block-end: 0.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.system {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
margin-block-end: 1rem;
|
||||
padding: 0.25rem;
|
||||
|
||||
color: var(--md-sys-color-on-secondary);
|
||||
|
||||
background: var(--md-sys-color-secondary);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
p.input::before {
|
||||
content: "> ";
|
||||
font-weight: 900;
|
||||
color: var(--md-sys-color-primary);
|
||||
}
|
||||
|
||||
::selection {
|
||||
color: var(--md-sys-color-background);
|
||||
background: var(--md-sys-color-on-background);
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
100%,
|
||||
60% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
40%,
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
7
src/lib/serial/connection.js
Normal file
7
src/lib/serial/connection.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import {writable} from "svelte/store"
|
||||
|
||||
/** @type {import('svelte/store').Writable<import('./device.js').CharaDevice>} */
|
||||
export const serialPort = writable()
|
||||
|
||||
/** @type {import('svelte/store').Writable<Array<{type: 'input' | 'output' | 'system'; value: string}>>} */
|
||||
export const serialLog = writable([])
|
||||
133
src/lib/serial/device.js
Normal file
133
src/lib/serial/device.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import {LineBreakTransformer} from "$lib/serial/webserial/util/line-break-transformer.js"
|
||||
import {serialLog} from "$lib/serial/connection.js"
|
||||
|
||||
export class CharaDevice {
|
||||
/** @type {Promise<SerialPort>} */
|
||||
#port
|
||||
/** @type {Promise<ReadableStreamDefaultReader<string>>} */
|
||||
#reader
|
||||
|
||||
#encoder = new TextEncoder()
|
||||
|
||||
#abortController1 = new AbortController()
|
||||
#abortController2 = new AbortController()
|
||||
|
||||
/** @type {Promise<true> | undefined} */
|
||||
#lock
|
||||
|
||||
/** @type {Promise<string>} */
|
||||
version
|
||||
/** @type {Promise<string>} */
|
||||
deviceId
|
||||
|
||||
/**
|
||||
* @param baudRate
|
||||
*/
|
||||
constructor(baudRate = 115200) {
|
||||
this.#port = navigator.serial.getPorts().then(async ports => {
|
||||
const port = ports.find(it => it.getInfo().usbVendorId === 0x239a)
|
||||
await port.open({baudRate})
|
||||
const info = port.getInfo()
|
||||
serialLog.update(it => {
|
||||
it.push({
|
||||
type: "system",
|
||||
value: `Connected; ID: 0x${info.usbProductId.toString(16)}; Vendor: 0x${info.usbVendorId.toString(
|
||||
16,
|
||||
)}`,
|
||||
})
|
||||
return it
|
||||
})
|
||||
return port
|
||||
})
|
||||
this.#reader = this.#port.then(async port => {
|
||||
const decoderStream = new TextDecoderStream()
|
||||
void port.readable.pipeTo(decoderStream.writable, {signal: this.#abortController1.signal})
|
||||
|
||||
return decoderStream.readable
|
||||
.pipeThrough(new TransformStream(new LineBreakTransformer()), {signal: this.#abortController2.signal})
|
||||
.getReader()
|
||||
})
|
||||
this.#lock = this.#reader.then(() => {
|
||||
this.#lock = undefined
|
||||
return true
|
||||
})
|
||||
this.version = this.send("VERSION")
|
||||
this.deviceId = this.send("ID")
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async #read() {
|
||||
return this.#reader.then(async it => {
|
||||
const result = await it.read().then(({value}) => value)
|
||||
serialLog.update(it => {
|
||||
it.push({
|
||||
type: "output",
|
||||
value: result,
|
||||
})
|
||||
return it
|
||||
})
|
||||
return result
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a command to the device
|
||||
* @param command {string}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async #send(...command) {
|
||||
const port = await this.#port
|
||||
const writer = port.writable.getWriter()
|
||||
try {
|
||||
serialLog.update(it => {
|
||||
it.push({
|
||||
type: "input",
|
||||
value: command.join(" "),
|
||||
})
|
||||
return it
|
||||
})
|
||||
await writer.write(new TextEncoder().encode(`${command.join(" ")}\r\n`))
|
||||
} finally {
|
||||
writer.releaseLock()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read/write to serial port
|
||||
* @template T
|
||||
* @param callback {(send: (...commands: string) => Promise<void>, read: () => Promise<string>) => T | Promise<T>}
|
||||
* @returns Promise<T>
|
||||
*/
|
||||
async runWith(callback) {
|
||||
while (this.#lock) {
|
||||
await this.#lock
|
||||
}
|
||||
const send = this.#send.bind(this)
|
||||
const read = this.#read.bind(this)
|
||||
const exec = new Promise(async resolve => {
|
||||
let result
|
||||
try {
|
||||
result = await callback(send, read)
|
||||
} finally {
|
||||
this.#lock = undefined
|
||||
resolve(result)
|
||||
}
|
||||
})
|
||||
this.#lock = exec.then(() => true)
|
||||
return exec
|
||||
}
|
||||
|
||||
/**
|
||||
* Send to serial port
|
||||
* @param command {string}
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
async send(...command) {
|
||||
return this.runWith(async (send, read) => {
|
||||
await send(...command)
|
||||
return read()
|
||||
})
|
||||
}
|
||||
}
|
||||
132
src/lib/serial/webserial.js
Normal file
132
src/lib/serial/webserial.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import {LineBreakTransformer} from "$lib/serial/webserial/util/line-break-transformer.js"
|
||||
import {CONFIG_ID} from "$lib/serial/webserial/constants/config-id.js"
|
||||
let _chordMaps = []
|
||||
|
||||
let serialPort = null
|
||||
let portReader = null
|
||||
let lineReader = null
|
||||
let lineReaderDone = null
|
||||
let abortController1 = new AbortController()
|
||||
let abortController2 = new AbortController()
|
||||
|
||||
async function disconnectSerialConnection() {
|
||||
console.log("disconnectSerialConnection()")
|
||||
if (serialPort) {
|
||||
console.log("closing serial port")
|
||||
lineReader.releaseLock()
|
||||
|
||||
console.log(serialPort.readable)
|
||||
await abortController1.abort()
|
||||
await lineReaderDone.catch(() => {
|
||||
/* Ingore the error */
|
||||
})
|
||||
await serialPort.close()
|
||||
|
||||
console.log("serial port is closed")
|
||||
document.getElementById("statusDiv").innerHTML = "status: closed serial port"
|
||||
} else {
|
||||
console.log("there is no serial connection open to close")
|
||||
}
|
||||
}
|
||||
|
||||
//TODO not sure this actually works
|
||||
async function cancelReader() {
|
||||
if (serialPort) {
|
||||
if (lineReader) {
|
||||
// if(lineReader.locked){
|
||||
await lineReader.cancel().then(() => {
|
||||
console.log("cleared line reader")
|
||||
})
|
||||
// await serialPort.readable.releaseLock();
|
||||
console.log(abortController1)
|
||||
await abortController1.abort()
|
||||
console.log(serialPort.readable)
|
||||
await lineReaderDone.catch(() => {
|
||||
/* Ingore the error */
|
||||
}) //this frees up the serialPort.readable after the abortControl1.abort() signal
|
||||
// await serialPort.readable.cancel();
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function resetReader() {
|
||||
console.log("resetting lineReader")
|
||||
if (serialPort) {
|
||||
if (lineReader) {
|
||||
if (lineReader.locked) {
|
||||
await lineReader.releaseLock()
|
||||
}
|
||||
await lineReader.cancel().then(() => {
|
||||
console.log("cleared line reader")
|
||||
})
|
||||
await lineReaderDone.catch(() => {
|
||||
/* Ingore the error */
|
||||
})
|
||||
}
|
||||
await setupLineReader()
|
||||
}
|
||||
console.log("reset lineReader")
|
||||
}
|
||||
|
||||
async function getCount() {
|
||||
await sendCommandString("SELECT BASE")
|
||||
await readGetChordmapCount()
|
||||
document.getElementById("countDiv").innerHTML = "count: " + _chordmapCountOnDevice
|
||||
}
|
||||
|
||||
async function getGetAll1() {
|
||||
await selectBase() //select BASE
|
||||
await sendCommandString("GETALL")
|
||||
await readGetAllChordmaps()
|
||||
}
|
||||
|
||||
async function getGetAll2() {
|
||||
await selectBase() //select BASE
|
||||
await sendCommandString("GETSOME 0 " + _chordmapCountOnDevice)
|
||||
await readGetSomeChordmaps(_chordmapCountOnDevice)
|
||||
}
|
||||
|
||||
async function getGetAll() {
|
||||
await selectBase() //select BASE
|
||||
for (let i = 0; i < _chordmapCountOnDevice; i++) {
|
||||
await sendCommandString("GETSOME " + (i + 0).toString() + " " + (i + 1).toString())
|
||||
await readGetOneChordmap()
|
||||
}
|
||||
}
|
||||
|
||||
let _chordmapId = "DEFAULT"
|
||||
let _chordmapCountOnDevice = 50 //TODO set this to zero by default
|
||||
let _firmwareVersion = "0"
|
||||
|
||||
async function readGetChordmapCount() {
|
||||
const {value, done} = await lineReader.read()
|
||||
if (value) {
|
||||
_chordmapCountOnDevice = parseInt(value)
|
||||
console.log(_chordmapCountOnDevice)
|
||||
}
|
||||
}
|
||||
|
||||
async function readGetAll() {
|
||||
readGetSomeChordmaps(_chordmapCountOnDevice)
|
||||
}
|
||||
|
||||
function commitAll() {
|
||||
console.log("commitAll()")
|
||||
const dataTable = document.getElementById("dataTable")
|
||||
//iterate through table from bottom to top to see if there's a commit enabled
|
||||
//TODO check if we need to skip the header row
|
||||
for (let i = dataTable.rows.length - 1; i >= 1; i--) {
|
||||
//iterate through rows
|
||||
let row = dataTable.rows[i]
|
||||
// console.log(row);
|
||||
// console.log(row.cells);
|
||||
// console.log(row.cells[0]);
|
||||
// console.log(row.cells[0].innerHTML);
|
||||
let virtualId = parseInt(row.cells[0].innerHTML)
|
||||
console.log("table row " + i + " has virtualId of " + virtualId)
|
||||
// document.getElementById(virtualId.toString()+"-commit")
|
||||
setTimeout(pressCommitButton, i * 100, virtualId)
|
||||
//rows would be accessed using the "row" variable assigned in the for loop
|
||||
}
|
||||
}
|
||||
11
src/lib/serial/webserial/boot.js
Normal file
11
src/lib/serial/webserial/boot.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export async function bootLoader() {
|
||||
//Sends the bootloader command to the charachorder via the serial API
|
||||
await sendCommandString("BOOTLOADER")
|
||||
await readGetNone()
|
||||
}
|
||||
|
||||
export async function reboot() {
|
||||
//Sends the restart command to the charachorder via the serial API
|
||||
await sendCommandString("RESTART")
|
||||
await readGetNone()
|
||||
}
|
||||
638
src/lib/serial/webserial/constants/action-map.js
Normal file
638
src/lib/serial/webserial/constants/action-map.js
Normal file
@@ -0,0 +1,638 @@
|
||||
/**
|
||||
* 512 'actions'
|
||||
* phrase is an 'action sequence'
|
||||
*
|
||||
* ```js
|
||||
* let _keys_to_humanreadableoutput_dict = {
|
||||
* '0x0061':'a',
|
||||
* '0x0062':'b',
|
||||
* '0x0063':'c',
|
||||
* '0x0064':'d',
|
||||
* '0x0030':'0',
|
||||
* '0x0031':'1',
|
||||
* '0x0032':'2',
|
||||
* '0x013D':'Mouse Left Button Press and Release',
|
||||
* '0x0149':'Mouse Move Down',
|
||||
* '0x0151':'Double Click',
|
||||
* '0x0180':'LeftControl', // E0 in HID Keyboard Table
|
||||
* '0x0181':'LeftShift',
|
||||
* '0x0182':'LeftAlt',
|
||||
* '0x0183':'LeftGUI',
|
||||
* '0x0189':'F1',
|
||||
* '0x018A':'F2',
|
||||
* '0x018B':'F3',
|
||||
* ```
|
||||
*
|
||||
* 64-bit integer as hexadecimal, string of hexadecimal pairs that represent ascii+ value
|
||||
*
|
||||
* `"a + f + t"`,
|
||||
* `27,30,43`
|
||||
* `00000000000000000000000000100100000000000010000000000000000000`
|
||||
* `38,655,229,952`
|
||||
* `0x00000000900080000`
|
||||
*/
|
||||
export const _actionMap = [
|
||||
"NUL", //0x00 0
|
||||
"CCFunc", //0x01
|
||||
"STX", //0x02 2
|
||||
"ETX", //0x03 3
|
||||
"EOT", //0x04 4
|
||||
"ENQ", //0x05 5
|
||||
"ACK", //0x06 6
|
||||
"BEL", //0x07 7
|
||||
"BAC", //0x08 8
|
||||
"Tab", //0x09 9
|
||||
"ENT", //0x0A 10
|
||||
"VT", //0x0B 11
|
||||
"FF", //0x0C 12
|
||||
"CR", //0x0D 13
|
||||
"SOH", //0x0E 14
|
||||
"SI", //0x0F 15
|
||||
"DLE", //0x10 16
|
||||
"DC1", //0x11 17
|
||||
"DC2", //0x12 18
|
||||
"DC3", //0x13 19
|
||||
"DC4", //0x14 20
|
||||
"NAK", //0x15 21
|
||||
"SYN", //0x16 22
|
||||
"ETB", //0x17 23
|
||||
"CAN", //0x18 24
|
||||
"EM", //0x19 25
|
||||
"SUB", //0x1A 26
|
||||
"ESC", //0x1B 27
|
||||
"FS", //0x1C 28
|
||||
"GS", //0x1D 29
|
||||
"RS", //0x1E 30
|
||||
"US", //0x1F 31
|
||||
"SPA", //0x20 32
|
||||
"!", //0x21 33
|
||||
'"', //0x22 34
|
||||
"#", //0x23 35
|
||||
"$", //0x24 36
|
||||
"%", //0x25 37
|
||||
"&", //0x26 38
|
||||
"'", //0x27 39
|
||||
"(", //0x28 40
|
||||
")", //0x29 41
|
||||
"*", //0x2A 42
|
||||
"+", //0x2B 43
|
||||
",", //0x2C 44
|
||||
"-", //0x2D 45
|
||||
".", //0x2E 46
|
||||
"/", //0x2F 47
|
||||
"0", //0x30 48
|
||||
"1", //0x31 49
|
||||
"2", //0x32 50
|
||||
"3", //0x33 51
|
||||
"4", //0x34 52
|
||||
"5", //0x35 53
|
||||
"6", //0x36 54
|
||||
"7", //0x37 55
|
||||
"8", //0x38 56
|
||||
"9", //0x39 57
|
||||
":", //0x3A 58
|
||||
";", //0x3B 59
|
||||
"<", //0x3C 60
|
||||
"=", //0x3D 61
|
||||
">", //0x3E 62
|
||||
"?", //0x3F 63
|
||||
"@", //0x40 64
|
||||
"A", //0x41 65
|
||||
"B", //0x42 66
|
||||
"C", //0x43 67
|
||||
"D", //0x44 68
|
||||
"E", //0x45 69
|
||||
"F", //0x46 70
|
||||
"G", //0x47 71
|
||||
"H", //0x48 72
|
||||
"I", //0x49 73
|
||||
"J", //0x4A 74
|
||||
"K", //0x4B 75
|
||||
"L", //0x4C 76
|
||||
"M", //0x4D 77
|
||||
"N", //0x4E 78
|
||||
"O", //0x4F 79
|
||||
"P", //0x50 80
|
||||
"Q", //0x51 81
|
||||
"R", //0x52 82
|
||||
"S", //0x53 83
|
||||
"T", //0x54 84
|
||||
"U", //0x55 85
|
||||
"V", //0x56 86
|
||||
"W", //0x57 87
|
||||
"X", //0x58 88
|
||||
"Y", //0x59 89
|
||||
"Z", //0x5A 90
|
||||
"[", //0x5B 91
|
||||
"\\", //0x5C 92
|
||||
"]", //0x5D 93
|
||||
"^", //0x5E 94
|
||||
"_", //0x5F 95
|
||||
"`", //0x60 96
|
||||
"a", //0x61 97
|
||||
"b", //0x62 98
|
||||
"c", //0x63 99
|
||||
"d", //0x64 100
|
||||
"e", //0x65 101
|
||||
"f", //0x66 102
|
||||
"g", //0x67 103
|
||||
"h", //0x68 104
|
||||
"i", //0x69 105
|
||||
"j", //0x6A 106
|
||||
"k", //0x6B 107
|
||||
"l", //0x6C 108
|
||||
"m", //0x6D 109
|
||||
"n", //0x6E 110
|
||||
"o", //0x6F 111
|
||||
"p", //0x70 112
|
||||
"q", //0x71 113
|
||||
"r", //0x72 114
|
||||
"s", //0x73 115
|
||||
"t", //0x74 116
|
||||
"u", //0x75 117
|
||||
"v", //0x76 118
|
||||
"w", //0x77 119
|
||||
"x", //0x78 120
|
||||
"y", //0x79 121
|
||||
"z", //0x7A 122
|
||||
"{", //0x7B 123
|
||||
"|", //0x7C 124
|
||||
"}", //0x7D 125
|
||||
"~", //0x7E 126
|
||||
"DEL", //0x7F 127
|
||||
"Ç", //0x80 128
|
||||
"ü", //0x81 129
|
||||
"é", //0x82 130
|
||||
"â", //0x83 131
|
||||
"ä", //0x84 132
|
||||
"à", //0x85 133
|
||||
"å", //0x86 134
|
||||
"ç", //0x87 135
|
||||
"ê", //0x88 136
|
||||
"ë", //0x89 137
|
||||
"è", //0x8A 138
|
||||
"ï", //0x8B 139
|
||||
"î", //0x8C 140
|
||||
"ì", //0x8D 141
|
||||
"Ä", //0x8E 142
|
||||
"Å", //0x8F 143
|
||||
"É", //0x90 144
|
||||
"æ", //0x91 145
|
||||
"Æ", //0x92 146
|
||||
"ô", //0x93 147
|
||||
"ö", //0x94 148
|
||||
"ò", //0x95 149
|
||||
"û", //0x96 150
|
||||
"ù", //0x97 151
|
||||
"ÿ", //0x98 152
|
||||
"Ö", //0x99 153
|
||||
"Ü", //0x9A 154
|
||||
"ø", //0x9B 155
|
||||
"£", //0x9C 156
|
||||
"Ø", //0x9D 157
|
||||
"×", //0x9E 158
|
||||
"ƒ", //0x9F 159
|
||||
"á", //0xA0 160
|
||||
"í", //0xA1 161
|
||||
"ó", //0xA2 162
|
||||
"ú", //0xA3 163
|
||||
"ñ", //0xA4 164
|
||||
"Ñ", //0xA5 165
|
||||
"ª", //0xA6 166
|
||||
"º", //0xA7 167
|
||||
"¿", //0xA8 168
|
||||
"®", //0xA9 169
|
||||
"¬", //0xAA 170
|
||||
"½", //0xAB 171
|
||||
"¼", //0xAC 172
|
||||
"¡", //0xAD 173
|
||||
"«", //0xAE 174
|
||||
"»", //0xAF 175
|
||||
"░", //0xB0 176
|
||||
"▒", //0xB1 177
|
||||
"▓", //0xB2 178
|
||||
"│", //0xB3 179
|
||||
"┤", //0xB4 180
|
||||
"Á", //0xB5 181
|
||||
"Â", //0xB6 182
|
||||
"À", //0xB7 183
|
||||
"©", //0xB8 184
|
||||
"╣", //0xB9 185
|
||||
"║", //0xBA 186
|
||||
"╗", //0xBB 187
|
||||
"╝", //0xBC 188
|
||||
"¢", //0xBD 189
|
||||
"¥", //0xBE 190
|
||||
"┐", //0xBF 191
|
||||
"└", //0xC0 192
|
||||
"┴", //0xC1 193
|
||||
"┬", //0xC2 194
|
||||
"├", //0xC3 195
|
||||
"─", //0xC4 196
|
||||
"┼", //0xC5 197
|
||||
"ã", //0xC6 198
|
||||
"Ã", //0xC7 199
|
||||
"╚", //0xC8 200
|
||||
"╔", //0xC9 201
|
||||
"╩", //0xCA 202
|
||||
"╦", //0xCB 203
|
||||
"╠", //0xCC 204
|
||||
"═", //0xCD 205
|
||||
"╬", //0xCE 206
|
||||
"¤", //0xCF 207
|
||||
"ð", //0xD0 208
|
||||
"Ð", //0xD1 209
|
||||
"Ê", //0xD2 210
|
||||
"Ë", //0xD3 211
|
||||
"È", //0xD4 212
|
||||
"ı", //0xD5 213
|
||||
"Í", //0xD6 214
|
||||
"Î", //0xD7 215
|
||||
"Ï", //0xD8 216
|
||||
"┘", //0xD9 217
|
||||
"┌", //0xDA 218
|
||||
"█", //0xDB 219
|
||||
"▄", //0xDC 220
|
||||
"¦", //0xDD 221
|
||||
"Ì", //0xDE 222
|
||||
"▀", //0xDF 223
|
||||
"Ó", //0xE0 224
|
||||
"ß", //0xE1 225
|
||||
"Ô", //0xE2 226
|
||||
"Ò", //0xE3 227
|
||||
"õ", //0xE4 228
|
||||
"Õ", //0xE5 229
|
||||
"µ", //0xE6 230
|
||||
"þ", //0xE7 231
|
||||
"Þ", //0xE8 232
|
||||
"Ú", //0xE9 233
|
||||
"Û", //0xEA 234
|
||||
"Ù", //0xEB 235
|
||||
"ý", //0xEC 236
|
||||
"Ý", //0xED 237
|
||||
"¯", //0xEE 238
|
||||
"´", //0xEF 239
|
||||
"≡", //0xF0 240
|
||||
"±", //0xF1 241
|
||||
"‗", //0xF2 242
|
||||
"¾", //0xF3 243
|
||||
"¶", //0xF4 244
|
||||
"§", //0xF5 245
|
||||
"÷", //0xF6 246
|
||||
"¸", //0xF7 247
|
||||
"°", //0xF8 248
|
||||
"¨", //0xF9 249
|
||||
"·", //0xFA 250
|
||||
"¹", //0xFB 251
|
||||
"³", //0xFC 252
|
||||
"²", //0xFD 253
|
||||
"■", //0xFE 254
|
||||
"NBSP", //0xFF 255
|
||||
"Reset", //0x0100 256
|
||||
"Delay0001ms", //0x0101 257
|
||||
"Delay0010ms", //0x0102 258
|
||||
"Delay0100ms", //0x0103 259
|
||||
"Delay1000ms", //0x0104 260
|
||||
"0x0105", //0x0105 261
|
||||
"0x0106", //0x0106 262
|
||||
"0x0107", //0x0107 263
|
||||
"0x0108", //0x0108 264
|
||||
"0x0109", //0x0109 265
|
||||
"0x010A", //0x010A 266
|
||||
"0x010B", //0x010B 267
|
||||
"0x010C", //0x010C 268
|
||||
"0x010D", //0x010D 269
|
||||
"0x010E", //0x010E 270
|
||||
"Impulse", //0x010F 271
|
||||
"LAT", //0x0110 272
|
||||
"RAT", //0x0111 273
|
||||
"LNS", //0x0112 274
|
||||
"RNS", //0x0113 275
|
||||
"SpurToggle", //0x0114 276
|
||||
"Prev", //0x0115 277
|
||||
"ImpulseToggle", //0x0116 278
|
||||
"GTM", //0x0117 279
|
||||
"0x0118", //0x0118 280
|
||||
"0x0119", //0x0119 281
|
||||
"0x011A", //0x011A 282
|
||||
"0x011B", //0x011B 283
|
||||
"0x011C", //0x011C 284
|
||||
"0x011D", //0x011D 285
|
||||
"0x011E", //0x011E 286
|
||||
"0x011F", //0x011F 287
|
||||
"0x0120", //0x0120 288
|
||||
"0x0121", //0x0121 289
|
||||
"0x0122", //0x0122 290
|
||||
"0x0123", //0x0123 291
|
||||
"0x0124", //0x0124 292
|
||||
"0x0125", //0x0125 293
|
||||
"0x0126", //0x0126 294
|
||||
"0x0127", //0x0127 295
|
||||
"0x0128", //0x0128 296
|
||||
"0x0129", //0x0129 297
|
||||
"0x012A", //0x012A 298
|
||||
"0x012B", //0x012B 299
|
||||
"0x012C", //0x012C 300
|
||||
"0x012D", //0x012D 301
|
||||
"0x012E", //0x012E 302
|
||||
"0x012F", //0x012F 303
|
||||
"0x0130", //0x0130 304
|
||||
"0x0131", //0x0131 305
|
||||
"0x0132", //0x0132 306
|
||||
"0x0133", //0x0133 307
|
||||
"0x0134", //0x0134 308
|
||||
"0x0135", //0x0135 309
|
||||
"0x0136", //0x0136 310
|
||||
"0x0137", //0x0137 311
|
||||
"0x0138", //0x0138 312
|
||||
"0x0139", //0x0139 313
|
||||
"0x013A", //0x013A 314
|
||||
"0x013B", //0x013B 315
|
||||
"0x013C", //0x013C 316
|
||||
"MLB", //0x013D 317
|
||||
"RMC", //0x013E 318
|
||||
"MMB", //0x013F 319
|
||||
"MouseLeftBtnToggle", //0x0140 320
|
||||
"MouseRightBtnToggle", //0x0141 321
|
||||
"MouseMiddleBtnToggle", //0x0142 322
|
||||
"MouseLeftBtnPress", //0x0143 323
|
||||
"MouseRightBtnPress", //0x0144 324
|
||||
"MouseMiddleBtnPress", //0x0145 325
|
||||
"MouseLeftBtnRelease", //0x0146 326
|
||||
"MouseRightBtnRelease", //0x0147 327
|
||||
"MouseMiddleBtnRelease", //0x0148 328
|
||||
"M↓", //0x0149 329
|
||||
"M→", //0x014A 330
|
||||
"M↑", //0x014B 331
|
||||
"M←", //0x014C 332
|
||||
"MSD", //0x014D 333
|
||||
"MouseScrollCoastRight", //0x014E 334
|
||||
"MSU", //0x014F 335
|
||||
"MouseScrollCoastLeft", //0x0150 336
|
||||
"LeftDoubleClick", //0x0151 337
|
||||
"RightDoubleClick", //0x0152 338
|
||||
"TripleClick", //0x0153 339
|
||||
"0x0154", //0x0154 340
|
||||
"0x0155", //0x0155 341
|
||||
"0x0156", //0x0156 342
|
||||
"0x0157", //0x0157 343
|
||||
"0x0158", //0x0158 344
|
||||
"0x0159", //0x0159 345
|
||||
"0x015A", //0x015A 346
|
||||
"0x015B", //0x015B 347
|
||||
"0x015C", //0x015C 348
|
||||
"0x015D", //0x015D 349
|
||||
"0x015E", //0x015E 350
|
||||
"0x015F", //0x015F 351
|
||||
"0x0160", //0x0160 352
|
||||
"0x0161", //0x0161 353
|
||||
"0x0162", //0x0162 354
|
||||
"0x0163", //0x0163 355
|
||||
"0x0164", //0x0164 356
|
||||
"0x0165", //0x0165 357
|
||||
"PwrStat", //0x0166 358
|
||||
"0x0167", //0x0167 359
|
||||
"0x0168", //0x0168 360
|
||||
"0x0169", //0x0169 361
|
||||
"0x016A", //0x016A 362
|
||||
"0x016B", //0x016B 363
|
||||
"0x016C", //0x016C 364
|
||||
"0x016D", //0x016D 365
|
||||
"0x016E", //0x016E 366
|
||||
"0x016F", //0x016F 367
|
||||
"0x0170", //0x0170 368
|
||||
"0x0171", //0x0171 369
|
||||
"0x0172", //0x0172 370
|
||||
"0x0173", //0x0173 371
|
||||
"0x0174", //0x0174 372
|
||||
"0x0175", //0x0175 373
|
||||
"0x0176", //0x0176 374
|
||||
"0x0177", //0x0177 375
|
||||
"0x0178", //0x0178 376
|
||||
"0x0179", //0x0179 377
|
||||
"0x017A", //0x017A 378
|
||||
"0x017B", //0x017B 379
|
||||
"0x017C", //0x017C 380
|
||||
"0x017D", //0x017D 381
|
||||
"0x017E", //0x017E 382
|
||||
"ReleaseMods", //0x017F 383
|
||||
"LCK", //0x0180 384
|
||||
"LSK", //0x0181 385
|
||||
"LAK", //0x0182 386
|
||||
"LGK", //0x0183 387
|
||||
"RCK", //0x0184 388
|
||||
"RSK", //0x0185 389
|
||||
"RAK", //0x0186 390
|
||||
"RGK", //0x0187 391
|
||||
"CAP", //0x0188 392
|
||||
"F1", //0x0189 393
|
||||
"F2", //0x018A 394
|
||||
"F3", //0x018B 395
|
||||
"F4", //0x018C 396
|
||||
"F5", //0x018D 397
|
||||
"F6", //0x018E 398
|
||||
"F7", //0x018F 399
|
||||
"F8", //0x0190 400
|
||||
"F9", //0x0191 401
|
||||
"F10", //0x0192 402
|
||||
"F11", //0x0193 403
|
||||
"F12", //0x0194 404
|
||||
"PrintScreen", //0x0195 405
|
||||
"ScrollLock", //0x0196 406
|
||||
"Pause", //0x0197 407
|
||||
"Insert", //0x0198 408
|
||||
"Home", //0x0199 409
|
||||
"PageUp", //0x019A 410
|
||||
"DeleteForward", //0x019B 411
|
||||
"End", //0x019C 412
|
||||
"PageDown", //0x019D 413
|
||||
"→", //0x019E 414
|
||||
"←", //0x019F 415
|
||||
"↓", //0x01A0 416
|
||||
"↑", //0x01A1 417
|
||||
"NumLock", //0x01A2 418
|
||||
"F13", //0x01A3 419
|
||||
"F14", //0x01A4 420
|
||||
"F15", //0x01A5 421
|
||||
"F16", //0x01A6 422
|
||||
"F17", //0x01A7 423
|
||||
"F18", //0x01A8 424
|
||||
"F19", //0x01A9 425
|
||||
"F20", //0x01AA 426
|
||||
"F21", //0x01AB 427
|
||||
"F22", //0x01AC 428
|
||||
"F23", //0x01AD 429
|
||||
"F24", //0x01AE 430
|
||||
"Execute", //0x01AF 431
|
||||
"Help", //0x01B0 432
|
||||
"Menu", //0x01B1 433
|
||||
"Select", //0x01B2 434
|
||||
"Stop", //0x01B3 435
|
||||
"Again", //0x01B4 436
|
||||
"Undo", //0x01B5 437
|
||||
"Cut", //0x01B6 438
|
||||
"Copy", //0x01B7 439
|
||||
"Paste", //0x01B8 440
|
||||
"Find", //0x01B9 441
|
||||
"Mute", //0x01BA 442
|
||||
"VolUp", //0x01BB 443
|
||||
"VolDn", //0x01BC 444
|
||||
"Intl1", //0x01BD 445
|
||||
"Intl2", //0x01BE 446
|
||||
"Intl3", //0x01BF 447
|
||||
"Intl4", //0x01C0 448
|
||||
"Intl5", //0x01C1 449
|
||||
"Intl6", //0x01C2 450
|
||||
"Intl7", //0x01C3 451
|
||||
"Intl8", //0x01C4 452
|
||||
"Intl9", //0x01C5 453
|
||||
"LANG1", //0x01C6 454
|
||||
"LANG2", //0x01C7 455
|
||||
"LANG3", //0x01C8 456
|
||||
"LANG4", //0x01C9 457
|
||||
"LANG5", //0x01CA 458
|
||||
"LANG6", //0x01CB 459
|
||||
"LANG7", //0x01CC 460
|
||||
"LANG8", //0x01CD 461
|
||||
"LANG9", //0x01CE 462
|
||||
"AtlErase", //0x01CF 463
|
||||
"SysReq", //0x01D0 464
|
||||
"Cancel", //0x01D1 465
|
||||
"Clear", //0x01D2 466
|
||||
"Prior", //0x01D3 467
|
||||
"Return", //0x01D4 468
|
||||
"Separator", //0x01D5 469
|
||||
"Out", //0x01D6 470
|
||||
"Oper", //0x01D7 471
|
||||
"Clear/Again", //0x01D8 472
|
||||
"CrSel/Props", //0x01D9 473
|
||||
"ExSel", //0x01DA 474
|
||||
"ThouSep", //0x01DB 475
|
||||
"DeciSep", //0x01DC 476
|
||||
"CurrencyUnit", //0x01DD 477
|
||||
"CurrencySubUnit", //0x01DE 478
|
||||
"KPMStore", //0x01DF 479
|
||||
"KPMRecall", //0x01E0 480
|
||||
"KPMClear", //0x01E1 481
|
||||
"KPMAdd", //0x01E2 482
|
||||
"KPMSub", //0x01E3 483
|
||||
"KPMMult", //0x01E4 484
|
||||
"KPMDiv", //0x01E5 485
|
||||
"KP+/-", //0x01E6 486
|
||||
"KPClear", //0x01E7 487
|
||||
"KPClearEntry", //0x01E8 488
|
||||
"KPBin", //0x01E9 489
|
||||
"KPOct", //0x01EA 490
|
||||
"KPDec", //0x01EB 491
|
||||
"KPHex", //0x01EC 492
|
||||
"KMPlayPause", //0x01ED 493
|
||||
"KMStopCD", //0x01EE 494
|
||||
"KMPrevSong", //0x01EF 495
|
||||
"KMNextSong", //0x01F0 496
|
||||
"KMEjectCD", //0x01F1 497
|
||||
"KMVolUp", //0x01F2 498
|
||||
"KMVolDn", //0x01F3 499
|
||||
"KMMute", //0x01F4 500
|
||||
"KMwww", //0x01F5 501
|
||||
"KMBack", //0x01F6 502
|
||||
"KMForward", //0x01F7 503
|
||||
"KMStop", //0x01F8 504
|
||||
"KMFind", //0x01F9 505
|
||||
"KMScrollUp", //0x01FA 506
|
||||
"KMScrollDn", //0x01FB 507
|
||||
"KMEdit", //0x01FC 508
|
||||
"KMSleep", //0x01FD 509
|
||||
"KMCoffee", //0x01FE 510
|
||||
"KMRefresh", //0x01FF 511
|
||||
"CC_Physical", //0x0200 512
|
||||
"RH_Thumb_3_Left", //0x0201 513
|
||||
"RH_Thumb_3_Down", //0x0202 514
|
||||
"RH_Thumb_3_Right", //0x0203 515
|
||||
"RH_Thumb_3_Up", //0x0204 516
|
||||
"RH_Thumb_3_Center", //0x0205 517
|
||||
"RH_Thumb_2_Left", //0x0206 518
|
||||
"RH_Thumb_2_Down", //0x0207 519
|
||||
"RH_Thumb_2_Right", //0x0208 520
|
||||
"RH_Thumb_2_Up", //0x0209 521
|
||||
"RH_Thumb_2_Center", //0x0210 522
|
||||
"RH_Thumb_1_Left", //0x0211 523
|
||||
"RH_Thumb_1_Down", //0x0212 524
|
||||
"RH_Thumb_1_Right", //0x0213 525
|
||||
"RH_Thumb_1_Up", //0x0214 526
|
||||
"RH_Thumb_1_Center", //0x0215 527
|
||||
"RH_Pinky_Left", //0x0216 528
|
||||
"RH_Pinky_Down", //0x0217 529
|
||||
"RH_Pinky_Right", //0x0218 530
|
||||
"RH_Pinky_Up", //0x0219 531
|
||||
"RH_Pinky_Center", //0x0220 532
|
||||
"RH_Ring_Secondary_Left", //0x0221 533
|
||||
"RH_Ring_Secondary_Down", //0x0222 534
|
||||
"RH_Ring_Secondary_Right", //0x0223 535
|
||||
"RH_Ring_Secondary_Up", //0x0224 536
|
||||
"RH_Ring_Secondary_Center", //0x0225 537
|
||||
"RH_Ring_Primary_Left", //0x0226 538
|
||||
"RH_Ring_Primary_Down", //0x0227 539
|
||||
"RH_Ring_Primary_Right", //0x0228 540
|
||||
"RH_Ring_Primary_Up", //0x0229 541
|
||||
"RH_Ring_Primary_Center", //0x0230 542
|
||||
"RH_Middle_Secondary_Left", //0x0231 543
|
||||
"RH_Middle_Secondary_Down", //0x0232 544
|
||||
"RH_Middle_Secondary_Right", //0x0233 545
|
||||
"RH_Middle_Secondary_Up", //0x0234 546
|
||||
"RH_Middle_Secondary_Center", //0x0235 547
|
||||
"RH_Middle_Primary_Left", //0x0236 548
|
||||
"RH_Middle_Primary_Down", //0x0237 549
|
||||
"RH_Middle_Primary_Right", //0x0238 550
|
||||
"RH_Middle_Primary_Up", //0x0239 551
|
||||
"RH_Middle_Primary_Center", //0x0240 552
|
||||
"RH_Index_Left", //0x0241 553
|
||||
"RH_Index_Down", //0x0242 554
|
||||
"RH_Index_Right", //0x0243 555
|
||||
"RH_Index_Up", //0x0244 556
|
||||
"RH_Index_Center", //0x0245 557
|
||||
"LH_Thumb_3_Left", //0x0246 558
|
||||
"LH_Thumb_3_Down", //0x0247 559
|
||||
"LH_Thumb_3_Right", //0x0248 560
|
||||
"LH_Thumb_3_Up", //0x0249 561
|
||||
"LH_Thumb_3_Center", //0x0250 562
|
||||
"LH_Thumb_2_Left", //0x0251 563
|
||||
"LH_Thumb_2_Down", //0x0252 564
|
||||
"LH_Thumb_2_Right", //0x0253 565
|
||||
"LH_Thumb_2_Up", //0x0254 566
|
||||
"LH_Thumb_2_Center", //0x0255 567
|
||||
"LH_Thumb_1_Left", //0x0256 568
|
||||
"LH_Thumb_1_Down", //0x0257 569
|
||||
"LH_Thumb_1_Right", //0x0258 570
|
||||
"LH_Thumb_1_Up", //0x0259 571
|
||||
"LH_Thumb_1_Center", //0x0260 572
|
||||
"LH_Pinky_Left", //0x0261 573
|
||||
"LH_Pinky_Down", //0x0262 574
|
||||
"LH_Pinky_Right", //0x0263 575
|
||||
"LH_Pinky_Up", //0x0264 576
|
||||
"LH_Pinky_Center", //0x0265 577
|
||||
"LH_Ring_Secondary_Left", //0x0266 578
|
||||
"LH_Ring_Secondary_Down", //0x0267 579
|
||||
"LH_Ring_Secondary_Right", //0x0268 580
|
||||
"LH_Ring_Secondary_Up", //0x0269 581
|
||||
"LH_Ring_Secondary_Center", //0x0270 582
|
||||
"LH_Ring_Primary_Left", //0x0271 583
|
||||
"LH_Ring_Primary_Down", //0x0272 584
|
||||
"LH_Ring_Primary_Right", //0x0273 585
|
||||
"LH_Ring_Primary_Up", //0x0274 586
|
||||
"LH_Ring_Primary_Center", //0x0275 587
|
||||
"LH_Middle_Secondary_Left", //0x0276 588
|
||||
"LH_Middle_Secondary_Down", //0x0277 589
|
||||
"LH_Middle_Secondary_Right", //0x0278 590
|
||||
"LH_Middle_Secondary_Up", //0x0279 591
|
||||
"LH_Middle_Secondary_Center", //0x0280 592
|
||||
"LH_Middle_Primary_Left", //0x0281 593
|
||||
"LH_Middle_Primary_Down", //0x0282 594
|
||||
"LH_Middle_Primary_Right", //0x0283 595
|
||||
"LH_Middle_Primary_Up", //0x0284 596
|
||||
"LH_Middle_Primary_Center", //0x0285 597
|
||||
"LH_Index_Left", //0x0286 598
|
||||
"LH_Index_Down", //0x0287 599
|
||||
"LH_Index_Right", //0x0288 600
|
||||
"LH_Index_Up", //0x0289 601
|
||||
"LH_Index_Center", //0x0290 602
|
||||
]
|
||||
20
src/lib/serial/webserial/constants/config-id.js
Normal file
20
src/lib/serial/webserial/constants/config-id.js
Normal file
@@ -0,0 +1,20 @@
|
||||
export const CONFIG_ID = {
|
||||
ENABLE_SERIAL_LOG: "01",
|
||||
ENABLE_SERIAL_RAW: "02",
|
||||
ENABLE_SERIAL_CHORD: "03",
|
||||
ENABLE_SERIAL_KEYBOARD: "04",
|
||||
ENABLE_SERIAL_MOUSE: "05",
|
||||
ENABLE_SERIAL_DEBUG: "06",
|
||||
ENABLE_SERIAL_HEADER: "07",
|
||||
ENABLE_HID_KEYBOARD: "0A",
|
||||
PRESS_THRESHOLD: "0B",
|
||||
RELEASE_THRESHOLD: "0C",
|
||||
ENABLE_HID_MOUSE: "14",
|
||||
SCROLL_DELAY: "15",
|
||||
ENABLE_SPURRING: "1E",
|
||||
SPUR_KILLER_TOGGLE: "1F",
|
||||
SPUR_KILLER: "20",
|
||||
ENABLE_CHORDING: "28",
|
||||
CHAR_KILLER_TOGGLE: "29",
|
||||
CHAR_COUNTER_KILLER: "2A",
|
||||
}
|
||||
160
src/lib/serial/webserial/constants/key-map-defaults.js
Normal file
160
src/lib/serial/webserial/constants/key-map-defaults.js
Normal file
@@ -0,0 +1,160 @@
|
||||
export let _keyMapDefaults = {
|
||||
CHARACHORDER: [
|
||||
0x0000, // 0,
|
||||
0x013e, // 1, mouse right button press-and-release
|
||||
"!".charCodeAt(0), // 2, !
|
||||
0x0187, // 3, right gui
|
||||
0x003f, // 4, ?
|
||||
0x0000, // 5,
|
||||
"b".charCodeAt(0), // 6, b
|
||||
"q".charCodeAt(0), // 7, q
|
||||
0x0115, // 8, previous phrase
|
||||
"x".charCodeAt(0), // 9, x
|
||||
0x0000, //10,
|
||||
"f".charCodeAt(0), //11, f
|
||||
"d".charCodeAt(0), //12, d
|
||||
"h".charCodeAt(0), //13, h
|
||||
"p".charCodeAt(0), //14, p
|
||||
0x0000, //15, //'fed' is using this
|
||||
0x0111, //16, ambi throw right
|
||||
0x0113, //17, num-shift right
|
||||
0x0186, //18, alt right
|
||||
0x0185, //19, shift right
|
||||
0x0000, //20,
|
||||
0x0149, //21, mouse left hand down
|
||||
0x014a, //22, mouse left hand right
|
||||
0x014b, //23, mouse left hand up
|
||||
0x014c, //24, mouse left hand left
|
||||
0x0000, //25,
|
||||
"s".charCodeAt(0), //26, s
|
||||
";".charCodeAt(0), //27, ;
|
||||
0x0184, //28, ctrl right
|
||||
"y".charCodeAt(0), //29, y
|
||||
0x0000, //30,
|
||||
0x01a0, //31, arrow down
|
||||
0x019e, //32, arrow right
|
||||
0x01a1, //33, arrow up
|
||||
0x019f, //34, arrow left
|
||||
0x0000, //35,
|
||||
"n".charCodeAt(0), //36, n
|
||||
"j".charCodeAt(0), //37, j
|
||||
0x0009, //38, tab horizontal
|
||||
"l".charCodeAt(0), //39, l
|
||||
0x0000, //40,
|
||||
"t".charCodeAt(0), //41, t
|
||||
" ".charCodeAt(0), //42, (space)
|
||||
0x000a, //43, enter (line feed)
|
||||
"a".charCodeAt(0), //44, a
|
||||
0x0000, //45,
|
||||
"/".charCodeAt(0), //46, /
|
||||
"-".charCodeAt(0), //47, -
|
||||
0x0183, //48, left gui
|
||||
0x001b, //49, escape
|
||||
0x0000, //50,
|
||||
"w".charCodeAt(0), //51, w
|
||||
0x013d, //52, mouse left button press-and-release
|
||||
"g".charCodeAt(0), //53, g
|
||||
"z".charCodeAt(0), //54, z
|
||||
0x0151, //55, double click
|
||||
"k".charCodeAt(0), //56, k
|
||||
"v".charCodeAt(0), //57, v
|
||||
"m".charCodeAt(0), //58, m
|
||||
"c".charCodeAt(0), //59, c
|
||||
0x0000, //60,
|
||||
0x0110, //61, ambi throw left
|
||||
0x0181, //62, shift left
|
||||
0x0182, //63, alt left
|
||||
0x0110, //64, num-shift left
|
||||
0x0000, //65,
|
||||
0x0149, //66, mouse right hand down
|
||||
0x014a, //67, mouse right hand right
|
||||
0x014b, //68, mouse right hand up
|
||||
0x014c, //69, mouse right hand left
|
||||
0x0000, //70,
|
||||
"u".charCodeAt(0), //71, u
|
||||
"\\".charCodeAt(0), //72, \
|
||||
0x0180, //73, left ctrl
|
||||
",".charCodeAt(0), //74, ,
|
||||
0x0000, //75,
|
||||
0x01a0, //76, arrow down
|
||||
0x019e, //77, arrow right
|
||||
0x01a1, //78, arrow up
|
||||
0x019f, //79, arrow left
|
||||
0x0000, //80,
|
||||
"o".charCodeAt(0), //81, o
|
||||
"i".charCodeAt(0), //82, i
|
||||
0x007f, //83, del forward
|
||||
".".charCodeAt(0), //84, .
|
||||
0x0000, //85,
|
||||
"e".charCodeAt(0), //86, e
|
||||
"r".charCodeAt(0), //87, r
|
||||
0x0008, //88, backspace
|
||||
" ".charCodeAt(0), //89, (space)
|
||||
],
|
||||
CHARACHORDERLITE: [
|
||||
"GTM", //0
|
||||
"LCtrl", //1
|
||||
"LAlt", //2
|
||||
"LSpace", //3
|
||||
"Present", //4
|
||||
"Plural", //5
|
||||
"RSpace", //6
|
||||
"Dup", //7
|
||||
"Win", //8
|
||||
"Left", //9
|
||||
"Down", //10
|
||||
"Right", //11
|
||||
"LShift", //12
|
||||
"z", //13
|
||||
"x", //14
|
||||
"c", //15
|
||||
"v", //16
|
||||
"b", //17
|
||||
"n", //18
|
||||
"m", //19
|
||||
",", //20
|
||||
".", //21
|
||||
"/", //22
|
||||
"RShift", //23
|
||||
"Up", //24
|
||||
"Del", //25
|
||||
"Spur", //26
|
||||
"0x0061", //27
|
||||
"s", //28
|
||||
"d", //29
|
||||
"f", //30
|
||||
"g", //31
|
||||
"h", //32
|
||||
"j", //33
|
||||
"k", //34
|
||||
"l", //35
|
||||
";", //36
|
||||
"'", //37
|
||||
"Tab", //38
|
||||
"q", //39
|
||||
"w", //40
|
||||
"e", //41
|
||||
"r", //42
|
||||
"t", //43
|
||||
"y", //44
|
||||
"u", //45
|
||||
"i", //46
|
||||
"o", //47
|
||||
"p", //48
|
||||
"[", //49
|
||||
"\\", //50
|
||||
"1", //51
|
||||
"2", //52
|
||||
"3", //53
|
||||
"4", //54
|
||||
"5", //55
|
||||
"6", //56
|
||||
"7", //57
|
||||
"8", //58
|
||||
"9", //59
|
||||
"0", //60
|
||||
"-", //61
|
||||
"=", //62
|
||||
"Back", //63
|
||||
],
|
||||
}
|
||||
71
src/lib/serial/webserial/constants/key-map.js
Normal file
71
src/lib/serial/webserial/constants/key-map.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* this shouldn't be used anymore
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
export const _keyMap = [
|
||||
"GTM", //0
|
||||
"LCtrl", //1
|
||||
"LAlt", //2
|
||||
"LSpace", //3
|
||||
"Present", //4
|
||||
"Plural", //5
|
||||
"RSpace", //6
|
||||
"Dup", //7
|
||||
"Win", //8
|
||||
"Left", //9
|
||||
"Down", //10
|
||||
"Right", //11
|
||||
"LShift", //12
|
||||
"z", //13
|
||||
"x", //14
|
||||
"c", //15
|
||||
"v", //16
|
||||
"b", //17
|
||||
"n", //18
|
||||
"m", //19
|
||||
",", //20
|
||||
".", //21
|
||||
"/", //22
|
||||
"RShift", //23
|
||||
"Up", //24
|
||||
"Del", //25
|
||||
"Spur", //26
|
||||
"0x0061", //27
|
||||
"s", //28
|
||||
"d", //29
|
||||
"f", //30
|
||||
"g", //31
|
||||
"h", //32
|
||||
"j", //33
|
||||
"k", //34
|
||||
"l", //35
|
||||
";", //36
|
||||
"'", //37
|
||||
"Tab", //38
|
||||
"q", //39
|
||||
"w", //40
|
||||
"e", //41
|
||||
"r", //42
|
||||
"t", //43
|
||||
"y", //44
|
||||
"u", //45
|
||||
"i", //46
|
||||
"o", //47
|
||||
"p", //48
|
||||
"[", //49
|
||||
"\\", //50
|
||||
"1", //51
|
||||
"2", //52
|
||||
"3", //53
|
||||
"4", //54
|
||||
"5", //55
|
||||
"6", //56
|
||||
"7", //57
|
||||
"8", //58
|
||||
"9", //59
|
||||
"0", //60
|
||||
"-", //61
|
||||
"=", //62
|
||||
"Back", //63
|
||||
].reverse()
|
||||
27
src/lib/serial/webserial/hex-chord.js
Normal file
27
src/lib/serial/webserial/hex-chord.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import {readGetOneAndToss} from "$lib/serial/webserial/noop.js"
|
||||
|
||||
/**
|
||||
* Unused?
|
||||
* @param lineReader {ReadableStreamDefaultReader<string>}
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function readGetHexChord(lineReader) {
|
||||
let hexChordString = ""
|
||||
await readGetOneAndToss(lineReader) //this is added for the latest firmware with customers, where decimal version
|
||||
|
||||
const {value, done} = await lineReader.read()
|
||||
if (done) {
|
||||
console.log("reader is done")
|
||||
} else {
|
||||
console.log(["value", value])
|
||||
|
||||
if (value) {
|
||||
let arrValue = [...value]
|
||||
const strValue = String(arrValue.join(""))
|
||||
console.log(strValue)
|
||||
hexChordString = strValue.substr(0, 16)
|
||||
await readGetOneAndToss(lineReader) // the "processing chord:" decimal output
|
||||
}
|
||||
}
|
||||
return hexChordString
|
||||
}
|
||||
5
src/lib/serial/webserial/noop.js
Normal file
5
src/lib/serial/webserial/noop.js
Normal file
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* @param lineReader {ReadableStreamDefaultReader<string>}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function readGetOneAndToss(lineReader) {}
|
||||
19
src/lib/serial/webserial/util/big-math.js
Normal file
19
src/lib/serial/webserial/util/big-math.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* JavaScript handles up to 53-bit bs it uses float64 to operate with integers
|
||||
*/
|
||||
function bitwiseAndLarge(val1, val2) {
|
||||
let shift = 0,
|
||||
result = 0
|
||||
const mask = ~(~0 << 30) // Gives us a bit mask like 01111..1 (30 ones)
|
||||
const divisor = 1 << 30 // To work with the bit mask, we need to clear bits at a time
|
||||
while (val1 !== 0 && val2 !== 0) {
|
||||
let rs = mask & val1 & (mask & val2)
|
||||
val1 = Math.floor(val1 / divisor) // val1 >>> 30
|
||||
val2 = Math.floor(val2 / divisor) // val2 >>> 30
|
||||
for (let i = shift++; i--; ) {
|
||||
rs *= divisor // rs << 30
|
||||
}
|
||||
result += rs
|
||||
}
|
||||
return result
|
||||
}
|
||||
208
src/lib/serial/webserial/util/chord-hex.js
Normal file
208
src/lib/serial/webserial/util/chord-hex.js
Normal file
@@ -0,0 +1,208 @@
|
||||
import {_actionMap} from "$lib/serial/webserial/constants/action-map.js"
|
||||
import {_keyMap} from "$lib/serial/webserial/constants/key-map.js"
|
||||
import {_keyMapDefaults} from "$lib/serial/webserial/constants/key-map-defaults.js"
|
||||
|
||||
/**
|
||||
* @param hexString {string}
|
||||
* @param chordMapId {keyof typeof import('$lib/serial/webserial/constants/key-map-defaults.js')._keyMapDefaults}
|
||||
* @returns {string}
|
||||
*/
|
||||
export function convertHexadecimalChordToHumanString(hexString, chordMapId) {
|
||||
let humanString = ""
|
||||
console.log(hexString)
|
||||
if (hexString.length <= 0) {
|
||||
hexString = "00"
|
||||
}
|
||||
let bigNum = BigInt("0x" + hexString)
|
||||
|
||||
if (chordMapId === "CHARACHORDER") {
|
||||
// CharaChorder original uses different key map structure
|
||||
let decString = String(bigNum).split("") //no left zeros; that's ok
|
||||
console.log(decString)
|
||||
for (let i = 0; i < decString.length; i++) {
|
||||
if (decString[i] !== "0") {
|
||||
if (humanString.length > 0) {
|
||||
humanString += " + "
|
||||
}
|
||||
console.log({
|
||||
"i": i,
|
||||
"decString[i]": decString[i],
|
||||
"decString.length": decString.length,
|
||||
"decString": decString,
|
||||
"10exp": decString.length - i - 1,
|
||||
"decChordComp": decString[i] * 10 ** (decString.length - i - 1),
|
||||
// 'decChordCompBigInt':BigInt(decString[i])*BigInt((BigInt(10)**(decString.length-i-1))),
|
||||
"noteId": chord_to_noteId(decString[i] * 10 ** (decString.length - i - 1)),
|
||||
})
|
||||
let noteId
|
||||
let actionId
|
||||
if (decString[i] % 2 === 1) {
|
||||
//if it is odd, then it is simple
|
||||
noteId = chord_to_noteId(decString[i] * 10 ** (decString.length - i - 1))
|
||||
actionId = _keyMapDefaults["CHARACHORDER"][noteId]
|
||||
if (actionId === 0) {
|
||||
actionId = 0x0200 + noteId
|
||||
}
|
||||
humanString += _actionMap[actionId]
|
||||
} else {
|
||||
//value is even, odd plus a 1
|
||||
noteId = chord_to_noteId((decString[i] - 1) * 10 ** (decString.length - i - 1))
|
||||
actionId = _keyMapDefaults["CHARACHORDER"][noteId]
|
||||
if (actionId === 0) {
|
||||
actionId = 0x0200 + noteId
|
||||
}
|
||||
humanString += _actionMap[actionId]
|
||||
|
||||
humanString += " + "
|
||||
|
||||
noteId = chord_to_noteId(10 ** (decString.length - i - 1))
|
||||
actionId = _keyMapDefaults["CHARACHORDER"][noteId]
|
||||
if (actionId === 0) {
|
||||
actionId = 0x0200 + noteId
|
||||
}
|
||||
humanString += _actionMap[actionId]
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let binString = bigNum.toString(2) //no left zeros; that's ok
|
||||
console.log(binString)
|
||||
for (let i = 0; i < binString.length; i++) {
|
||||
if (binString[i] === "1") {
|
||||
if (humanString.length > 0) {
|
||||
humanString += " + "
|
||||
}
|
||||
humanString += _keyMap[64 - binString.length + i]
|
||||
//console.log(i);
|
||||
//humanString+=_keyMap[(64-binString.length+i)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(humanString)
|
||||
return humanString
|
||||
}
|
||||
|
||||
/**
|
||||
* @param humanString {string}
|
||||
* @returns {string}
|
||||
*/
|
||||
export function convertHumanStringToHexadecimalPhrase(humanString) {
|
||||
let hexString = ""
|
||||
for (let i = 0; i < humanString.length; i++) {
|
||||
let hex = Number(humanString.charCodeAt(i)).toString(16)
|
||||
hexString += hex
|
||||
}
|
||||
hexString = hexString.toUpperCase()
|
||||
console.log(hexString)
|
||||
return hexString
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hexString {string}
|
||||
* @returns {string}
|
||||
*/
|
||||
function convertHexadecimalPhraseToAsciiString(hexString) {
|
||||
let asciiString = ""
|
||||
console.log("convertHexadecimalPhraseToAsciiString()")
|
||||
|
||||
//assume 2x size
|
||||
//get every 2 characters
|
||||
//TODO covert to byte array and account for non-ascii inputs like mouse moves
|
||||
for (let i = 0; i < hexString.length; i += 2) {
|
||||
asciiString += String.fromCharCode(parseInt(hexString.substr(i, 2), 16))
|
||||
//console.log("0x"+hexString.substr(i, 2));
|
||||
//asciiString += String.fromCharCode("0x"+hexString.substr(i, 2));
|
||||
}
|
||||
console.log(asciiString)
|
||||
return asciiString
|
||||
}
|
||||
|
||||
function noteId_to_chord(note) {
|
||||
return BigInt(2 * ((note - 1) % 5) + 1) * BigInt(10) ** BigInt(Math.floor((note - 1) / 5))
|
||||
}
|
||||
|
||||
function chord_to_noteId(chord) {
|
||||
const part1 = 5 * Math.floor(Math.log10(chord))
|
||||
const part2 = Math.floor(chord / 10 ** Math.floor(Math.log10(chord)) + 1) / 2
|
||||
const part3 = Math.log10(chord)
|
||||
|
||||
const full = Math.floor(
|
||||
5 * Math.floor(Math.log10(chord)) + Math.floor(chord / 10 ** Math.floor(Math.log10(chord)) + 1) / 2,
|
||||
)
|
||||
console.log([chord, part1, part2, part3, full])
|
||||
return full
|
||||
}
|
||||
|
||||
/**
|
||||
* @param humanString {string}
|
||||
* @param chordMapId {keyof typeof import('$lib/serial/webserial/constants/key-map-defaults.js')._keyMapDefaults}
|
||||
* @returns {Promise<bigint>}
|
||||
*/
|
||||
export async function convertHumanStringToBigNum(humanString, chordMapId) {
|
||||
console.log("convertHumanStringToBigNum")
|
||||
let bigNum = BigInt(0)
|
||||
//parse the pieces with _+_
|
||||
let humanStringParts = humanString.split(" + ") //assumes plus isn't being used; bc default is = for the +/= key
|
||||
console.log(humanStringParts)
|
||||
for (const part of humanStringParts) {
|
||||
let actionId = _actionMap.indexOf(part)
|
||||
console.log(actionId)
|
||||
if (chordMapId === "CHARACHORDER") {
|
||||
//charachorder original uses different key map structure
|
||||
let keyId
|
||||
if (actionId < 0x0200) {
|
||||
keyId = _keyMapDefaults["CHARACHORDER"].indexOf(actionId)
|
||||
} else {
|
||||
keyId = actionId - 0x0200 //using the physical key position
|
||||
}
|
||||
|
||||
console.log(keyId)
|
||||
bigNum = BigInt(noteId_to_chord(keyId))
|
||||
// bigNum+= BigInt(noteId_to_chord(keyId));
|
||||
console.log(bigNum)
|
||||
} else {
|
||||
//use other keymap
|
||||
}
|
||||
}
|
||||
console.log(bigNum)
|
||||
return bigNum
|
||||
}
|
||||
|
||||
/**
|
||||
* @param humanString {string}
|
||||
* @param chordMapId {keyof typeof import('$lib/serial/webserial/constants/key-map-defaults.js')._keyMapDefaults}
|
||||
* @returns {string}
|
||||
*/
|
||||
export function convertHumanStringToHexadecimalChord(humanString, chordMapId) {
|
||||
let bigNum = BigInt(0)
|
||||
//parse the pieces with _+_
|
||||
let humanStringParts = humanString.split(" + ") //assumes plus isn't being used; bc default is = for the +/= key
|
||||
console.log(humanStringParts)
|
||||
humanStringParts.forEach(async part => {
|
||||
let actionId = _actionMap.indexOf(part)
|
||||
console.log(actionId)
|
||||
if (chordMapId === "CHARACHORDER") {
|
||||
//charachorder original uses different key map structure
|
||||
let keyId
|
||||
if (actionId < 0x0200) {
|
||||
keyId = _keyMapDefaults["CHARACHORDER"].indexOf(actionId)
|
||||
} else {
|
||||
keyId = actionId - 0x0200 //using the physical key position
|
||||
}
|
||||
|
||||
console.log(keyId)
|
||||
bigNum += BigInt(noteId_to_chord(keyId))
|
||||
console.log(bigNum)
|
||||
} else {
|
||||
//use other keymap
|
||||
}
|
||||
})
|
||||
console.log(bigNum)
|
||||
|
||||
let hexString = bigNum.toString(16).toUpperCase()
|
||||
hexString = "0".repeat(16 - hexString.length) + hexString //add leading zeros up to 16 characters
|
||||
console.log(hexString)
|
||||
|
||||
return hexString
|
||||
}
|
||||
21
src/lib/serial/webserial/util/line-break-transformer.js
Normal file
21
src/lib/serial/webserial/util/line-break-transformer.js
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-check
|
||||
export class LineBreakTransformer {
|
||||
constructor() {
|
||||
this.chunks = ""
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
transform(chunk, controller) {
|
||||
this.chunks += chunk
|
||||
const lines = this.chunks.split("\r\n")
|
||||
this.chunks = lines.pop()
|
||||
for (const line of lines) {
|
||||
controller.enqueue(line)
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
flush(controller) {
|
||||
controller.enqueue(this.chunks)
|
||||
}
|
||||
}
|
||||
17
src/lib/serial/webserial/version.js
Normal file
17
src/lib/serial/webserial/version.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import {readGetOneAndToss} from "$lib/serial/webserial/noop.js"
|
||||
|
||||
export let FIRMWARE_VERSION = "0"
|
||||
|
||||
/**
|
||||
* @param lineReader {ReadableStreamDefaultReader<string>}
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function readVersion(lineReader) {
|
||||
await readGetOneAndToss(lineReader) //electronics board version
|
||||
const {value, done} = await lineReader.read()
|
||||
if (value) {
|
||||
FIRMWARE_VERSION = value
|
||||
console.log("Firmware Version:", FIRMWARE_VERSION)
|
||||
}
|
||||
await readGetOneAndToss(lineReader) //serial api version
|
||||
}
|
||||
30
src/lib/style/fonts/material-symbols-rounded.scss
Normal file
30
src/lib/style/fonts/material-symbols-rounded.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
/* fallback */
|
||||
@font-face {
|
||||
font-family: 'Material Symbols Rounded';
|
||||
font-weight: 100 700;
|
||||
font-style: normal;
|
||||
src: url("https://fonts.gstatic.com/s/materialsymbolsrounded/v121/sykg-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190Fjzag.woff2") format('woff2');
|
||||
}
|
||||
|
||||
.icon {
|
||||
direction: ltr;
|
||||
display: inline-block;
|
||||
|
||||
/* stylelint-disable-next-line */
|
||||
font-family: 'Material Symbols Rounded';
|
||||
font-size: 24px;
|
||||
font-feature-settings: 'liga';
|
||||
font-variation-settings: "FILL" var(--icon-fill, 0) "wght" var(--icon-weigth, 400) "GRAD"
|
||||
var(--icon-grade, 0);
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
|
||||
transition: all 250ms ease;
|
||||
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
153
src/lib/style/fonts/noto-sans-mono.scss
Normal file
153
src/lib/style/fonts/noto-sans-mono.scss
Normal file
@@ -0,0 +1,153 @@
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 320;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 77.8%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCLwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 320;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 77.8%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCCwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 320;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 77.8%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCKwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 320;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 77.8%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCFwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 320;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 77.8%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCJwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 320;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 77.8%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCIwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 320;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 77.8%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCGwR0.woff2") format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 100%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCLwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 100%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCCwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 100%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCKwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 100%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCFwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 100%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCJwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 100%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCIwR26eg.woff2") format('woff2');
|
||||
unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Noto Sans Mono';
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-stretch: 100%;
|
||||
src: url("https://fonts.gstatic.com/s/notosansmono/v27/BngRUXNETWXI6LwhGYvaxZikqbCGwR0.woff2") format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
49
src/routes/+layout.svelte
Normal file
49
src/routes/+layout.svelte
Normal file
@@ -0,0 +1,49 @@
|
||||
<script>
|
||||
import "$lib/style/fonts/noto-sans-mono.scss"
|
||||
import "$lib/style/fonts/material-symbols-rounded.scss"
|
||||
import {onMount} from "svelte"
|
||||
import {applyTheme, argbFromHex, themeFromSourceColor} from "@material/material-color-utilities"
|
||||
import Navigation from "$lib/components/Navigation.svelte"
|
||||
import {serialPort} from "$lib/serial/connection.js"
|
||||
import {CharaDevice} from "$lib/serial/device.js"
|
||||
|
||||
/** @type {import('$lib/serial/device.js').CharaDevice} */
|
||||
let device // @hmr:keep
|
||||
|
||||
onMount(async () => {
|
||||
const theme = themeFromSourceColor(argbFromHex("#6D81C7"), [
|
||||
{name: "success", value: argbFromHex("#00ff00"), blend: true},
|
||||
])
|
||||
const dark = true // window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
applyTheme(theme, {target: document.body, dark})
|
||||
|
||||
device ??= new CharaDevice()
|
||||
serialPort.set(device)
|
||||
})
|
||||
</script>
|
||||
|
||||
<Navigation />
|
||||
|
||||
<slot />
|
||||
|
||||
<style lang="scss" global>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--md-sys-color-tertiary);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Noto Sans Mono", monospace;
|
||||
color: var(--md-sys-color-on-background);
|
||||
background: var(--md-sys-color-background);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
font-weight: 900;
|
||||
color: var(--md-sys-color-secondary);
|
||||
}
|
||||
</style>
|
||||
6
src/routes/+page.svelte
Normal file
6
src/routes/+page.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<svelte:head>
|
||||
<title>dot i/o</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>dot i/o V2</h1>
|
||||
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
|
||||
165
src/routes/device-manager/+page.svelte
Normal file
165
src/routes/device-manager/+page.svelte
Normal file
@@ -0,0 +1,165 @@
|
||||
<script>
|
||||
import {serialPort} from "$lib/serial/connection.js"
|
||||
import Terminal from "$lib/components/Terminal.svelte"
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>dot i/o device manager</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>Device Manager</h1>
|
||||
|
||||
<div class="device-grid">
|
||||
<section>
|
||||
<h2>Control</h2>
|
||||
<div class="icon bg">memory</div>
|
||||
<div class="row">
|
||||
<button disabled class="icon secondary" title="Save changes to device">rule_settings</button>
|
||||
<button disabled title="Reboot" class="icon">restart_alt</button>
|
||||
<button disabled>
|
||||
{#if $serialPort}
|
||||
<span class="icon">usb_off</span> Disconnect
|
||||
{:else}
|
||||
<span class="icon">usb</span> Connect
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
{#if $serialPort}
|
||||
<pre>{#await $serialPort.version then version}{version}{/await}<br
|
||||
/>{#await $serialPort.deviceId then id}{id}{/await}</pre>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Layout</h2>
|
||||
<div class="icon bg">keyboard</div>
|
||||
<div class="row">
|
||||
<button class="icon" title="Import Layout">download</button>
|
||||
<button class="icon" title="Export Layout">upload</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Chords</h2>
|
||||
<div class="icon bg">piano</div>
|
||||
<table>
|
||||
<tr>
|
||||
<th>three</th>
|
||||
<td><i>␣</i><i>3</i></td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Serial Terminal</h2>
|
||||
<div class="icon bg">terminal</div>
|
||||
<Terminal />
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
section {
|
||||
position: relative;
|
||||
min-height: 128px;
|
||||
padding: 8px;
|
||||
border-radius: 32px;
|
||||
|
||||
> h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
> div.icon.bg {
|
||||
user-select: none;
|
||||
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: -4px;
|
||||
left: -8px;
|
||||
|
||||
font-size: 64px;
|
||||
|
||||
opacity: 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
padding: 8px;
|
||||
padding-inline-end: 16px;
|
||||
|
||||
font-size: 1rem;
|
||||
color: var(--md-sys-color-on-background);
|
||||
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 1rem;
|
||||
|
||||
transition: all 250ms ease;
|
||||
|
||||
&:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.icon {
|
||||
aspect-ratio: 1;
|
||||
padding-inline-end: 8px;
|
||||
font-size: 24px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
color: var(--md-sys-color-on-primary);
|
||||
background: var(--md-sys-color-primary);
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
color: var(--md-sys-color-on-secondary);
|
||||
background: var(--md-sys-color-secondary);
|
||||
}
|
||||
|
||||
&.tertiary {
|
||||
color: var(--md-sys-color-on-tertiary);
|
||||
background: var(--md-sys-color-tertiary);
|
||||
}
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
color: var(--md-sys-color-on-surface-variant);
|
||||
background: var(--md-sys-color-surface-variant);
|
||||
}
|
||||
}
|
||||
|
||||
table td {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
table i {
|
||||
display: block;
|
||||
|
||||
aspect-ratio: 1;
|
||||
padding-block: 4px;
|
||||
padding-inline: 8px;
|
||||
|
||||
font-style: normal;
|
||||
|
||||
border: 1px solid var(--md-sys-color-outline);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.device-grid {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
</style>
|
||||
BIN
static/favicon.png
Normal file
BIN
static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
12
svelte.config.js
Normal file
12
svelte.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import adapter from "@sveltejs/adapter-static"
|
||||
import preprocess from "svelte-preprocess"
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
preprocess: [preprocess()],
|
||||
kit: {
|
||||
adapter: adapter(),
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
6
vite.config.js
Normal file
6
vite.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import {sveltekit} from "@sveltejs/kit/vite"
|
||||
import {defineConfig} from "vite"
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
})
|
||||
Reference in New Issue
Block a user