Compare commits

...

No commits in common. "useCaseDrivenRefact" and "master" have entirely different histories.

59 changed files with 1046 additions and 185 deletions

3
.gitignore vendored
View File

@ -1,2 +1 @@
node_modules
dist
node_modules

View File

@ -1 +1,19 @@
# 🐱Cat 🔫Cannon
# 🐱Cat 🔫Cannon
The Cat Cannon is an automatically aiming water cannon designed to keep cats out of any location in which there presence is not desired. This solution is built on top of the Raspberry Pi driven by TypeScript and very little Python.
## Software Setup
Clone this repo and navigate to its saved directory
npm install
ts-node ./src/Robitics/main.ts
open a browser at http://localhost:5005
wait for cat to enter view of camera
what the machine protect your assets

12
dist/Vision/index.html vendored Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>Cat Cannon</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
</body>
<script src="main.js" defer></script>
</html>

3
dist/Vision/main.js vendored Normal file

File diff suppressed because one or more lines are too long

149
dist/Vision/main.js.LICENSE.txt vendored Normal file
View File

@ -0,0 +1,149 @@
/**
* @license
* Copyright 2017 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2018 Google LLC
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
* =============================================================================
*/
/**
* @license
* Copyright 2018 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
/**
* @license
* Copyright 2018 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2019 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
/**
* @license
* Copyright 2019 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2020 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/**
* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
/** @license See the LICENSE file. */

24
dist/Vision/styles.css vendored Normal file
View File

@ -0,0 +1,24 @@
* {
margin: 0;
padding: 0;
}
.PredictedObject {
border: 2px solid green;
}
.predictedObjectLabel {
color: white;
background-color: green;
font-size: 12px;
padding: 5px 10px;
text-transform: uppercase;
font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif
}
#VideoView {
position: absolute;
top: 0;
left: 0;
}

407
package-lock.json generated
View File

@ -86,6 +86,49 @@
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-2.8.2.tgz",
"integrity": "sha512-bEYwMeBuiWl+fB5fBmhqwxjjbwBme7KgTDCquOyHoP1P01HZNBAmyJIDCtpqGHBJuGHBOpFga/DBl+9yF7gR6g=="
},
"@types/body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
"dev": true,
"requires": {
"@types/connect": "*",
"@types/node": "*"
}
},
"@types/component-emitter": {
"version": "1.2.10",
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
"integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
},
"@types/connect": {
"version": "3.4.34",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
"integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
},
"@types/cors": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz",
"integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg=="
},
"@types/engine.io": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/@types/engine.io/-/engine.io-3.1.5.tgz",
"integrity": "sha512-DLVpLEGTEZGBXOYoYoagHSxXkDHONc0fZouF2ayw7Q18aRu1Afwci+1CFKvPpouCUOVWP+dmCaAWpQjswe7kpg==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/eslint": {
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
@ -112,6 +155,29 @@
"integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==",
"dev": true
},
"@types/express": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz",
"integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==",
"dev": true,
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.18",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"@types/express-serve-static-core": {
"version": "4.17.18",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz",
"integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==",
"dev": true,
"requires": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
}
},
"@types/glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
@ -128,6 +194,12 @@
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
"dev": true
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
"dev": true
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@ -153,11 +225,59 @@
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.3.0.tgz",
"integrity": "sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q=="
},
"@types/qs": {
"version": "6.9.5",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
"integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==",
"dev": true
},
"@types/range-parser": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
"dev": true
},
"@types/seedrandom": {
"version": "2.4.27",
"resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz",
"integrity": "sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE="
},
"@types/serve-static": {
"version": "1.13.9",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz",
"integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==",
"dev": true,
"requires": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"@types/socket.io": {
"version": "2.1.12",
"resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.12.tgz",
"integrity": "sha512-oStc5VFkpb0AsjOxQUj9ztX5Iziatyla/rjZTYbFGoVrrKwd+JU2mtxk7iSl5RGYx9WunLo6UXW1fBzQok/ZyA==",
"dev": true,
"requires": {
"@types/engine.io": "*",
"@types/node": "*",
"@types/socket.io-parser": "*"
}
},
"@types/socket.io-client": {
"version": "1.4.35",
"resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-1.4.35.tgz",
"integrity": "sha512-MI8YmxFS+jMkIziycT5ickBWK1sZwDwy16mgH/j99Mcom6zRG/NimNGQ3vJV0uX5G6g/hEw0FG3w3b3sT5OUGw==",
"dev": true
},
"@types/socket.io-parser": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@types/socket.io-parser/-/socket.io-parser-2.2.1.tgz",
"integrity": "sha512-+JNb+7N7tSINyXPxAJb62+NcpC1x/fPn7z818W4xeNCdPTp6VsO/X8fCsg6+ug4a56m1v9sEiTIIUKVupcHOFQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/webgl-ext": {
"version": "0.0.30",
"resolved": "https://registry.npmjs.org/@types/webgl-ext/-/webgl-ext-0.0.30.tgz",
@ -374,7 +494,6 @@
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
"dev": true,
"requires": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
@ -650,6 +769,11 @@
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"dev": true
},
"backo2": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@ -711,6 +835,16 @@
}
}
},
"base64-arraybuffer": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
},
"base64id": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
},
"batch": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
@ -743,7 +877,6 @@
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
"dev": true,
"requires": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
@ -760,14 +893,12 @@
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
"dev": true
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
@ -1063,8 +1194,7 @@
"component-emitter": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
"dev": true
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
},
"compressible": {
"version": "2.0.18",
@ -1117,7 +1247,6 @@
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
"dev": true,
"requires": {
"safe-buffer": "5.1.2"
}
@ -1125,20 +1254,17 @@
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
"dev": true
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
"dev": true
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
"dev": true
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"copy-descriptor": {
"version": "0.1.1",
@ -1157,6 +1283,15 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@ -1182,7 +1317,6 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
},
@ -1190,8 +1324,7 @@
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
@ -1304,14 +1437,12 @@
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
"dev": true
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
"dev": true
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"detect-node": {
"version": "2.0.4",
@ -1347,8 +1478,7 @@
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
"dev": true
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"electron-to-chromium": {
"version": "1.3.633",
@ -1370,8 +1500,7 @@
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
"dev": true
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"end-of-stream": {
"version": "1.4.4",
@ -1382,6 +1511,64 @@
"once": "^1.4.0"
}
},
"engine.io": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.0.tgz",
"integrity": "sha512-vW7EAtn0HDQ4MtT5QbmCHF17TaYLONv2/JwdYsq9USPRZVM4zG7WB3k0Nc321z8EuSOlhGokrYlYx4176QhD0A==",
"requires": {
"accepts": "~1.3.4",
"base64id": "2.0.0",
"cookie": "~0.4.1",
"cors": "~2.8.5",
"debug": "~4.3.1",
"engine.io-parser": "~4.0.0",
"ws": "~7.4.2"
},
"dependencies": {
"cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
},
"ws": {
"version": "7.4.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
}
}
},
"engine.io-client": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-4.1.0.tgz",
"integrity": "sha512-OUmn4m71/lW3ixICv4h3DuBRuh3ri0w3cDuepjsrINSbbqbni4Xw1shTFiKhl0v58lEtNpwJTpSKJJ3fondu5Q==",
"requires": {
"base64-arraybuffer": "0.1.4",
"component-emitter": "~1.3.0",
"debug": "~4.3.1",
"engine.io-parser": "~4.0.1",
"has-cors": "1.1.0",
"parseqs": "0.0.6",
"parseuri": "0.0.6",
"ws": "~7.4.2",
"xmlhttprequest-ssl": "~1.5.4",
"yeast": "0.1.2"
},
"dependencies": {
"ws": {
"version": "7.4.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA=="
}
}
},
"engine.io-parser": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
"requires": {
"base64-arraybuffer": "0.1.4"
}
},
"enhanced-resolve": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz",
@ -1463,8 +1650,7 @@
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
"dev": true
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"escape-string-regexp": {
"version": "1.0.5",
@ -1508,8 +1694,7 @@
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"dev": true
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"eventemitter3": {
"version": "4.0.7",
@ -1595,7 +1780,6 @@
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
"dev": true,
"requires": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
@ -1632,14 +1816,12 @@
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
"dev": true
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
@ -1779,7 +1961,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"dev": true,
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
@ -1794,7 +1975,6 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
@ -1836,8 +2016,7 @@
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
"dev": true
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
},
"fragment-cache": {
"version": "0.2.1",
@ -1851,8 +2030,7 @@
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
"dev": true
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"fs.realpath": {
"version": "1.0.0",
@ -1991,6 +2169,11 @@
"function-bind": "^1.1.1"
}
},
"has-cors": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
"integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@ -2082,7 +2265,6 @@
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
"dev": true,
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
@ -2094,8 +2276,7 @@
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
}
}
},
@ -2243,7 +2424,6 @@
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
@ -2359,8 +2539,7 @@
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"dev": true
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"is-absolute-url": {
"version": "3.0.3",
@ -2697,8 +2876,7 @@
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
"dev": true
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"memory-fs": {
"version": "0.5.0",
@ -2713,8 +2891,7 @@
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
"dev": true
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"merge-stream": {
"version": "2.0.0",
@ -2725,8 +2902,7 @@
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
"dev": true
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"micromatch": {
"version": "4.0.2",
@ -2741,8 +2917,7 @@
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dev": true
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.45.0",
@ -2817,8 +2992,7 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"multicast-dns": {
"version": "6.2.3",
@ -2865,8 +3039,7 @@
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
"dev": true
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"neo-async": {
"version": "2.6.2",
@ -2915,8 +3088,7 @@
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-copy": {
"version": "0.1.0",
@ -3011,7 +3183,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"dev": true,
"requires": {
"ee-first": "1.1.1"
}
@ -3103,11 +3274,20 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"parseqs": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz",
"integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w=="
},
"parseuri": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz",
"integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"dev": true
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"pascalcase": {
"version": "0.1.1",
@ -3154,8 +3334,7 @@
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
"dev": true
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"picomatch": {
"version": "2.2.2",
@ -3237,7 +3416,6 @@
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
"dev": true,
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.9.1"
@ -3268,8 +3446,7 @@
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
"dev": true
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
},
"querystring": {
"version": "0.2.0",
@ -3295,14 +3472,12 @@
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"dev": true
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
"dev": true,
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
@ -3313,8 +3488,7 @@
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
"dev": true
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
}
}
},
@ -3573,8 +3747,7 @@
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safe-regex": {
"version": "1.1.0",
@ -3588,8 +3761,7 @@
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"schema-utils": {
"version": "3.0.0",
@ -3632,7 +3804,6 @@
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
"dev": true,
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
@ -3653,7 +3824,6 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
},
@ -3661,16 +3831,14 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
}
}
},
@ -3737,7 +3905,6 @@
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
"dev": true,
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
@ -3777,8 +3944,7 @@
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
"dev": true
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"shebang-command": {
"version": "1.2.0",
@ -3923,6 +4089,51 @@
}
}
},
"socket.io": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz",
"integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==",
"requires": {
"@types/cookie": "^0.4.0",
"@types/cors": "^2.8.8",
"@types/node": "^14.14.10",
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.1",
"engine.io": "~4.1.0",
"socket.io-adapter": "~2.1.0",
"socket.io-parser": "~4.0.3"
}
},
"socket.io-adapter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz",
"integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg=="
},
"socket.io-client": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-3.1.0.tgz",
"integrity": "sha512-T4qPOL80KnoBwkdR70zMpiR6aH6zv3ZqLNriofHqsO9wvQllNTOez0mpV4GdVqo1Y55Z+h8YOlBo7c8pOxDlHw==",
"requires": {
"@types/component-emitter": "^1.2.10",
"backo2": "~1.0.2",
"component-emitter": "~1.3.0",
"debug": "~4.3.1",
"engine.io-client": "~4.1.0",
"parseuri": "0.0.6",
"socket.io-parser": "~4.0.4"
}
},
"socket.io-parser": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz",
"integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==",
"requires": {
"@types/component-emitter": "^1.2.10",
"component-emitter": "~1.3.0",
"debug": "~4.3.1"
}
},
"sockjs": {
"version": "0.3.21",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
@ -4084,8 +4295,7 @@
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
"dev": true
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"string-width": {
"version": "4.2.0",
@ -4243,8 +4453,7 @@
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
"dev": true
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"ts-loader": {
"version": "8.0.13",
@ -4321,7 +4530,6 @@
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"dev": true,
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
@ -4348,8 +4556,7 @@
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
"dev": true
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"unset-value": {
"version": "1.0.0",
@ -4455,8 +4662,7 @@
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
"dev": true
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "3.4.0",
@ -4473,8 +4679,7 @@
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
"dev": true
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"watchpack": {
"version": "2.1.0",
@ -5122,6 +5327,11 @@
"async-limiter": "~1.0.0"
}
},
"xmlhttprequest-ssl": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
"integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
},
"y18n": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
@ -5146,6 +5356,11 @@
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
},
"yeast": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
},
"yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

View File

@ -4,16 +4,24 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack serve",
"dev": "ts-node ./src/Robotics/main.ts",
"vision": "webpack serve",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@tensorflow-models/coco-ssd": "^2.2.1",
"@tensorflow/tfjs": "^2.8.2"
"@tensorflow/tfjs": "^2.8.2",
"express": "^4.17.1",
"socket.io": "^3.1.0",
"socket.io-client": "^3.1.0"
},
"devDependencies": {
"@types/express": "^4.17.11",
"@types/socket.io": "^2.1.12",
"@types/socket.io-client": "^1.4.35",
"ts-loader": "^8.0.13",
"typescript": "^4.1.3",
"webpack": "^5.11.1",

View File

@ -1,32 +0,0 @@
import PredictedObject from "../Models/PredictedObject"
import PredictedObjectCollection from "../Models/PredictedObjectCollection"
import PredictedObjectView from "../Views/PredictedObjectView"
class PredictedObjectCollectionController {
private model: PredictedObjectCollection
constructor () {
this.model = new PredictedObjectCollection()
this.renderView()
}
set predictedObjects (objects: PredictedObject[]) {
this.model.objects = objects
this.renderView()
}
public renderView = () => {
const existingPredictedObjectViews = document.querySelectorAll('.PredictedObject')
existingPredictedObjectViews.forEach(v => {
v.outerHTML = ''
})
const body = document.querySelector('body')!
this.model.objects.forEach((object: PredictedObject) => {
const predictedObjectView = new PredictedObjectView(object)
body.appendChild(predictedObjectView.element)
})
}
}
export default PredictedObjectCollectionController

View File

@ -1,48 +0,0 @@
import Video from "../Models/Video"
import VideoView from '../Views/VideoView'
class VideoController {
private defaultWidth: number = 640
private defaultHeight: number = 480
private userMediaConstraints = { video: true }
public model: Video
private view: VideoView
constructor (props: { width?: number, height?: number } = {}) {
this.model = new Video({
width: props.width || this.defaultWidth,
height: props.height || this.defaultHeight
})
this.view = new VideoView(this.model)
this.renderView()
this.enableCamera()
}
get imageData () {
if (!this.view.element.srcObject) return null
const canvas: HTMLCanvasElement = document.createElement('canvas')
canvas.width = this.model.width
canvas.height = this.model.height
const context = canvas.getContext('2d')!
context.drawImage(this.view.element, 0, 0, this.model.width, this.model.height)
return context.getImageData(0, 0, this.model.width, this.model.height)
}
private enableCamera = async () => {
const stream = await navigator.mediaDevices.getUserMedia(this.userMediaConstraints)
this.view.srcObject = stream
}
private renderView () {
const existingVideoView = document.querySelector('#videoView')
if (existingVideoView) existingVideoView.outerHTML = ''
const body = document.querySelector('body')!
body.appendChild(this.view.element)
}
}
export default VideoController

View File

@ -0,0 +1,26 @@
import { EventEmitter } from 'events'
import IEventManager from '../Interfaces/IEventManager'
let instance: EventManager | null = null
class EventManager implements IEventManager {
eventEmitter: EventEmitter
constructor () {
if (!instance) instance = this
this.eventEmitter = new EventEmitter()
return instance
}
listen = (eventName: string, callback: any) => {
this.eventEmitter.addListener(eventName, callback)
}
emit = (eventName: string, detail: any) => {
this.eventEmitter.emit(eventName, detail)
}
}
export default EventManager

View File

@ -0,0 +1,17 @@
import IMotor from "../Interfaces/IMotor"
class Motor implements IMotor {
public pinOne: number
public pinTwo: number
public pinThree: number
public pinFour: number
constructor (props: IMotor) {
this.pinOne = props.pinOne
this.pinTwo = props.pinTwo
this.pinThree = props.pinThree
this.pinFour = props.pinFour
}
}
export default Motor

View File

@ -0,0 +1,70 @@
import IMotor from "../Interfaces/IMotor"
import makeMotor from "../UseCases/Factories/makeMotor"
import * as childProcesses from 'child_process'
import IMotorMoverConstructor from "../Interfaces/IMotorMoverConstructor"
import IMotorMover from "../Interfaces/IMotorMover"
class MotorMover implements IMotorMover {
motor: IMotor
moveProcess: childProcesses.ChildProcessWithoutNullStreams | null = null
pauseIntervalTime: number
movementState: 'CLOCKWISE' | 'COUNTERCLOCKWISE' | "IDLE" = 'IDLE'
constructor (props: IMotorMoverConstructor) {
this.motor = makeMotor(props.motor)
this.pauseIntervalTime = props.pauseIntervalTime
}
public moveClockwise = () => {
if (this.movementState === 'CLOCKWISE') return
else {
if (!this.moveProcess?.killed) this.moveProcess?.kill()
}
const motorProcessArguments = [
'src/Robotics/moveStepper.py',
this.motor.pinOne.toString(),
this.motor.pinTwo.toString(),
this.motor.pinThree.toString(),
this.motor.pinFour.toString(),
'clockwise',
this.pauseIntervalTime.toString()
]
console.log('start clockwise')
this.moveProcess = childProcesses.spawn('python', motorProcessArguments)
this.movementState = 'CLOCKWISE'
}
public moveCounterClockwise = () => {
if (this.movementState === 'COUNTERCLOCKWISE') return
else {
if (!this.moveProcess?.killed) this.moveProcess?.kill()
}
const motorProcessArguments = [
'src/Robotics/moveStepper.py',
this.motor.pinOne.toString(),
this.motor.pinTwo.toString(),
this.motor.pinThree.toString(),
this.motor.pinFour.toString(),
'counterClockwise',
this.pauseIntervalTime.toString()
]
console.log('start counterclockwise')
this.moveProcess = childProcesses.spawn('python', motorProcessArguments)
this.movementState = 'COUNTERCLOCKWISE'
}
public stopMovement = () => {
if (this.movementState === 'IDLE') return
else {
if (!this.moveProcess?.killed) this.moveProcess?.kill()
console.log('start idle')
this.movementState = 'IDLE'
}
}
}
export default MotorMover

View File

@ -0,0 +1,69 @@
import express from 'express'
import path from 'path'
import bodyParser from 'body-parser'
import http from 'http'
import { Socket } from 'socket.io'
import IEventManager from '../Interfaces/IEventManager'
import EventManager from './EventManager'
class Server {
public app = express()
private eventManager: IEventManager
constructor (port: number) {
this.createApp()
this.setupAppOptions()
this.setupAppRoutes()
this.startServer(port)
this.eventManager = new EventManager()
}
createApp = () => {
this.app.use(express.json())
this.app.use(express.urlencoded({ extended: false }))
this.app.use(express.static(path.join(process.cwd(), '/dist/Vision/')))
this.app.use(bodyParser.json())
}
setupAppRoutes = () => {
this.app.use('/', (request, response, next) => {
response.sendFile(path.join(process.cwd(), './dist/Vision/index.html'))
})
}
setupAppOptions = () => {
this.app.use((request, response, next) => {
response.header('Access-Control-Allow-Origin', request.headers.origin || '*')
response.header('Access-Control-Allow-Methods', 'GET,POST,PUT,PATCH,HEAD,DELETE,OPTIONS')
response.header('Access-Control-Allow-Headers', 'Content-Type,x-requested-with')
next()
})
}
startServer = (port: number) => {
const webService = new http.Server(this.app)
const socketService = require("socket.io")(webService)
this.openSockets(socketService)
webService.listen(port, () => {
console.log(`Server is listening on ${port}`)
})
}
openSockets = (socketService: any) => {
socketService.on('connection', (socket: Socket) => {
console.log('client connected')
socket.on('offsets', (offsets: any[]) => {
this.onReceiveOffsets(offsets)
})
})
}
public onReceiveOffsets = (offsets: any[]) => {
this.eventManager.emit('onReceiveOffsets', offsets)
}
}
export default Server

View File

@ -0,0 +1,13 @@
import IWaterPump from '../Interfaces/IWaterPump'
class WaterPump implements IWaterPump {
public pinOne: number
public pinTwo: number
constructor (props: IWaterPump) {
this.pinOne = props.pinOne
this.pinTwo = props.pinTwo
}
}
export default WaterPump

View File

@ -0,0 +1,46 @@
import IWaterPump from '../Interfaces/IWaterPump'
import * as childProcesses from 'child_process'
import IWaterPumperConstructor from '../Interfaces/IWaterPumperConstructor'
import IWaterPumper from '../Interfaces/IWaterPumper'
import makeWaterPump from '../UseCases/Factories/makeWaterPump'
class WaterPumper implements IWaterPumper {
public waterPump: IWaterPump
public isActive: boolean = false
private pumpProcess: childProcesses.ChildProcessWithoutNullStreams | null = null
private pumpActiveTimeInSeconds: number
private pumpCoolDownTimeInSeconds: number
constructor (props: IWaterPumperConstructor) {
this.waterPump = makeWaterPump({
pinOne: props.pinOne,
pinTwo: props.pinTwo
})
this.pumpActiveTimeInSeconds =props.pumpActiveTimeInSeconds
this.pumpCoolDownTimeInSeconds = props.pumpCoolDownTimeInSeconds
}
private async coolDown () {
return new Promise(resolve => setTimeout(resolve, this.pumpCoolDownTimeInSeconds * 1000))
}
public async pump () {
if (this.isActive) return
const pumpProcessArguments = [
'src/Robotics/moveDcMotor.py',
this.waterPump.pinOne.toString(),
this.waterPump.pinTwo.toString(),
this.pumpActiveTimeInSeconds.toString()
]
this.pumpProcess = childProcesses.spawn('python', pumpProcessArguments)
this.isActive = true
await this.coolDown()
this.isActive = false
}
}
export default WaterPumper

View File

@ -0,0 +1,6 @@
interface IEventManager {
listen(eventName: string, callback: any): void,
emit(eventName: string, detail: any): void
}
export default IEventManager

View File

@ -0,0 +1,8 @@
interface IMotor {
pinOne: number,
pinTwo: number,
pinThree: number,
pinFour: number
}
export default IMotor

View File

@ -0,0 +1,8 @@
interface IMotorMover {
moveClockwise(): void,
moveCounterClockwise(): void,
stopMovement(): void,
movementState: 'CLOCKWISE' | 'COUNTERCLOCKWISE' | "IDLE"
}
export default IMotorMover

View File

@ -0,0 +1,8 @@
import IMotor from "./IMotor";
interface IMotorMoverConstructor {
motor: IMotor,
pauseIntervalTime: number
}
export default IMotorMoverConstructor

View File

@ -0,0 +1,5 @@
interface IServer {
port: number
}
export default IServer

View File

@ -0,0 +1,6 @@
interface IWaterPump {
pinOne: number,
pinTwo: number
}
export default IWaterPump

View File

@ -0,0 +1,9 @@
import IWaterPump from "./IWaterPump";
interface IWaterPumper {
pump(): void
isActive: boolean
waterPump: IWaterPump
}
export default IWaterPumper

View File

@ -0,0 +1,8 @@
interface IWaterPumperConstructor {
pinOne: number,
pinTwo: number,
pumpActiveTimeInSeconds: number,
pumpCoolDownTimeInSeconds: number
}
export default IWaterPumperConstructor

View File

@ -0,0 +1,7 @@
import EventManager from "../../Entities/EventManager"
function makeEventManager () {
return new EventManager()
}
export default makeEventManager

View File

@ -0,0 +1,8 @@
import Motor from "../../Entities/Motor"
import IMotor from "../../Interfaces/IMotor"
function makeMotor (props: IMotor) {
return new Motor(props)
}
export default makeMotor

View File

@ -0,0 +1,8 @@
import MotorMover from "../../Entities/MotorMover"
import IMotorMoverConstructor from "../../Interfaces/IMotorMoverConstructor"
function makeMotorMover (props: IMotorMoverConstructor) {
return new MotorMover(props)
}
export default makeMotorMover

View File

@ -0,0 +1,9 @@
import Server from "../../Entities/Server"
function makeServer (port: number) {
const defaultPort = 5005
return new Server(port || defaultPort)
}
export default makeServer

View File

@ -0,0 +1,8 @@
import WaterPump from "../../Entities/WaterPump"
import IWaterPump from "../../Interfaces/IWaterPump"
function makeWaterPump (props: IWaterPump) {
return new WaterPump(props)
}
export default makeWaterPump

View File

@ -0,0 +1,8 @@
import WaterPumper from "../../Entities/WaterPumper"
import IWaterPumperConstructor from "../../Interfaces/IWaterPumperConstructor"
function makeWaterPumper (props: IWaterPumperConstructor) {
return new WaterPumper(props)
}
export default makeWaterPumper

60
src/Robotics/main.ts Normal file
View File

@ -0,0 +1,60 @@
import IEventManager from './Interfaces/IEventManager'
import IMotorMover from './Interfaces/IMotorMover'
import IWaterPumper from './Interfaces/IWaterPumper'
import makeServer from './UseCases/Factories/makeServer'
import makeEventManager from './UseCases/Factories/makeEventManager'
import makeMotorMover from './UseCases/Factories/makeMotorMover'
import makeWaterPumper from './UseCases/Factories/makeWaterPumper'
const main = () => {
console.log('Starting Robotics')
const port = 5005
makeServer(port)
const eventManager: IEventManager = makeEventManager()
const xAxisMotorMover: IMotorMover = makeMotorMover({
motor: { pinOne: 3, pinTwo: 5, pinThree: 7, pinFour: 11 },
pauseIntervalTime: 0.05
})
const yAxisMotorMover: IMotorMover = makeMotorMover({
motor: { pinOne: 13, pinTwo: 15, pinThree: 19, pinFour: 21 },
pauseIntervalTime: 0.05
})
const waterPumper: IWaterPumper = makeWaterPumper({
pinOne: 37,
pinTwo: 35,
pumpActiveTimeInSeconds: 1,
pumpCoolDownTimeInSeconds: 5
})
eventManager.listen('onReceiveOffsets', (offsets: any[]) => {
if (offsets[0]?.x > 50) {
xAxisMotorMover.moveCounterClockwise()
} else if (offsets[0]?.x < - 50) {
xAxisMotorMover.moveClockwise()
} else {
xAxisMotorMover.stopMovement()
}
if (offsets[0]?.y > 50) {
yAxisMotorMover.moveClockwise()
} else if (offsets[0]?.y < - 50) {
yAxisMotorMover.moveCounterClockwise()
} else {
yAxisMotorMover.stopMovement()
}
if (offsets[0]?.hypotenuse <= 80) {
waterPumper.pump()
}
})
}
main()
export { main }

View File

@ -0,0 +1,22 @@
# command arguments to run process
# 1: int pin_one
# 2: int pin_two
# 3: int motor_active_time
import RPi.GPIO as GPIO
from time import sleep
import sys
motor_channel = (int(sys.argv[1]), int(sys.argv[2])) # (37, 35)
motor_active_time = int(sys.argv[3])
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(motor_channel, GPIO.OUT)
GPIO.output(motor_channel, (GPIO.HIGH, GPIO.LOW))
print('Should be on')
sleep(motor_active_time)
GPIO.output(motor_channel, (GPIO.LOW, GPIO.LOW))

View File

@ -0,0 +1,48 @@
# command arguments to run process
# 1: int pin_one
# 2: int pin_two
# 3: int pin_three
# 4: int pin_four
# 5: string clockwise or counterClockwise
# 6: float: interval_time
import RPi.GPIO as GPIO
from time import sleep
import sys
motor_channel = (int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4]))
motor_direction = sys.argv[5]
interval_time = float(sys.argv[6])
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(motor_channel, GPIO.OUT)
while True:
try:
if(motor_direction == 'clockwise'):
print('motor running clockwise\n')
GPIO.output(motor_channel, (GPIO.HIGH,GPIO.LOW,GPIO.LOW,GPIO.HIGH))
sleep(interval_time)
GPIO.output(motor_channel, (GPIO.HIGH,GPIO.HIGH,GPIO.LOW,GPIO.LOW))
sleep(interval_time)
GPIO.output(motor_channel, (GPIO.LOW,GPIO.HIGH,GPIO.HIGH,GPIO.LOW))
sleep(interval_time)
GPIO.output(motor_channel, (GPIO.LOW,GPIO.LOW,GPIO.HIGH,GPIO.HIGH))
sleep(interval_time)
elif(motor_direction == 'counterClockwise'):
print('motor running anti-clockwise\n')
GPIO.output(motor_channel, (GPIO.HIGH,GPIO.LOW,GPIO.LOW,GPIO.HIGH))
sleep(interval_time)
GPIO.output(motor_channel, (GPIO.LOW,GPIO.LOW,GPIO.HIGH,GPIO.HIGH))
sleep(interval_time)
GPIO.output(motor_channel, (GPIO.LOW,GPIO.HIGH,GPIO.HIGH,GPIO.LOW))
sleep(interval_time)
GPIO.output(motor_channel, (GPIO.HIGH,GPIO.HIGH,GPIO.LOW,GPIO.LOW))
sleep(interval_time)
except KeyboardInterrupt:
sys.exit(0)

View File

@ -0,0 +1,7 @@
import IOffset from "./IOffset";
interface IRoboticsCommunicator {
sendOffsets(offsets: IOffset[]): void
}
export default IRoboticsCommunicator

View File

@ -0,0 +1,8 @@
import RoboticsCommunicator from "../RoboticsCommunicator"
function makeRoboticsCommunicator () {
return new RoboticsCommunicator()
}
export default makeRoboticsCommunicator

View File

@ -0,0 +1,16 @@
import * as io from 'socket.io-client'
import IOffset from '../Interfaces/IOffset'
class RoboticsCommunicator {
socket: SocketIOClient.Socket
constructor () {
this.socket = io.connect()
}
sendOffsets = (offsets: IOffset[]) => {
this.socket.emit('offsets', offsets)
}
}
export default RoboticsCommunicator

View File

@ -1,6 +1,7 @@
import IObjectDetector from './Interfaces/IObjectDetector'
import IObjectLocator from './Interfaces/IObjectLocator'
import IOffset from './Interfaces/IOffset'
import IRoboticsCommunicator from './Interfaces/IRoboticsCommunicator'
import IUiRenderer from './Interfaces/IUiRenderer'
import IVideoCapturer from "./Interfaces/IVideoCapturer"
@ -8,17 +9,20 @@ import makeObjectDetector from './UseCases/Factories/makeObjectDetector'
import makeObjectLocator from './UseCases/Factories/makeObjectLocator'
import makeUiRenderer from './UseCases/Factories/makeUiRenderer'
import makeVideoCapturer from './UseCases/Factories/makeVideoCatpurer'
import makeRoboticsCommunicator from './UseCases/Factories/mkaeRoboticsCommunicator'
class App {
private objectDetector: IObjectDetector
private objectLocator: IObjectLocator
private videoCapturer: IVideoCapturer
private roboticsCommunicator: IRoboticsCommunicator
private uiRenderer: IUiRenderer
constructor () {
this.videoCapturer = makeVideoCapturer()
this.objectDetector = makeObjectDetector()
this.objectLocator = makeObjectLocator()
this.roboticsCommunicator = makeRoboticsCommunicator()
this.uiRenderer = makeUiRenderer()
const eventTarget = new EventTarget()
@ -36,6 +40,7 @@ class App {
const predictedObjects = await this.objectDetector.getPredictionsFromImageData(imageData)
const offsets: IOffset[] = predictedObjects.map(obj => this.objectLocator.getOffsetsFromPredictions(obj))
this.roboticsCommunicator.sendOffsets(offsets)
this.uiRenderer.render({ imageData, predictedObjects, offsets })
window.requestAnimationFrame(this.predictImage)

View File

@ -1,10 +1,10 @@
const path = require('path');
module.exports = {
entry: './src/app.ts',
entry: './src/Vision/main.ts',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
contentBase: './dist/Vision',
hot: true,
},
module: {
@ -20,7 +20,7 @@ module.exports = {
extensions: [ '.tsx', '.ts', '.js' ],
},
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'),
filename: 'main.js',
path: path.resolve(__dirname, 'dist', 'Vision'),
},
};