├── .eslintignore ├── __mocks__ ├── styleMock.js └── fileMock.js ├── cypress ├── fixtures │ ├── example.json │ └── adult-1868750_1920.jpg ├── support │ ├── index.js │ └── commands.js ├── downloads │ └── _assets_girl-250--with-background.png ├── plugins │ └── index.js └── integration │ └── application.spec.js ├── .gitpod.yml ├── cypress.env.json ├── src ├── component │ ├── collapse │ │ ├── index.js │ │ ├── index.css │ │ └── events.js │ ├── output │ │ ├── index.js │ │ ├── index.css │ │ └── events.js │ ├── settings │ │ ├── index.js │ │ ├── events.js │ │ ├── index.css │ │ ├── state.js │ │ └── __tests__ │ │ │ └── state.js │ ├── input-source │ │ ├── index.js │ │ ├── index.css │ │ └── events.js │ ├── suggestions │ │ ├── index.js │ │ ├── index.css │ │ └── events.js │ ├── core-css │ │ ├── index.js │ │ ├── views.css │ │ ├── vars.css │ │ ├── screen-readers.css │ │ ├── site.css │ │ ├── base-styles.css │ │ └── reset.css │ ├── test-example │ │ └── __tests__ │ │ │ └── example.tests.js │ ├── alert │ │ ├── alert.js │ │ └── __tests__ │ │ │ └── alert.js │ ├── utils │ │ └── index.js │ └── background-removal │ │ ├── background-removal.js │ │ └── __tests__ │ │ └── background-removal.js └── index.js ├── cypress.json ├── .firebaserc ├── public ├── assets │ ├── social.jpg │ ├── adult-1868750_1920.jpg │ ├── girl-2501094_640.jpg │ ├── snow-1217124_640.jpg │ ├── tfjs-backend-wasm.wasm │ ├── tfjs-backend-wasm-simd.wasm │ ├── tfjs-backend-wasm-threaded-simd.wasm │ ├── tfjs-backend-wasm-threaded-simd.d.ts │ ├── tfjs-backend-wasm.d.ts │ ├── tfjs-backend-wasm-threaded-simd.worker.js │ ├── diagram.svg │ ├── tfjs-backend-wasm.js │ └── tfjs-backend-wasm-threaded-simd.js └── index.html ├── .lintstagedrc ├── postcss.config.js ├── .gitignore ├── setup-jest.js ├── firebase.json ├── .babelrc.js ├── .editorconfig ├── .stylelintrc.json ├── setup-tests.js ├── .eslintrc.js ├── LICENSE ├── .github └── workflows │ ├── monthly-visual-testing.yml │ └── ci.yml ├── webpack.js ├── README.MD └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /cypress/support/index.js: -------------------------------------------------------------------------------- 1 | import './commands' 2 | -------------------------------------------------------------------------------- /__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub'; 2 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: npm install 3 | command: npm start 4 | -------------------------------------------------------------------------------- /cypress.env.json: -------------------------------------------------------------------------------- 1 | { 2 | "CYPRESS_BASE_URL": "http://localhost:5000" 3 | } 4 | -------------------------------------------------------------------------------- /src/component/collapse/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import './events' 3 | -------------------------------------------------------------------------------- /src/component/output/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import './events' 3 | -------------------------------------------------------------------------------- /src/component/settings/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import './events' 3 | -------------------------------------------------------------------------------- /src/component/input-source/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import './events' 3 | -------------------------------------------------------------------------------- /src/component/suggestions/index.js: -------------------------------------------------------------------------------- 1 | import './index.css' 2 | import './events' 3 | -------------------------------------------------------------------------------- /cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | import '@percy/cypress' 2 | import 'cypress-file-upload' 3 | -------------------------------------------------------------------------------- /cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultCommandTimeout": 60000, 3 | "projectId": "jp2thc" 4 | } 5 | -------------------------------------------------------------------------------- /src/component/output/index.css: -------------------------------------------------------------------------------- 1 | .output__preview { 2 | position: sticky; 3 | top: 0; 4 | } 5 | -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "tensorflowjs-remove-background" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/social.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/public/assets/social.jpg -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.js": ["eslint --fix", "jest --bail --findRelatedTests --passWithNoTests"], 3 | "*.css": "stylelint --fix", 4 | } 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | 'postcss-preset-env', 4 | 'autoprefixer', 5 | ], 6 | }; 7 | -------------------------------------------------------------------------------- /src/component/collapse/index.css: -------------------------------------------------------------------------------- 1 | .collapse { 2 | height: 0; 3 | overflow: hidden; 4 | transition: height 0.15s ease-in-out; 5 | } 6 | -------------------------------------------------------------------------------- /public/assets/adult-1868750_1920.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/public/assets/adult-1868750_1920.jpg -------------------------------------------------------------------------------- /public/assets/girl-2501094_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/public/assets/girl-2501094_640.jpg -------------------------------------------------------------------------------- /public/assets/snow-1217124_640.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/public/assets/snow-1217124_640.jpg -------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/public/assets/tfjs-backend-wasm.wasm -------------------------------------------------------------------------------- /cypress/fixtures/adult-1868750_1920.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/cypress/fixtures/adult-1868750_1920.jpg -------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm-simd.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/public/assets/tfjs-backend-wasm-simd.wasm -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | node_modules/ 3 | dist/ 4 | coverage/ 5 | cypress/videos/ 6 | cypress/screenshots/ 7 | .scannerwork/ 8 | .tmp/ 9 | *-debug.log 10 | -------------------------------------------------------------------------------- /setup-jest.js: -------------------------------------------------------------------------------- 1 | import { configure } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | configure({ adapter: new Adapter() }); 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm-threaded-simd.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/public/assets/tfjs-backend-wasm-threaded-simd.wasm -------------------------------------------------------------------------------- /cypress/downloads/_assets_girl-250--with-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poly-glot/tensorflowjs-remove-background/HEAD/cypress/downloads/_assets_girl-250--with-background.png -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "dist", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/component/core-css/index.js: -------------------------------------------------------------------------------- 1 | import './vars.css' 2 | import './reset.css' 3 | import './screen-readers.css' 4 | import './base-styles.css' 5 | 6 | import './site.css' 7 | import './views.css' 8 | -------------------------------------------------------------------------------- /src/component/test-example/__tests__/example.tests.js: -------------------------------------------------------------------------------- 1 | describe('Example', () => { 2 | it('Should load public/index.html by default', async () => { 3 | expect(document.querySelector('body')).toBeTruthy() 4 | }) 5 | }) 6 | -------------------------------------------------------------------------------- /src/component/alert/alert.js: -------------------------------------------------------------------------------- 1 | export class Alert { 2 | init () { 3 | this._elem = document.getElementById('js-alert') 4 | } 5 | 6 | announce (text) { 7 | this._elem.innerHTML = text 8 | } 9 | } 10 | 11 | export default new Alert() 12 | -------------------------------------------------------------------------------- /.babelrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@babel/preset-env"], 3 | plugins: [ 4 | '@babel/plugin-proposal-object-rest-spread', 5 | '@babel/plugin-syntax-dynamic-import', 6 | '@babel/plugin-proposal-class-properties', 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [package.json] 13 | indent_style = space 14 | indent_size = 2 15 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard", 3 | "plugins": [ 4 | "stylelint-order" 5 | ], 6 | "rules": { 7 | "order/order": [ 8 | "custom-properties", 9 | "declarations" 10 | ], 11 | "order/properties-alphabetical-order": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/component/core-css/views.css: -------------------------------------------------------------------------------- 1 | .views { 2 | display: flex; 3 | flex: 1 0 auto; 4 | } 5 | 6 | .views__child { 7 | display: flex; 8 | flex: 1; 9 | position: relative; 10 | } 11 | 12 | .views__frame { 13 | border: 0; 14 | height: 100%; 15 | left: 0; 16 | position: absolute; 17 | top: 0; 18 | width: 100%; 19 | } 20 | -------------------------------------------------------------------------------- /src/component/settings/events.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | 3 | import state from './state' 4 | const settingsForm = document.getElementById('js-input-source') 5 | 6 | settingsForm.addEventListener('change', onChange) 7 | 8 | function onChange (evt) { 9 | const { target } = evt 10 | 11 | state.set(target.id, target.value) 12 | } 13 | -------------------------------------------------------------------------------- /setup-tests.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | const html = fs.readFileSync(path.resolve(path.join(__dirname, 'public', 'index.html')), { encoding: "utf8" }); 5 | 6 | global.beforeEach(() => { 7 | document.documentElement.innerHTML = html; 8 | }); 9 | 10 | global.afterEach(() => { 11 | jest.clearAllMocks(); 12 | }); 13 | -------------------------------------------------------------------------------- /src/component/input-source/index.css: -------------------------------------------------------------------------------- 1 | .input-source { 2 | border-right: 1px solid var(--borderColor); 3 | display: flex; 4 | flex: 1; 5 | flex-direction: column; 6 | } 7 | 8 | .input-source__preview { 9 | border-bottom: 1px solid var(--borderColor); 10 | flex: 1; 11 | } 12 | 13 | .input-source__image { 14 | max-height: 426px; 15 | width: 100%; 16 | } 17 | -------------------------------------------------------------------------------- /src/component/suggestions/index.css: -------------------------------------------------------------------------------- 1 | .suggestions { 2 | background: #f6f6f6; 3 | display: flex; 4 | height: 100%; 5 | margin-top: 8px; 6 | padding: 15px; 7 | width: 100%; 8 | } 9 | 10 | .suggestions__label { 11 | font-size: 0.8rem; 12 | font-weight: bold; 13 | margin-right: 10px; 14 | } 15 | 16 | .suggestions__option { 17 | margin: 0 5px; 18 | } 19 | -------------------------------------------------------------------------------- /src/component/input-source/events.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | 3 | const imgPickerElem = document.getElementById('js-image-picker') 4 | const imgPreviewElem = document.getElementById('js-input-preview') 5 | 6 | imgPickerElem.addEventListener('change', onChange) 7 | 8 | function onChange () { 9 | const [selectedFile] = imgPickerElem.files 10 | imgPreviewElem.src = URL.createObjectURL(selectedFile) 11 | } 12 | -------------------------------------------------------------------------------- /src/component/core-css/vars.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --main-bg-color: #fff; 3 | --main-color: #222; 4 | --font: -apple-system, blinkmacsystemfont, "Segoe UI", roboto, "Helvetica Neue", arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 5 | --brand: #01189b; 6 | --brand-highlight: #011271; 7 | --brand-text: #fff; 8 | --borderColor: rgba(0, 0, 0, 0.15); 9 | } 10 | -------------------------------------------------------------------------------- /src/component/settings/index.css: -------------------------------------------------------------------------------- 1 | .settings__item { 2 | border-bottom: 1px solid var(--borderColor); 3 | display: flex; 4 | flex-direction: column; 5 | padding: 8px 15px; 6 | } 7 | 8 | .settings__item--column { 9 | flex-direction: row; 10 | } 11 | 12 | .settings__column { 13 | display: flex; 14 | flex: 1; 15 | flex-direction: column; 16 | } 17 | 18 | .settings__advance { 19 | margin: 8px 0 8px 0; 20 | } 21 | -------------------------------------------------------------------------------- /src/component/core-css/screen-readers.css: -------------------------------------------------------------------------------- 1 | .sr-only { 2 | border: 0; 3 | clip: rect(0, 0, 0, 0); 4 | height: 1px; 5 | margin: -1px; 6 | overflow: hidden; 7 | padding: 0; 8 | position: absolute; 9 | white-space: nowrap; 10 | width: 1px; 11 | } 12 | 13 | .sr-only-focusable:active, 14 | .sr-only-focusable:focus { 15 | clip: auto; 16 | height: auto; 17 | overflow: visible; 18 | position: static; 19 | white-space: normal; 20 | width: auto; 21 | } 22 | -------------------------------------------------------------------------------- /src/component/alert/__tests__/alert.js: -------------------------------------------------------------------------------- 1 | import AlertService from '../alert' 2 | 3 | describe('AlertService test', () => { 4 | beforeEach(() => { 5 | AlertService.init() 6 | }) 7 | 8 | describe('AlertService.announce()', () => { 9 | it('Should set text to alert element', () => { 10 | AlertService.announce('new text') 11 | 12 | const alertElem = document.getElementById('js-alert') 13 | 14 | expect(alertElem).toBeDefined() 15 | expect(alertElem.innerHTML).toEqual('new text') 16 | }) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | jest: true 6 | }, 7 | extends: [ 8 | 'standard' 9 | ], 10 | globals: { 11 | Atomics: 'readonly', 12 | SharedArrayBuffer: 'readonly', 13 | cy: true, 14 | Cypress: true 15 | }, 16 | parser: "@babel/eslint-parser", 17 | parserOptions: { 18 | ecmaVersion: 2018, 19 | sourceType: 'module' 20 | }, 21 | plugins: [ 22 | "@babel" 23 | ], 24 | rules: { 25 | 'max-len': ["error", { "code": 180 }] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/component/core-css/site.css: -------------------------------------------------------------------------------- 1 | .site__header { 2 | border-bottom: 1px solid var(--borderColor); 3 | display: flex; 4 | justify-content: space-between; 5 | padding: 15px; 6 | } 7 | 8 | .site__body { 9 | display: flex; 10 | flex: 1 0 auto; 11 | flex-direction: column; 12 | } 13 | 14 | .site__footer { 15 | border-top: 1px solid var(--borderColor); 16 | font-size: 0.85rem; 17 | padding: 15px; 18 | } 19 | 20 | .site__footer a { 21 | font-weight: normal; 22 | } 23 | 24 | .site__notificaton { 25 | background: #fff; 26 | border-bottom: 1px solid var(--borderColor); 27 | display: flex; 28 | font-size: 0.75rem; 29 | justify-content: space-between; 30 | padding: 15px; 31 | position: sticky; 32 | text-transform: uppercase; 33 | top: 0; 34 | z-index: 5; 35 | } 36 | -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | /// 2 | // *********************************************************** 3 | // This example plugins/index.js can be used to load plugins 4 | // 5 | // You can change the location of this file or turn off loading 6 | // the plugins file with the 'pluginsFile' configuration option. 7 | // 8 | // You can read more here: 9 | // https://on.cypress.io/plugins-guide 10 | // *********************************************************** 11 | 12 | // This function is called when a project is opened or re-opened (e.g. due to 13 | // the project's config changing) 14 | 15 | /** 16 | * @type {Cypress.PluginConfig} 17 | */ 18 | // eslint-disable-next-line no-unused-vars 19 | module.exports = (on, config) => { 20 | // `on` is used to hook into various events Cypress emits 21 | // `config` is the resolved Cypress config 22 | } 23 | -------------------------------------------------------------------------------- /src/component/suggestions/events.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | import { getImageDataFromImg, onImageLoaded, suggestedDownloadFilename } from '../utils' 3 | import { setImageData } from '../output/events' 4 | 5 | const imgPreviewElem = document.getElementById('js-input-preview') 6 | const downloadLink = document.getElementById('js-download-link') 7 | 8 | document.addEventListener('click', (evt) => { 9 | if (evt.target.closest('.suggestions__option')) { 10 | const button = evt.target.closest('.suggestions__option') 11 | const imgUrl = button.getAttribute('data-asset') 12 | 13 | downloadLink.setAttribute('download', suggestedDownloadFilename(imgUrl)) 14 | 15 | trySuggestion(imgUrl) 16 | } 17 | }) 18 | 19 | async function trySuggestion (imgUrl) { 20 | imgPreviewElem.src = imgUrl 21 | 22 | await onImageLoaded(imgPreviewElem) 23 | 24 | setImageData(getImageDataFromImg(imgPreviewElem)) 25 | } 26 | -------------------------------------------------------------------------------- /src/component/collapse/events.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | 3 | document.addEventListener('click', (evt) => { 4 | if (evt.target.closest('[aria-expanded]')) { 5 | const source = evt.target.closest('[aria-expanded]') 6 | const textElem = source.querySelector('[data-collapse-text]') 7 | const state = source.getAttribute('aria-expanded') 8 | const target = document.getElementById(source.getAttribute('aria-controls')) 9 | 10 | if (!(target instanceof HTMLElement)) { 11 | return 12 | } 13 | 14 | // Toggle State 15 | source.setAttribute('aria-expanded', state === 'false' ? 'true' : 'false') 16 | textElem.innerHTML = source.getAttribute(state === 'false' ? 'data-label-expanded' : 'data-label-collapse') 17 | 18 | if (state === 'false') { 19 | target.style.height = `${target.scrollHeight}px` 20 | return 21 | } 22 | 23 | // Close it 24 | target.style.height = 0 25 | } 26 | }) 27 | -------------------------------------------------------------------------------- /src/component/settings/state.js: -------------------------------------------------------------------------------- 1 | export class State { 2 | constructor () { 3 | this.state = { 4 | flipHorizontal: false, 5 | internalResolution: 'medium', 6 | segmentationThreshold: 0.7, 7 | backgroundColour: '#ffffff' 8 | } 9 | 10 | this.subscribers = new Set() 11 | } 12 | 13 | set (key, value) { 14 | if (!key || !(key in this.state)) { 15 | return false 16 | } 17 | 18 | value = this._transformValue(key, value) 19 | 20 | if (value === this.state[key]) { 21 | return false 22 | } 23 | 24 | this.state[key] = value 25 | 26 | this._notify() 27 | 28 | return true 29 | } 30 | 31 | _transformValue (key, value) { 32 | if (key === 'segmentationThreshold') { 33 | return parseFloat(value) 34 | } 35 | 36 | return value 37 | } 38 | 39 | _notify () { 40 | this.subscribers.forEach(callback => callback(this.state)) 41 | } 42 | } 43 | 44 | export default new State() 45 | -------------------------------------------------------------------------------- /src/component/settings/__tests__/state.js: -------------------------------------------------------------------------------- 1 | import state from '../state' 2 | 3 | describe('State test', () => { 4 | describe('state.set()', () => { 5 | afterEach(() => { 6 | // Reset state 7 | state.set('flipHorizontal', false) 8 | }) 9 | 10 | it('Should only allow to set value to known keys', () => { 11 | expect(state.set('RandomKey', 'yeye')).toBeFalsy() 12 | expect(state.set('flipHorizontal', true)).toBeTruthy() 13 | }) 14 | 15 | it('Should transform values to correct type', () => { 16 | state.set('segmentationThreshold', '0.5') 17 | expect(state.state.segmentationThreshold).toEqual(0.5) 18 | }) 19 | 20 | it('Should notify subscribers about any changes to state', () => { 21 | const listener = jest.fn() 22 | state.subscribers.add(listener) 23 | 24 | state.set('flipHorizontal', false) 25 | expect(listener).not.toBeCalled() 26 | 27 | state.set('flipHorizontal', true) 28 | expect(listener).toBeCalled() 29 | 30 | state.set('flipHorizontal', true) 31 | expect(listener).toHaveBeenCalledTimes(1) 32 | }) 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Junaid Ahmed 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | 3 | import * as tf from '@tensorflow/tfjs' 4 | import { setWasmPaths } from '@tensorflow/tfjs-backend-wasm' 5 | 6 | import BackgroundRemoval from './component/background-removal/background-removal' 7 | import AlertService from './component/alert/alert' 8 | 9 | import './component/core-css' 10 | import './component/input-source' 11 | import './component/settings' 12 | import './component/output' 13 | import './component/suggestions' 14 | import './component/collapse' 15 | 16 | async function main () { 17 | AlertService.init() 18 | 19 | tf.enableProdMode() 20 | setWasmPaths({ 21 | 'tfjs-backend-wasm.wasm': '/assets/tfjs-backend-wasm.wasm', 22 | 'tfjs-backend-wasm-simd.wasm': '/assets/tfjs-backend-wasm-simd.wasm', 23 | 'tfjs-backend-wasm-threaded-simd.wasm': '/assets/tfjs-backend-wasm-threaded-simd.wasm' 24 | }) 25 | await tf.setBackend('wasm') 26 | 27 | AlertService.announce('Loading Necessary image processing files.') 28 | const bgRemovalInstance = new BackgroundRemoval() 29 | await bgRemovalInstance.loadModel() 30 | 31 | AlertService.announce('Application is ready to use') 32 | } 33 | 34 | main() 35 | -------------------------------------------------------------------------------- /src/component/core-css/base-styles.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 16px; 3 | } 4 | 5 | html, 6 | body { 7 | background-color: var(--main-bg-color); 8 | color: var(--main-color); 9 | display: flex; 10 | flex-direction: column; 11 | font-family: var(--font); 12 | height: 100%; 13 | } 14 | 15 | h1 { 16 | font-size: 1.2rem; 17 | margin-bottom: 20px; 18 | text-transform: uppercase; 19 | } 20 | 21 | a { 22 | color: var(--brand); 23 | font-weight: bold; 24 | text-decoration: none; 25 | } 26 | 27 | a:focus, 28 | a:hover, 29 | a:active { 30 | text-decoration: underline; 31 | } 32 | 33 | a[aria-disabled] { 34 | color: rgba(0, 0, 0, 0.5); 35 | pointer-events: none; 36 | } 37 | 38 | button { 39 | appearance: none; 40 | background: var(--brand); 41 | border: 1px solid var(--brand); 42 | color: var(--brand-text); 43 | cursor: pointer; 44 | min-width: 150px; 45 | padding: 10px 20px; 46 | text-align: center; 47 | } 48 | 49 | button:focus, 50 | button:hover, 51 | button:active { 52 | background-color: var(--brand-highlight); 53 | } 54 | 55 | .button-transparent { 56 | background: transparent; 57 | border: 0; 58 | min-width: 70px; 59 | padding: 0; 60 | } 61 | 62 | label { 63 | display: block; 64 | font-size: 0.75rem; 65 | margin-bottom: 4px; 66 | text-transform: uppercase; 67 | } 68 | 69 | img { 70 | height: auto; 71 | } 72 | -------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm-threaded-simd.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | import {BackendWasmModule} from './tfjs-backend-wasm'; 19 | 20 | export interface BackendWasmThreadedSimdModule extends BackendWasmModule { 21 | PThread: { 22 | // Terminates all webworkers 23 | terminateAllThreads(): void, 24 | }; 25 | } 26 | 27 | export interface WasmFactoryConfig { 28 | mainScriptUrlOrBlob?: string|Blob; 29 | locateFile?(path: string, prefix: string): string; 30 | instantiateWasm?: Function; 31 | onRuntimeInitialized?: () => void; 32 | onAbort?: (msg: string) => void; 33 | } 34 | 35 | declare var moduleFactory: (settings: WasmFactoryConfig) => 36 | Promise; 37 | export default moduleFactory; 38 | -------------------------------------------------------------------------------- /src/component/core-css/reset.css: -------------------------------------------------------------------------------- 1 | /* Box sizing rules */ 2 | *, 3 | *::before, 4 | *::after { 5 | box-sizing: border-box; 6 | } 7 | 8 | /* Remove default padding */ 9 | ul[class], 10 | ol[class] { 11 | list-style: none; 12 | padding: 0; 13 | } 14 | 15 | /* Remove default margin */ 16 | body, 17 | h1, 18 | h2, 19 | h3, 20 | h4, 21 | p, 22 | ul[class], 23 | ol[class], 24 | li, 25 | figure, 26 | figcaption, 27 | blockquote, 28 | dl, 29 | dd { 30 | margin: 0; 31 | } 32 | 33 | /* Set core body defaults */ 34 | body { 35 | line-height: 1.5; 36 | min-height: 100vh; 37 | scroll-behavior: smooth; 38 | text-rendering: optimizeSpeed; 39 | } 40 | 41 | /* A elements that don't have a class get default styles */ 42 | a:not([class]) { 43 | text-decoration-skip-ink: auto; 44 | } 45 | 46 | /* Make images easier to work with */ 47 | img { 48 | display: block; 49 | max-width: 100%; 50 | } 51 | 52 | /* Natural flow and rhythm in articles by default */ 53 | article > * + * { 54 | margin-top: 1em; 55 | } 56 | 57 | /* Inherit fonts for inputs and buttons */ 58 | input, 59 | button, 60 | textarea, 61 | select { 62 | font: inherit; 63 | } 64 | 65 | /* Remove all animations and transitions for people that prefer not to see them */ 66 | @media (prefers-reduced-motion: reduce) { 67 | * { 68 | animation-duration: 0.01ms !important; 69 | animation-iteration-count: 1 !important; 70 | scroll-behavior: auto !important; 71 | transition-duration: 0.01ms !important; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/component/utils/index.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | 3 | export function hex2rgba (hex) { 4 | hex = hex.replace('#', '') 5 | 6 | const r = parseInt(hex.slice(0, 2), 16) 7 | const g = parseInt(hex.slice(2, 4), 16) 8 | const b = parseInt(hex.slice(4, 6), 16) 9 | 10 | return [ 11 | r, 12 | g, 13 | b, 14 | 255 15 | ] 16 | } 17 | 18 | export function getImageDataFromImg (imgElem) { 19 | const { width, height } = imgElem 20 | 21 | const canvas = document.createElement('canvas') 22 | const context = canvas.getContext('2d') 23 | 24 | canvas.width = width 25 | canvas.height = height 26 | 27 | context.drawImage(imgElem, 0, 0) 28 | 29 | return context.getImageData(0, 0, width, height) 30 | } 31 | 32 | export function loadImage (fileBlob) { 33 | const imgElem = new Image() 34 | imgElem.src = fileBlob 35 | 36 | return onImageLoaded(imgElem) 37 | } 38 | 39 | export function onImageLoaded (imgElem) { 40 | return new Promise((resolve, reject) => { 41 | imgElem.addEventListener('load', () => { 42 | resolve(imgElem) 43 | }, { once: true }) 44 | 45 | imgElem.addEventListener('error', (err) => { 46 | reject(err) 47 | }, { once: true }) 48 | }) 49 | } 50 | 51 | export function suggestedDownloadFilename (filename) { 52 | const extIndex = filename.split('/').pop().lastIndexOf('.') 53 | const postfix = '--with-background.png' 54 | 55 | if (extIndex === -1) { 56 | return `${filename}${postfix}` 57 | } 58 | 59 | return `${filename.substr(0, extIndex)}${postfix}` 60 | } 61 | -------------------------------------------------------------------------------- /.github/workflows/monthly-visual-testing.yml: -------------------------------------------------------------------------------- 1 | name: Refresh screenshots 2 | 3 | on: 4 | schedule: 5 | # Every 1st day of a month at 1am 6 | - cron: '0 1 1 * *' 7 | 8 | jobs: 9 | remove-old-artifacts: 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 10 12 | 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v2 16 | 17 | - name: Setup Nodejs 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: '14.x' 21 | 22 | - name: Cache node modules 23 | uses: actions/cache@v1 24 | env: 25 | cache-name: cache-node-modules 26 | with: 27 | path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS 28 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 29 | restore-keys: | 30 | ${{ runner.os }}-build-${{ env.cache-name }}- 31 | ${{ runner.os }}-build- 32 | ${{ runner.os }}- 33 | 34 | - name: Install Dependencies 35 | run: npm install 36 | 37 | - name: Build 38 | run: npm run build 39 | 40 | - name: Cypress run 41 | uses: cypress-io/github-action@v2 42 | with: 43 | record: true 44 | start: npm run start:serve 45 | wait-on: 'http://localhost:5000' 46 | command-prefix: 'percy exec -- npx' 47 | env: 48 | CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} 49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 50 | PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }} 51 | -------------------------------------------------------------------------------- /src/component/output/events.js: -------------------------------------------------------------------------------- 1 | /* istanbul ignore file */ 2 | 3 | import BackgroundRemoval from '../background-removal/background-removal' 4 | import { loadImage, getImageDataFromImg, suggestedDownloadFilename } from '../utils' 5 | import state from '../settings/state' 6 | import AlertService from '../alert/alert' 7 | 8 | const imgPickerElem = document.getElementById('js-image-picker') 9 | const imgOutputElem = document.getElementById('js-output-image') 10 | const downloadLink = document.getElementById('js-download-link') 11 | 12 | const bgRemovalInstance = new BackgroundRemoval() 13 | 14 | let imageData 15 | 16 | state.subscribers.add(updatePreview) 17 | 18 | imgPickerElem.addEventListener('change', async function () { 19 | const [selectedFile] = imgPickerElem.files 20 | 21 | downloadLink.setAttribute('download', suggestedDownloadFilename(selectedFile.name)) 22 | 23 | const imgElem = await loadImage(window.URL.createObjectURL(selectedFile)) 24 | imageData = getImageDataFromImg(imgElem) 25 | 26 | updatePreview() 27 | }) 28 | 29 | export function setImageData (data) { 30 | imageData = data 31 | updatePreview() 32 | } 33 | 34 | export function updatePreview () { 35 | if (!imageData) { 36 | return 37 | } 38 | 39 | AlertService.announce('Processing your image.') 40 | 41 | setTimeout(async () => { 42 | imgOutputElem.src = await bgRemovalInstance.remove(imageData, state.state) 43 | downloadLink.setAttribute('href', imgOutputElem.src) 44 | downloadLink.removeAttribute('aria-disabled') 45 | 46 | AlertService.announce('Image has been processed.') 47 | }, 0) 48 | } 49 | -------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | export interface BackendWasmModule extends EmscriptenModule { 19 | // Using the tfjs namespace to avoid conflict with emscripten's API. 20 | tfjs: { 21 | init(): void, 22 | registerTensor(id: number, size: number, memoryOffset: number): void, 23 | // Disposes the data behind the data bucket. 24 | disposeData(id: number): void, 25 | // Disposes the backend and all of its associated data. 26 | dispose(): void, 27 | } 28 | } 29 | 30 | export interface WasmFactoryConfig { 31 | mainScriptUrlOrBlob?: string|Blob; 32 | locateFile?(path: string, prefix: string): string; 33 | instantiateWasm?: Function; 34 | onRuntimeInitialized?: () => void; 35 | onAbort?: (msg: string) => void; 36 | } 37 | 38 | declare var moduleFactory: (settings: WasmFactoryConfig) => 39 | Promise; 40 | export default moduleFactory; 41 | -------------------------------------------------------------------------------- /cypress/integration/application.spec.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | const messages = { 4 | READY: 'Application is ready to use', 5 | PROCESS_STARTED: 'Processing your image.', 6 | PROCESS_FINISHED: 'Image has been processed.' 7 | } 8 | 9 | describe('BackgroundRemove Application', () => { 10 | it('As a User I should be able to visit application', function () { 11 | cy.visit(Cypress.env('CYPRESS_BASE_URL')) 12 | cy.percySnapshot() 13 | }) 14 | 15 | it('Should inform me when application is ready to use', function () { 16 | cy.contains(messages.READY) 17 | cy.percySnapshot() 18 | }) 19 | 20 | it('As a User I should be able to select an image from my machine to remove Background', function () { 21 | cy.get('#js-image-picker').attachFile('adult-1868750_1920.jpg') 22 | 23 | cy.contains(messages.PROCESS_STARTED) 24 | cy.contains(messages.PROCESS_FINISHED) 25 | cy.percySnapshot() 26 | }) 27 | 28 | it('Should be able to pick suggested image from provided options', function () { 29 | cy.get('.suggestions__option').eq(2).click() 30 | 31 | cy.contains(messages.PROCESS_FINISHED) 32 | cy.percySnapshot() 33 | }) 34 | 35 | it('Should be able to interact with advance options', function () { 36 | cy.get('#internalResolution').should('not.be.visible') 37 | cy.get('[aria-controls="advance-options"]').click() 38 | cy.get('#internalResolution').should('be.visible') 39 | cy.percySnapshot() 40 | 41 | cy.get('[aria-controls="advance-options"]').click() 42 | cy.get('#internalResolution').should('not.be.visible') 43 | cy.percySnapshot() 44 | }) 45 | 46 | it('Should be able to specify background colour for processed image', function () { 47 | cy.get('[aria-controls="advance-options"]').click() 48 | cy.get('#backgroundColour').invoke('val', '#ff0000').trigger('change') 49 | 50 | cy.contains(messages.PROCESS_FINISHED) 51 | cy.percySnapshot() 52 | }) 53 | 54 | it('Should be able to download processed image', function () { 55 | cy.get('#js-download-link').click() 56 | cy.percySnapshot() 57 | }) 58 | }) 59 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI/CD 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | types: [opened, synchronize, reopened] 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v2 17 | 18 | - name: Setup Nodejs 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: '14.x' 22 | 23 | - name: Cache node modules 24 | uses: actions/cache@v1 25 | env: 26 | cache-name: cache-node-modules 27 | with: 28 | path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS 29 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} 30 | restore-keys: | 31 | ${{ runner.os }}-build-${{ env.cache-name }}- 32 | ${{ runner.os }}-build- 33 | ${{ runner.os }}- 34 | 35 | - name: Install Dependencies 36 | run: npm install 37 | 38 | - name: Test 39 | run: npm run test:coverage 40 | 41 | - name: Upload coverage to Codecov 42 | uses: codecov/codecov-action@v1 43 | with: 44 | token: ${{ secrets.CODECOV_TOKEN }} 45 | flags: unittests 46 | name: codecov-umbrella 47 | fail_ci_if_error: true 48 | 49 | - name: Build 50 | run: npm run build 51 | 52 | - name: Cypress run 53 | uses: cypress-io/github-action@v2 54 | with: 55 | record: true 56 | start: npm run start:serve 57 | wait-on: 'http://localhost:5000' 58 | command-prefix: 'percy exec -- npx' 59 | env: 60 | CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} 61 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 62 | PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }} 63 | 64 | - name: Deployment 65 | if: ${{ github.ref == 'refs/heads/main' }} 66 | uses: FirebaseExtended/action-hosting-deploy@v0 67 | with: 68 | repoToken: '${{ secrets.GITHUB_TOKEN }}' 69 | firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_TENSORFLOWJS_REMOVE_BACKGROUND }}' 70 | channelId: live 71 | projectId: tensorflowjs-remove-background 72 | -------------------------------------------------------------------------------- /webpack.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const { CleanWebpackPlugin } = require("clean-webpack-plugin"); 3 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 5 | const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); 6 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 7 | const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin'); 8 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 9 | 10 | const plugins = [ 11 | new CleanWebpackPlugin({}), 12 | 13 | new MiniCssExtractPlugin({ 14 | filename: '[name].[contenthash].css' 15 | }), 16 | 17 | new HtmlWebpackPlugin({ 18 | template: 'public/index.html' 19 | }), 20 | 21 | new PreloadWebpackPlugin({ 22 | rel: 'preload', 23 | include: 'all' 24 | }), 25 | 26 | new CopyWebpackPlugin({ 27 | patterns: [{ 28 | from: path.resolve(__dirname, 'public', 'assets'), 29 | to: path.resolve(__dirname, 'dist', 'assets') 30 | }] 31 | }) 32 | ] 33 | 34 | if (process.env.BUNDLE_ANALYZE) { 35 | plugins.push(new BundleAnalyzerPlugin()) 36 | } 37 | 38 | module.exports = { 39 | mode: "development", 40 | entry: { 41 | main: "./src/index.js", 42 | }, 43 | output: { 44 | filename: "[name].[contenthash].js", 45 | path: path.resolve(__dirname, "dist") 46 | }, 47 | devServer: { 48 | historyApiFallback: true, 49 | disableHostCheck: true, 50 | stats: "minimal", 51 | contentBase: path.join(__dirname, 'public'), 52 | compress: true, 53 | open: true, 54 | hot: true 55 | }, 56 | target: 'web', 57 | resolve: { 58 | fallback: { 59 | "os": false 60 | } 61 | }, 62 | module: { 63 | rules: [ 64 | { 65 | test: /\.m?js$/, 66 | exclude: /(node_modules|bower_components)/, 67 | use: { 68 | loader: 'babel-loader', 69 | options: require("./.babelrc") 70 | } 71 | }, 72 | { 73 | test: /\.css$/, 74 | use: [ 75 | { 76 | loader: MiniCssExtractPlugin.loader 77 | }, 78 | 'css-loader', 79 | 'postcss-loader' 80 | ] 81 | } 82 | ] 83 | }, 84 | optimization: { 85 | minimizer: [ 86 | new CssMinimizerPlugin(), 87 | ], 88 | }, 89 | externals: { 90 | firebase: 'firebase', 91 | }, 92 | plugins 93 | }; 94 | -------------------------------------------------------------------------------- /src/component/background-removal/background-removal.js: -------------------------------------------------------------------------------- 1 | import * as bodyPix from '@tensorflow-models/body-pix' 2 | import { hex2rgba } from '../utils' 3 | 4 | const defaultBodyPixConfig = { 5 | flipHorizontal: false, 6 | internalResolution: 'full', 7 | segmentationThreshold: 0.7, 8 | backgroundColour: '#ffffff' 9 | } 10 | 11 | export default class BackgroundRemoval { 12 | constructor () { 13 | this.model = null 14 | } 15 | 16 | async remove (imgData, newConfig = {}) { 17 | const { width, height } = imgData 18 | const config = { ...defaultBodyPixConfig, ...newConfig } 19 | 20 | await this.loadModel() 21 | 22 | const predictedImgData = await this._predict(imgData, config) 23 | const rawImageData = await this._intersectPixels(imgData, predictedImgData, config.backgroundColour) 24 | 25 | const canvas = document.createElement('canvas') 26 | canvas.setAttribute('width', width) 27 | canvas.setAttribute('height', height) 28 | 29 | const ctx = canvas.getContext('2d') 30 | 31 | const imageData = ctx.createImageData(width, height) 32 | for (let i = 0; i < imageData.data.length; i++) { 33 | imageData.data[i] = rawImageData.data[i] 34 | } 35 | 36 | ctx.putImageData(imageData, 0, 0) 37 | 38 | return canvas.toDataURL() 39 | } 40 | 41 | async loadModel () { 42 | if (this.model) { 43 | return this.model 44 | } 45 | 46 | this.model = await bodyPix.load() 47 | 48 | return this.model 49 | } 50 | 51 | async _predict (imgData, config = {}) { 52 | await this.loadModel() 53 | 54 | return this.model.segmentPerson(imgData, config) 55 | } 56 | 57 | async _intersectPixels (imgData, predictedImgData, backgroundColour = '#ffffff') { 58 | const { width, height } = imgData 59 | const [r, g, b, a] = hex2rgba(backgroundColour) 60 | 61 | const newImageData = { 62 | width, 63 | height, 64 | data: new Uint8ClampedArray(width * height * 4) 65 | } 66 | 67 | for (let index = 0; index < (width * height * 4); index += 4) { 68 | // Use a background colour specified by user 69 | const isBody = predictedImgData.data[index / 4] > 0 70 | 71 | newImageData.data[index] = isBody ? imgData.data[index] : r 72 | newImageData.data[index + 1] = isBody ? imgData.data[index + 1] : g 73 | newImageData.data[index + 2] = isBody ? imgData.data[index + 2] : b 74 | newImageData.data[index + 3] = isBody ? imgData.data[index + 3] : a 75 | } 76 | 77 | return newImageData 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # tensorflowjs-remove-background 2 | ![CI/CD](https://github.com/poly-glot/tensorflowjs-remove-background/workflows/CI/CD/badge.svg) 3 | [![codecov](https://codecov.io/gh/poly-glot/tensorflowjs-remove-background/branch/master/graph/badge.svg)](https://codecov.io/gh/poly-glot/tensorflowjs-remove-background) 4 | [![This project is using Percy.io for visual regression testing.](https://percy.io/static/images/percy-badge.svg)](https://percy.io/328a6753/tensorflowjs-remove-background) 5 | [![Cypress.io Dashboard](https://img.shields.io/badge/cypress-dashboard-brightgreen.svg)](https://dashboard.cypress.io/projects/jp2thc/runs) 6 | [![DeepScan grade](https://deepscan.io/api/teams/8408/projects/10623/branches/149386/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=8408&pid=10623&bid=149386) 7 | [![Maintainability](https://api.codeclimate.com/v1/badges/e9ab18c4667689e347de/maintainability)](https://codeclimate.com/github/poly-glot/tensorflowjs-remove-background/maintainability) 8 | [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/poly-glot/tensorflowjs-remove-background) 9 | 10 | Remove Background from the picture using WebAssembly & TensorFlow.js 11 | 12 | # Getting Started 13 | ``` 14 | npm install 15 | npm start 16 | ``` 17 | 18 | ## Demonstration 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
CanvasHow to manipulate ImageData to build a new image.
CanvasSave Canvas image.
SEOExcluding Unwanted Text from the Google Index <!--googleoff: index-->
HTMLUse referrerpolicy="no-referrer" to disable hotlink protection.
HTMLUse accept attribute e.g. accept=".jpg,.png,.jpeg" to allow users to select required file type.
JSHandle events using Event Bubbling.
AccessibilityA small & Accessible Collapse implementation.
49 | 50 | # Browser Support 51 | 2 most recent versions of Chrome, Firefox, Safari & MS Edge. 52 | -------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm-threaded-simd.worker.js: -------------------------------------------------------------------------------- 1 | export const wasmWorkerContents = 'var Module={};function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;this.alert=threadAlert;Module["instantiateWasm"]=function(info,receiveInstance){var instance=new WebAssembly.Instance(Module["wasmModule"],info);Module["wasmModule"]=null;receiveInstance(instance);return instance.exports};function moduleLoaded(){}this.onmessage=function(e){try{if(e.data.cmd==="load"){Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}WasmBackendModuleThreadedSimd(Module).then(function(instance){Module=instance;moduleLoaded()})}else if(e.data.cmd==="objectTransfer"){Module["PThread"].receiveObjectTransfer(e.data)}else if(e.data.cmd==="run"){Module["__performance_now_clock_drift"]=performance.now()-e.data.time;Module["__emscripten_thread_init"](e.data.threadInfoStruct,0,0);var max=e.data.stackBase;var top=e.data.stackBase+e.data.stackSize;Module["establishStackSpace"](top,max);Module["_emscripten_tls_init"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].setThreadStatus(Module["_pthread_self"](),1);try{var result=Module["invokeEntryPoint"](e.data.start_routine,e.data.arg);if(!Module["getNoExitRuntime"]())Module["PThread"].threadExit(result)}catch(ex){if(ex==="Canceled!"){Module["PThread"].threadCancel()}else if(ex!="unwind"){if(ex instanceof Module["ExitStatus"]){if(Module["getNoExitRuntime"]()){}else{Module["PThread"].threadExit(ex.status)}}else{Module["PThread"].threadExit(-2);throw ex}}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["PThread"].threadCancel()}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="processThreadQueue"){if(Module["_pthread_self"]()){Module["_emscripten_current_thread_process_queued_calls"]()}}else{err("worker.js received unknown command "+e.data.cmd);err(e.data)}}catch(ex){err("worker.js onmessage() captured an uncaught exception: "+ex);if(ex&&ex.stack)err(ex.stack);throw ex}};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){self={location:{href:__filename}};var onmessage=this.onmessage;var nodeWorkerThreads=require("worker_threads");global.Worker=nodeWorkerThreads.Worker;var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");var nodeRead=function(filename){return nodeFS.readFileSync(filename,"utf8")};function globalEval(x){global.require=require;global.Module=Module;eval.call(null,x)}importScripts=function(f){globalEval(nodeRead(f))};postMessage=function(msg){parentPort.postMessage(msg)};if(typeof performance==="undefined"){performance={now:function(){return Date.now()}}}}'; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tensorflowjs-remove-background", 3 | "version": "2.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest", 8 | "test:coverage": "jest --coverage", 9 | "cy:open": "cypress open", 10 | "cy:run": "cypress run", 11 | "percy": "percy exec -- npm run cy:run", 12 | "start": "webpack serve --config webpack.js --mode development --progress --devtool hidden-nosources-source-map", 13 | "start:serve": "serve -s ./dist", 14 | "build": "webpack --config webpack.js --mode production", 15 | "lint:js": "eslint src/ --fix", 16 | "lint:css": "stylelint --fix src/**/*.css", 17 | "precommit": "lint-staged" 18 | }, 19 | "author": "", 20 | "license": "MIT", 21 | "dependencies": { 22 | "@tensorflow-models/body-pix": "^2.2.0", 23 | "@tensorflow/tfjs": "^3.7.0", 24 | "@tensorflow/tfjs-backend-wasm": "^3.7.0" 25 | }, 26 | "devDependencies": { 27 | "@babel/core": "^7.14.6", 28 | "@babel/eslint-parser": "^7.14.5", 29 | "@babel/eslint-plugin": "^7.14.5", 30 | "@babel/plugin-proposal-class-properties": "^7.14.5", 31 | "@babel/plugin-proposal-object-rest-spread": "^7.14.5", 32 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 33 | "@babel/preset-env": "^7.14.5", 34 | "@percy/cli": "^1.0.0-beta.58", 35 | "@percy/cypress": "^3.1.0", 36 | "@vue/preload-webpack-plugin": "^2.0.0", 37 | "babel-jest": "^27.0.2", 38 | "babel-loader": "^8.2.2", 39 | "babel-plugin-transform-runtime": "^6.23.0", 40 | "babel-polyfill": "^6.26.0", 41 | "canvas": "^2.8.0", 42 | "clean-webpack-plugin": "^4.0.0-alpha.0", 43 | "copy-webpack-plugin": "^9.0.0", 44 | "css-loader": "^5.2.6", 45 | "css-minimizer-webpack-plugin": "^3.0.1", 46 | "cssnano": "^5.0.6", 47 | "cypress": "^7.6.0", 48 | "cypress-file-upload": "^5.0.8", 49 | "enzyme": "^3.11.0", 50 | "enzyme-adapter-react-16": "^1.15.6", 51 | "eslint": "^7.28.0", 52 | "eslint-config-standard": "^16.0.3", 53 | "eslint-plugin-import": "^2.23.4", 54 | "eslint-plugin-node": "^11.1.0", 55 | "eslint-plugin-promise": "^5.1.0", 56 | "eslint-plugin-standard": "^5.0.0", 57 | "html-webpack-plugin": "^5.3.1", 58 | "husky": "^6.0.0", 59 | "jest": "^27.0.4", 60 | "lint-staged": "^11.0.0", 61 | "mini-css-extract-plugin": "^1.6.0", 62 | "postcss": "^8.3.5", 63 | "postcss-loader": "^5.3.0", 64 | "postcss-preset-env": "^6.7.0", 65 | "react": "^17.0.2", 66 | "react-dom": "^17.0.2", 67 | "serve": "^12.0.0", 68 | "sonarqube-scanner": "^2.8.1", 69 | "style-loader": "^2.0.0", 70 | "stylelint": "^13.13.1", 71 | "stylelint-config-standard": "^22.0.0", 72 | "stylelint-order": "^4.1.0", 73 | "webpack": "^5.39.1", 74 | "webpack-bundle-analyzer": "^4.4.2", 75 | "webpack-cli": "^4.7.2", 76 | "webpack-dev-server": "^3.11.2" 77 | }, 78 | "jest": { 79 | "testEnvironment": "jsdom", 80 | "setupFiles": [ 81 | "/setup-jest.js" 82 | ], 83 | "setupFilesAfterEnv": [ 84 | "/setup-tests.js" 85 | ], 86 | "coverageReporters": [ 87 | "html", 88 | "clover" 89 | ], 90 | "collectCoverageFrom": [ 91 | "src/**/*.js" 92 | ], 93 | "testPathIgnorePatterns": [ 94 | "/.history", 95 | "/cypress" 96 | ], 97 | "moduleNameMapper": { 98 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/__mocks__/fileMock.js", 99 | "\\.(css|less)$": "/__mocks__/styleMock.js" 100 | } 101 | }, 102 | "browserslist": [ 103 | "last 2 chrome versions", 104 | "last 2 safari versions" 105 | ], 106 | "husky": { 107 | "hooks": { 108 | "pre-commit": "npm run precommit", 109 | "pre-push": "npm test" 110 | } 111 | }, 112 | "engines": { 113 | "node": "^14.15.0" 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/component/background-removal/__tests__/background-removal.js: -------------------------------------------------------------------------------- 1 | import * as bodyPix from '@tensorflow-models/body-pix' 2 | import BackgroundRemoval from '../background-removal' 3 | 4 | jest.mock('@tensorflow-models/body-pix', () => { 5 | return { 6 | load: jest.fn() 7 | } 8 | }) 9 | 10 | describe('BackgroundRemoval test', () => { 11 | let instance 12 | 13 | beforeEach(() => { 14 | instance = new BackgroundRemoval() 15 | }) 16 | 17 | describe('BackgroundRemoval.loadModel()', () => { 18 | beforeEach(() => { 19 | jest.spyOn(bodyPix, 'load').mockResolvedValue('body-pix-object') 20 | }) 21 | 22 | it('Should exists', () => { 23 | expect(instance.loadModel).toBeTruthy() 24 | }) 25 | 26 | it('Should load & return bodyPix model', () => { 27 | expect(instance.loadModel()).resolves.toEqual('body-pix-object') 28 | }) 29 | 30 | it('Should only call bodyPix once', async () => { 31 | await instance.loadModel() 32 | await instance.loadModel() 33 | await instance.loadModel() 34 | 35 | expect(bodyPix.load.mock.calls.length).toEqual(1) 36 | }) 37 | }) 38 | 39 | describe('BackgroundRemoval._predict()', () => { 40 | const mockBodyPix = { 41 | segmentPerson: jest.fn() 42 | } 43 | 44 | beforeEach(() => { 45 | jest.spyOn(bodyPix, 'load').mockResolvedValue(mockBodyPix) 46 | }) 47 | 48 | it('Should exists', () => { 49 | expect(instance._predict).toBeTruthy() 50 | }) 51 | 52 | it('Should pass arguments to bodyPix', async () => { 53 | const imgData = 'imgData' 54 | const config = 'config' 55 | await instance._predict(imgData, config) 56 | 57 | expect(mockBodyPix.segmentPerson).toBeCalled() 58 | expect(mockBodyPix.segmentPerson).toBeCalledWith(imgData, config) 59 | }) 60 | }) 61 | 62 | describe('BackgroundRemoval._intersectPixels()', () => { 63 | const backgroundColour = '#0000ff' // blue 64 | 65 | it('Given I have 1x1 image and segment identified pixel as a body then return image body pixel', async () => { 66 | const imgData = { 67 | width: 1, 68 | height: 1, 69 | data: [ 70 | 255, 255, 255, 255 // white 71 | ] 72 | } 73 | 74 | const predictedSegmentPixelData = { 75 | width: 1, 76 | height: 1, 77 | data: [ 78 | 1 // match 79 | ] 80 | } 81 | 82 | const expected = { 83 | width: 1, 84 | height: 1, 85 | data: Uint8ClampedArray.from([ 86 | 255, 255, 255, 255 87 | ]) 88 | } 89 | 90 | const actual = await instance._intersectPixels(imgData, predictedSegmentPixelData, backgroundColour) 91 | 92 | expect(actual).toEqual(expected) 93 | }) 94 | 95 | it('Given I have 1x2 image then intersect the identified body with given image and replace other pixel by given background colour', async () => { 96 | const imgData = { 97 | width: 1, 98 | height: 2, 99 | data: [ 100 | 255, 255, 255, 255, // white 101 | 255, 0, 0, 255 // red 102 | ] 103 | } 104 | 105 | const predictedSegmentPixelData = { 106 | width: 1, 107 | height: 2, 108 | data: [ 109 | 0, // ignore 110 | 1 // match 111 | ] 112 | } 113 | 114 | const expected = { 115 | width: 1, 116 | height: 2, 117 | data: Uint8ClampedArray.from([ 118 | 0, 0, 255, 255, // blue 119 | 255, 0, 0, 255 // red 120 | ]) 121 | } 122 | 123 | const actual = await instance._intersectPixels(imgData, predictedSegmentPixelData, backgroundColour) 124 | 125 | expect(actual).toEqual(expected) 126 | }) 127 | 128 | it('Given I have 2x2 image then intersect the identified body with given image and replace other pixel by given background colour', async () => { 129 | const imgData = { 130 | width: 2, 131 | height: 2, 132 | data: [ 133 | 255, 255, 255, 255, // white 134 | 255, 0, 0, 255, // red 135 | 255, 0, 0, 255, // red 136 | 255, 255, 255, 255 // white 137 | ] 138 | } 139 | 140 | const predictedSegmentPixelData = { 141 | width: 2, 142 | height: 2, 143 | data: [ 144 | 0, // ignore 145 | 0, // ignore 146 | 1, // match 147 | 0 // ignore 148 | ] 149 | } 150 | 151 | const expected = { 152 | width: 2, 153 | height: 2, 154 | data: Uint8ClampedArray.from([ 155 | 0, 0, 255, 255, // ignore 156 | 0, 0, 255, 255, // ignore 157 | 255, 0, 0, 255, // red from imgData 158 | 0, 0, 255, 255 // ignore 159 | ]) 160 | } 161 | 162 | const actual = await instance._intersectPixels(imgData, predictedSegmentPixelData, backgroundColour) 163 | 164 | expect(actual).toEqual(expected) 165 | }) 166 | }) 167 | 168 | describe('BackgroundRemoval.remove(imgData, config)', () => { 169 | const imgData = { 170 | width: 1, 171 | height: 1, 172 | data: Uint8ClampedArray.from([ 173 | 255, 255, 255, 255 // white 174 | ]) 175 | } 176 | 177 | beforeEach(() => { 178 | jest.spyOn(instance, 'loadModel').mockResolvedValue('') 179 | jest.spyOn(instance, '_predict').mockResolvedValue('') 180 | jest.spyOn(instance, '_intersectPixels').mockResolvedValue(imgData) 181 | }) 182 | 183 | it('Should return data URI to be used by img element', async () => { 184 | const actual = await instance.remove(imgData, {}) 185 | expect(actual).toEqual(expect.stringContaining('data:image/png;')) 186 | }) 187 | }) 188 | }) 189 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Remove Background from the picture using WebAssembly & TensorFlow.js 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 39 |
40 | 41 |
42 | 43 | Download 44 |
45 | 46 | 47 |
48 |
49 |

Input Image

50 | 51 |
52 |
53 | Input source 54 |
55 |
56 |
57 |
58 | 59 | 60 |
61 |
62 |
63 |

64 | No image?
65 | Try one of these: 66 |

67 | 68 |
69 | 70 | 73 | 76 | 79 |
80 |
81 | 82 | 87 |
88 |
89 |
90 |
91 | 92 | 98 |
99 |
100 | 101 | 102 |
103 |
104 | 105 | 106 |
107 |
108 |
109 | 110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |

Output Image without Background

118 |
119 |
120 | Out put image without background image. 121 |
122 |
123 |
124 |
125 |
126 | 127 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /public/assets/diagram.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 |




Input Source
Input Source
Images provided by Suggestion Widget
Images provided by Suggestion...
Image uploaded by User
Image uploaded by User
Canvas Processing
Canvas Processing
Remove Browser Sandbox Restriction by cloning file into IMG element
Remove Browser Sandbox Restri...
onImageLoaded
onImageLoaded
BackgroundImage Service
BackgroundImage Service
Remove()
Remove()
predict pixels of human body in provided image
predict pixels of human b...
Copy predicted pixels from original image input source to compose a new image
Copy predicted pixels fro...
TensorFlow
TensorFlow
_segmentPerson
_segmentPerson
Output Preview
Output Preview
UpdatePreview
UpdatePreview
Update Preview Image
Update Preview Image
Viewer does not support full SVG 1.1
-------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm.js: -------------------------------------------------------------------------------- 1 | 2 | var WasmBackendModule = (function() { 3 | var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; 4 | if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; 5 | return ( 6 | function(WasmBackendModule) { 7 | WasmBackendModule = WasmBackendModule || {}; 8 | 9 | var Module=typeof WasmBackendModule!=="undefined"?WasmBackendModule:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;__ATINIT__.push({func:function(){___wasm_call_ctors()}});function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="tfjs-backend-wasm.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["i"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["o"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function _abort(){abort()}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},get64:function(low,high){return low}};function _fd_close(fd){return 0}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];for(var j=0;j>2]=num;return 0}function _pthread_create(){return 6}function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}function _sysconf(name){switch(name){case 30:return 16384;case 85:var maxHeapSize=2147483648;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:case 80:case 81:case 79:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}var asmLibraryArg={"a":_abort,"d":_emscripten_memcpy_big,"e":_emscripten_resize_heap,"f":_fd_close,"c":_fd_seek,"b":_fd_write,"g":_pthread_create,"h":_sysconf};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["j"]).apply(null,arguments)};var _init=Module["_init"]=function(){return(_init=Module["_init"]=Module["asm"]["k"]).apply(null,arguments)};var _register_tensor=Module["_register_tensor"]=function(){return(_register_tensor=Module["_register_tensor"]=Module["asm"]["l"]).apply(null,arguments)};var _dispose_data=Module["_dispose_data"]=function(){return(_dispose_data=Module["_dispose_data"]=Module["asm"]["m"]).apply(null,arguments)};var _dispose=Module["_dispose"]=function(){return(_dispose=Module["_dispose"]=Module["asm"]["n"]).apply(null,arguments)};var _Abs=Module["_Abs"]=function(){return(_Abs=Module["_Abs"]=Module["asm"]["p"]).apply(null,arguments)};var _Add=Module["_Add"]=function(){return(_Add=Module["_Add"]=Module["asm"]["q"]).apply(null,arguments)};var _AddN=Module["_AddN"]=function(){return(_AddN=Module["_AddN"]=Module["asm"]["r"]).apply(null,arguments)};var _All=Module["_All"]=function(){return(_All=Module["_All"]=Module["asm"]["s"]).apply(null,arguments)};var _Any=Module["_Any"]=function(){return(_Any=Module["_Any"]=Module["asm"]["t"]).apply(null,arguments)};var _ArgMax=Module["_ArgMax"]=function(){return(_ArgMax=Module["_ArgMax"]=Module["asm"]["u"]).apply(null,arguments)};var _AvgPool=Module["_AvgPool"]=function(){return(_AvgPool=Module["_AvgPool"]=Module["asm"]["v"]).apply(null,arguments)};var _BatchMatMul=Module["_BatchMatMul"]=function(){return(_BatchMatMul=Module["_BatchMatMul"]=Module["asm"]["w"]).apply(null,arguments)};var _Ceil=Module["_Ceil"]=function(){return(_Ceil=Module["_Ceil"]=Module["asm"]["x"]).apply(null,arguments)};var _ClipByValue=Module["_ClipByValue"]=function(){return(_ClipByValue=Module["_ClipByValue"]=Module["asm"]["y"]).apply(null,arguments)};var _Conv2D=Module["_Conv2D"]=function(){return(_Conv2D=Module["_Conv2D"]=Module["asm"]["z"]).apply(null,arguments)};var _Conv2DBackpropInput=Module["_Conv2DBackpropInput"]=function(){return(_Conv2DBackpropInput=Module["_Conv2DBackpropInput"]=Module["asm"]["A"]).apply(null,arguments)};var _Cos=Module["_Cos"]=function(){return(_Cos=Module["_Cos"]=Module["asm"]["B"]).apply(null,arguments)};var _CropAndResize=Module["_CropAndResize"]=function(){return(_CropAndResize=Module["_CropAndResize"]=Module["asm"]["C"]).apply(null,arguments)};var _Cumsum=Module["_Cumsum"]=function(){return(_Cumsum=Module["_Cumsum"]=Module["asm"]["D"]).apply(null,arguments)};var _DepthToSpace=Module["_DepthToSpace"]=function(){return(_DepthToSpace=Module["_DepthToSpace"]=Module["asm"]["E"]).apply(null,arguments)};var _DepthwiseConv2dNative=Module["_DepthwiseConv2dNative"]=function(){return(_DepthwiseConv2dNative=Module["_DepthwiseConv2dNative"]=Module["asm"]["F"]).apply(null,arguments)};var _Equal=Module["_Equal"]=function(){return(_Equal=Module["_Equal"]=Module["asm"]["G"]).apply(null,arguments)};var _Exp=Module["_Exp"]=function(){return(_Exp=Module["_Exp"]=Module["asm"]["H"]).apply(null,arguments)};var _FlipLeftRight=Module["_FlipLeftRight"]=function(){return(_FlipLeftRight=Module["_FlipLeftRight"]=Module["asm"]["I"]).apply(null,arguments)};var _Floor=Module["_Floor"]=function(){return(_Floor=Module["_Floor"]=Module["asm"]["J"]).apply(null,arguments)};var _FloorDiv=Module["_FloorDiv"]=function(){return(_FloorDiv=Module["_FloorDiv"]=Module["asm"]["K"]).apply(null,arguments)};var _FusedBatchNorm=Module["_FusedBatchNorm"]=function(){return(_FusedBatchNorm=Module["_FusedBatchNorm"]=Module["asm"]["L"]).apply(null,arguments)};var _FusedConv2D=Module["_FusedConv2D"]=function(){return(_FusedConv2D=Module["_FusedConv2D"]=Module["asm"]["M"]).apply(null,arguments)};var _FusedDepthwiseConv2D=Module["_FusedDepthwiseConv2D"]=function(){return(_FusedDepthwiseConv2D=Module["_FusedDepthwiseConv2D"]=Module["asm"]["N"]).apply(null,arguments)};var _Gather=Module["_Gather"]=function(){return(_Gather=Module["_Gather"]=Module["asm"]["O"]).apply(null,arguments)};var _GatherNd=Module["_GatherNd"]=function(){return(_GatherNd=Module["_GatherNd"]=Module["asm"]["P"]).apply(null,arguments)};var _Greater=Module["_Greater"]=function(){return(_Greater=Module["_Greater"]=Module["asm"]["Q"]).apply(null,arguments)};var _GreaterEqual=Module["_GreaterEqual"]=function(){return(_GreaterEqual=Module["_GreaterEqual"]=Module["asm"]["R"]).apply(null,arguments)};var _LeakyRelu=Module["_LeakyRelu"]=function(){return(_LeakyRelu=Module["_LeakyRelu"]=Module["asm"]["S"]).apply(null,arguments)};var _Less=Module["_Less"]=function(){return(_Less=Module["_Less"]=Module["asm"]["T"]).apply(null,arguments)};var _LessEqual=Module["_LessEqual"]=function(){return(_LessEqual=Module["_LessEqual"]=Module["asm"]["U"]).apply(null,arguments)};var _Log=Module["_Log"]=function(){return(_Log=Module["_Log"]=Module["asm"]["V"]).apply(null,arguments)};var _LogicalAnd=Module["_LogicalAnd"]=function(){return(_LogicalAnd=Module["_LogicalAnd"]=Module["asm"]["W"]).apply(null,arguments)};var _Max=Module["_Max"]=function(){return(_Max=Module["_Max"]=Module["asm"]["X"]).apply(null,arguments)};var _MaxPool=Module["_MaxPool"]=function(){return(_MaxPool=Module["_MaxPool"]=Module["asm"]["Y"]).apply(null,arguments)};var _Maximum=Module["_Maximum"]=function(){return(_Maximum=Module["_Maximum"]=Module["asm"]["Z"]).apply(null,arguments)};var _Mean=Module["_Mean"]=function(){return(_Mean=Module["_Mean"]=Module["asm"]["_"]).apply(null,arguments)};var _Min=Module["_Min"]=function(){return(_Min=Module["_Min"]=Module["asm"]["$"]).apply(null,arguments)};var _Minimum=Module["_Minimum"]=function(){return(_Minimum=Module["_Minimum"]=Module["asm"]["aa"]).apply(null,arguments)};var _MirrorPad=Module["_MirrorPad"]=function(){return(_MirrorPad=Module["_MirrorPad"]=Module["asm"]["ba"]).apply(null,arguments)};var _Multiply=Module["_Multiply"]=function(){return(_Multiply=Module["_Multiply"]=Module["asm"]["ca"]).apply(null,arguments)};var _Neg=Module["_Neg"]=function(){return(_Neg=Module["_Neg"]=Module["asm"]["da"]).apply(null,arguments)};var _NonMaxSuppressionV3=Module["_NonMaxSuppressionV3"]=function(){return(_NonMaxSuppressionV3=Module["_NonMaxSuppressionV3"]=Module["asm"]["ea"]).apply(null,arguments)};var _NonMaxSuppressionV4=Module["_NonMaxSuppressionV4"]=function(){return(_NonMaxSuppressionV4=Module["_NonMaxSuppressionV4"]=Module["asm"]["fa"]).apply(null,arguments)};var _NonMaxSuppressionV5=Module["_NonMaxSuppressionV5"]=function(){return(_NonMaxSuppressionV5=Module["_NonMaxSuppressionV5"]=Module["asm"]["ga"]).apply(null,arguments)};var _NotEqual=Module["_NotEqual"]=function(){return(_NotEqual=Module["_NotEqual"]=Module["asm"]["ha"]).apply(null,arguments)};var _OneHot=Module["_OneHot"]=function(){return(_OneHot=Module["_OneHot"]=Module["asm"]["ia"]).apply(null,arguments)};var _PadV2=Module["_PadV2"]=function(){return(_PadV2=Module["_PadV2"]=Module["asm"]["ja"]).apply(null,arguments)};var _Pow=Module["_Pow"]=function(){return(_Pow=Module["_Pow"]=Module["asm"]["ka"]).apply(null,arguments)};var _Prelu=Module["_Prelu"]=function(){return(_Prelu=Module["_Prelu"]=Module["asm"]["la"]).apply(null,arguments)};var _Prod=Module["_Prod"]=function(){return(_Prod=Module["_Prod"]=Module["asm"]["ma"]).apply(null,arguments)};var _RealDiv=Module["_RealDiv"]=function(){return(_RealDiv=Module["_RealDiv"]=Module["asm"]["na"]).apply(null,arguments)};var _Relu=Module["_Relu"]=function(){return(_Relu=Module["_Relu"]=Module["asm"]["oa"]).apply(null,arguments)};var _Relu6=Module["_Relu6"]=function(){return(_Relu6=Module["_Relu6"]=Module["asm"]["pa"]).apply(null,arguments)};var _ResizeBilinear=Module["_ResizeBilinear"]=function(){return(_ResizeBilinear=Module["_ResizeBilinear"]=Module["asm"]["qa"]).apply(null,arguments)};var _Reverse=Module["_Reverse"]=function(){return(_Reverse=Module["_Reverse"]=Module["asm"]["ra"]).apply(null,arguments)};var _RotateWithOffset=Module["_RotateWithOffset"]=function(){return(_RotateWithOffset=Module["_RotateWithOffset"]=Module["asm"]["sa"]).apply(null,arguments)};var _Round=Module["_Round"]=function(){return(_Round=Module["_Round"]=Module["asm"]["ta"]).apply(null,arguments)};var _Rsqrt=Module["_Rsqrt"]=function(){return(_Rsqrt=Module["_Rsqrt"]=Module["asm"]["ua"]).apply(null,arguments)};var _ScatterNd=Module["_ScatterNd"]=function(){return(_ScatterNd=Module["_ScatterNd"]=Module["asm"]["va"]).apply(null,arguments)};var _SelectV2=Module["_SelectV2"]=function(){return(_SelectV2=Module["_SelectV2"]=Module["asm"]["wa"]).apply(null,arguments)};var _Sigmoid=Module["_Sigmoid"]=function(){return(_Sigmoid=Module["_Sigmoid"]=Module["asm"]["xa"]).apply(null,arguments)};var _Sin=Module["_Sin"]=function(){return(_Sin=Module["_Sin"]=Module["asm"]["ya"]).apply(null,arguments)};var _Softmax=Module["_Softmax"]=function(){return(_Softmax=Module["_Softmax"]=Module["asm"]["za"]).apply(null,arguments)};var _Sqrt=Module["_Sqrt"]=function(){return(_Sqrt=Module["_Sqrt"]=Module["asm"]["Aa"]).apply(null,arguments)};var _Square=Module["_Square"]=function(){return(_Square=Module["_Square"]=Module["asm"]["Ba"]).apply(null,arguments)};var _SquaredDifference=Module["_SquaredDifference"]=function(){return(_SquaredDifference=Module["_SquaredDifference"]=Module["asm"]["Ca"]).apply(null,arguments)};var _Step=Module["_Step"]=function(){return(_Step=Module["_Step"]=Module["asm"]["Da"]).apply(null,arguments)};var _StridedSlice=Module["_StridedSlice"]=function(){return(_StridedSlice=Module["_StridedSlice"]=Module["asm"]["Ea"]).apply(null,arguments)};var _Sub=Module["_Sub"]=function(){return(_Sub=Module["_Sub"]=Module["asm"]["Fa"]).apply(null,arguments)};var _Sum=Module["_Sum"]=function(){return(_Sum=Module["_Sum"]=Module["asm"]["Ga"]).apply(null,arguments)};var _Tan=Module["_Tan"]=function(){return(_Tan=Module["_Tan"]=Module["asm"]["Ha"]).apply(null,arguments)};var _Tanh=Module["_Tanh"]=function(){return(_Tanh=Module["_Tanh"]=Module["asm"]["Ia"]).apply(null,arguments)};var _Tile=Module["_Tile"]=function(){return(_Tile=Module["_Tile"]=Module["asm"]["Ja"]).apply(null,arguments)};var _TopK=Module["_TopK"]=function(){return(_TopK=Module["_TopK"]=Module["asm"]["Ka"]).apply(null,arguments)};var _Transform=Module["_Transform"]=function(){return(_Transform=Module["_Transform"]=Module["asm"]["La"]).apply(null,arguments)};var _Transpose=Module["_Transpose"]=function(){return(_Transpose=Module["_Transpose"]=Module["asm"]["Ma"]).apply(null,arguments)};var __FusedMatMul=Module["__FusedMatMul"]=function(){return(__FusedMatMul=Module["__FusedMatMul"]=Module["asm"]["Na"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["Oa"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["Pa"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["Qa"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["Ra"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["Sa"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["Ta"]).apply(null,arguments)};Module["cwrap"]=cwrap;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); 10 | 11 | 12 | return WasmBackendModule.ready 13 | } 14 | ); 15 | })(); 16 | if (typeof exports === 'object' && typeof module === 'object') 17 | module.exports = WasmBackendModule; 18 | else if (typeof define === 'function' && define['amd']) 19 | define([], function() { return WasmBackendModule; }); 20 | else if (typeof exports === 'object') 21 | exports["WasmBackendModule"] = WasmBackendModule; 22 | -------------------------------------------------------------------------------- /public/assets/tfjs-backend-wasm-threaded-simd.js: -------------------------------------------------------------------------------- 1 | 2 | var WasmBackendModuleThreadedSimd = (function() { 3 | var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; 4 | if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; 5 | return ( 6 | function(WasmBackendModuleThreadedSimd) { 7 | WasmBackendModuleThreadedSimd = WasmBackendModuleThreadedSimd || {}; 8 | 9 | function GROWABLE_HEAP_I8(){if(wasmMemory.buffer!=buffer){updateGlobalBufferAndViews(wasmMemory.buffer)}return HEAP8}function GROWABLE_HEAP_U8(){if(wasmMemory.buffer!=buffer){updateGlobalBufferAndViews(wasmMemory.buffer)}return HEAPU8}function GROWABLE_HEAP_I32(){if(wasmMemory.buffer!=buffer){updateGlobalBufferAndViews(wasmMemory.buffer)}return HEAP32}function GROWABLE_HEAP_U32(){if(wasmMemory.buffer!=buffer){updateGlobalBufferAndViews(wasmMemory.buffer)}return HEAPU32}function GROWABLE_HEAP_F64(){if(wasmMemory.buffer!=buffer){updateGlobalBufferAndViews(wasmMemory.buffer)}return HEAPF64}var Module=typeof WasmBackendModuleThreadedSimd!=="undefined"?WasmBackendModuleThreadedSimd:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var ENVIRONMENT_IS_PTHREAD=Module["ENVIRONMENT_IS_PTHREAD"]||false;if(ENVIRONMENT_IS_PTHREAD){buffer=Module["buffer"]}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"};var nodeWorkerThreads;try{nodeWorkerThreads=require("worker_threads")}catch(e){console.error('The "worker_threads" module is not supported in this node.js build - perhaps a newer version is needed?');throw e}global.Worker=nodeWorkerThreads.Worker}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(typeof _scriptDir !== "undefined" && _scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}if(ENVIRONMENT_IS_NODE){read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret}}else{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}if(ENVIRONMENT_IS_NODE){if(typeof performance==="undefined"){global.performance=require("perf_hooks").performance}}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var Atomics_load=Atomics.load;var Atomics_store=Atomics.store;var Atomics_compareExchange=Atomics.compareExchange;var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var wasmModule;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx)){var u0=heap[idx++];if(!u0)return str;if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(GROWABLE_HEAP_U8(),ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,GROWABLE_HEAP_U8(),outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function writeArrayToMemory(array,buffer){GROWABLE_HEAP_I8().set(array,buffer)}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(ENVIRONMENT_IS_PTHREAD){wasmMemory=Module["wasmMemory"];buffer=Module["buffer"]}else{if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_MEMORY/65536,"maximum":2147483648/65536,"shared":true});if(!(wasmMemory.buffer instanceof SharedArrayBuffer)){err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag");if(ENVIRONMENT_IS_NODE){console.log("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and also use a recent version)")}throw Error("bad memory")}}}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATEXIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;if(!ENVIRONMENT_IS_PTHREAD)__ATINIT__.push({func:function(){___wasm_call_ctors()}});function preRun(){if(ENVIRONMENT_IS_PTHREAD)return;if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(ENVIRONMENT_IS_PTHREAD)return;callRuntimeCallbacks(__ATINIT__)}function preMain(){if(ENVIRONMENT_IS_PTHREAD)return;callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){if(ENVIRONMENT_IS_PTHREAD)return;runtimeExited=true}function postRun(){if(ENVIRONMENT_IS_PTHREAD)return;if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){assert(!ENVIRONMENT_IS_PTHREAD,"addRunDependency cannot be used in a pthread worker");runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}if(ENVIRONMENT_IS_PTHREAD)console.error("Pthread aborting at "+(new Error).stack);what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="tfjs-backend-wasm-threaded-simd.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmTable=Module["asm"]["F"];wasmModule=module;if(!ENVIRONMENT_IS_PTHREAD){var numWorkersToLoad=PThread.unusedWorkers.length;PThread.unusedWorkers.forEach(function(w){PThread.loadWasmModuleToWorker(w,function(){if(!--numWorkersToLoad)removeRunDependency("wasm-instantiate")})})}}if(!ENVIRONMENT_IS_PTHREAD){addRunDependency("wasm-instantiate")}function receiveInstantiatedSource(output){receiveInstance(output["instance"],output["module"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var ASM_CONSTS={9816:function(){throw"Canceled!"},9834:function($0,$1){setTimeout(function(){__emscripten_do_dispatch_to_thread($0,$1)},0)}};function initPthreadsJS(){PThread.initRuntime()}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function _emscripten_futex_wake(addr,count){if(addr<=0||addr>GROWABLE_HEAP_I8().length||addr&3!=0||count<0)return-28;if(count==0)return 0;if(count>=2147483647)count=Infinity;var mainThreadWaitAddress=Atomics.load(GROWABLE_HEAP_I32(),__emscripten_main_thread_futex>>2);var mainThreadWoken=0;if(mainThreadWaitAddress==addr){var loadedAddr=Atomics.compareExchange(GROWABLE_HEAP_I32(),__emscripten_main_thread_futex>>2,mainThreadWaitAddress,0);if(loadedAddr==mainThreadWaitAddress){--count;mainThreadWoken=1;if(count<=0)return 1}}var ret=Atomics.notify(GROWABLE_HEAP_I32(),addr>>2,count);if(ret>=0)return ret+mainThreadWoken;throw"Atomics.notify returned an unexpected value "+ret}Module["_emscripten_futex_wake"]=_emscripten_futex_wake;function killThread(pthread_ptr){if(ENVIRONMENT_IS_PTHREAD)throw"Internal Error! killThread() can only ever be called from main application thread!";if(!pthread_ptr)throw"Internal Error! Null pthread_ptr in killThread!";GROWABLE_HEAP_I32()[pthread_ptr+12>>2]=0;var pthread=PThread.pthreads[pthread_ptr];pthread.worker.terminate();PThread.freeThreadData(pthread);PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(pthread.worker),1);pthread.worker.pthread=undefined}function cancelThread(pthread_ptr){if(ENVIRONMENT_IS_PTHREAD)throw"Internal Error! cancelThread() can only ever be called from main application thread!";if(!pthread_ptr)throw"Internal Error! Null pthread_ptr in cancelThread!";var pthread=PThread.pthreads[pthread_ptr];pthread.worker.postMessage({"cmd":"cancel"})}function cleanupThread(pthread_ptr){if(ENVIRONMENT_IS_PTHREAD)throw"Internal Error! cleanupThread() can only ever be called from main application thread!";if(!pthread_ptr)throw"Internal Error! Null pthread_ptr in cleanupThread!";var pthread=PThread.pthreads[pthread_ptr];if(pthread){GROWABLE_HEAP_I32()[pthread_ptr+12>>2]=0;var worker=pthread.worker;PThread.returnWorkerToPool(worker)}}var PThread={unusedWorkers:[],runningWorkers:[],initMainThreadBlock:function(){var pthreadPoolSize=Math.min(4,Math.max(1,(navigator.hardwareConcurrency||1)/2));for(var i=0;i>2]=tb;var headPtr=tb+152;GROWABLE_HEAP_I32()[headPtr>>2]=headPtr;var tlsMemory=_malloc(512);for(var i=0;i<128;++i)GROWABLE_HEAP_U32()[tlsMemory/4+i]=0;Atomics.store(GROWABLE_HEAP_U32(),tb+100>>2,tlsMemory);Atomics.store(GROWABLE_HEAP_U32(),tb+40>>2,tb);__emscripten_thread_init(tb,!ENVIRONMENT_IS_WORKER,1);_emscripten_register_main_browser_thread_id(tb)},initWorker:function(){},pthreads:{},threadExitHandlers:[],setThreadStatus:function(){},runExitHandlers:function(){while(PThread.threadExitHandlers.length>0){PThread.threadExitHandlers.pop()()}if(ENVIRONMENT_IS_PTHREAD&&_pthread_self())___pthread_tsd_run_dtors()},runExitHandlersAndDeinitThread:function(tb,exitCode){Atomics.store(GROWABLE_HEAP_U32(),tb+56>>2,1);Atomics.store(GROWABLE_HEAP_U32(),tb+60>>2,0);PThread.runExitHandlers();Atomics.store(GROWABLE_HEAP_U32(),tb+4>>2,exitCode);Atomics.store(GROWABLE_HEAP_U32(),tb+0>>2,1);_emscripten_futex_wake(tb+0,2147483647);__emscripten_thread_init(0,0,0)},threadExit:function(exitCode){var tb=_pthread_self();if(tb){PThread.runExitHandlersAndDeinitThread(tb,exitCode);if(ENVIRONMENT_IS_PTHREAD){postMessage({"cmd":"exit"})}}},threadCancel:function(){PThread.runExitHandlersAndDeinitThread(_pthread_self(),-1);postMessage({"cmd":"cancelDone"})},terminateAllThreads:function(){for(var t in PThread.pthreads){var pthread=PThread.pthreads[t];if(pthread&&pthread.worker){PThread.returnWorkerToPool(pthread.worker)}}PThread.pthreads={};for(var i=0;i>2];GROWABLE_HEAP_I32()[pthread.threadInfoStruct+100>>2]=0;_free(tlsMemory);_free(pthread.threadInfoStruct)}pthread.threadInfoStruct=0;if(pthread.allocatedOwnStack&&pthread.stackBase)_free(pthread.stackBase);pthread.stackBase=0;if(pthread.worker)pthread.worker.pthread=null},returnWorkerToPool:function(worker){PThread.runWithoutMainThreadQueuedCalls(function(){delete PThread.pthreads[worker.pthread.threadInfoStruct];PThread.unusedWorkers.push(worker);PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker),1);PThread.freeThreadData(worker.pthread);worker.pthread=undefined})},runWithoutMainThreadQueuedCalls:function(func){GROWABLE_HEAP_I32()[__emscripten_allow_main_runtime_queued_calls>>2]=0;try{func()}finally{GROWABLE_HEAP_I32()[__emscripten_allow_main_runtime_queued_calls>>2]=1}},receiveObjectTransfer:function(data){},loadWasmModuleToWorker:function(worker,onFinishedLoading){worker.onmessage=function(e){var d=e["data"];var cmd=d["cmd"];if(worker.pthread)PThread.currentProxiedOperationCallerThread=worker.pthread.threadInfoStruct;if(d["targetThread"]&&d["targetThread"]!=_pthread_self()){var thread=PThread.pthreads[d.targetThread];if(thread){thread.worker.postMessage(e.data,d["transferList"])}else{console.error('Internal error! Worker sent a message "'+cmd+'" to target pthread '+d["targetThread"]+", but that thread no longer exists!")}PThread.currentProxiedOperationCallerThread=undefined;return}if(cmd==="processQueuedMainThreadWork"){_emscripten_main_thread_process_queued_calls()}else if(cmd==="spawnThread"){spawnThread(e.data)}else if(cmd==="cleanupThread"){cleanupThread(d["thread"])}else if(cmd==="killThread"){killThread(d["thread"])}else if(cmd==="cancelThread"){cancelThread(d["thread"])}else if(cmd==="loaded"){worker.loaded=true;if(onFinishedLoading)onFinishedLoading(worker);if(worker.runPthread){worker.runPthread();delete worker.runPthread}}else if(cmd==="print"){out("Thread "+d["threadId"]+": "+d["text"])}else if(cmd==="printErr"){err("Thread "+d["threadId"]+": "+d["text"])}else if(cmd==="alert"){alert("Thread "+d["threadId"]+": "+d["text"])}else if(cmd==="exit"){var detached=worker.pthread&&Atomics.load(GROWABLE_HEAP_U32(),worker.pthread.threadInfoStruct+64>>2);if(detached){PThread.returnWorkerToPool(worker)}}else if(cmd==="exitProcess"){try{exit(d["returnCode"])}catch(e){if(e instanceof ExitStatus)return;throw e}}else if(cmd==="cancelDone"){PThread.returnWorkerToPool(worker)}else if(cmd==="objectTransfer"){PThread.receiveObjectTransfer(e.data)}else if(e.data.target==="setimmediate"){worker.postMessage(e.data)}else{err("worker sent an unknown command "+cmd)}PThread.currentProxiedOperationCallerThread=undefined};worker.onerror=function(e){err("pthread sent an error! "+e.filename+":"+e.lineno+": "+e.message)};if(ENVIRONMENT_IS_NODE){worker.on("message",function(data){worker.onmessage({data:data})});worker.on("error",function(data){worker.onerror(data)});worker.on("exit",function(data){})}worker.postMessage({"cmd":"load","urlOrBlob":Module["mainScriptUrlOrBlob"]||_scriptDir,"wasmMemory":wasmMemory,"wasmModule":wasmModule})},allocateUnusedWorker:function(){var pthreadMainJs=locateFile("tfjs-backend-wasm-threaded-simd.worker.js");PThread.unusedWorkers.push(new Worker(pthreadMainJs))},getNewWorker:function(){if(PThread.unusedWorkers.length==0){PThread.allocateUnusedWorker();PThread.loadWasmModuleToWorker(PThread.unusedWorkers[0])}if(PThread.unusedWorkers.length>0)return PThread.unusedWorkers.pop();else return null},busySpinWait:function(msecs){var t=performance.now()+msecs;while(performance.now()>2]=value;return value}function _atexit(func,arg){if(ENVIRONMENT_IS_PTHREAD)return _emscripten_proxy_to_main_thread_js(1,1,func,arg)}function __emscripten_notify_thread_queue(targetThreadId,mainThreadId){if(targetThreadId==mainThreadId){postMessage({"cmd":"processQueuedMainThreadWork"})}else if(ENVIRONMENT_IS_PTHREAD){postMessage({"targetThread":targetThreadId,"cmd":"processThreadQueue"})}else{var pthread=PThread.pthreads[targetThreadId];var worker=pthread&&pthread.worker;if(!worker){return}worker.postMessage({"cmd":"processThreadQueue"})}return 1}function _abort(){abort()}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function _emscripten_conditional_set_current_thread_status(expectedStatus,newStatus){}function _emscripten_futex_wait(addr,val,timeout){if(addr<=0||addr>GROWABLE_HEAP_I8().length||addr&3!=0)return-28;if(!ENVIRONMENT_IS_WEB){var ret=Atomics.wait(GROWABLE_HEAP_I32(),addr>>2,val,timeout);if(ret==="timed-out")return-73;if(ret==="not-equal")return-6;if(ret==="ok")return 0;throw"Atomics.wait returned an unexpected value "+ret}else{if(Atomics.load(GROWABLE_HEAP_I32(),addr>>2)!=val){return-6}var tNow=performance.now();var tEnd=tNow+timeout;var lastAddr=Atomics.exchange(GROWABLE_HEAP_I32(),__emscripten_main_thread_futex>>2,addr);while(1){tNow=performance.now();if(tNow>tEnd){lastAddr=Atomics.exchange(GROWABLE_HEAP_I32(),__emscripten_main_thread_futex>>2,0);return-73}lastAddr=Atomics.exchange(GROWABLE_HEAP_I32(),__emscripten_main_thread_futex>>2,0);if(lastAddr==0){break}_emscripten_main_thread_process_queued_calls();if(Atomics.load(GROWABLE_HEAP_I32(),addr>>2)!=val){return-6}lastAddr=Atomics.exchange(GROWABLE_HEAP_I32(),__emscripten_main_thread_futex>>2,addr)}return 0}}function _emscripten_memcpy_big(dest,src,num){GROWABLE_HEAP_U8().copyWithin(dest,src,src+num)}function _emscripten_num_logical_cores(){if(ENVIRONMENT_IS_NODE)return require("os").cpus().length;return navigator["hardwareConcurrency"]}function _emscripten_proxy_to_main_thread_js(index,sync){var numCallArgs=arguments.length-2;var stack=stackSave();var serializedNumCallArgs=numCallArgs;var args=stackAlloc(serializedNumCallArgs*8);var b=args>>3;for(var i=0;i>=2;while(ch=GROWABLE_HEAP_U8()[sigPtr++]){var double=ch<105;if(double&&buf&1)buf++;readAsmConstArgsArray.push(double?GROWABLE_HEAP_F64()[buf++>>1]:GROWABLE_HEAP_I32()[buf]);++buf}return readAsmConstArgsArray}function _emscripten_receive_on_main_thread_js(index,numCallArgs,args){_emscripten_receive_on_main_thread_js_callArgs.length=numCallArgs;var b=args>>3;for(var i=0;i>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=_emscripten_get_heap_size();if(requestedSize<=oldSize){return false}var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var JSEvents={inEventHandler:0,removeAllEventListeners:function(){for(var i=JSEvents.eventHandlers.length-1;i>=0;--i){JSEvents._removeHandler(i)}JSEvents.eventHandlers=[];JSEvents.deferredCalls=[]},registerRemoveEventListeners:function(){if(!JSEvents.removeEventListenersRegistered){__ATEXIT__.push(JSEvents.removeAllEventListeners);JSEvents.removeEventListenersRegistered=true}},deferredCalls:[],deferCall:function(targetFunction,precedence,argsList){function arraysHaveEqualContent(arrA,arrB){if(arrA.length!=arrB.length)return false;for(var i in arrA){if(arrA[i]!=arrB[i])return false}return true}for(var i in JSEvents.deferredCalls){var call=JSEvents.deferredCalls[i];if(call.targetFunction==targetFunction&&arraysHaveEqualContent(call.argsList,argsList)){return}}JSEvents.deferredCalls.push({targetFunction:targetFunction,precedence:precedence,argsList:argsList});JSEvents.deferredCalls.sort(function(x,y){return x.precedence>2]=eventTypeId;GROWABLE_HEAP_I32()[varargs+4>>2]=eventData;GROWABLE_HEAP_I32()[varargs+8>>2]=userData;__emscripten_call_on_thread(0,targetThread,637534208,eventHandlerFunc,eventData,varargs);stackRestore(stackTop)},getTargetThreadForEventCallback:function(targetThread){switch(targetThread){case 1:return 0;case 2:return PThread.currentProxiedOperationCallerThread;default:return targetThread}},getNodeNameForTarget:function(target){if(!target)return"";if(target==window)return"#window";if(target==screen)return"#screen";return target&&target.nodeName?target.nodeName:""},fullscreenEnabled:function(){return document.fullscreenEnabled||document.webkitFullscreenEnabled}};function stringToNewUTF8(jsString){var length=lengthBytesUTF8(jsString)+1;var cString=_malloc(length);stringToUTF8(jsString,cString,length);return cString}function _emscripten_set_offscreencanvas_size_on_target_thread_js(targetThread,targetCanvas,width,height){var stackTop=stackSave();var varargs=stackAlloc(12);var targetCanvasPtr=0;if(targetCanvas){targetCanvasPtr=stringToNewUTF8(targetCanvas)}GROWABLE_HEAP_I32()[varargs>>2]=targetCanvasPtr;GROWABLE_HEAP_I32()[varargs+4>>2]=width;GROWABLE_HEAP_I32()[varargs+8>>2]=height;__emscripten_call_on_thread(0,targetThread,657457152,0,targetCanvasPtr,varargs);stackRestore(stackTop)}function _emscripten_set_offscreencanvas_size_on_target_thread(targetThread,targetCanvas,width,height){targetCanvas=targetCanvas?UTF8ToString(targetCanvas):"";_emscripten_set_offscreencanvas_size_on_target_thread_js(targetThread,targetCanvas,width,height)}function maybeCStringToJsString(cString){return cString>2?UTF8ToString(cString):cString}var specialHTMLTargets=[0,typeof document!=="undefined"?document:0,typeof window!=="undefined"?window:0];function findEventTarget(target){target=maybeCStringToJsString(target);var domElement=specialHTMLTargets[target]||(typeof document!=="undefined"?document.querySelector(target):undefined);return domElement}function findCanvasEventTarget(target){return findEventTarget(target)}function _emscripten_set_canvas_element_size_calling_thread(target,width,height){var canvas=findCanvasEventTarget(target);if(!canvas)return-4;if(canvas.canvasSharedPtr){GROWABLE_HEAP_I32()[canvas.canvasSharedPtr>>2]=width;GROWABLE_HEAP_I32()[canvas.canvasSharedPtr+4>>2]=height}if(canvas.offscreenCanvas||!canvas.controlTransferredOffscreen){if(canvas.offscreenCanvas)canvas=canvas.offscreenCanvas;var autoResizeViewport=false;if(canvas.GLctxObject&&canvas.GLctxObject.GLctx){var prevViewport=canvas.GLctxObject.GLctx.getParameter(2978);autoResizeViewport=prevViewport[0]===0&&prevViewport[1]===0&&prevViewport[2]===canvas.width&&prevViewport[3]===canvas.height}canvas.width=width;canvas.height=height;if(autoResizeViewport){canvas.GLctxObject.GLctx.viewport(0,0,width,height)}}else if(canvas.canvasSharedPtr){var targetThread=GROWABLE_HEAP_I32()[canvas.canvasSharedPtr+8>>2];_emscripten_set_offscreencanvas_size_on_target_thread(targetThread,target,width,height);return 1}else{return-4}return 0}function _emscripten_set_canvas_element_size_main_thread(target,width,height){if(ENVIRONMENT_IS_PTHREAD)return _emscripten_proxy_to_main_thread_js(2,1,target,width,height);return _emscripten_set_canvas_element_size_calling_thread(target,width,height)}function _emscripten_set_canvas_element_size(target,width,height){var canvas=findCanvasEventTarget(target);if(canvas){return _emscripten_set_canvas_element_size_calling_thread(target,width,height)}else{return _emscripten_set_canvas_element_size_main_thread(target,width,height)}}function _emscripten_set_current_thread_status(newStatus){}function _emscripten_set_thread_name(threadId,name){}function __webgl_enable_ANGLE_instanced_arrays(ctx){var ext=ctx.getExtension("ANGLE_instanced_arrays");if(ext){ctx["vertexAttribDivisor"]=function(index,divisor){ext["vertexAttribDivisorANGLE"](index,divisor)};ctx["drawArraysInstanced"]=function(mode,first,count,primcount){ext["drawArraysInstancedANGLE"](mode,first,count,primcount)};ctx["drawElementsInstanced"]=function(mode,count,type,indices,primcount){ext["drawElementsInstancedANGLE"](mode,count,type,indices,primcount)};return 1}}function __webgl_enable_OES_vertex_array_object(ctx){var ext=ctx.getExtension("OES_vertex_array_object");if(ext){ctx["createVertexArray"]=function(){return ext["createVertexArrayOES"]()};ctx["deleteVertexArray"]=function(vao){ext["deleteVertexArrayOES"](vao)};ctx["bindVertexArray"]=function(vao){ext["bindVertexArrayOES"](vao)};ctx["isVertexArray"]=function(vao){return ext["isVertexArrayOES"](vao)};return 1}}function __webgl_enable_WEBGL_draw_buffers(ctx){var ext=ctx.getExtension("WEBGL_draw_buffers");if(ext){ctx["drawBuffers"]=function(n,bufs){ext["drawBuffersWEBGL"](n,bufs)};return 1}}function __webgl_enable_WEBGL_multi_draw(ctx){return!!(ctx.multiDrawWebgl=ctx.getExtension("WEBGL_multi_draw"))}var GL={counter:1,buffers:[],programs:[],framebuffers:[],renderbuffers:[],textures:[],uniforms:[],shaders:[],vaos:[],contexts:{},offscreenCanvases:{},timerQueriesEXT:[],programInfos:{},stringCache:{},unpackAlignment:4,recordError:function recordError(errorCode){if(!GL.lastError){GL.lastError=errorCode}},getNewId:function(table){var ret=GL.counter++;for(var i=table.length;i>2]:-1;source+=UTF8ToString(GROWABLE_HEAP_I32()[string+i*4>>2],len<0?undefined:len)}return source},createContext:function(canvas,webGLContextAttributes){var ctx=canvas.getContext("webgl",webGLContextAttributes);if(!ctx)return 0;var handle=GL.registerContext(ctx,webGLContextAttributes);return handle},registerContext:function(ctx,webGLContextAttributes){var handle=_malloc(8);GROWABLE_HEAP_I32()[handle+4>>2]=_pthread_self();var context={handle:handle,attributes:webGLContextAttributes,version:webGLContextAttributes.majorVersion,GLctx:ctx};if(ctx.canvas)ctx.canvas.GLctxObject=context;GL.contexts[handle]=context;if(typeof webGLContextAttributes.enableExtensionsByDefault==="undefined"||webGLContextAttributes.enableExtensionsByDefault){GL.initExtensions(context)}return handle},makeContextCurrent:function(contextHandle){GL.currentContext=GL.contexts[contextHandle];Module.ctx=GLctx=GL.currentContext&&GL.currentContext.GLctx;return!(contextHandle&&!GLctx)},getContext:function(contextHandle){return GL.contexts[contextHandle]},deleteContext:function(contextHandle){if(GL.currentContext===GL.contexts[contextHandle])GL.currentContext=null;if(typeof JSEvents==="object")JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas);if(GL.contexts[contextHandle]&&GL.contexts[contextHandle].GLctx.canvas)GL.contexts[contextHandle].GLctx.canvas.GLctxObject=undefined;_free(GL.contexts[contextHandle].handle);GL.contexts[contextHandle]=null},initExtensions:function(context){if(!context)context=GL.currentContext;if(context.initExtensionsDone)return;context.initExtensionsDone=true;var GLctx=context.GLctx;__webgl_enable_ANGLE_instanced_arrays(GLctx);__webgl_enable_OES_vertex_array_object(GLctx);__webgl_enable_WEBGL_draw_buffers(GLctx);GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query");__webgl_enable_WEBGL_multi_draw(GLctx);var exts=GLctx.getSupportedExtensions()||[];exts.forEach(function(ext){if(ext.indexOf("lose_context")<0&&ext.indexOf("debug")<0){GLctx.getExtension(ext)}})},populateUniformTable:function(program){var p=GL.programs[program];var ptable=GL.programInfos[program]={uniforms:{},maxUniformLength:0,maxAttributeLength:-1,maxUniformBlockNameLength:-1};var utable=ptable.uniforms;var numUniforms=GLctx.getProgramParameter(p,35718);for(var i=0;i>2;var powerPreference=GROWABLE_HEAP_I32()[a+(24>>2)];var contextAttributes={"alpha":!!GROWABLE_HEAP_I32()[a+(0>>2)],"depth":!!GROWABLE_HEAP_I32()[a+(4>>2)],"stencil":!!GROWABLE_HEAP_I32()[a+(8>>2)],"antialias":!!GROWABLE_HEAP_I32()[a+(12>>2)],"premultipliedAlpha":!!GROWABLE_HEAP_I32()[a+(16>>2)],"preserveDrawingBuffer":!!GROWABLE_HEAP_I32()[a+(20>>2)],"powerPreference":__emscripten_webgl_power_preferences[powerPreference],"failIfMajorPerformanceCaveat":!!GROWABLE_HEAP_I32()[a+(28>>2)],majorVersion:GROWABLE_HEAP_I32()[a+(32>>2)],minorVersion:GROWABLE_HEAP_I32()[a+(36>>2)],enableExtensionsByDefault:GROWABLE_HEAP_I32()[a+(40>>2)],explicitSwapControl:GROWABLE_HEAP_I32()[a+(44>>2)],proxyContextToMainThread:GROWABLE_HEAP_I32()[a+(48>>2)],renderViaOffscreenBackBuffer:GROWABLE_HEAP_I32()[a+(52>>2)]};var canvas=findCanvasEventTarget(target);if(!canvas){return 0}if(contextAttributes.explicitSwapControl){return 0}var contextHandle=GL.createContext(canvas,contextAttributes);return contextHandle}function _emscripten_webgl_create_context(a0,a1){return _emscripten_webgl_do_create_context(a0,a1)}var SYSCALLS={mappings:{},buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=GROWABLE_HEAP_I32()[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},get64:function(low,high){return low}};function _fd_close(fd){if(ENVIRONMENT_IS_PTHREAD)return _emscripten_proxy_to_main_thread_js(3,1,fd);return 0}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){if(ENVIRONMENT_IS_PTHREAD)return _emscripten_proxy_to_main_thread_js(4,1,fd,offset_low,offset_high,whence,newOffset)}function _fd_write(fd,iov,iovcnt,pnum){if(ENVIRONMENT_IS_PTHREAD)return _emscripten_proxy_to_main_thread_js(5,1,fd,iov,iovcnt,pnum);var num=0;for(var i=0;i>2];var len=GROWABLE_HEAP_I32()[iov+(i*8+4)>>2];for(var j=0;j>2]=num;return 0}function _pthread_cleanup_pop(execute){var routine=PThread.threadExitHandlers.pop();if(execute)routine()}function _pthread_cleanup_push(routine,arg){PThread.threadExitHandlers.push(function(){wasmTable.get(routine)(arg)})}function spawnThread(threadParams){if(ENVIRONMENT_IS_PTHREAD)throw"Internal Error! spawnThread() can only ever be called from main application thread!";var worker=PThread.getNewWorker();if(worker.pthread!==undefined)throw"Internal error!";if(!threadParams.pthread_ptr)throw"Internal error, no pthread ptr!";PThread.runningWorkers.push(worker);var tlsMemory=_malloc(128*4);for(var i=0;i<128;++i){GROWABLE_HEAP_I32()[tlsMemory+i*4>>2]=0}var stackHigh=threadParams.stackBase+threadParams.stackSize;var pthread=PThread.pthreads[threadParams.pthread_ptr]={worker:worker,stackBase:threadParams.stackBase,stackSize:threadParams.stackSize,allocatedOwnStack:threadParams.allocatedOwnStack,threadInfoStruct:threadParams.pthread_ptr};var tis=pthread.threadInfoStruct>>2;Atomics.store(GROWABLE_HEAP_U32(),tis+(64>>2),threadParams.detached);Atomics.store(GROWABLE_HEAP_U32(),tis+(100>>2),tlsMemory);Atomics.store(GROWABLE_HEAP_U32(),tis+(40>>2),pthread.threadInfoStruct);Atomics.store(GROWABLE_HEAP_U32(),tis+(80>>2),threadParams.stackSize);Atomics.store(GROWABLE_HEAP_U32(),tis+(76>>2),stackHigh);Atomics.store(GROWABLE_HEAP_U32(),tis+(104>>2),threadParams.stackSize);Atomics.store(GROWABLE_HEAP_U32(),tis+(104+8>>2),stackHigh);Atomics.store(GROWABLE_HEAP_U32(),tis+(104+12>>2),threadParams.detached);var global_libc=_emscripten_get_global_libc();var global_locale=global_libc+40;Atomics.store(GROWABLE_HEAP_U32(),tis+(172>>2),global_locale);worker.pthread=pthread;var msg={"cmd":"run","start_routine":threadParams.startRoutine,"arg":threadParams.arg,"threadInfoStruct":threadParams.pthread_ptr,"stackBase":threadParams.stackBase,"stackSize":threadParams.stackSize};worker.runPthread=function(){msg.time=performance.now();worker.postMessage(msg,threadParams.transferList)};if(worker.loaded){worker.runPthread();delete worker.runPthread}}function _pthread_create(pthread_ptr,attr,start_routine,arg){if(typeof SharedArrayBuffer==="undefined"){err("Current environment does not support SharedArrayBuffer, pthreads are not available!");return 6}if(!pthread_ptr){err("pthread_create called with a null thread pointer!");return 28}var transferList=[];var error=0;if(ENVIRONMENT_IS_PTHREAD&&(transferList.length===0||error)){return _emscripten_sync_run_in_main_thread_4(687865856,pthread_ptr,attr,start_routine,arg)}if(error)return error;var stackSize=0;var stackBase=0;var detached=0;if(attr&&attr!=-1){stackSize=GROWABLE_HEAP_I32()[attr>>2];stackSize+=81920;stackBase=GROWABLE_HEAP_I32()[attr+8>>2];detached=GROWABLE_HEAP_I32()[attr+12>>2]!==0}else{stackSize=2097152}var allocatedOwnStack=stackBase==0;if(allocatedOwnStack){stackBase=_memalign(16,stackSize)}else{stackBase-=stackSize;assert(stackBase>0)}var threadInfoStruct=_malloc(228);for(var i=0;i<228>>2;++i)GROWABLE_HEAP_U32()[(threadInfoStruct>>2)+i]=0;GROWABLE_HEAP_I32()[pthread_ptr>>2]=threadInfoStruct;GROWABLE_HEAP_I32()[threadInfoStruct+12>>2]=threadInfoStruct;var headPtr=threadInfoStruct+152;GROWABLE_HEAP_I32()[headPtr>>2]=headPtr;var threadParams={stackBase:stackBase,stackSize:stackSize,allocatedOwnStack:allocatedOwnStack,detached:detached,startRoutine:start_routine,pthread_ptr:threadInfoStruct,arg:arg,transferList:transferList};if(ENVIRONMENT_IS_PTHREAD){threadParams.cmd="spawnThread";postMessage(threadParams,transferList)}else{spawnThread(threadParams)}return 0}function _sysconf(name){if(ENVIRONMENT_IS_PTHREAD)return _emscripten_proxy_to_main_thread_js(6,1,name);switch(name){case 30:return 16384;case 85:var maxHeapSize=2147483648;return maxHeapSize/16384;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:case 80:case 81:case 79:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}setErrNo(28);return-1}if(!ENVIRONMENT_IS_PTHREAD)PThread.initMainThreadBlock();var GLctx;var proxiedFunctionTable=[null,_atexit,_emscripten_set_canvas_element_size_main_thread,_fd_close,_fd_seek,_fd_write,_sysconf];var asmLibraryArg={"e":___assert_fail,"r":___call_main,"x":__emscripten_notify_thread_queue,"b":_abort,"y":_emscripten_asm_const_int,"j":_emscripten_conditional_set_current_thread_status,"c":_emscripten_futex_wait,"d":_emscripten_futex_wake,"f":_emscripten_get_now,"p":_emscripten_memcpy_big,"z":_emscripten_num_logical_cores,"u":_emscripten_receive_on_main_thread_js,"q":_emscripten_resize_heap,"v":_emscripten_set_canvas_element_size,"i":_emscripten_set_current_thread_status,"t":_emscripten_set_thread_name,"w":_emscripten_webgl_create_context,"m":_fd_close,"n":_fd_seek,"g":_fd_write,"o":initPthreadsJS,"a":wasmMemory||Module["wasmMemory"],"k":_pthread_cleanup_pop,"l":_pthread_cleanup_push,"h":_pthread_create,"s":_sysconf};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["A"]).apply(null,arguments)};var _init=Module["_init"]=function(){return(_init=Module["_init"]=Module["asm"]["B"]).apply(null,arguments)};var _register_tensor=Module["_register_tensor"]=function(){return(_register_tensor=Module["_register_tensor"]=Module["asm"]["C"]).apply(null,arguments)};var _dispose_data=Module["_dispose_data"]=function(){return(_dispose_data=Module["_dispose_data"]=Module["asm"]["D"]).apply(null,arguments)};var _dispose=Module["_dispose"]=function(){return(_dispose=Module["_dispose"]=Module["asm"]["E"]).apply(null,arguments)};var _Abs=Module["_Abs"]=function(){return(_Abs=Module["_Abs"]=Module["asm"]["G"]).apply(null,arguments)};var _Add=Module["_Add"]=function(){return(_Add=Module["_Add"]=Module["asm"]["H"]).apply(null,arguments)};var _AddN=Module["_AddN"]=function(){return(_AddN=Module["_AddN"]=Module["asm"]["I"]).apply(null,arguments)};var _All=Module["_All"]=function(){return(_All=Module["_All"]=Module["asm"]["J"]).apply(null,arguments)};var _Any=Module["_Any"]=function(){return(_Any=Module["_Any"]=Module["asm"]["K"]).apply(null,arguments)};var _ArgMax=Module["_ArgMax"]=function(){return(_ArgMax=Module["_ArgMax"]=Module["asm"]["L"]).apply(null,arguments)};var _AvgPool=Module["_AvgPool"]=function(){return(_AvgPool=Module["_AvgPool"]=Module["asm"]["M"]).apply(null,arguments)};var _BatchMatMul=Module["_BatchMatMul"]=function(){return(_BatchMatMul=Module["_BatchMatMul"]=Module["asm"]["N"]).apply(null,arguments)};var _Ceil=Module["_Ceil"]=function(){return(_Ceil=Module["_Ceil"]=Module["asm"]["O"]).apply(null,arguments)};var _ClipByValue=Module["_ClipByValue"]=function(){return(_ClipByValue=Module["_ClipByValue"]=Module["asm"]["P"]).apply(null,arguments)};var _Conv2D=Module["_Conv2D"]=function(){return(_Conv2D=Module["_Conv2D"]=Module["asm"]["Q"]).apply(null,arguments)};var _Conv2DBackpropInput=Module["_Conv2DBackpropInput"]=function(){return(_Conv2DBackpropInput=Module["_Conv2DBackpropInput"]=Module["asm"]["R"]).apply(null,arguments)};var _Cos=Module["_Cos"]=function(){return(_Cos=Module["_Cos"]=Module["asm"]["S"]).apply(null,arguments)};var _CropAndResize=Module["_CropAndResize"]=function(){return(_CropAndResize=Module["_CropAndResize"]=Module["asm"]["T"]).apply(null,arguments)};var _Cumsum=Module["_Cumsum"]=function(){return(_Cumsum=Module["_Cumsum"]=Module["asm"]["U"]).apply(null,arguments)};var _DepthToSpace=Module["_DepthToSpace"]=function(){return(_DepthToSpace=Module["_DepthToSpace"]=Module["asm"]["V"]).apply(null,arguments)};var _DepthwiseConv2dNative=Module["_DepthwiseConv2dNative"]=function(){return(_DepthwiseConv2dNative=Module["_DepthwiseConv2dNative"]=Module["asm"]["W"]).apply(null,arguments)};var _Equal=Module["_Equal"]=function(){return(_Equal=Module["_Equal"]=Module["asm"]["X"]).apply(null,arguments)};var _Exp=Module["_Exp"]=function(){return(_Exp=Module["_Exp"]=Module["asm"]["Y"]).apply(null,arguments)};var _FlipLeftRight=Module["_FlipLeftRight"]=function(){return(_FlipLeftRight=Module["_FlipLeftRight"]=Module["asm"]["Z"]).apply(null,arguments)};var _Floor=Module["_Floor"]=function(){return(_Floor=Module["_Floor"]=Module["asm"]["_"]).apply(null,arguments)};var _FloorDiv=Module["_FloorDiv"]=function(){return(_FloorDiv=Module["_FloorDiv"]=Module["asm"]["$"]).apply(null,arguments)};var _FusedBatchNorm=Module["_FusedBatchNorm"]=function(){return(_FusedBatchNorm=Module["_FusedBatchNorm"]=Module["asm"]["aa"]).apply(null,arguments)};var _FusedConv2D=Module["_FusedConv2D"]=function(){return(_FusedConv2D=Module["_FusedConv2D"]=Module["asm"]["ba"]).apply(null,arguments)};var _FusedDepthwiseConv2D=Module["_FusedDepthwiseConv2D"]=function(){return(_FusedDepthwiseConv2D=Module["_FusedDepthwiseConv2D"]=Module["asm"]["ca"]).apply(null,arguments)};var _Gather=Module["_Gather"]=function(){return(_Gather=Module["_Gather"]=Module["asm"]["da"]).apply(null,arguments)};var _GatherNd=Module["_GatherNd"]=function(){return(_GatherNd=Module["_GatherNd"]=Module["asm"]["ea"]).apply(null,arguments)};var _Greater=Module["_Greater"]=function(){return(_Greater=Module["_Greater"]=Module["asm"]["fa"]).apply(null,arguments)};var _GreaterEqual=Module["_GreaterEqual"]=function(){return(_GreaterEqual=Module["_GreaterEqual"]=Module["asm"]["ga"]).apply(null,arguments)};var _LeakyRelu=Module["_LeakyRelu"]=function(){return(_LeakyRelu=Module["_LeakyRelu"]=Module["asm"]["ha"]).apply(null,arguments)};var _Less=Module["_Less"]=function(){return(_Less=Module["_Less"]=Module["asm"]["ia"]).apply(null,arguments)};var _LessEqual=Module["_LessEqual"]=function(){return(_LessEqual=Module["_LessEqual"]=Module["asm"]["ja"]).apply(null,arguments)};var _Log=Module["_Log"]=function(){return(_Log=Module["_Log"]=Module["asm"]["ka"]).apply(null,arguments)};var _LogicalAnd=Module["_LogicalAnd"]=function(){return(_LogicalAnd=Module["_LogicalAnd"]=Module["asm"]["la"]).apply(null,arguments)};var _Max=Module["_Max"]=function(){return(_Max=Module["_Max"]=Module["asm"]["ma"]).apply(null,arguments)};var _MaxPool=Module["_MaxPool"]=function(){return(_MaxPool=Module["_MaxPool"]=Module["asm"]["na"]).apply(null,arguments)};var _Maximum=Module["_Maximum"]=function(){return(_Maximum=Module["_Maximum"]=Module["asm"]["oa"]).apply(null,arguments)};var _Mean=Module["_Mean"]=function(){return(_Mean=Module["_Mean"]=Module["asm"]["pa"]).apply(null,arguments)};var _Min=Module["_Min"]=function(){return(_Min=Module["_Min"]=Module["asm"]["qa"]).apply(null,arguments)};var _Minimum=Module["_Minimum"]=function(){return(_Minimum=Module["_Minimum"]=Module["asm"]["ra"]).apply(null,arguments)};var _MirrorPad=Module["_MirrorPad"]=function(){return(_MirrorPad=Module["_MirrorPad"]=Module["asm"]["sa"]).apply(null,arguments)};var _Multiply=Module["_Multiply"]=function(){return(_Multiply=Module["_Multiply"]=Module["asm"]["ta"]).apply(null,arguments)};var _Neg=Module["_Neg"]=function(){return(_Neg=Module["_Neg"]=Module["asm"]["ua"]).apply(null,arguments)};var _NonMaxSuppressionV3=Module["_NonMaxSuppressionV3"]=function(){return(_NonMaxSuppressionV3=Module["_NonMaxSuppressionV3"]=Module["asm"]["va"]).apply(null,arguments)};var _NonMaxSuppressionV4=Module["_NonMaxSuppressionV4"]=function(){return(_NonMaxSuppressionV4=Module["_NonMaxSuppressionV4"]=Module["asm"]["wa"]).apply(null,arguments)};var _NonMaxSuppressionV5=Module["_NonMaxSuppressionV5"]=function(){return(_NonMaxSuppressionV5=Module["_NonMaxSuppressionV5"]=Module["asm"]["xa"]).apply(null,arguments)};var _NotEqual=Module["_NotEqual"]=function(){return(_NotEqual=Module["_NotEqual"]=Module["asm"]["ya"]).apply(null,arguments)};var _OneHot=Module["_OneHot"]=function(){return(_OneHot=Module["_OneHot"]=Module["asm"]["za"]).apply(null,arguments)};var _PadV2=Module["_PadV2"]=function(){return(_PadV2=Module["_PadV2"]=Module["asm"]["Aa"]).apply(null,arguments)};var _Pow=Module["_Pow"]=function(){return(_Pow=Module["_Pow"]=Module["asm"]["Ba"]).apply(null,arguments)};var _Prelu=Module["_Prelu"]=function(){return(_Prelu=Module["_Prelu"]=Module["asm"]["Ca"]).apply(null,arguments)};var _Prod=Module["_Prod"]=function(){return(_Prod=Module["_Prod"]=Module["asm"]["Da"]).apply(null,arguments)};var _RealDiv=Module["_RealDiv"]=function(){return(_RealDiv=Module["_RealDiv"]=Module["asm"]["Ea"]).apply(null,arguments)};var _Relu=Module["_Relu"]=function(){return(_Relu=Module["_Relu"]=Module["asm"]["Fa"]).apply(null,arguments)};var _Relu6=Module["_Relu6"]=function(){return(_Relu6=Module["_Relu6"]=Module["asm"]["Ga"]).apply(null,arguments)};var _ResizeBilinear=Module["_ResizeBilinear"]=function(){return(_ResizeBilinear=Module["_ResizeBilinear"]=Module["asm"]["Ha"]).apply(null,arguments)};var _Reverse=Module["_Reverse"]=function(){return(_Reverse=Module["_Reverse"]=Module["asm"]["Ia"]).apply(null,arguments)};var _RotateWithOffset=Module["_RotateWithOffset"]=function(){return(_RotateWithOffset=Module["_RotateWithOffset"]=Module["asm"]["Ja"]).apply(null,arguments)};var _Round=Module["_Round"]=function(){return(_Round=Module["_Round"]=Module["asm"]["Ka"]).apply(null,arguments)};var _Rsqrt=Module["_Rsqrt"]=function(){return(_Rsqrt=Module["_Rsqrt"]=Module["asm"]["La"]).apply(null,arguments)};var _ScatterNd=Module["_ScatterNd"]=function(){return(_ScatterNd=Module["_ScatterNd"]=Module["asm"]["Ma"]).apply(null,arguments)};var _SelectV2=Module["_SelectV2"]=function(){return(_SelectV2=Module["_SelectV2"]=Module["asm"]["Na"]).apply(null,arguments)};var _Sigmoid=Module["_Sigmoid"]=function(){return(_Sigmoid=Module["_Sigmoid"]=Module["asm"]["Oa"]).apply(null,arguments)};var _Sin=Module["_Sin"]=function(){return(_Sin=Module["_Sin"]=Module["asm"]["Pa"]).apply(null,arguments)};var _Softmax=Module["_Softmax"]=function(){return(_Softmax=Module["_Softmax"]=Module["asm"]["Qa"]).apply(null,arguments)};var _Sqrt=Module["_Sqrt"]=function(){return(_Sqrt=Module["_Sqrt"]=Module["asm"]["Ra"]).apply(null,arguments)};var _Square=Module["_Square"]=function(){return(_Square=Module["_Square"]=Module["asm"]["Sa"]).apply(null,arguments)};var _SquaredDifference=Module["_SquaredDifference"]=function(){return(_SquaredDifference=Module["_SquaredDifference"]=Module["asm"]["Ta"]).apply(null,arguments)};var _Step=Module["_Step"]=function(){return(_Step=Module["_Step"]=Module["asm"]["Ua"]).apply(null,arguments)};var _StridedSlice=Module["_StridedSlice"]=function(){return(_StridedSlice=Module["_StridedSlice"]=Module["asm"]["Va"]).apply(null,arguments)};var _Sub=Module["_Sub"]=function(){return(_Sub=Module["_Sub"]=Module["asm"]["Wa"]).apply(null,arguments)};var _Sum=Module["_Sum"]=function(){return(_Sum=Module["_Sum"]=Module["asm"]["Xa"]).apply(null,arguments)};var _Tan=Module["_Tan"]=function(){return(_Tan=Module["_Tan"]=Module["asm"]["Ya"]).apply(null,arguments)};var _Tanh=Module["_Tanh"]=function(){return(_Tanh=Module["_Tanh"]=Module["asm"]["Za"]).apply(null,arguments)};var _Tile=Module["_Tile"]=function(){return(_Tile=Module["_Tile"]=Module["asm"]["_a"]).apply(null,arguments)};var _TopK=Module["_TopK"]=function(){return(_TopK=Module["_TopK"]=Module["asm"]["$a"]).apply(null,arguments)};var _Transform=Module["_Transform"]=function(){return(_Transform=Module["_Transform"]=Module["asm"]["ab"]).apply(null,arguments)};var _Transpose=Module["_Transpose"]=function(){return(_Transpose=Module["_Transpose"]=Module["asm"]["bb"]).apply(null,arguments)};var __FusedMatMul=Module["__FusedMatMul"]=function(){return(__FusedMatMul=Module["__FusedMatMul"]=Module["asm"]["cb"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["db"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["eb"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["fb"]).apply(null,arguments)};var _emscripten_get_global_libc=Module["_emscripten_get_global_libc"]=function(){return(_emscripten_get_global_libc=Module["_emscripten_get_global_libc"]=Module["asm"]["gb"]).apply(null,arguments)};var _pthread_self=Module["_pthread_self"]=function(){return(_pthread_self=Module["_pthread_self"]=Module["asm"]["hb"]).apply(null,arguments)};var ___pthread_tsd_run_dtors=Module["___pthread_tsd_run_dtors"]=function(){return(___pthread_tsd_run_dtors=Module["___pthread_tsd_run_dtors"]=Module["asm"]["ib"]).apply(null,arguments)};var _emscripten_main_thread_process_queued_calls=Module["_emscripten_main_thread_process_queued_calls"]=function(){return(_emscripten_main_thread_process_queued_calls=Module["_emscripten_main_thread_process_queued_calls"]=Module["asm"]["jb"]).apply(null,arguments)};var _emscripten_current_thread_process_queued_calls=Module["_emscripten_current_thread_process_queued_calls"]=function(){return(_emscripten_current_thread_process_queued_calls=Module["_emscripten_current_thread_process_queued_calls"]=Module["asm"]["kb"]).apply(null,arguments)};var _emscripten_register_main_browser_thread_id=Module["_emscripten_register_main_browser_thread_id"]=function(){return(_emscripten_register_main_browser_thread_id=Module["_emscripten_register_main_browser_thread_id"]=Module["asm"]["lb"]).apply(null,arguments)};var __emscripten_do_dispatch_to_thread=Module["__emscripten_do_dispatch_to_thread"]=function(){return(__emscripten_do_dispatch_to_thread=Module["__emscripten_do_dispatch_to_thread"]=Module["asm"]["mb"]).apply(null,arguments)};var _emscripten_sync_run_in_main_thread_4=Module["_emscripten_sync_run_in_main_thread_4"]=function(){return(_emscripten_sync_run_in_main_thread_4=Module["_emscripten_sync_run_in_main_thread_4"]=Module["asm"]["nb"]).apply(null,arguments)};var _emscripten_run_in_main_runtime_thread_js=Module["_emscripten_run_in_main_runtime_thread_js"]=function(){return(_emscripten_run_in_main_runtime_thread_js=Module["_emscripten_run_in_main_runtime_thread_js"]=Module["asm"]["ob"]).apply(null,arguments)};var __emscripten_call_on_thread=Module["__emscripten_call_on_thread"]=function(){return(__emscripten_call_on_thread=Module["__emscripten_call_on_thread"]=Module["asm"]["pb"]).apply(null,arguments)};var _emscripten_tls_init=Module["_emscripten_tls_init"]=function(){return(_emscripten_tls_init=Module["_emscripten_tls_init"]=Module["asm"]["qb"]).apply(null,arguments)};var __emscripten_thread_init=Module["__emscripten_thread_init"]=function(){return(__emscripten_thread_init=Module["__emscripten_thread_init"]=Module["asm"]["rb"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["sb"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["tb"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["ub"]).apply(null,arguments)};var _emscripten_stack_set_limits=Module["_emscripten_stack_set_limits"]=function(){return(_emscripten_stack_set_limits=Module["_emscripten_stack_set_limits"]=Module["asm"]["vb"]).apply(null,arguments)};var _memalign=Module["_memalign"]=function(){return(_memalign=Module["_memalign"]=Module["asm"]["wb"]).apply(null,arguments)};var __emscripten_allow_main_runtime_queued_calls=Module["__emscripten_allow_main_runtime_queued_calls"]=9808;var __emscripten_main_thread_futex=Module["__emscripten_main_thread_futex"]=11432;Module["cwrap"]=cwrap;Module["PThread"]=PThread;Module["PThread"]=PThread;Module["wasmMemory"]=wasmMemory;Module["ExitStatus"]=ExitStatus;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}if(ENVIRONMENT_IS_PTHREAD){readyPromiseResolve(Module);initRuntime();postMessage({"cmd":"loaded"});return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&noExitRuntime&&status===0){return}if(!implicit){if(ENVIRONMENT_IS_PTHREAD){postMessage({"cmd":"exitProcess","returnCode":status});throw new ExitStatus(status)}else{}}if(noExitRuntime){}else{PThread.terminateAllThreads();EXITSTATUS=status;exitRuntime();if(Module["onExit"])Module["onExit"](status);ABORT=true}quit_(status,new ExitStatus(status))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}if(ENVIRONMENT_IS_PTHREAD){noExitRuntime=false;PThread.initWorker()}run(); 10 | 11 | 12 | return WasmBackendModuleThreadedSimd.ready 13 | } 14 | ); 15 | })(); 16 | if (typeof exports === 'object' && typeof module === 'object') 17 | module.exports = WasmBackendModuleThreadedSimd; 18 | else if (typeof define === 'function' && define['amd']) 19 | define([], function() { return WasmBackendModuleThreadedSimd; }); 20 | else if (typeof exports === 'object') 21 | exports["WasmBackendModuleThreadedSimd"] = WasmBackendModuleThreadedSimd; 22 | --------------------------------------------------------------------------------