Compare commits
19 Commits
v0.5.0-alp
...
9e90823858
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e90823858 | |||
| 269e62b5fb | |||
| 1c62f2783c | |||
| 9ba3580056 | |||
| 9415fa3783 | |||
| 966782d8b9 | |||
| ce76528958 | |||
| c3420dbcdf | |||
| f32f107078 | |||
| 43ccf20561 | |||
| 8c2a135afb | |||
| ab6af04e5b | |||
| 8ba930ed2e | |||
| d2ee45c61a | |||
| e4a3d1ab46 | |||
| 862773d622 | |||
| 47ec235cfa | |||
| dcdde0289b | |||
| 390faf0a29 |
@@ -13,6 +13,8 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install node modules
|
- name: Install node modules
|
||||||
run: npm install
|
run: npm install
|
||||||
|
- name: Add build number
|
||||||
|
run: sed -i 's/####/#${{ github.run_number }}/' ./src/js/store.js
|
||||||
- name: Build pwa
|
- name: Build pwa
|
||||||
run: npm run build
|
run: npm run build
|
||||||
- name: Replace previous dev pwa
|
- name: Replace previous dev pwa
|
||||||
|
|||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -40,7 +40,8 @@ cordova/platforms/
|
|||||||
cordova/plugins/
|
cordova/plugins/
|
||||||
cordova/www/
|
cordova/www/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Production build
|
# Production build
|
||||||
www/
|
www/
|
||||||
|
|
||||||
|
# VSCode settings
|
||||||
|
.vscode/settings.json
|
||||||
|
|||||||
@@ -47,9 +47,10 @@ The following site settings are avaible:
|
|||||||
| name | description | values | default |
|
| name | description | values | default |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `agreeExpire` | number of months before users are shown the site agreement dialog again<br />set to 0 to display dialog on every reload | integer >= 0 | 3 |
|
| `agreeExpire` | number of months before users are shown the site agreement dialog again<br />set to 0 to display dialog on every reload | integer >= 0 | 3 |
|
||||||
| `demo` | set to **true** to enable demo mode by default | boolean | false
|
| `demo` | set to **true** to enable demo mode by default | boolean | false |
|
||||||
| `regions` | array of regions names to enable | thorax, abdomen, limbs, head | [thorax, abdomen, limbs, head] |
|
| `regions` | array of regions names to enable | thorax, abdomen, limbs, head | [thorax, abdomen, limbs, head] |
|
||||||
| `useExternal` | detemines the ability to use an external detection server:<br />**none** - external server cannot be configured<br />**optional** - external server can be configured in the app's settings page<br />**list** - external server can be selected in the app's settings page but only the configured server(s) may be selected<br />**required** - external server settings from conf file will be used by default and disable server options in the settings page | none, optional, list, required | **optional** |
|
| `useExternal` | detemines the ability to use an external detection server:<br />**none** - external server cannot be configured<br />**optional** - external server can be configured in the app's settings page<br />**list** - external server can be selected in the app's settings page but only the configured server(s) may be selected<br />**required** - external server settings from conf file will be used by default and disable server options in the settings page | none, optional, list, required | **optional** |
|
||||||
|
| `disableWorkers` | force app to use a single thread for detection computations instead of multi threading web workers | boolean | **optional** |
|
||||||
| `external` | properties of the external server(s) ALVINN may connect to<br />This setting must be a single element array if **useExternal** is set to **required**.<br />This setting must be an array of one or more elements if **useExternal** is set to **list** | external server settings array | []|
|
| `external` | properties of the external server(s) ALVINN may connect to<br />This setting must be a single element array if **useExternal** is set to **required**.<br />This setting must be an array of one or more elements if **useExternal** is set to **list** | external server settings array | []|
|
||||||
| `infoUrl` | root url for links to information about identified structures<br />Structure labels with spaces replaced by underscores will be appended to this value for full information links (*e.g.,* Abdominal_diapragm) | string | info link not shown |
|
| `infoUrl` | root url for links to information about identified structures<br />Structure labels with spaces replaced by underscores will be appended to this value for full information links (*e.g.,* Abdominal_diapragm) | string | info link not shown |
|
||||||
|
|
||||||
|
|||||||
173
package-lock.json
generated
173
package-lock.json
generated
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "alvinn",
|
"name": "alvinn",
|
||||||
"version": "0.5.0-rc",
|
"version": "0.5.0-alpha",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "alvinn",
|
"name": "alvinn",
|
||||||
"version": "0.5.0-rc",
|
"version": "0.5.0-alpha",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tensorflow/tfjs": "^4.17.0",
|
"@tensorflow/tfjs": "^4.21.0",
|
||||||
"dom7": "^4.0.6",
|
"dom7": "^4.0.6",
|
||||||
"framework7": "^8.3.0",
|
"framework7": "^8.3.0",
|
||||||
"framework7-icons": "^5.0.5",
|
"framework7-icons": "^5.0.5",
|
||||||
@@ -3354,16 +3354,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs": {
|
"node_modules/@tensorflow/tfjs": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.21.0.tgz",
|
||||||
"integrity": "sha512-yXRBhpM3frlNA/YaPp6HNk9EfIi8han5RYeQA3R8OCa0Od+AfoG1PUmlxV8fE2wCorlGVyHsgpiJ6M9YZPB56w==",
|
"integrity": "sha512-7D/+H150ptvt+POMbsME3WlIvLiuBR2rCC2Z0hOKKb/5Ygkj7xsp/K2HzOvUj0g0yjk+utkU45QEYhnhjnbHRA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tensorflow/tfjs-backend-cpu": "4.17.0",
|
"@tensorflow/tfjs-backend-cpu": "4.21.0",
|
||||||
"@tensorflow/tfjs-backend-webgl": "4.17.0",
|
"@tensorflow/tfjs-backend-webgl": "4.21.0",
|
||||||
"@tensorflow/tfjs-converter": "4.17.0",
|
"@tensorflow/tfjs-converter": "4.21.0",
|
||||||
"@tensorflow/tfjs-core": "4.17.0",
|
"@tensorflow/tfjs-core": "4.21.0",
|
||||||
"@tensorflow/tfjs-data": "4.17.0",
|
"@tensorflow/tfjs-data": "4.21.0",
|
||||||
"@tensorflow/tfjs-layers": "4.17.0",
|
"@tensorflow/tfjs-layers": "4.21.0",
|
||||||
"argparse": "^1.0.10",
|
"argparse": "^1.0.10",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"core-js": "3.29.1",
|
"core-js": "3.29.1",
|
||||||
@@ -3375,9 +3376,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs-backend-cpu": {
|
"node_modules/@tensorflow/tfjs-backend-cpu": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.21.0.tgz",
|
||||||
"integrity": "sha512-2VSCHnX9qhYTjw9HiVwTBSnRVlntKXeBlK7aSVsmZfHGwWE2faErTtO7bWmqNqw0U7gyznJbVAjlow/p+0RNGw==",
|
"integrity": "sha512-yS9Oisg4L48N7ML6677ilv1eP5Jt59S74skSU1cCsM4yBAtH4DAn9b89/JtqBISh6JadanfX26b4HCWQvMvqFg==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/seedrandom": "^2.4.28",
|
"@types/seedrandom": "^2.4.28",
|
||||||
"seedrandom": "^3.0.5"
|
"seedrandom": "^3.0.5"
|
||||||
@@ -3386,15 +3388,16 @@
|
|||||||
"yarn": ">= 1.3.2"
|
"yarn": ">= 1.3.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tensorflow/tfjs-core": "4.17.0"
|
"@tensorflow/tfjs-core": "4.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs-backend-webgl": {
|
"node_modules/@tensorflow/tfjs-backend-webgl": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.21.0.tgz",
|
||||||
"integrity": "sha512-CC5GsGECCd7eYAUaKq0XJ48FjEZdgXZWPxgUYx4djvfUx5fQPp35hCSP9w/k463jllBMbjl2tKRg8u7Ia/LYzg==",
|
"integrity": "sha512-7k6mb7dd0uF9jI51iunF3rhEXjvR/a613kjWZ0Rj3o1COFrneyku2C7cRMZERWPhbgXZ+dF+j9MdpGIpgtShIQ==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tensorflow/tfjs-backend-cpu": "4.17.0",
|
"@tensorflow/tfjs-backend-cpu": "4.21.0",
|
||||||
"@types/offscreencanvas": "~2019.3.0",
|
"@types/offscreencanvas": "~2019.3.0",
|
||||||
"@types/seedrandom": "^2.4.28",
|
"@types/seedrandom": "^2.4.28",
|
||||||
"seedrandom": "^3.0.5"
|
"seedrandom": "^3.0.5"
|
||||||
@@ -3403,21 +3406,23 @@
|
|||||||
"yarn": ">= 1.3.2"
|
"yarn": ">= 1.3.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tensorflow/tfjs-core": "4.17.0"
|
"@tensorflow/tfjs-core": "4.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs-converter": {
|
"node_modules/@tensorflow/tfjs-converter": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.21.0.tgz",
|
||||||
"integrity": "sha512-qFxIjPfomCuTrYxsFjtKbi3QfdmTTCWo+RvqD64oCMS0sjp7sUDNhJyKDoLx6LZhXlwXpHIVDJctLMRMwet0Zw==",
|
"integrity": "sha512-cUhU+F1lGx2qnKk/gRy8odBh0PZlFz0Dl71TG8LVnj0/g352DqiNrKXlKO/po9aWzP8x0KUGC3gNMSMJW+T0DA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tensorflow/tfjs-core": "4.17.0"
|
"@tensorflow/tfjs-core": "4.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs-core": {
|
"node_modules/@tensorflow/tfjs-core": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.21.0.tgz",
|
||||||
"integrity": "sha512-v9Q5430EnRpyhWNd9LVgXadciKvxLiq+sTrLKRowh26BHyAsams4tZIgX3lFKjB7b90p+FYifVMcqLTTHgjGpQ==",
|
"integrity": "sha512-ZbECwXps5wb9XXcGq4ZXvZDVjr5okc3I0+i/vU6bpQ+nVApyIrMiyEudP8f6vracVTvNmnlN62vUXoEsQb2F8g==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/long": "^4.0.1",
|
"@types/long": "^4.0.1",
|
||||||
"@types/offscreencanvas": "~2019.7.0",
|
"@types/offscreencanvas": "~2019.7.0",
|
||||||
@@ -3434,28 +3439,31 @@
|
|||||||
"node_modules/@tensorflow/tfjs-core/node_modules/@types/offscreencanvas": {
|
"node_modules/@tensorflow/tfjs-core/node_modules/@types/offscreencanvas": {
|
||||||
"version": "2019.7.3",
|
"version": "2019.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
|
||||||
"integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A=="
|
"integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs-data": {
|
"node_modules/@tensorflow/tfjs-data": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.21.0.tgz",
|
||||||
"integrity": "sha512-aPKrDFip+gXicWOFALeNT7KKQjRXFkHd/hNe/zs4mCFcIN00hy1PkZ6xkYsgrsdLDQMBSGeS4B4ZM0k5Cs88QA==",
|
"integrity": "sha512-LpJ/vyQMwYHkcVCqIRg7IVVw13VBY7rNAiuhmKP9S5NP/2ye4KA8BJ4XwDIDgjCVQM7glK9L8bMav++xCDf7xA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node-fetch": "^2.1.2",
|
"@types/node-fetch": "^2.1.2",
|
||||||
"node-fetch": "~2.6.1",
|
"node-fetch": "~2.6.1",
|
||||||
"string_decoder": "^1.3.0"
|
"string_decoder": "^1.3.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tensorflow/tfjs-core": "4.17.0",
|
"@tensorflow/tfjs-core": "4.21.0",
|
||||||
"seedrandom": "^3.0.5"
|
"seedrandom": "^3.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs-layers": {
|
"node_modules/@tensorflow/tfjs-layers": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.21.0.tgz",
|
||||||
"integrity": "sha512-DEE0zRKvf3LJ0EcvG5XouJYOgFGWYAneZ0K1d23969z7LfSyqVmBdLC6BTwdLKuJk3ouUJIKXU1TcpFmjDuh7g==",
|
"integrity": "sha512-a8KaMYlY3+llvE9079nvASKpaaf8xpCMdOjbgn+eGhdOGOcY7QuFUkd/2odvnXDG8fK/jffE1LoNOlfYoBHC4w==",
|
||||||
|
"license": "Apache-2.0 AND MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@tensorflow/tfjs-core": "4.17.0"
|
"@tensorflow/tfjs-core": "4.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tensorflow/tfjs/node_modules/regenerator-runtime": {
|
"node_modules/@tensorflow/tfjs/node_modules/regenerator-runtime": {
|
||||||
@@ -3472,7 +3480,8 @@
|
|||||||
"node_modules/@types/long": {
|
"node_modules/@types/long": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
|
||||||
"integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="
|
"integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/minimist": {
|
"node_modules/@types/minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
@@ -3492,6 +3501,7 @@
|
|||||||
"version": "2.6.11",
|
"version": "2.6.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz",
|
||||||
"integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==",
|
"integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"form-data": "^4.0.0"
|
"form-data": "^4.0.0"
|
||||||
@@ -3506,7 +3516,8 @@
|
|||||||
"node_modules/@types/offscreencanvas": {
|
"node_modules/@types/offscreencanvas": {
|
||||||
"version": "2019.3.0",
|
"version": "2019.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz",
|
||||||
"integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q=="
|
"integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.17.1",
|
"version": "1.17.1",
|
||||||
@@ -3520,7 +3531,8 @@
|
|||||||
"node_modules/@types/seedrandom": {
|
"node_modules/@types/seedrandom": {
|
||||||
"version": "2.4.34",
|
"version": "2.4.34",
|
||||||
"resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.34.tgz",
|
"resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.34.tgz",
|
||||||
"integrity": "sha512-ytDiArvrn/3Xk6/vtylys5tlY6eo7Ane0hvcx++TKo6RxQXuVfW0AF/oeWqAj9dN29SyhtawuXstgmPlwNcv/A=="
|
"integrity": "sha512-ytDiArvrn/3Xk6/vtylys5tlY6eo7Ane0hvcx++TKo6RxQXuVfW0AF/oeWqAj9dN29SyhtawuXstgmPlwNcv/A==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/trusted-types": {
|
"node_modules/@types/trusted-types": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
@@ -3646,7 +3658,8 @@
|
|||||||
"node_modules/@webgpu/types": {
|
"node_modules/@webgpu/types": {
|
||||||
"version": "0.1.38",
|
"version": "0.1.38",
|
||||||
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.38.tgz",
|
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.38.tgz",
|
||||||
"integrity": "sha512-7LrhVKz2PRh+DD7+S+PVaFd5HxaWQvoMqBbsV9fNJO1pjUs1P8bM2vQVNfk+3URTqbuTI7gkXi0rfsN0IadoBA=="
|
"integrity": "sha512-7LrhVKz2PRh+DD7+S+PVaFd5HxaWQvoMqBbsV9fNJO1pjUs1P8bM2vQVNfk+3URTqbuTI7gkXi0rfsN0IadoBA==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.11.2",
|
"version": "8.11.2",
|
||||||
@@ -3814,7 +3827,8 @@
|
|||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/at-least-node": {
|
"node_modules/at-least-node": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -4412,6 +4426,7 @@
|
|||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"delayed-stream": "~1.0.0"
|
"delayed-stream": "~1.0.0"
|
||||||
},
|
},
|
||||||
@@ -4872,6 +4887,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
@@ -5357,6 +5373,7 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"asynckit": "^0.4.0",
|
"asynckit": "^0.4.0",
|
||||||
"combined-stream": "^1.0.8",
|
"combined-stream": "^1.0.8",
|
||||||
@@ -6577,7 +6594,8 @@
|
|||||||
"node_modules/long": {
|
"node_modules/long": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/lower-case": {
|
"node_modules/lower-case": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
@@ -6688,6 +6706,7 @@
|
|||||||
"version": "1.52.0",
|
"version": "1.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@@ -6696,6 +6715,7 @@
|
|||||||
"version": "2.1.35",
|
"version": "2.1.35",
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"mime-db": "1.52.0"
|
"mime-db": "1.52.0"
|
||||||
},
|
},
|
||||||
@@ -6823,6 +6843,7 @@
|
|||||||
"version": "2.6.13",
|
"version": "2.6.13",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz",
|
||||||
"integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
|
"integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"whatwg-url": "^5.0.0"
|
"whatwg-url": "^5.0.0"
|
||||||
},
|
},
|
||||||
@@ -6841,17 +6862,20 @@
|
|||||||
"node_modules/node-fetch/node_modules/tr46": {
|
"node_modules/node-fetch/node_modules/tr46": {
|
||||||
"version": "0.0.3",
|
"version": "0.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
"node_modules/node-fetch/node_modules/webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
|
||||||
|
"license": "BSD-2-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/node-fetch/node_modules/whatwg-url": {
|
"node_modules/node-fetch/node_modules/whatwg-url": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tr46": "~0.0.3",
|
"tr46": "~0.0.3",
|
||||||
"webidl-conversions": "^3.0.0"
|
"webidl-conversions": "^3.0.0"
|
||||||
@@ -8481,7 +8505,8 @@
|
|||||||
"node_modules/seedrandom": {
|
"node_modules/seedrandom": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
|
||||||
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
|
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.1",
|
||||||
@@ -11858,16 +11883,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs": {
|
"@tensorflow/tfjs": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs/-/tfjs-4.21.0.tgz",
|
||||||
"integrity": "sha512-yXRBhpM3frlNA/YaPp6HNk9EfIi8han5RYeQA3R8OCa0Od+AfoG1PUmlxV8fE2wCorlGVyHsgpiJ6M9YZPB56w==",
|
"integrity": "sha512-7D/+H150ptvt+POMbsME3WlIvLiuBR2rCC2Z0hOKKb/5Ygkj7xsp/K2HzOvUj0g0yjk+utkU45QEYhnhjnbHRA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@tensorflow/tfjs-backend-cpu": "4.17.0",
|
"@tensorflow/tfjs-backend-cpu": "4.21.0",
|
||||||
"@tensorflow/tfjs-backend-webgl": "4.17.0",
|
"@tensorflow/tfjs-backend-webgl": "4.21.0",
|
||||||
"@tensorflow/tfjs-converter": "4.17.0",
|
"@tensorflow/tfjs-converter": "4.21.0",
|
||||||
"@tensorflow/tfjs-core": "4.17.0",
|
"@tensorflow/tfjs-core": "4.21.0",
|
||||||
"@tensorflow/tfjs-data": "4.17.0",
|
"@tensorflow/tfjs-data": "4.21.0",
|
||||||
"@tensorflow/tfjs-layers": "4.17.0",
|
"@tensorflow/tfjs-layers": "4.21.0",
|
||||||
"argparse": "^1.0.10",
|
"argparse": "^1.0.10",
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"core-js": "3.29.1",
|
"core-js": "3.29.1",
|
||||||
@@ -11883,35 +11908,35 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-backend-cpu": {
|
"@tensorflow/tfjs-backend-cpu": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-cpu/-/tfjs-backend-cpu-4.21.0.tgz",
|
||||||
"integrity": "sha512-2VSCHnX9qhYTjw9HiVwTBSnRVlntKXeBlK7aSVsmZfHGwWE2faErTtO7bWmqNqw0U7gyznJbVAjlow/p+0RNGw==",
|
"integrity": "sha512-yS9Oisg4L48N7ML6677ilv1eP5Jt59S74skSU1cCsM4yBAtH4DAn9b89/JtqBISh6JadanfX26b4HCWQvMvqFg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/seedrandom": "^2.4.28",
|
"@types/seedrandom": "^2.4.28",
|
||||||
"seedrandom": "^3.0.5"
|
"seedrandom": "^3.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-backend-webgl": {
|
"@tensorflow/tfjs-backend-webgl": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-4.21.0.tgz",
|
||||||
"integrity": "sha512-CC5GsGECCd7eYAUaKq0XJ48FjEZdgXZWPxgUYx4djvfUx5fQPp35hCSP9w/k463jllBMbjl2tKRg8u7Ia/LYzg==",
|
"integrity": "sha512-7k6mb7dd0uF9jI51iunF3rhEXjvR/a613kjWZ0Rj3o1COFrneyku2C7cRMZERWPhbgXZ+dF+j9MdpGIpgtShIQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@tensorflow/tfjs-backend-cpu": "4.17.0",
|
"@tensorflow/tfjs-backend-cpu": "4.21.0",
|
||||||
"@types/offscreencanvas": "~2019.3.0",
|
"@types/offscreencanvas": "~2019.3.0",
|
||||||
"@types/seedrandom": "^2.4.28",
|
"@types/seedrandom": "^2.4.28",
|
||||||
"seedrandom": "^3.0.5"
|
"seedrandom": "^3.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-converter": {
|
"@tensorflow/tfjs-converter": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-4.21.0.tgz",
|
||||||
"integrity": "sha512-qFxIjPfomCuTrYxsFjtKbi3QfdmTTCWo+RvqD64oCMS0sjp7sUDNhJyKDoLx6LZhXlwXpHIVDJctLMRMwet0Zw==",
|
"integrity": "sha512-cUhU+F1lGx2qnKk/gRy8odBh0PZlFz0Dl71TG8LVnj0/g352DqiNrKXlKO/po9aWzP8x0KUGC3gNMSMJW+T0DA==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-core": {
|
"@tensorflow/tfjs-core": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-core/-/tfjs-core-4.21.0.tgz",
|
||||||
"integrity": "sha512-v9Q5430EnRpyhWNd9LVgXadciKvxLiq+sTrLKRowh26BHyAsams4tZIgX3lFKjB7b90p+FYifVMcqLTTHgjGpQ==",
|
"integrity": "sha512-ZbECwXps5wb9XXcGq4ZXvZDVjr5okc3I0+i/vU6bpQ+nVApyIrMiyEudP8f6vracVTvNmnlN62vUXoEsQb2F8g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/long": "^4.0.1",
|
"@types/long": "^4.0.1",
|
||||||
"@types/offscreencanvas": "~2019.7.0",
|
"@types/offscreencanvas": "~2019.7.0",
|
||||||
@@ -11930,9 +11955,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-data": {
|
"@tensorflow/tfjs-data": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-data/-/tfjs-data-4.21.0.tgz",
|
||||||
"integrity": "sha512-aPKrDFip+gXicWOFALeNT7KKQjRXFkHd/hNe/zs4mCFcIN00hy1PkZ6xkYsgrsdLDQMBSGeS4B4ZM0k5Cs88QA==",
|
"integrity": "sha512-LpJ/vyQMwYHkcVCqIRg7IVVw13VBY7rNAiuhmKP9S5NP/2ye4KA8BJ4XwDIDgjCVQM7glK9L8bMav++xCDf7xA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node-fetch": "^2.1.2",
|
"@types/node-fetch": "^2.1.2",
|
||||||
"node-fetch": "~2.6.1",
|
"node-fetch": "~2.6.1",
|
||||||
@@ -11940,9 +11965,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-layers": {
|
"@tensorflow/tfjs-layers": {
|
||||||
"version": "4.17.0",
|
"version": "4.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-4.21.0.tgz",
|
||||||
"integrity": "sha512-DEE0zRKvf3LJ0EcvG5XouJYOgFGWYAneZ0K1d23969z7LfSyqVmBdLC6BTwdLKuJk3ouUJIKXU1TcpFmjDuh7g==",
|
"integrity": "sha512-a8KaMYlY3+llvE9079nvASKpaaf8xpCMdOjbgn+eGhdOGOcY7QuFUkd/2odvnXDG8fK/jffE1LoNOlfYoBHC4w==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@types/estree": {
|
"@types/estree": {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
"last 5 Firefox versions"
|
"last 5 Firefox versions"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tensorflow/tfjs": "^4.17.0",
|
"@tensorflow/tfjs": "^4.21.0",
|
||||||
"dom7": "^4.0.6",
|
"dom7": "^4.0.6",
|
||||||
"framework7": "^8.3.0",
|
"framework7": "^8.3.0",
|
||||||
"framework7-icons": "^5.0.5",
|
"framework7-icons": "^5.0.5",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ regions:
|
|||||||
- limbs
|
- limbs
|
||||||
- head
|
- head
|
||||||
useExternal: none
|
useExternal: none
|
||||||
|
disableWorkers: false
|
||||||
external:
|
external:
|
||||||
- name: Mserver
|
- name: Mserver
|
||||||
address: "192.169.1.105"
|
address: "192.169.1.105"
|
||||||
|
|||||||
@@ -74,12 +74,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created () {
|
async created () {
|
||||||
|
/*
|
||||||
|
document.addEventListener('wheel', event => {
|
||||||
|
event.preventDefault()
|
||||||
|
}, {passive: false})
|
||||||
|
document.addEventListener('touchmove', event => {
|
||||||
|
event.preventDefault()
|
||||||
|
}, {passive: false})
|
||||||
|
*/
|
||||||
if (!window.cordova) {
|
if (!window.cordova) {
|
||||||
const confText = await fetch('./conf/conf.yaml')
|
const confText = await fetch('./conf/conf.yaml')
|
||||||
.then((mod) => { return mod.text() })
|
.then((mod) => { return mod.text() })
|
||||||
this.siteConf = YAML.parse(confText)
|
this.siteConf = YAML.parse(confText)
|
||||||
}
|
}
|
||||||
if (window.safari !== undefined) {store().safariDetected()}
|
|
||||||
const loadSiteSettings = localStorage.getItem('siteSettings')
|
const loadSiteSettings = localStorage.getItem('siteSettings')
|
||||||
if (loadSiteSettings) {
|
if (loadSiteSettings) {
|
||||||
let loadedSettings = JSON.parse(loadSiteSettings)
|
let loadedSettings = JSON.parse(loadSiteSettings)
|
||||||
@@ -99,6 +106,9 @@
|
|||||||
store().set('siteDemo',this.siteConf?.demo)
|
store().set('siteDemo',this.siteConf?.demo)
|
||||||
store().set('infoUrl',this.siteConf?.infoUrl)
|
store().set('infoUrl',this.siteConf?.infoUrl)
|
||||||
const loadServerSettings = localStorage.getItem('serverSettings')
|
const loadServerSettings = localStorage.getItem('serverSettings')
|
||||||
|
if (this.siteConf.disableWorkers) {
|
||||||
|
store().disableWorkers()
|
||||||
|
}
|
||||||
if (this.siteConf?.useExternal) {
|
if (this.siteConf?.useExternal) {
|
||||||
if (!['none','list','optional','required'].includes(this.siteConf.useExternal)) {
|
if (!['none','list','optional','required'].includes(this.siteConf.useExternal)) {
|
||||||
console.warn(`'${this.siteConf.useExternal}' is not a valid value for useExternal configuration: using 'optional'`)
|
console.warn(`'${this.siteConf.useExternal}' is not a valid value for useExternal configuration: using 'optional'`)
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
<path v-else-if="icon == 'head'" d="M194-80v-395h80v315h280v-193l105-105q29-29 45-65t16-77q0-40-16.5-76T659-741l-25-26-127 127H347l-43 43-57-56 67-67h160l160-160 82 82q40 40 62 90.5T800-600q0 57-22 107.5T716-402l-82 82v240H194Zm197-187L183-475q-11-11-17-26t-6-31q0-16 6-30.5t17-25.5l84-85 124 123q28 28 43.5 64.5T450-409q0 40-15 76.5T391-267Z"/>
|
<path v-else-if="icon == 'head'" d="M194-80v-395h80v315h280v-193l105-105q29-29 45-65t16-77q0-40-16.5-76T659-741l-25-26-127 127H347l-43 43-57-56 67-67h160l160-160 82 82q40 40 62 90.5T800-600q0 57-22 107.5T716-402l-82 82v240H194Zm197-187L183-475q-11-11-17-26t-6-31q0-16 6-30.5t17-25.5l84-85 124 123q28 28 43.5 64.5T450-409q0 40-15 76.5T391-267Z"/>
|
||||||
<path v-else-if="icon == 'photo_sample'" d="M240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h480q33 0 56.5 23.5T800-800v640q0 33-23.5 56.5T720-80H240Zm0-80h480v-640h-80v280l-100-60-100 60v-280H240v640Zm40-80h400L545-420 440-280l-65-87-95 127Zm-40 80v-640 640Zm200-360 100-60 100 60-100-60-100 60Z"/>
|
<path v-else-if="icon == 'photo_sample'" d="M240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h480q33 0 56.5 23.5T800-800v640q0 33-23.5 56.5T720-80H240Zm0-80h480v-640h-80v280l-100-60-100 60v-280H240v640Zm40-80h400L545-420 440-280l-65-87-95 127Zm-40 80v-640 640Zm200-360 100-60 100 60-100-60-100 60Z"/>
|
||||||
<path v-else-if="icon == 'reset_slide'" d="M520-330v-60h160v60H520Zm60 210v-50h-60v-60h60v-50h60v160h-60Zm100-50v-60h160v60H680Zm40-110v-160h60v50h60v60h-60v50h-60Zm111-280h-83q-26-88-99-144t-169-56q-117 0-198.5 81.5T200-480q0 72 32.5 132t87.5 98v-110h80v240H160v-80h94q-62-50-98-122.5T120-480q0-75 28.5-140.5t77-114q48.5-48.5 114-77T480-840q129 0 226.5 79.5T831-560Z"/>
|
<path v-else-if="icon == 'reset_slide'" d="M520-330v-60h160v60H520Zm60 210v-50h-60v-60h60v-50h60v160h-60Zm100-50v-60h160v60H680Zm40-110v-160h60v50h60v60h-60v50h-60Zm111-280h-83q-26-88-99-144t-169-56q-117 0-198.5 81.5T200-480q0 72 32.5 132t87.5 98v-110h80v240H160v-80h94q-62-50-98-122.5T120-480q0-75 28.5-140.5t77-114q48.5-48.5 114-77T480-840q129 0 226.5 79.5T831-560Z"/>
|
||||||
|
<path v-else-if="icon == 'zoom_to'" d="M440-40v-167l-44 43-56-56 140-140 140 140-56 56-44-43v167h-80ZM220-340l-56-56 43-44H40v-80h167l-43-44 56-56 140 140-140 140Zm520 0L600-480l140-140 56 56-43 44h167v80H753l43 44-56 56Zm-260-80q-25 0-42.5-17.5T420-480q0-25 17.5-42.5T480-540q25 0 42.5 17.5T540-480q0 25-17.5 42.5T480-420Zm0-180L340-740l56-56 44 43v-167h80v167l44-43 56 56-140 140Z"/>
|
||||||
|
<path v-else-if="icon == 'reset_zoom'" d="M480-320v-100q0-25 17.5-42.5T540-480h100v60H540v100h-60Zm60 240q-25 0-42.5-17.5T480-140v-100h60v100h100v60H540Zm280-240v-100H720v-60h100q25 0 42.5 17.5T880-420v100h-60ZM720-80v-60h100v-100h60v100q0 25-17.5 42.5T820-80H720Zm111-480h-83q-26-88-99-144t-169-56q-117 0-198.5 81.5T200-480q0 72 32.5 132t87.5 98v-110h80v240H160v-80h94q-62-50-98-122.5T120-480q0-75 28.5-140.5t77-114q48.5-48.5 114-77T480-840q129 0 226.5 79.5T831-560Z"/>
|
||||||
|
<path v-else-if="icon == 'clipboard'" d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h167q11-35 43-57.5t70-22.5q40 0 71.5 22.5T594-840h166q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560h-80v120H280v-120h-80v560Zm280-560q17 0 28.5-11.5T520-800q0-17-11.5-28.5T480-840q-17 0-28.5 11.5T440-800q0 17 11.5 28.5T480-760Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -44,7 +47,10 @@
|
|||||||
'limbs',
|
'limbs',
|
||||||
'head',
|
'head',
|
||||||
'photo_sample',
|
'photo_sample',
|
||||||
'reset_slide'
|
'reset_slide',
|
||||||
|
'zoom_to',
|
||||||
|
'reset_zoom',
|
||||||
|
'clipboard'
|
||||||
]
|
]
|
||||||
return iconList.includes(value)
|
return iconList.includes(value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,8 +150,7 @@
|
|||||||
.structure-info {
|
.structure-info {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
color: rgb(15, 32, 108);
|
color: #0f206c;
|
||||||
background: yellow;
|
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<meta name="msapplication-tap-highlight" content="no">
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
<title>ALVINN</title>
|
<title>ALVINN</title>
|
||||||
<% if (TARGET === 'web') { %>
|
<% if (TARGET === 'web') { %>
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
<link rel="apple-touch-icon" href="icons/apple-touch-icon.png">
|
<link rel="apple-touch-icon" href="icons/apple-touch-icon.png">
|
||||||
<link rel="icon" href="icons/favicon.png">
|
<link rel="icon" href="icons/favicon.png">
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ const state = reactive({
|
|||||||
enabledRegions: ['thorax','abdomen','limbs','head'],
|
enabledRegions: ['thorax','abdomen','limbs','head'],
|
||||||
regionIconSet: Math.floor(Math.random() * 3) + 1,
|
regionIconSet: Math.floor(Math.random() * 3) + 1,
|
||||||
version: '0.5.0-alpha',
|
version: '0.5.0-alpha',
|
||||||
|
build: '####',
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
useExternal: 'optional',
|
useExternal: 'optional',
|
||||||
|
workersEnabled: 'true',
|
||||||
siteDemo: false,
|
siteDemo: false,
|
||||||
externalServerList: [],
|
externalServerList: [],
|
||||||
infoUrl: false,
|
infoUrl: false
|
||||||
safariBrowser: false
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const set = (config, confObj) => {
|
const set = (config, confObj) => {
|
||||||
@@ -22,8 +23,8 @@ const agree = () => {
|
|||||||
state.disclaimerAgreement = true
|
state.disclaimerAgreement = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const safariDetected = () => {
|
const disableWorkers = () => {
|
||||||
state.safariBrowser = true
|
state.workersEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const getServerList = () => {
|
const getServerList = () => {
|
||||||
@@ -51,14 +52,15 @@ export default () => ({
|
|||||||
isFullscreen: computed(() => state.fullscreen),
|
isFullscreen: computed(() => state.fullscreen),
|
||||||
demoMode: computed(() => state.siteDemo),
|
demoMode: computed(() => state.siteDemo),
|
||||||
externalType: computed(() => state.useExternal),
|
externalType: computed(() => state.useExternal),
|
||||||
|
useWorkers: computed(() => state.workersEnabled),
|
||||||
getRegions: computed(() => state.enabledRegions),
|
getRegions: computed(() => state.enabledRegions),
|
||||||
getVersion: computed(() => state.version),
|
getVersion: computed(() => state.version),
|
||||||
|
getBuild: computed(() => state.build),
|
||||||
getIconSet: computed(() => state.regionIconSet),
|
getIconSet: computed(() => state.regionIconSet),
|
||||||
getInfoUrl: computed(() => state.infoUrl),
|
getInfoUrl: computed(() => state.infoUrl),
|
||||||
isSafari: computed(() => state.safariBrowser),
|
|
||||||
set,
|
set,
|
||||||
agree,
|
agree,
|
||||||
safariDetected,
|
disableWorkers,
|
||||||
getServerList,
|
getServerList,
|
||||||
toggleFullscreen
|
toggleFullscreen
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<f7-page name="detect" :id="detectorName + '-detect-page'">
|
<f7-page name="detect" :id="detectorName + '-detect-page'" @wheel="(e = $event) => e.preventDefault()" @touchmove="(e = $event) => e.preventDefault()">
|
||||||
<!-- Top Navbar -->
|
<!-- Top Navbar -->
|
||||||
<f7-navbar :sliding="false" :back-link="true" back-link-url="/" back-link-force>
|
<f7-navbar :sliding="false" :back-link="true" back-link-url="/" back-link-force>
|
||||||
<f7-nav-title sliding>{{ regions[activeRegion] }}</f7-nav-title>
|
<f7-nav-title sliding>{{ regions[activeRegion] }}</f7-nav-title>
|
||||||
@@ -9,16 +9,28 @@
|
|||||||
</f7-nav-right>
|
</f7-nav-right>
|
||||||
</f7-navbar>
|
</f7-navbar>
|
||||||
<f7-block class="detect-grid">
|
<f7-block class="detect-grid">
|
||||||
|
<!--<div style="position: absolute;">{{ debugInfo ? JSON.stringify(debugInfo) : "No Info Available" }}</div>-->
|
||||||
<div class="image-container" ref="image_container">
|
<div class="image-container" ref="image_container">
|
||||||
<SvgIcon v-if="!imageView.src && !videoAvailable" :icon="f7route.params.region" fill-color="var(--avn-theme-color)"/>
|
<SvgIcon v-if="!imageView.src && !videoAvailable" :icon="f7route.params.region" fill-color="var(--avn-theme-color)"/>
|
||||||
<div class="vid-container" :style="`display: ${videoAvailable ? 'block' : 'none'}; position: absolute; width: 100%; height: 100%;`">
|
<div class="vid-container" :style="`display: ${videoAvailable ? 'block' : 'none'}; position: absolute; width: 100%; height: 100%;`">
|
||||||
<video id="vid-view" ref="vid_viewer" :srcObject="cameraStream" :autoPlay="true" style="width: 100%; height: 100%"></video>
|
<video id="vid-view" ref="vid_viewer" :srcObject="cameraStream" :autoPlay="true" style="width: 100%; height: 100%"></video>
|
||||||
<f7-button @click="captureVidFrame()" style="position: absolute; bottom: 32px; left: 50%; transform: translateX(-50%); z-index: 3;" fill large>Capture</f7-button>
|
<f7-button @click="captureVidFrame()" style="position: absolute; bottom: 32px; left: 50%; transform: translateX(-50%); z-index: 3;" fill large>Capture</f7-button>
|
||||||
</div>
|
</div>
|
||||||
<canvas id="im-draw" ref="image_cvs" @click="structureClick" :style="`display: ${(imageLoaded || videoAvailable) ? 'block' : 'none'}; flex: 1 1 0%; max-width: 100%; max-height: 100%; min-width: 0; min-height: 0; background-size: contain; background-position: center; background-repeat: no-repeat; z-index: 2;`" />
|
<canvas
|
||||||
|
id="im-draw"
|
||||||
|
ref="image_cvs"
|
||||||
|
@wheel="spinWheel($event)"
|
||||||
|
@mousedown.middle="startMove($event)"
|
||||||
|
@mousemove="makeMove($event)"
|
||||||
|
@mouseup.middle="endMove($event)"
|
||||||
|
@touchstart="startTouch($event)"
|
||||||
|
@touchend="endTouch($event)"
|
||||||
|
@touchmove="moveTouch($event)"
|
||||||
|
@click="structureClick"
|
||||||
|
:style="`display: ${(imageLoaded || videoAvailable) ? 'block' : 'none'}; flex: 1 1 0%; max-width: 100%; max-height: 100%; min-width: 0; min-height: 0; background-size: contain; background-position: center; background-repeat: no-repeat; z-index: 2;`"
|
||||||
|
></canvas>
|
||||||
<f7-link v-if="getInfoUrl && (selectedChip > -1)"
|
<f7-link v-if="getInfoUrl && (selectedChip > -1)"
|
||||||
:style="`left: ${infoLinkPos.x}px; top: ${infoLinkPos.y}px; transform: translate(calc(-50% - ${infoLinkPos.adj}px),calc(-50% - ${infoLinkPos.adj}px));`"
|
:style="`left: ${infoLinkPos.x}px; top: ${infoLinkPos.y}px; transform: translate(-50%,-50%); background: hsla(${showResults[selectedChip].confidence / 100 * 120}deg, 100%, 50%, .5)`" class="structure-info"
|
||||||
class="structure-info"
|
|
||||||
:icon-only="true"
|
:icon-only="true"
|
||||||
icon-f7="info"
|
icon-f7="info"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -61,16 +73,19 @@
|
|||||||
</f7-button>
|
</f7-button>
|
||||||
</div>
|
</div>
|
||||||
<f7-segmented class="image-menu" raised>
|
<f7-segmented class="image-menu" raised>
|
||||||
<f7-button popover-open="#region-popover">
|
|
||||||
<RegionIcon :region="activeRegion" :iconSet="getIconSet" />
|
|
||||||
</f7-button>
|
|
||||||
<f7-button v-if="!videoAvailable" :class="(!modelLoading) ? '' : 'disabled'" popover-open="#capture-popover">
|
<f7-button v-if="!videoAvailable" :class="(!modelLoading) ? '' : 'disabled'" popover-open="#capture-popover">
|
||||||
<SvgIcon icon="camera_add"/>
|
<SvgIcon icon="camera_add"/>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button v-if="videoAvailable" @click="closeCamera()">
|
<f7-button v-if="videoAvailable" @click="closeCamera()">
|
||||||
<SvgIcon icon="no_photography"/>
|
<SvgIcon icon="no_photography"/>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button @click="() => showDetectSettings = !showDetectSettings" :class="(imageLoaded) ? '' : 'disabled'">
|
<f7-button v-if="!structureZoomed && selectedChip >= 0" style="height: auto; width: auto;" popover-close="#image-popover" @click="zoomToSelected()">
|
||||||
|
<SvgIcon icon="zoom_to" />
|
||||||
|
</f7-button>
|
||||||
|
<f7-button v-else :class="(canvasZoom != 1) ? '' : 'disabled'" style="height: auto; width: auto;" popover-close="#image-popover" @click="resetZoom()">
|
||||||
|
<SvgIcon icon="reset_zoom" />
|
||||||
|
</f7-button>
|
||||||
|
<f7-button @click="toggleSettings()" :class="(imageLoaded) ? '' : 'disabled'">
|
||||||
<SvgIcon icon="visibility"/>
|
<SvgIcon icon="visibility"/>
|
||||||
<f7-badge v-if="numResults && (showResults.length != numResults)" color="red" style="position: absolute; right: 15%; top: 15%;">{{ showResults.length - numResults }}</f7-badge>
|
<f7-badge v-if="numResults && (showResults.length != numResults)" color="red" style="position: absolute; right: 15%; top: 15%;">{{ showResults.length - numResults }}</f7-badge>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
@@ -93,23 +108,6 @@
|
|||||||
</f7-page>
|
</f7-page>
|
||||||
</f7-panel>
|
</f7-panel>
|
||||||
|
|
||||||
<f7-popover id="region-popover" class="popover-button-menu">
|
|
||||||
<f7-segmented raised class="segment-button-menu">
|
|
||||||
<f7-button :class="(getRegions.includes('thorax')) ? '' : ' disabled'" style="height: auto; width: auto;" href="/detect/thorax/" popover-close="#region-popover">
|
|
||||||
<RegionIcon :region="0" :iconSet="getIconSet" />
|
|
||||||
</f7-button>
|
|
||||||
<f7-button :class="(getRegions.includes('abdomen')) ? '' : ' disabled'" style="height: auto; width: auto;" href="/detect/abdomen/" popover-close="#region-popover">
|
|
||||||
<RegionIcon :region="1" :iconSet="getIconSet" />
|
|
||||||
</f7-button>
|
|
||||||
<f7-button :class="(getRegions.includes('limbs')) ? '' : ' disabled'" style="height: auto; width: auto;" href="/detect/limbs/" popover-close="#region-popover">
|
|
||||||
<RegionIcon :region="2" :iconSet="getIconSet" />
|
|
||||||
</f7-button>
|
|
||||||
<f7-button :class="(getRegions.includes('head')) ? '' : ' disabled'" style="height: auto; width: auto;" href="/detect/head/" popover-close="#region-popover">
|
|
||||||
<RegionIcon :region="3" :iconSet="getIconSet" />
|
|
||||||
</f7-button>
|
|
||||||
</f7-segmented>
|
|
||||||
</f7-popover>
|
|
||||||
|
|
||||||
<f7-popover id="capture-popover" class="popover-button-menu">
|
<f7-popover id="capture-popover" class="popover-button-menu">
|
||||||
<f7-segmented raised class="segment-button-menu">
|
<f7-segmented raised class="segment-button-menu">
|
||||||
<f7-button style="height: auto; width: auto;" popover-close="#capture-popover" @click="selectImage('camera')">
|
<f7-button style="height: auto; width: auto;" popover-close="#capture-popover" @click="selectImage('camera')">
|
||||||
@@ -118,6 +116,9 @@
|
|||||||
<f7-button style="height: auto; width: auto;" popover-close="#capture-popover" @click="selectImage('file')">
|
<f7-button style="height: auto; width: auto;" popover-close="#capture-popover" @click="selectImage('file')">
|
||||||
<SvgIcon icon="photo_library" />
|
<SvgIcon icon="photo_library" />
|
||||||
</f7-button>
|
</f7-button>
|
||||||
|
<f7-button v-if="secureProtocol" style="height: auto; width: auto;" popover-close="#capture-popover" @click="selectImage('clipboard')">
|
||||||
|
<SvgIcon icon="clipboard" />
|
||||||
|
</f7-button>
|
||||||
<f7-button v-if="demoEnabled" style="height: auto; width: auto;" popover-close="#capture-popover" @click="selectImage('sample')">
|
<f7-button v-if="demoEnabled" style="height: auto; width: auto;" popover-close="#capture-popover" @click="selectImage('sample')">
|
||||||
<SvgIcon icon="photo_sample"/>
|
<SvgIcon icon="photo_sample"/>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
@@ -139,11 +140,12 @@
|
|||||||
import submitMixin from './submit-mixin'
|
import submitMixin from './submit-mixin'
|
||||||
import detectionMixin from './detection-mixin'
|
import detectionMixin from './detection-mixin'
|
||||||
import cameraMixin from './camera-mixin'
|
import cameraMixin from './camera-mixin'
|
||||||
|
import touchMixin from './touch-mixin'
|
||||||
|
|
||||||
import detectionWorker from '@/assets/detect-worker.js?worker&inline'
|
import detectionWorker from '@/assets/detect-worker.js?worker&inline'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [submitMixin, detectionMixin, cameraMixin],
|
mixins: [submitMixin, detectionMixin, cameraMixin, touchMixin],
|
||||||
props: {
|
props: {
|
||||||
f7route: Object,
|
f7route: Object,
|
||||||
},
|
},
|
||||||
@@ -160,6 +162,7 @@
|
|||||||
classesList: [],
|
classesList: [],
|
||||||
imageLoaded: false,
|
imageLoaded: false,
|
||||||
imageView: new Image(),
|
imageView: new Image(),
|
||||||
|
imCvsLocation: {},
|
||||||
imageLoadMode: "environment",
|
imageLoadMode: "environment",
|
||||||
detecting: false,
|
detecting: false,
|
||||||
detectPanel: false,
|
detectPanel: false,
|
||||||
@@ -170,6 +173,7 @@
|
|||||||
serverSettings: {},
|
serverSettings: {},
|
||||||
otherSettings: {},
|
otherSettings: {},
|
||||||
isCordova: !!window.cordova,
|
isCordova: !!window.cordova,
|
||||||
|
secureProtocol: location.protocol == 'https:',
|
||||||
uploadUid: null,
|
uploadUid: null,
|
||||||
uploadDirty: false,
|
uploadDirty: false,
|
||||||
modelLocation: '',
|
modelLocation: '',
|
||||||
@@ -181,7 +185,12 @@
|
|||||||
cameraStream: null,
|
cameraStream: null,
|
||||||
infoLinkPos: {},
|
infoLinkPos: {},
|
||||||
detectWorker: null,
|
detectWorker: null,
|
||||||
vidWorker: null
|
vidWorker: null,
|
||||||
|
canvasMoving: false,
|
||||||
|
canvasOffset: {x: 0, y: 0},
|
||||||
|
canvasZoom: 1,
|
||||||
|
structureZoomed: false,
|
||||||
|
debugInfo: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
@@ -205,9 +214,12 @@
|
|||||||
this.activeRegion = 3
|
this.activeRegion = 3
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.modelLocation = URL.parse(`../models/${this.detectorName}${this.otherSettings.mini ? '-mini' : ''}/model.json`,import.meta.url).href
|
let modelJ = `../models/${this.detectorName}${this.otherSettings.mini ? '-mini' : ''}/model.json`
|
||||||
this.miniLocation = URL.parse(`../models/${this.detectorName}-mini/model.json`,import.meta.url).href
|
let miniJ = `../models/${this.detectorName}-mini/model.json`
|
||||||
fetch(URL.parse(`../models/${this.detectorName}/classes.json`,import.meta.url).href)
|
this.modelLocation = new URL(modelJ,import.meta.url).href
|
||||||
|
this.miniLocation = new URL(miniJ,import.meta.url).href
|
||||||
|
let classesJ = `../models/${this.detectorName}/classes.json`
|
||||||
|
fetch(new URL(classesJ,import.meta.url).href)
|
||||||
.then((mod) => { return mod.json() })
|
.then((mod) => { return mod.json() })
|
||||||
.then((classes) => {
|
.then((classes) => {
|
||||||
this.classesList = classes
|
this.classesList = classes
|
||||||
@@ -217,6 +229,20 @@
|
|||||||
if (loadServerSettings) this.serverSettings = JSON.parse(loadServerSettings)
|
if (loadServerSettings) this.serverSettings = JSON.parse(loadServerSettings)
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
if (this.serverSettings && this.serverSettings.use) {
|
||||||
|
this.getRemoteLabels()
|
||||||
|
this.modelLoading = false
|
||||||
|
} else {
|
||||||
|
this.modelLoading = true
|
||||||
|
if (!this.useWorkers) {
|
||||||
|
this.loadModel(this.modelLocation, true).then(() => {
|
||||||
|
this.modelLoading = false
|
||||||
|
}).catch((e) => {
|
||||||
|
console.log(e.message)
|
||||||
|
f7.dialog.alert(`ALVINN AI model error: ${e.message}`)
|
||||||
|
this.modelLoading = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
this.detectWorker = new detectionWorker()
|
this.detectWorker = new detectionWorker()
|
||||||
this.detectWorker.onmessage = (eMount) => {
|
this.detectWorker.onmessage = (eMount) => {
|
||||||
self = this
|
self = this
|
||||||
@@ -234,21 +260,6 @@
|
|||||||
f7.dialog.alert(`ALVINN AI nano model error: ${eMount.data.message}`)
|
f7.dialog.alert(`ALVINN AI nano model error: ${eMount.data.message}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.serverSettings && this.serverSettings.use) {
|
|
||||||
this.getRemoteLabels()
|
|
||||||
this.modelLoading = false
|
|
||||||
} else {
|
|
||||||
this.modelLoading = true
|
|
||||||
if (this.isSafari) {
|
|
||||||
this.loadModel(this.modelLocation, true).then(() => {
|
|
||||||
this.modelLoading = false
|
|
||||||
}).catch((e) => {
|
|
||||||
console.log(e.message)
|
|
||||||
f7.dialog.alert(`ALVINN AI model error: ${e.message}`)
|
|
||||||
this.modelLoading = false
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.detectWorker.postMessage({call: 'loadModel', weights: this.modelLocation, preload: true})
|
this.detectWorker.postMessage({call: 'loadModel', weights: this.modelLocation, preload: true})
|
||||||
this.vidWorker.postMessage({call: 'loadModel', weights: this.miniLocation, preload: true})
|
this.vidWorker.postMessage({call: 'loadModel', weights: this.miniLocation, preload: true})
|
||||||
}
|
}
|
||||||
@@ -305,7 +316,7 @@
|
|||||||
if (!this.getInfoUrl) return ''
|
if (!this.getInfoUrl) return ''
|
||||||
let structure = this.showResults.find( r => r.resultIndex == this.selectedChip)
|
let structure = this.showResults.find( r => r.resultIndex == this.selectedChip)
|
||||||
return structure ? this.getInfoUrl + structure.label.replaceAll(' ','_') : ''
|
return structure ? this.getInfoUrl + structure.label.replaceAll(' ','_') : ''
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
chipGradient (confVal) {
|
chipGradient (confVal) {
|
||||||
@@ -313,6 +324,7 @@
|
|||||||
return `--chip-media-gradient: conic-gradient(from ${270 - (confFactor * 360 / 2)}deg, hsl(${confFactor * 120}deg, 100%, 50%) ${confFactor}turn, hsl(${confFactor * 120}deg, 50%, 66%) ${confFactor}turn)`
|
return `--chip-media-gradient: conic-gradient(from ${270 - (confFactor * 360 / 2)}deg, hsl(${confFactor * 120}deg, 100%, 50%) ${confFactor}turn, hsl(${confFactor * 120}deg, 50%, 66%) ${confFactor}turn)`
|
||||||
},
|
},
|
||||||
async setData () {
|
async setData () {
|
||||||
|
if (this.detectWorker) {
|
||||||
this.detectWorker.onmessage = (eDetect) => {
|
this.detectWorker.onmessage = (eDetect) => {
|
||||||
self = this
|
self = this
|
||||||
if (eDetect.data.error) {
|
if (eDetect.data.error) {
|
||||||
@@ -331,12 +343,16 @@
|
|||||||
self.reloadModel = false
|
self.reloadModel = false
|
||||||
loadSuccess()
|
loadSuccess()
|
||||||
}
|
}
|
||||||
|
f7.utils.nextFrame(() => {
|
||||||
|
this.selectChip("redraw")
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let loadSuccess = null
|
let loadSuccess = null
|
||||||
let loadFailure = null
|
let loadFailure = null
|
||||||
let modelReloading = null
|
let modelReloading = null
|
||||||
if (this.isSafari && this.reloadModel) {
|
if (!this.useWorkers && this.reloadModel) {
|
||||||
await this.loadModel(this.modelLocation)
|
await this.loadModel(this.modelLocation)
|
||||||
this.reloadModel = false
|
this.reloadModel = false
|
||||||
} else {
|
} else {
|
||||||
@@ -353,12 +369,14 @@
|
|||||||
|
|
||||||
if (this.serverSettings && this.serverSettings.use) {
|
if (this.serverSettings && this.serverSettings.use) {
|
||||||
this.remoteDetect()
|
this.remoteDetect()
|
||||||
} else if (!this.isSafari) {
|
} else if (this.useWorkers) {
|
||||||
Promise.all([modelReloading,createImageBitmap(this.imageView)]).then(res => {
|
Promise.all([modelReloading,createImageBitmap(this.imageView)]).then(res => {
|
||||||
this.detectWorker.postMessage({call: 'localDetect', image: res[1]}, [res[1]])
|
this.detectWorker.postMessage({call: 'localDetect', image: res[1]}, [res[1]])
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.localDetect(this.imageView).then(dets => {
|
createImageBitmap(this.imageView).then(res => {
|
||||||
|
return this.localDetect(res)
|
||||||
|
}).then(dets => {
|
||||||
this.detecting = false
|
this.detecting = false
|
||||||
this.resultData = dets
|
this.resultData = dets
|
||||||
this.uploadDirty = true
|
this.uploadDirty = true
|
||||||
@@ -369,6 +387,9 @@
|
|||||||
f7.dialog.alert(`ALVINN structure finding error: ${e.message}`)
|
f7.dialog.alert(`ALVINN structure finding error: ${e.message}`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
f7.utils.nextFrame(() => {
|
||||||
|
this.selectChip("redraw")
|
||||||
|
})
|
||||||
},
|
},
|
||||||
selectAll (ev) {
|
selectAll (ev) {
|
||||||
if (ev.target.checked) {
|
if (ev.target.checked) {
|
||||||
@@ -395,7 +416,7 @@
|
|||||||
var vidElement = this.$refs.vid_viewer
|
var vidElement = this.$refs.vid_viewer
|
||||||
vidElement.width = trackDetails.width
|
vidElement.width = trackDetails.width
|
||||||
vidElement.height = trackDetails.height
|
vidElement.height = trackDetails.height
|
||||||
if (this.isSafari) {
|
if (!this.useWorkers) {
|
||||||
this.videoFrameDetect(vidElement)
|
this.videoFrameDetect(vidElement)
|
||||||
} else {
|
} else {
|
||||||
this.videoFrameDetectWorker(vidElement)
|
this.videoFrameDetectWorker(vidElement)
|
||||||
@@ -416,23 +437,46 @@
|
|||||||
}).open()
|
}).open()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (mode == 'clipboard') {
|
||||||
|
navigator.clipboard.read().then(clip => {
|
||||||
|
if (!clip[0].types.includes("image/png")) {
|
||||||
|
throw new Error("Clipboard does not contain valid image data.");
|
||||||
|
}
|
||||||
|
return clip[0].getType("image/png");
|
||||||
|
}).then(blob => {
|
||||||
|
let clipImage = URL.createObjectURL(blob);
|
||||||
|
console.log(clipImage)
|
||||||
|
this.getImage(clipImage)
|
||||||
|
}).catch(e => {
|
||||||
|
console.log(e)
|
||||||
|
f7.dialog.alert(`Error pasting image: ${e.message}`)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
this.$refs.image_chooser.click()
|
this.$refs.image_chooser.click()
|
||||||
},
|
},
|
||||||
onFail (message) {
|
onFail (message) {
|
||||||
alert(`Camera fail: ${message}`)
|
alert(`Camera fail: ${message}`)
|
||||||
},
|
},
|
||||||
selectChip ( iChip ) {
|
selectChip ( iChip ) {
|
||||||
const [imCanvas, imageCtx] = this.resetView()
|
|
||||||
|
|
||||||
if (this.selectedChip == iChip) {
|
if (this.selectedChip == iChip) {
|
||||||
this.selectedChip = -1
|
this.selectedChip = -1
|
||||||
|
this.resetView()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iChip == 'redraw') {
|
if (iChip == 'redraw') {
|
||||||
if (this.selectedChip == -1) return
|
if (this.selectedChip == -1) {
|
||||||
|
this.resetView()
|
||||||
|
return
|
||||||
|
}
|
||||||
iChip = this.selectedChip
|
iChip = this.selectedChip
|
||||||
}
|
}
|
||||||
|
const [imCanvas, imageCtx] = this.resetView(true)
|
||||||
|
let structLeft = this.imageView.width * this.resultData.detections[iChip].left
|
||||||
|
let structTop = this.imageView.height * this.resultData.detections[iChip].top
|
||||||
|
let structWidth = this.imageView.width * (this.resultData.detections[iChip].right - this.resultData.detections[iChip].left)
|
||||||
|
let structHeight = this.imageView.height * (this.resultData.detections[iChip].bottom - this.resultData.detections[iChip].top)
|
||||||
|
|
||||||
const boxCoords = this.box2cvs(this.resultData.detections[iChip])[0]
|
const boxCoords = this.box2cvs(this.resultData.detections[iChip])[0]
|
||||||
|
|
||||||
@@ -440,12 +484,24 @@
|
|||||||
let boxTop = boxCoords.cvsTop
|
let boxTop = boxCoords.cvsTop
|
||||||
let boxWidth = boxCoords.cvsRight - boxCoords.cvsLeft
|
let boxWidth = boxCoords.cvsRight - boxCoords.cvsLeft
|
||||||
let boxHeight = boxCoords.cvsBottom - boxCoords.cvsTop
|
let boxHeight = boxCoords.cvsBottom - boxCoords.cvsTop
|
||||||
this.infoLinkPos.x = boxCoords.cvsLeft
|
this.infoLinkPos.x = Math.min(Math.max(boxCoords.cvsLeft * this.canvasZoom + this.canvasOffset.x, 0),imCanvas.width)
|
||||||
this.infoLinkPos.y = boxCoords.cvsTop
|
this.infoLinkPos.y = Math.min(Math.max(boxCoords.cvsTop * this.canvasZoom + this.canvasOffset.y, 0), imCanvas.height)
|
||||||
let boxMin = Math.min(boxHeight, boxWidth)
|
|
||||||
this.infoLinkPos.adj = (boxMin >= 50) ? 0 : Math.min(10, 50 - boxMin)
|
|
||||||
|
|
||||||
imageCtx.strokeRect(boxLeft, boxTop, boxWidth, boxHeight)
|
let imageScale = Math.max(this.imageView.width / imCanvas.width, this.imageView.height / imCanvas.height)
|
||||||
|
imageCtx.drawImage(this.imageView, structLeft, structTop, structWidth, structHeight, boxLeft, boxTop, boxWidth, boxHeight)
|
||||||
|
imageCtx.save()
|
||||||
|
imageCtx.arc(boxLeft, boxTop, 14 / this.canvasZoom, 0, 2 * Math.PI)
|
||||||
|
imageCtx.closePath()
|
||||||
|
imageCtx.clip()
|
||||||
|
imageCtx.drawImage(this.imageView,
|
||||||
|
structLeft - (14 / this.canvasZoom * imageScale),
|
||||||
|
structTop - (14 / this.canvasZoom * imageScale),
|
||||||
|
(28 / this.canvasZoom * imageScale),
|
||||||
|
(28 / this.canvasZoom * imageScale),
|
||||||
|
boxLeft - (14 / this.canvasZoom),
|
||||||
|
boxTop - (14 / this.canvasZoom),
|
||||||
|
(28 / this.canvasZoom), (28 / this.canvasZoom))
|
||||||
|
imageCtx.restore()
|
||||||
this.selectedChip = iChip
|
this.selectedChip = iChip
|
||||||
this.resultData.detections[iChip].beenViewed = true
|
this.resultData.detections[iChip].beenViewed = true
|
||||||
|
|
||||||
@@ -461,15 +517,28 @@
|
|||||||
this.uploadDirty = true
|
this.uploadDirty = true
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
resetView () {
|
resetView (drawChip) {
|
||||||
const imCanvas = this.$refs.image_cvs
|
const imCanvas = this.$refs.image_cvs
|
||||||
const imageCtx = imCanvas.getContext("2d")
|
const imageCtx = imCanvas.getContext("2d")
|
||||||
imCanvas.width = imCanvas.clientWidth
|
imCanvas.width = imCanvas.clientWidth
|
||||||
imCanvas.height = imCanvas.clientHeight
|
imCanvas.height = imCanvas.clientHeight
|
||||||
imageCtx.clearRect(0,0,imCanvas.width,imCanvas.height)
|
imageCtx.clearRect(0,0,imCanvas.width,imCanvas.height)
|
||||||
|
imageCtx.translate(this.canvasOffset.x,this.canvasOffset.y)
|
||||||
|
imageCtx.scale(this.canvasZoom,this.canvasZoom)
|
||||||
imageCtx.globalAlpha = 1
|
imageCtx.globalAlpha = 1
|
||||||
imageCtx.strokeStyle = 'yellow'
|
imageCtx.strokeStyle = 'yellow'
|
||||||
imageCtx.lineWidth = 3
|
imageCtx.lineWidth = 3 / this.canvasZoom
|
||||||
|
if (this.imageLoaded) {
|
||||||
|
let imageLoc = this.box2cvs({top: 0,left: 0,right: 1,bottom: 1})
|
||||||
|
this.imCvsLocation.top = imageLoc[0].cvsTop
|
||||||
|
this.imCvsLocation.left = imageLoc[0].cvsLeft
|
||||||
|
this.imCvsLocation.width = imageLoc[0].cvsRight - imageLoc[0].cvsLeft
|
||||||
|
this.imCvsLocation.height = imageLoc[0].cvsBottom - imageLoc[0].cvsTop
|
||||||
|
if (drawChip) {imageCtx.globalAlpha = .5}
|
||||||
|
imageCtx.drawImage(this.imageView, 0, 0, this.imageView.width, this.imageView.height, this.imCvsLocation.left, this.imCvsLocation.top, this.imCvsLocation.width, this.imCvsLocation.height)
|
||||||
|
if (drawChip) {imageCtx.globalAlpha = 1}
|
||||||
|
}
|
||||||
|
this.structureZoomed = false
|
||||||
return [imCanvas, imageCtx]
|
return [imCanvas, imageCtx]
|
||||||
},
|
},
|
||||||
getImage (searchImage) {
|
getImage (searchImage) {
|
||||||
@@ -483,6 +552,10 @@
|
|||||||
this.detecting = true
|
this.detecting = true
|
||||||
resolve('data:image/jpg;base64,' + searchImage)
|
resolve('data:image/jpg;base64,' + searchImage)
|
||||||
}
|
}
|
||||||
|
if (this.imageLoadMode == 'clipboard') {
|
||||||
|
this.detecting = true
|
||||||
|
resolve(searchImage)
|
||||||
|
}
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
reader.addEventListener("load", () => {
|
reader.addEventListener("load", () => {
|
||||||
this.detecting = true
|
this.detecting = true
|
||||||
@@ -510,8 +583,18 @@
|
|||||||
this.imageView.src = imgData
|
this.imageView.src = imgData
|
||||||
return(this.imageView.decode())
|
return(this.imageView.decode())
|
||||||
}).then( () => {
|
}).then( () => {
|
||||||
const [imCanvas, _] = this.resetView()
|
this.canvasOffset = {x: 0, y: 0}
|
||||||
imCanvas.style['background-image'] = `url(${this.imageView.src})`
|
this.canvasZoom = 1
|
||||||
|
const imCanvas = this.$refs.image_cvs
|
||||||
|
imCanvas.width = imCanvas.clientWidth
|
||||||
|
imCanvas.height = imCanvas.clientHeight
|
||||||
|
const imageCtx = imCanvas.getContext("2d")
|
||||||
|
let imageLoc = this.box2cvs({top: 0,left: 0,right: 1,bottom: 1})
|
||||||
|
this.imCvsLocation.top = imageLoc[0].cvsTop
|
||||||
|
this.imCvsLocation.left = imageLoc[0].cvsLeft
|
||||||
|
this.imCvsLocation.width = imageLoc[0].cvsRight - imageLoc[0].cvsLeft
|
||||||
|
this.imCvsLocation.height = imageLoc[0].cvsBottom - imageLoc[0].cvsTop
|
||||||
|
imageCtx.drawImage(this.imageView, 0, 0, this.imageView.width, this.imageView.height, this.imCvsLocation.left, this.imCvsLocation.top, this.imCvsLocation.width, this.imCvsLocation.height)
|
||||||
f7.utils.nextFrame(() => {
|
f7.utils.nextFrame(() => {
|
||||||
this.setData()
|
this.setData()
|
||||||
})
|
})
|
||||||
@@ -531,22 +614,36 @@
|
|||||||
this.detectorLevel = value
|
this.detectorLevel = value
|
||||||
},
|
},
|
||||||
structureClick(e) {
|
structureClick(e) {
|
||||||
const boxCoords = this.box2cvs(this.showResults)
|
let self = this
|
||||||
var findBox = boxCoords.findIndex( (r, i) => { return r.cvsLeft <= e.offsetX &&
|
function loopIndex(i) {
|
||||||
r.cvsRight >= e.offsetX &&
|
if (self.selectedChip == -1) return i
|
||||||
r.cvsTop <= e.offsetY &&
|
let li = i + self.selectedChip
|
||||||
r.cvsBottom >= e.offsetY &&
|
if (li >= numBoxes) li -= numBoxes
|
||||||
this.resultData.detections[i].resultIndex > this.selectedChip &&
|
return li
|
||||||
this.resultData.detections[i].aboveThreshold &&
|
}
|
||||||
this.resultData.detections[i].isSearched &&
|
let boxCoords = this.box2cvs(this.showResults)
|
||||||
!this.resultData.detections[i].isDeleted
|
const numBoxes = boxCoords.length
|
||||||
|
let clickX = (e.offsetX - this.canvasOffset.x) / this.canvasZoom
|
||||||
|
let clickY = (e.offsetY - this.canvasOffset.y) / this.canvasZoom
|
||||||
|
let boxEnd = boxCoords.splice(0, this.selectedChip)
|
||||||
|
boxCoords = boxCoords.concat(boxEnd)
|
||||||
|
var findBox = boxCoords.findIndex( (r, i) => {
|
||||||
|
let di = loopIndex(i)
|
||||||
|
if (di == this.selectedChip ) return false
|
||||||
|
return r.cvsLeft <= clickX &&
|
||||||
|
r.cvsRight >= clickX &&
|
||||||
|
r.cvsTop <= clickY &&
|
||||||
|
r.cvsBottom >= clickY &&
|
||||||
|
this.resultData.detections[di].aboveThreshold &&
|
||||||
|
this.resultData.detections[di].isSearched &&
|
||||||
|
!this.resultData.detections[di].isDeleted
|
||||||
})
|
})
|
||||||
this.selectChip(findBox >= 0 ? this.resultData.detections[findBox].resultIndex : this.selectedChip)
|
this.selectChip(findBox >= 0 ? this.resultData.detections[loopIndex(findBox)].resultIndex : this.selectedChip)
|
||||||
},
|
},
|
||||||
box2cvs(boxInput) {
|
box2cvs(boxInput) {
|
||||||
if (!boxInput || boxInput.length == 0) return []
|
if (!boxInput || boxInput.length == 0) return []
|
||||||
const boxList = boxInput.length ? boxInput : [boxInput]
|
const boxList = boxInput.length ? boxInput : [boxInput]
|
||||||
const [imCanvas, imageCtx] = this.resetView()
|
const imCanvas = this.$refs.image_cvs
|
||||||
var imgWidth
|
var imgWidth
|
||||||
var imgHeight
|
var imgHeight
|
||||||
const imgAspect = this.imageView.width / this.imageView.height
|
const imgAspect = this.imageView.width / this.imageView.height
|
||||||
@@ -567,6 +664,57 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
return cvsCoords
|
return cvsCoords
|
||||||
|
},
|
||||||
|
toggleSettings() {
|
||||||
|
this.showDetectSettings = !this.showDetectSettings
|
||||||
|
f7.utils.nextFrame(() => {
|
||||||
|
this.selectChip("redraw")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
startMove() {
|
||||||
|
this.canvasMoving = true
|
||||||
|
},
|
||||||
|
endMove() {
|
||||||
|
this.canvasMoving = false
|
||||||
|
},
|
||||||
|
makeMove(event) {
|
||||||
|
if (this.canvasMoving) {
|
||||||
|
this.canvasOffset.x += event.movementX
|
||||||
|
this.canvasOffset.y += event.movementY
|
||||||
|
this.selectChip("redraw")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
spinWheel(event) {
|
||||||
|
let zoomFactor
|
||||||
|
if (event.wheelDelta > 0) {
|
||||||
|
zoomFactor = 1.05
|
||||||
|
} else if (event.wheelDelta < 0) {
|
||||||
|
zoomFactor = 1 / 1.05
|
||||||
|
}
|
||||||
|
this.canvasZoom *= zoomFactor
|
||||||
|
this.canvasOffset.x = event.offsetX * (1 - zoomFactor) + this.canvasOffset.x * zoomFactor
|
||||||
|
this.canvasOffset.y = event.offsetY * (1 - zoomFactor) + this.canvasOffset.y * zoomFactor
|
||||||
|
this.selectChip("redraw")
|
||||||
|
},
|
||||||
|
resetZoom() {
|
||||||
|
this.canvasZoom = 1
|
||||||
|
this.canvasOffset.x = 0
|
||||||
|
this.canvasOffset.y = 0
|
||||||
|
this.selectChip("redraw")
|
||||||
|
},
|
||||||
|
zoomToSelected() {
|
||||||
|
const imCanvas = this.$refs.image_cvs
|
||||||
|
const boxCoords = this.box2cvs(this.resultData.detections[this.selectedChip])[0]
|
||||||
|
const boxWidth = boxCoords.cvsRight - boxCoords.cvsLeft
|
||||||
|
const boxHeight = boxCoords.cvsBottom - boxCoords.cvsTop
|
||||||
|
const boxMidX = (boxCoords.cvsRight + boxCoords.cvsLeft ) / 2
|
||||||
|
const boxMidY = (boxCoords.cvsBottom + boxCoords.cvsTop ) / 2
|
||||||
|
const zoomFactor = Math.min(imCanvas.width / boxWidth * .9, imCanvas.height / boxHeight * .9, 8)
|
||||||
|
this.canvasZoom = zoomFactor
|
||||||
|
this.canvasOffset.x = -(boxMidX * zoomFactor) + imCanvas.width / 2
|
||||||
|
this.canvasOffset.y = -(boxMidY * zoomFactor) + imCanvas.height / 2
|
||||||
|
this.selectChip("redraw")
|
||||||
|
this.structureZoomed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>Click on the image file icon <SvgIcon icon="photo_library" class="list-svg"/> to load a picture from the device storage.</li>
|
<li>Click on the image file icon <SvgIcon icon="photo_library" class="list-svg"/> to load a picture from the device storage.</li>
|
||||||
|
<li>If the clipboard is available on the system, then there will be a paste icon <SvgIcon icon="clipboard" class="list-svg"/> to paste image data directly into the app.</li>
|
||||||
<li>If demo mode is turned on, you can click on the marked image icon <SvgIcon icon="photo_sample" class="list-svg"/> to load an ALVINN sample image.</li>
|
<li>If demo mode is turned on, you can click on the marked image icon <SvgIcon icon="photo_sample" class="list-svg"/> to load an ALVINN sample image.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@@ -30,8 +31,11 @@
|
|||||||
<li>Click on each tag to see the structure highlighted in the image or click on the image to see the tag for that structure (additional clicks to the same area will select overlapping structres).</li>
|
<li>Click on each tag to see the structure highlighted in the image or click on the image to see the tag for that structure (additional clicks to the same area will select overlapping structres).</li>
|
||||||
<li>Tag color and proportion filled indicate ALVINN's level of confidence in the identification.</li>
|
<li>Tag color and proportion filled indicate ALVINN's level of confidence in the identification.</li>
|
||||||
<li>An incorrect tag can be deleted by clicking on the tag's <f7-icon icon="chip-delete" style="margin-right: 1px;"></f7-icon> button.</li>
|
<li>An incorrect tag can be deleted by clicking on the tag's <f7-icon icon="chip-delete" style="margin-right: 1px;"></f7-icon> button.</li>
|
||||||
|
<li>Click on the zoom to structure button <SvgIcon icon="zoom_to" class="list-svg"/> to magnify the view of the selected structure</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>Pan (middle click or touch and drag) and zoom (mouse wheel or pinch) to manually select detailed views in the image.</li>
|
||||||
|
<li>The reset zoom button <SvgIcon icon="reset_zoom" class="list-svg"/> will return the image to its initial position and magnification.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h2>Advanced Features</h2>
|
<h2>Advanced Features</h2>
|
||||||
<h3>Detection Parameters</h3>
|
<h3>Detection Parameters</h3>
|
||||||
|
|||||||
@@ -97,8 +97,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { touchstart } from 'dom7'
|
import RegionIcon from '../components/region-icon.vue'
|
||||||
import RegionIcon from '../components/region-icon.vue'
|
|
||||||
import store from '../js/store'
|
import store from '../js/store'
|
||||||
import { f7 } from 'framework7-vue'
|
import { f7 } from 'framework7-vue'
|
||||||
|
|
||||||
@@ -113,6 +112,11 @@ import RegionIcon from '../components/region-icon.vue'
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
//URL TESTING CODE
|
||||||
|
//let testUrl = URL.parse(`../models/thorax/model.json`,import.meta.url).href
|
||||||
|
//console.log(testUrl)
|
||||||
|
//let testUrl2 = new URL(`../models/thorax/model.json`,import.meta.url)
|
||||||
|
//console.log(testUrl2)
|
||||||
return store()
|
return store()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
<f7-block-title medium>Details</f7-block-title>
|
<f7-block-title medium>Details</f7-block-title>
|
||||||
<f7-list>
|
<f7-list>
|
||||||
<f7-list-item title="Version" :after="alvinnVersion"></f7-list-item>
|
<f7-list-item title="Version" :after="alvinnVersion"></f7-list-item>
|
||||||
<f7-list-item v-if="isSafari" title="Safari" after="Workers disabled"></f7-list-item>
|
<f7-list-item title="Build" :after="alvinnBuild"></f7-list-item>
|
||||||
|
<f7-list-item title="Workers" :after="useWorkers ? 'Enabled' : 'Disabled'"></f7-list-item>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
<f7-block-title medium>Models</f7-block-title>
|
<f7-block-title medium>Models</f7-block-title>
|
||||||
<f7-list style="width: 100%;">
|
<f7-list style="width: 100%;">
|
||||||
@@ -52,8 +53,9 @@
|
|||||||
headneckDetails: {},
|
headneckDetails: {},
|
||||||
miniHeadneckDetails: {},
|
miniHeadneckDetails: {},
|
||||||
alvinnVersion: store().getVersion,
|
alvinnVersion: store().getVersion,
|
||||||
|
alvinnBuild: store().getBuild,
|
||||||
isCordova: !!window.cordova,
|
isCordova: !!window.cordova,
|
||||||
isSafari: store().isSafari,
|
useWorkers: store().useWorkers,
|
||||||
otherSettings: {}
|
otherSettings: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
52
src/pages/touch-mixin.js
Normal file
52
src/pages/touch-mixin.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
touchPrevious: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
startTouch(event) {
|
||||||
|
if (event.touches.length == 1) {
|
||||||
|
this.touchPrevious = {x: event.touches[0].clientX, y: event.touches[0].clientY}
|
||||||
|
}
|
||||||
|
if (event.touches.length == 2) {
|
||||||
|
let midX = (event.touches.item(0).clientX + event.touches.item(1).clientX) / 2
|
||||||
|
let midY = (event.touches.item(0).clientY + event.touches.item(1).clientY) / 2
|
||||||
|
this.touchPrevious = {distance: this.touchDistance(event.touches), x: midX, y: midY}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endTouch(event) {
|
||||||
|
if (event.touches.length == 1) {
|
||||||
|
this.touchPrevious = {x: event.touches[0].clientX, y: event.touches[0].clientY}
|
||||||
|
} else {
|
||||||
|
//this.debugInfo = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
moveTouch(event) {
|
||||||
|
switch (event.touches.length) {
|
||||||
|
case 1:
|
||||||
|
console.log(event)
|
||||||
|
this.canvasOffset.x += event.touches[0].clientX - this.touchPrevious.x
|
||||||
|
this.canvasOffset.y += event.touches[0].clientY - this.touchPrevious.y
|
||||||
|
this.touchPrevious = {x: event.touches[0].clientX, y: event.touches[0].clientY}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
let newDistance = this.touchDistance(event.touches)
|
||||||
|
let midX = (event.touches.item(0).clientX + event.touches.item(1).clientX) / 2
|
||||||
|
let midY = (event.touches.item(0).clientY + event.touches.item(1).clientY) / 2
|
||||||
|
let zoomFactor = newDistance / this.touchPrevious.distance
|
||||||
|
this.canvasZoom *= zoomFactor
|
||||||
|
this.canvasOffset.x = (midX - 16) * (1 - zoomFactor) + this.canvasOffset.x * zoomFactor + (midX - this.touchPrevious.x)
|
||||||
|
this.canvasOffset.y = (midY - 96) * (1 - zoomFactor) + this.canvasOffset.y * zoomFactor + (midY - this.touchPrevious.y)
|
||||||
|
this.touchPrevious = {distance: newDistance, x: midX, y: midY}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.selectChip("redraw")
|
||||||
|
},
|
||||||
|
touchDistance(touches) {
|
||||||
|
let touch1 = touches.item(0)
|
||||||
|
let touch2 = touches.item(1)
|
||||||
|
return Math.sqrt((touch1.clientX - touch2.clientX) ** 2 + (touch1.clientY - touch2.clientY) ** 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user