mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-14 17:49:52 +00:00
Bug fixes
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
// Not really clean, but we need these to access the type of the functions
|
// Not really clean, but we need these to access the type of the functions
|
||||||
// for comlink
|
// for comlink
|
||||||
"src/features/**/worker/**/*",
|
"src/features/**/worker/**/*",
|
||||||
"src/features-worker/**/*"
|
"src/features-worker/**/*",
|
||||||
|
"src/features/worker-utils/**/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ export default function () {
|
|||||||
]),
|
]),
|
||||||
`};`,
|
`};`,
|
||||||
`export type ProcessorWorkerApi = typeof exports;`,
|
`export type ProcessorWorkerApi = typeof exports;`,
|
||||||
`expose(exports, self);`,
|
`// 'as any' to work around the way our client code has insight into worker code`,
|
||||||
|
`expose(exports, self as any);`,
|
||||||
]
|
]
|
||||||
.flat(Infinity)
|
.flat(Infinity)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|||||||
86
package-lock.json
generated
86
package-lock.json
generated
@@ -146,13 +146,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@rollup/plugin-replace": {
|
"@rollup/plugin-replace": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.3.4.tgz",
|
||||||
"integrity": "sha512-XPmVXZ7IlaoWaJLkSCDaa0Y6uVo5XQYHhiMFzOd5qSv5rE+t/UJToPIOE56flKIxBFQI27ONsxb7dqHnwSsjKQ==",
|
"integrity": "sha512-waBhMzyAtjCL1GwZes2jaE9MjuQ/DQF2BatH3fRivUF3z0JBFrU0U6iBNC/4WR+2rLKhaAhPWDNPYp4mI6RqdQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@rollup/pluginutils": "^3.0.8",
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
"magic-string": "^0.25.5"
|
"magic-string": "^0.25.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@rollup/pluginutils": {
|
"@rollup/pluginutils": {
|
||||||
@@ -205,9 +205,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "14.11.5",
|
"version": "14.14.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.7.tgz",
|
||||||
"integrity": "sha512-jVFzDV6NTbrLMxm4xDSIW/gKnk8rQLF9wAzLWIOg+5nU6ACrIMndeBdXci0FGtqJbP9tQvm6V39eshc96TO2wQ==",
|
"integrity": "sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/parse-json": {
|
"@types/parse-json": {
|
||||||
@@ -860,9 +860,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"commander": {
|
"commander": {
|
||||||
"version": "6.1.0",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.0.tgz",
|
||||||
"integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==",
|
"integrity": "sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"commondir": {
|
"commondir": {
|
||||||
@@ -1684,9 +1684,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"execa": {
|
"execa": {
|
||||||
"version": "4.0.3",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
|
||||||
"integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==",
|
"integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"cross-spawn": "^7.0.0",
|
"cross-spawn": "^7.0.0",
|
||||||
@@ -2319,20 +2319,20 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"version": "10.4.0",
|
"version": "10.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.1.tgz",
|
||||||
"integrity": "sha512-uaiX4U5yERUSiIEQc329vhCTDDwUcSvKdRLsNomkYLRzijk3v8V9GWm2Nz0RMVB87VcuzLvtgy6OsjoH++QHIg==",
|
"integrity": "sha512-fTkTGFtwFIJJzn/PbUO3RXyEBHIhbfYBE7+rJyLcOXabViaO/h6OslgeK6zpeUtzkDrzkgyAYDTLAwx6JzDTHw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"cli-truncate": "^2.1.0",
|
"cli-truncate": "^2.1.0",
|
||||||
"commander": "^6.0.0",
|
"commander": "^6.2.0",
|
||||||
"cosmiconfig": "^7.0.0",
|
"cosmiconfig": "^7.0.0",
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.2.0",
|
||||||
"dedent": "^0.7.0",
|
"dedent": "^0.7.0",
|
||||||
"enquirer": "^2.3.6",
|
"enquirer": "^2.3.6",
|
||||||
"execa": "^4.0.3",
|
"execa": "^4.1.0",
|
||||||
"listr2": "^2.6.0",
|
"listr2": "^3.2.2",
|
||||||
"log-symbols": "^4.0.0",
|
"log-symbols": "^4.0.0",
|
||||||
"micromatch": "^4.0.2",
|
"micromatch": "^4.0.2",
|
||||||
"normalize-path": "^3.0.0",
|
"normalize-path": "^3.0.0",
|
||||||
@@ -2342,9 +2342,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"listr2": {
|
"listr2": {
|
||||||
"version": "2.6.2",
|
"version": "3.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-2.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/listr2/-/listr2-3.2.2.tgz",
|
||||||
"integrity": "sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA==",
|
"integrity": "sha512-AajqcZEUikF2ioph6PfH3dIuxJclhr3i3kHgTOP0xeXdWQohrvJAAmqVcV43/GI987HFY/vzT73jYXoa4esDHg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
@@ -2353,7 +2353,7 @@
|
|||||||
"indent-string": "^4.0.0",
|
"indent-string": "^4.0.0",
|
||||||
"log-update": "^4.0.0",
|
"log-update": "^4.0.0",
|
||||||
"p-map": "^4.0.0",
|
"p-map": "^4.0.0",
|
||||||
"rxjs": "^6.6.2",
|
"rxjs": "^6.6.3",
|
||||||
"through": "^2.3.8"
|
"through": "^2.3.8"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -5843,15 +5843,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"preact": {
|
"preact": {
|
||||||
"version": "10.5.4",
|
"version": "10.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/preact/-/preact-10.5.5.tgz",
|
||||||
"integrity": "sha512-u0LnVtL9WWF61RLzIbEsVFOdsahoTQkQqeRwyf4eWuLMFrxTH/C47tqcnizbUH54E4KG8UzuuZaMc9KarHmpqQ==",
|
"integrity": "sha512-5ONLNH1SXMzzbQoExZX4TELemNt+TEDb622xXFNfZngjjM9qtrzseJt+EfiUu4TZ6EJ95X5sE1ES4yqHFSIdhg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"preact-render-to-string": {
|
"preact-render-to-string": {
|
||||||
"version": "5.1.10",
|
"version": "5.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.1.11.tgz",
|
||||||
"integrity": "sha512-40svy7NDe5Qe0ymdsIC11f0hZb05MeTSUqqIaWJ5DEFCh/sF86KcpRW0kN/ymGYDVVUCfv9qFrVuLCXR7aQxgQ==",
|
"integrity": "sha512-8DXkx8WzeUexYyh9ZjlBSsqcJVOndidw10t1MK1gLx6at4QxQE3RfqaObPgy5WOnw2piyh9kanNB7w7+dmaq4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"pretty-format": "^3.8.0"
|
"pretty-format": "^3.8.0"
|
||||||
@@ -5863,6 +5863,12 @@
|
|||||||
"integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
|
"integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"pretty-bytes": {
|
||||||
|
"version": "5.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz",
|
||||||
|
"integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"pretty-format": {
|
"pretty-format": {
|
||||||
"version": "3.8.0",
|
"version": "3.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
|
||||||
@@ -5996,9 +6002,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rollup": {
|
"rollup": {
|
||||||
"version": "2.28.2",
|
"version": "2.33.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.28.2.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.33.1.tgz",
|
||||||
"integrity": "sha512-8txbsFBFLmm9Xdt4ByTOGa9Muonmc8MfNjnGAR8U8scJlF1ZW7AgNZa7aqBXaKtlvnYP/ab++fQIq9dB9NWUbg==",
|
"integrity": "sha512-uY4O/IoL9oNW8MMcbA5hcOaz6tZTMIh7qJHx/tzIJm+n1wLoY38BLn6fuy7DhR57oNFLMbDQtDeJoFURt5933w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fsevents": "~2.1.2"
|
"fsevents": "~2.1.2"
|
||||||
@@ -6643,9 +6649,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "1.13.0",
|
"version": "1.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"type-fest": {
|
"type-fest": {
|
||||||
@@ -6655,9 +6661,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz",
|
||||||
"integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==",
|
"integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uniq": {
|
"uniq": {
|
||||||
|
|||||||
15
package.json
15
package.json
@@ -12,9 +12,9 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^15.1.0",
|
"@rollup/plugin-commonjs": "^15.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^9.0.0",
|
"@rollup/plugin-node-resolve": "^9.0.0",
|
||||||
"@rollup/plugin-replace": "^2.3.3",
|
"@rollup/plugin-replace": "^2.3.4",
|
||||||
"@surma/rollup-plugin-off-main-thread": "^1.4.1",
|
"@surma/rollup-plugin-off-main-thread": "^1.4.1",
|
||||||
"@types/node": "^14.11.5",
|
"@types/node": "^14.14.7",
|
||||||
"comlink": "^4.3.0",
|
"comlink": "^4.3.0",
|
||||||
"cssnano": "^4.1.10",
|
"cssnano": "^4.1.10",
|
||||||
"del": "^5.1.0",
|
"del": "^5.1.0",
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"husky": "^4.3.0",
|
"husky": "^4.3.0",
|
||||||
"idb-keyval": "^3.2.0",
|
"idb-keyval": "^3.2.0",
|
||||||
"linkstate": "^1.1.1",
|
"linkstate": "^1.1.1",
|
||||||
"lint-staged": "^10.4.0",
|
"lint-staged": "^10.5.1",
|
||||||
"lodash.camelcase": "^4.3.0",
|
"lodash.camelcase": "^4.3.0",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"pointer-tracker": "^2.4.0",
|
"pointer-tracker": "^2.4.0",
|
||||||
@@ -31,13 +31,14 @@
|
|||||||
"postcss-nested": "^4.2.3",
|
"postcss-nested": "^4.2.3",
|
||||||
"postcss-simple-vars": "^5.0.2",
|
"postcss-simple-vars": "^5.0.2",
|
||||||
"postcss-url": "^8.0.0",
|
"postcss-url": "^8.0.0",
|
||||||
"preact": "^10.5.4",
|
"preact": "^10.5.5",
|
||||||
"preact-render-to-string": "^5.1.10",
|
"preact-render-to-string": "^5.1.11",
|
||||||
"prettier": "^2.1.2",
|
"prettier": "^2.1.2",
|
||||||
"rollup": "^2.28.2",
|
"pretty-bytes": "^5.4.1",
|
||||||
|
"rollup": "^2.33.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"serve": "^11.3.2",
|
"serve": "^11.3.2",
|
||||||
"typescript": "^4.0.3"
|
"typescript": "^4.0.5"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import * as style from './style.css';
|
import * as style from './style.css';
|
||||||
import 'add-css:./styles.css';
|
import 'add-css:./style.css';
|
||||||
import { UncheckedIcon, CheckedIcon } from '../../../icons';
|
import { UncheckedIcon, CheckedIcon } from '../../../icons';
|
||||||
|
|
||||||
interface Props extends preact.JSX.HTMLAttributes {}
|
interface Props extends preact.JSX.HTMLAttributes {}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { h, Component, ComponentChild, ComponentChildren } from 'preact';
|
import { h, Component, ComponentChild, ComponentChildren } from 'preact';
|
||||||
import * as style from './style.css';
|
import * as style from './style.css';
|
||||||
import 'add-css:./styles.css';
|
import 'add-css:./style.css';
|
||||||
import { transitionHeight } from '../../../util';
|
import { transitionHeight } from '../../../util';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -17,41 +17,39 @@ export default class Expander extends Component<Props, State> {
|
|||||||
private lastElHeight: number = 0;
|
private lastElHeight: number = 0;
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: Props) {
|
componentWillReceiveProps(nextProps: Props) {
|
||||||
const children = this.props.children as ComponentChild[];
|
const children = this.props.children as ComponentChild[] | undefined;
|
||||||
const nextChildren = nextProps.children as ComponentChild[];
|
const nextChildren = nextProps.children as ComponentChild[] | undefined;
|
||||||
|
|
||||||
if (!nextChildren[0] && children[0]) {
|
if (!nextChildren && children && children[0]) {
|
||||||
// Cache the current children for the shrink animation.
|
// Cache the current children for the shrink animation.
|
||||||
this.setState({ outgoingChildren: children });
|
this.setState({ outgoingChildren: children });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUpdate(nextProps: Props) {
|
componentWillUpdate(nextProps: Props) {
|
||||||
const children = this.props.children as ComponentChild[];
|
const children = this.props.children as ComponentChild[] | undefined;
|
||||||
const nextChildren = nextProps.children as ComponentChild[];
|
const nextChildren = nextProps.children as ComponentChild[] | undefined;
|
||||||
|
|
||||||
// Only interested if going from empty to not-empty, or not-empty to empty.
|
// Only interested if going from empty to not-empty, or not-empty to empty.
|
||||||
if ((children[0] && nextChildren[0]) || (!children[0] && !nextChildren[0]))
|
if ((children && nextChildren) || (!children && !nextChildren)) return;
|
||||||
return;
|
|
||||||
this.lastElHeight = (this
|
this.lastElHeight = (this
|
||||||
.base as HTMLElement).getBoundingClientRect().height;
|
.base as HTMLElement).getBoundingClientRect().height;
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidUpdate(previousProps: Props) {
|
async componentDidUpdate(previousProps: Props) {
|
||||||
const children = this.props.children as ComponentChild[];
|
const children = this.props.children as ComponentChild[] | undefined;
|
||||||
const previousChildren = previousProps.children as ComponentChild[];
|
const previousChildren = previousProps.children as
|
||||||
|
| ComponentChild[]
|
||||||
|
| undefined;
|
||||||
|
|
||||||
// Only interested if going from empty to not-empty, or not-empty to empty.
|
// Only interested if going from empty to not-empty, or not-empty to empty.
|
||||||
if (
|
if ((children && previousChildren) || (!children && !previousChildren))
|
||||||
(children[0] && previousChildren[0]) ||
|
|
||||||
(!children[0] && !previousChildren[0])
|
|
||||||
)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// What height do we need to transition to?
|
// What height do we need to transition to?
|
||||||
(this.base as HTMLElement).style.height = '';
|
(this.base as HTMLElement).style.height = '';
|
||||||
(this.base as HTMLElement).style.overflow = 'hidden';
|
(this.base as HTMLElement).style.overflow = 'hidden';
|
||||||
const newHeight = children[0]
|
const newHeight = children
|
||||||
? (this.base as HTMLElement).getBoundingClientRect().height
|
? (this.base as HTMLElement).getBoundingClientRect().height
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
@@ -68,12 +66,12 @@ export default class Expander extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(props: Props, { outgoingChildren }: State) {
|
render(props: Props, { outgoingChildren }: State) {
|
||||||
const children = props.children as ComponentChild[];
|
const children = props.children as ComponentChild[] | undefined;
|
||||||
const childrenExiting = !children[0] && outgoingChildren[0];
|
const childrenExiting = (!children || !children[0]) && outgoingChildren[0];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={childrenExiting ? style.childrenExiting : ''}>
|
<div class={childrenExiting ? style.childrenExiting : ''}>
|
||||||
{children[0] ? children : outgoingChildren}
|
{children && children[0] ? children : outgoingChildren}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import PointerTracker from 'pointer-tracker';
|
import PointerTracker from 'pointer-tracker';
|
||||||
import * as style from './style.css';
|
import * as style from './style.css';
|
||||||
import 'add-css:./styles.css';
|
import 'add-css:./style.css';
|
||||||
|
|
||||||
const RETARGETED_EVENTS = ['focus', 'blur'];
|
const RETARGETED_EVENTS = ['focus', 'blur'];
|
||||||
const UPDATE_EVENTS = ['input', 'change'];
|
const UPDATE_EVENTS = ['input', 'change'];
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import * as style from './style.css';
|
import * as style from './style.css';
|
||||||
import 'add-css:./styles.css';
|
import 'add-css:./style.css';
|
||||||
import RangeInputElement from './custom-els/RangeInput';
|
import RangeInputElement from './custom-els/RangeInput';
|
||||||
import '../../custom-els/RangeInput';
|
import './custom-els/RangeInput';
|
||||||
import { linkRef } from 'shared/initial-app/util';
|
import { linkRef } from 'shared/initial-app/util';
|
||||||
|
|
||||||
interface Props extends preact.JSX.HTMLAttributes {}
|
interface Props extends preact.JSX.HTMLAttributes {}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
color: #000;
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the number controls
|
/* Remove the number controls */
|
||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
|
|
||||||
&::-webkit-outer-spin-button,
|
&::-webkit-outer-spin-button,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import * as style from './style.css';
|
import * as style from './style.css';
|
||||||
import 'add-css:./styles.css';
|
import 'add-css:./style.css';
|
||||||
|
|
||||||
interface Props extends preact.JSX.HTMLAttributes {
|
interface Props extends preact.JSX.HTMLAttributes {
|
||||||
large?: boolean;
|
large?: boolean;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
|
|
||||||
import * as style from './style.css';
|
import * as style from './style.css';
|
||||||
import 'add-css:./styles.css';
|
import 'add-css:./style.css';
|
||||||
import { cleanSet, cleanMerge } from '../../util/clean-modify';
|
import { cleanSet, cleanMerge } from '../../util/clean-modify';
|
||||||
|
|
||||||
import type { SourceImage, OutputType } from '..';
|
import type { SourceImage, OutputType } from '..';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { ScaleToOpts } from './custom-els/PinchZoom';
|
|||||||
import './custom-els/PinchZoom';
|
import './custom-els/PinchZoom';
|
||||||
import './custom-els/TwoUp';
|
import './custom-els/TwoUp';
|
||||||
import * as style from './style.css';
|
import * as style from './style.css';
|
||||||
import 'add-css:./styles.css';
|
import 'add-css:./style.css';
|
||||||
import { shallowEqual, drawDataToCanvas } from '../../util';
|
import { shallowEqual, drawDataToCanvas } from '../../util';
|
||||||
import {
|
import {
|
||||||
ToggleBackgroundIcon,
|
ToggleBackgroundIcon,
|
||||||
|
|||||||
43
src/client/lazy-app/Compress/Results/FileSize.tsx
Normal file
43
src/client/lazy-app/Compress/Results/FileSize.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { h, Component } from 'preact';
|
||||||
|
import prettyBytes from 'pretty-bytes';
|
||||||
|
import * as style from './style.css';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
blob: Blob;
|
||||||
|
compareTo?: Blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {}
|
||||||
|
|
||||||
|
export default class FileSize extends Component<Props, State> {
|
||||||
|
render({ blob, compareTo }: Props) {
|
||||||
|
let comparison: preact.JSX.Element | undefined;
|
||||||
|
|
||||||
|
if (compareTo) {
|
||||||
|
const delta = blob.size / compareTo.size;
|
||||||
|
if (delta > 1) {
|
||||||
|
const percent = Math.round((delta - 1) * 100) + '%';
|
||||||
|
comparison = (
|
||||||
|
<span class={`${style.sizeDelta} ${style.sizeIncrease}`}>
|
||||||
|
{percent === '0%' ? 'slightly' : percent} bigger
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else if (delta < 1) {
|
||||||
|
const percent = Math.round((1 - delta) * 100) + '%';
|
||||||
|
comparison = (
|
||||||
|
<span class={`${style.sizeDelta} ${style.sizeDecrease}`}>
|
||||||
|
{percent === '0%' ? 'slightly' : percent} smaller
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
comparison = <span class={style.sizeDelta}>no change</span>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
{prettyBytes(blob.size)} {comparison}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
135
src/client/lazy-app/Compress/Results/index.tsx
Normal file
135
src/client/lazy-app/Compress/Results/index.tsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import { h, Component, ComponentChildren, ComponentChild } from 'preact';
|
||||||
|
|
||||||
|
import * as style from './style.css';
|
||||||
|
import 'add-css:./style.css';
|
||||||
|
import FileSize from './FileSize';
|
||||||
|
import {
|
||||||
|
DownloadIcon,
|
||||||
|
CopyAcrossIcon,
|
||||||
|
CopyAcrossIconProps,
|
||||||
|
} from 'client/lazy-app/icons';
|
||||||
|
import 'shared/initial-app/custom-els/loading-spinner';
|
||||||
|
import { SourceImage } from '../../compress';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
loading: boolean;
|
||||||
|
source?: SourceImage;
|
||||||
|
imageFile?: File;
|
||||||
|
downloadUrl?: string;
|
||||||
|
children: ComponentChildren;
|
||||||
|
copyDirection: CopyAcrossIconProps['copyDirection'];
|
||||||
|
buttonPosition: keyof typeof buttonPositionClass;
|
||||||
|
onCopyToOtherClick(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
showLoadingState: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttonPositionClass = {
|
||||||
|
'stack-right': style.stackRight,
|
||||||
|
'download-right': style.downloadRight,
|
||||||
|
'download-left': style.downloadLeft,
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadingReactionDelay = 500;
|
||||||
|
|
||||||
|
export default class Results extends Component<Props, State> {
|
||||||
|
state: State = {
|
||||||
|
showLoadingState: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The timeout ID between entering the loading state, and changing UI */
|
||||||
|
private loadingTimeoutId: number = 0;
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: Props, prevState: State) {
|
||||||
|
if (prevProps.loading && !this.props.loading) {
|
||||||
|
// Just stopped loading
|
||||||
|
clearTimeout(this.loadingTimeoutId);
|
||||||
|
this.setState({ showLoadingState: false });
|
||||||
|
} else if (!prevProps.loading && this.props.loading) {
|
||||||
|
// Just started loading
|
||||||
|
this.loadingTimeoutId = self.setTimeout(
|
||||||
|
() => this.setState({ showLoadingState: true }),
|
||||||
|
loadingReactionDelay,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onCopyToOtherClick = (event: Event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
this.props.onCopyToOtherClick();
|
||||||
|
};
|
||||||
|
|
||||||
|
private onDownload = () => {
|
||||||
|
// GA can’t do floats. So we round to ints. We're deliberately rounding to nearest kilobyte to
|
||||||
|
// avoid cases where exact image sizes leak something interesting about the user.
|
||||||
|
const before = Math.round(this.props.source!.file.size / 1024);
|
||||||
|
const after = Math.round(this.props.imageFile!.size / 1024);
|
||||||
|
const change = Math.round((after / before) * 1000);
|
||||||
|
|
||||||
|
ga('send', 'event', 'compression', 'download', {
|
||||||
|
metric1: before,
|
||||||
|
metric2: after,
|
||||||
|
metric3: change,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render(
|
||||||
|
{
|
||||||
|
source,
|
||||||
|
imageFile,
|
||||||
|
downloadUrl,
|
||||||
|
children,
|
||||||
|
copyDirection,
|
||||||
|
buttonPosition,
|
||||||
|
}: Props,
|
||||||
|
{ showLoadingState }: State,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<div class={`${style.results} ${buttonPositionClass[buttonPosition]}`}>
|
||||||
|
<div class={style.resultData}>
|
||||||
|
{children ? <div class={style.resultTitle}>{children}</div> : null}
|
||||||
|
{!imageFile || showLoadingState ? (
|
||||||
|
'Working…'
|
||||||
|
) : (
|
||||||
|
<FileSize
|
||||||
|
blob={imageFile}
|
||||||
|
compareTo={
|
||||||
|
source && imageFile !== source.file ? source.file : undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class={style.copyToOther}
|
||||||
|
title="Copy settings to other side"
|
||||||
|
onClick={this.onCopyToOtherClick}
|
||||||
|
>
|
||||||
|
<CopyAcrossIcon
|
||||||
|
class={style.copyIcon}
|
||||||
|
copyDirection={copyDirection}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class={style.download}>
|
||||||
|
{downloadUrl && imageFile && (
|
||||||
|
<a
|
||||||
|
class={`${style.downloadLink} ${
|
||||||
|
showLoadingState ? style.downloadLinkDisable : ''
|
||||||
|
}`}
|
||||||
|
href={downloadUrl}
|
||||||
|
download={imageFile.name}
|
||||||
|
title="Download"
|
||||||
|
onClick={this.onDownload}
|
||||||
|
>
|
||||||
|
<DownloadIcon class={style.downloadIcon} />
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
{showLoadingState && <loading-spinner class={style.spinner} />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
131
src/client/lazy-app/Compress/Results/style.css
Normal file
131
src/client/lazy-app/Compress/Results/style.css
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
@keyframes action-enter {
|
||||||
|
from {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
opacity: 0;
|
||||||
|
animation-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes action-leave {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
opacity: 1;
|
||||||
|
animation-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.results {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: [text] 1fr [copy-button] auto [download-button] auto;
|
||||||
|
background: rgba(0, 0, 0, 0.9);
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
@media (min-width: 400px) {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 600px) {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-data {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: text;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-right {
|
||||||
|
grid-template-columns: [copy-button] auto [text] 1fr [download-button] auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-left {
|
||||||
|
grid-template-columns: [download-button] auto [text] 1fr [copy-button] auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stack-right {
|
||||||
|
& .result-data {
|
||||||
|
padding: 0 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 0.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size-delta {
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-style: italic;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
margin-left: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size-increase {
|
||||||
|
color: #e35050;
|
||||||
|
}
|
||||||
|
|
||||||
|
.size-decrease {
|
||||||
|
color: #50e3c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: download-button;
|
||||||
|
background: #34b9eb;
|
||||||
|
--size: 38px;
|
||||||
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
|
justify-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-link {
|
||||||
|
animation: action-enter 0.2s;
|
||||||
|
grid-area: 1/1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-link-disable {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
animation: action-leave 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-icon,
|
||||||
|
.copy-icon {
|
||||||
|
color: #fff;
|
||||||
|
display: block;
|
||||||
|
--size: 24px;
|
||||||
|
width: var(--size);
|
||||||
|
height: var(--size);
|
||||||
|
padding: 7px;
|
||||||
|
filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.7));
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
--color: #fff;
|
||||||
|
--delay: 0;
|
||||||
|
--size: 22px;
|
||||||
|
grid-area: 1/1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-to-other {
|
||||||
|
grid-row: 1;
|
||||||
|
grid-column: copy-button;
|
||||||
|
composes: unbutton from '../../../../shared/initial-app/util.css';
|
||||||
|
composes: download;
|
||||||
|
|
||||||
|
background: #656565;
|
||||||
|
}
|
||||||
@@ -27,8 +27,7 @@ import Options from './Options';
|
|||||||
import ResultCache from './result-cache';
|
import ResultCache from './result-cache';
|
||||||
import { cleanMerge, cleanSet } from '../util/clean-modify';
|
import { cleanMerge, cleanSet } from '../util/clean-modify';
|
||||||
import './custom-els/MultiPanel';
|
import './custom-els/MultiPanel';
|
||||||
// TODO: you are here
|
import Results from './results';
|
||||||
import Results from '../results';
|
|
||||||
import WorkerBridge from '../worker-bridge';
|
import WorkerBridge from '../worker-bridge';
|
||||||
import { resize } from 'features/processors/resize/client';
|
import { resize } from 'features/processors/resize/client';
|
||||||
import type SnackBarElement from 'shared/initial-app/custom-els/snack-bar';
|
import type SnackBarElement from 'shared/initial-app/custom-els/snack-bar';
|
||||||
@@ -462,7 +461,10 @@ export default class Compress extends Component<Props, State> {
|
|||||||
preprocessorState: currentState.preprocessorState,
|
preprocessorState: currentState.preprocessorState,
|
||||||
};
|
};
|
||||||
const sideJobStates: SideJob[] = currentState.sides.map((side) => ({
|
const sideJobStates: SideJob[] = currentState.sides.map((side) => ({
|
||||||
processorState: side.latestSettings.processorState,
|
// If there isn't an encoder selected, we don't process either
|
||||||
|
processorState: side.latestSettings.encoderState
|
||||||
|
? side.latestSettings.processorState
|
||||||
|
: defaultProcessorState,
|
||||||
encoderState: side.latestSettings.encoderState,
|
encoderState: side.latestSettings.encoderState,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -471,14 +473,18 @@ export default class Compress extends Component<Props, State> {
|
|||||||
const needsPreprocessing =
|
const needsPreprocessing =
|
||||||
needsDecoding ||
|
needsDecoding ||
|
||||||
latestMainJobState.preprocessorState !== mainJobState.preprocessorState;
|
latestMainJobState.preprocessorState !== mainJobState.preprocessorState;
|
||||||
const sideWorksNeeded = latestSideJobStates.map((latestSideJob, i) => ({
|
const sideWorksNeeded = latestSideJobStates.map((latestSideJob, i) => {
|
||||||
processing:
|
const needsProcessing =
|
||||||
needsPreprocessing ||
|
needsPreprocessing ||
|
||||||
latestSideJob.processorState !== sideJobStates[i].processorState,
|
latestSideJob.processorState !== sideJobStates[i].processorState;
|
||||||
|
|
||||||
|
return {
|
||||||
|
processing: needsProcessing,
|
||||||
encoding:
|
encoding:
|
||||||
needsPreprocessing ||
|
needsProcessing ||
|
||||||
latestSideJob.encoderState !== sideJobStates[i].encoderState,
|
latestSideJob.encoderState !== sideJobStates[i].encoderState,
|
||||||
}));
|
};
|
||||||
|
});
|
||||||
|
|
||||||
let jobNeeded = false;
|
let jobNeeded = false;
|
||||||
|
|
||||||
@@ -499,7 +505,12 @@ export default class Compress extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!jobNeeded) {
|
if (!jobNeeded) {
|
||||||
// Clear any loading that may be happening
|
// Clear any loading that may be happening.
|
||||||
|
// Putting this behind an if to avoid looping.
|
||||||
|
if (
|
||||||
|
currentState.loading ||
|
||||||
|
currentState.sides.some((side) => side.loading)
|
||||||
|
) {
|
||||||
this.setState((state) => ({
|
this.setState((state) => ({
|
||||||
loading: false,
|
loading: false,
|
||||||
sides: state.sides.map((side) => ({ ...side, loading: false })) as [
|
sides: state.sides.map((side) => ({ ...side, loading: false })) as [
|
||||||
@@ -507,6 +518,7 @@ export default class Compress extends Component<Props, State> {
|
|||||||
Side,
|
Side,
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,7 +657,7 @@ export default class Compress extends Component<Props, State> {
|
|||||||
// If there's no encoder state, this is "original image", which also
|
// If there's no encoder state, this is "original image", which also
|
||||||
// doesn't allow processing.
|
// doesn't allow processing.
|
||||||
if (!jobState.encoderState) {
|
if (!jobState.encoderState) {
|
||||||
file = currentState.source!.file;
|
file = source.file;
|
||||||
data = source.preprocessed;
|
data = source.preprocessed;
|
||||||
} else {
|
} else {
|
||||||
const cacheResult = this.encodeCache.match(
|
const cacheResult = this.encodeCache.match(
|
||||||
@@ -731,10 +743,7 @@ export default class Compress extends Component<Props, State> {
|
|||||||
loading: false,
|
loading: false,
|
||||||
processed,
|
processed,
|
||||||
encodedSettings: {
|
encodedSettings: {
|
||||||
// If we didn't encode, we didn't preprocess either
|
processorState: jobState.processorState,
|
||||||
processorState: jobState.encoderState
|
|
||||||
? jobState.processorState
|
|
||||||
: defaultProcessorState,
|
|
||||||
encoderState: jobState.encoderState,
|
encoderState: jobState.encoderState,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { wrap } from 'comlink';
|
import { wrap } from 'comlink';
|
||||||
import { BridgeMethods, methodNames } from './meta';
|
import { BridgeMethods, methodNames } from './meta';
|
||||||
import workerURL from 'omt:../features-worker';
|
import workerURL from 'omt:../../../features-worker';
|
||||||
import type { ProcessorWorkerApi } from '../../../features-worker';
|
import type { ProcessorWorkerApi } from '../../../features-worker';
|
||||||
import { abortable } from '../util';
|
import { abortable } from '../util';
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
/// <reference path="../../../../../missing-types.d.ts" />
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
/// <reference path="../../../../../missing-types.d.ts" />
|
|
||||||
Reference in New Issue
Block a user