Compare commits

..

278 Commits

Author SHA1 Message Date
daemon1024
f5a6ceae62 modify read log util and make a single test pass by adding blocking code 2021-03-12 22:08:06 +00:00
Jeffrey Warren
a8ae036077 Merge branch 'main' into daemon1024/cli-test-suite-1747 2021-03-12 12:33:56 -05:00
waridrox
417c1b1826 Fixed buggy file upload container (#1841)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-03-11 23:24:49 -05:00
Shazeb Ata
5298d1e0ec Convert url to blob for large file size download (#1455)
* Convert url to blob for large size download

* Replaced var with let

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-03-11 11:23:58 -05:00
dependabot-preview[bot]
7751024d71 Bump jspdf from 2.3.0 to 2.3.1 (#1838)
Bumps [jspdf](https://github.com/MrRio/jsPDF) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/MrRio/jsPDF/releases)
- [Changelog](https://github.com/MrRio/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/MrRio/jsPDF/compare/v2.3.0...v2.3.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-10 14:10:54 -05:00
dependabot-preview[bot]
3204bafd44 Bump imagemin-pngquant from 9.0.1 to 9.0.2 (#1835)
Bumps [imagemin-pngquant](https://github.com/imagemin/imagemin-pngquant) from 9.0.1 to 9.0.2.
- [Release notes](https://github.com/imagemin/imagemin-pngquant/releases)
- [Commits](https://github.com/imagemin/imagemin-pngquant/compare/v9.0.1...v9.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-10 12:35:27 -05:00
dependabot-preview[bot]
3b8181a26a Bump @babel/core from 7.13.8 to 7.13.10 (#1837)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.13.8 to 7.13.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.13.10/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-09 12:06:57 -05:00
dependabot-preview[bot]
66442b9d25 [Security] Bump elliptic from 6.5.3 to 6.5.4 (#1836)
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4. **This update includes a security fix.**
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-08 16:37:05 -05:00
dependabot-preview[bot]
5cef13ba9a Bump jsdom from 16.4.0 to 16.5.0 (#1834)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 16.4.0 to 16.5.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/16.4.0...16.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-08 08:44:07 -05:00
daemon1024
73b49371ab test cli steps parsing 2021-03-07 22:26:26 +00:00
daemon1024
f6949c9bbd make utility to read stdout and stderr 2021-03-07 22:26:11 +00:00
dependabot-preview[bot]
b04a5cbc6c Bump tape from 5.2.1 to 5.2.2 (#1832)
Bumps [tape](https://github.com/substack/tape) from 5.2.1 to 5.2.2.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v5.2.1...v5.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-04 00:36:55 -05:00
dependabot-preview[bot]
48b08c69da Bump @babel/plugin-proposal-object-rest-spread from 7.13.0 to 7.13.8 (#1828)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-object-rest-spread) from 7.13.0 to 7.13.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.13.8/packages/babel-plugin-proposal-object-rest-spread)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-03-03 10:16:16 -05:00
Vivek Singh
f31859bd9c made update-prompt responsive (#1831) 2021-03-03 09:26:34 -05:00
dependabot-preview[bot]
e34f69c706 Bump @babel/core from 7.13.1 to 7.13.8 (#1827)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.13.1 to 7.13.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.13.8/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-01 15:09:15 -05:00
dependabot-preview[bot]
269703a27b Bump tape from 5.2.0 to 5.2.1 (#1829)
Bumps [tape](https://github.com/substack/tape) from 5.2.0 to 5.2.1.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v5.2.0...v5.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-03-01 12:24:13 -05:00
Vivek Singh
71bf8c872b Try To fetch latest data first then shift to cached one. (#1819)
* fetch latest data first then shift to cached one

* improved offline experience

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-27 11:38:45 -05:00
daemon1024
0580218c63 use t.plan instead of t.end
plan the no of tape tests instead of waiting for ending in options-test
2021-02-26 21:05:15 +00:00
daemon1024
cc297ee3f7 use Float32Array instead of standard array in expected output in tests 2021-02-26 21:05:15 +00:00
dependabot-preview[bot]
e5039d8daa Bump tape from 4.13.0 to 5.2.0
Bumps [tape](https://github.com/substack/tape) from 4.13.0 to 5.2.0.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v4.13.0...v5.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-26 21:05:15 +00:00
dependabot-preview[bot]
f59b64fb96 Bump lodash from 4.17.20 to 4.17.21 (#1823)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-23 14:13:37 -05:00
dependabot-preview[bot]
aa3238e1ba Bump @babel/plugin-proposal-object-rest-spread from 7.12.13 to 7.13.0 (#1822)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-object-rest-spread) from 7.12.13 to 7.13.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.13.0/packages/babel-plugin-proposal-object-rest-spread)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-23 14:09:34 -05:00
dependabot-preview[bot]
3a3abd28bd Bump @babel/core from 7.12.17 to 7.13.1 (#1821)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.17 to 7.13.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.13.1/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-23 14:02:31 -05:00
Vivek Singh
3b857796af Notify Users for the failure in loading Image via external URL (#1813)
* Load image via URL

* notify users for image load failue due to CORS error

* added a check for notifybox

* added some more checks

* added bootstrap version v4 classes

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-19 14:29:43 -05:00
Vivek Singh
e08b706497 close webcam auto. after clicking picture (#1816)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-19 10:42:59 -05:00
Vivek Singh
72175fa789 notify users for selecting empty step (#1818)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-19 10:26:05 -05:00
dependabot-preview[bot]
97b4f38db3 Bump @babel/core from 7.12.16 to 7.12.17 (#1817)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.16 to 7.12.17.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.17/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-19 10:19:22 -05:00
GuptaTanisha
9a281746bf Update Modules.js to add documentation (#1814) 2021-02-17 12:32:15 -05:00
dependabot-preview[bot]
25275e4987 Bump commander from 7.0.0 to 7.1.0 (#1812)
Bumps [commander](https://github.com/tj/commander.js) from 7.0.0 to 7.1.0.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v7.0.0...v7.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-16 00:45:23 -05:00
Jeffrey Warren
4609d0a9c6 switch to expr-eval for dynamic module (#1729)
* switch to expr-eval for dynamic module

* added expr-eval module

* Update Module.js

* update options test to correctly label varied options

* Update options-test.js

* make expressions/options case insensitive

* Update Module.js

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2021-02-15 13:22:31 -05:00
Vivek Singh
0bdf71a47d fixed registration problem of service worker (#1807)
* fixed registration problem of service worker

* added a test for service worker

* reused some existing code to avoid code duplication

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-15 11:48:52 -05:00
Vivek Singh
ed94a0fb39 Text Alignment made easy and convenient. (#1804)
* text alignment made easy

* added description and removed id

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-15 11:45:58 -05:00
dependabot-preview[bot]
49a21cf4a9 Bump @babel/core from 7.12.13 to 7.12.16 (#1809)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.13 to 7.12.16.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.16/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-12 07:59:22 -05:00
Tanish
eb81b7de4b standardised util functions comments (#1805)
* standardised util functions comments

* Update pixelSetter.js

* Update pixelSetter.js

* Update pixelSetter.js

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2021-02-10 10:19:36 -05:00
dependabot-preview[bot]
a73cba8d3c Bump commander from 6.2.0 to 7.0.0 (#1791)
* Bump commander from 6.2.0 to 7.0.0

Bumps [commander](https://github.com/tj/commander.js) from 6.2.0 to 7.0.0.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v6.2.0...v7.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* migrate code for commander 7.0.0

* generate new program on each function call

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: daemon1024 <barun1024@gmail.com>
Co-authored-by: Barun Acharya <47106543+daemon1024@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-08 18:05:20 -05:00
dependabot-preview[bot]
240fd5356d Bump lint-staged from 10.5.3 to 10.5.4
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.5.3 to 10.5.4.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.5.3...v10.5.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-08 15:52:36 +00:00
Vivek Singh
f7ca35af23 improved way of displaying docs link (#1799)
* improved the way of displaying the doc links

* fix: check whether docs-link exists

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-06 16:05:02 -05:00
dependabot-preview[bot]
d340a78aab Bump looks-same from 7.2.4 to 7.3.0 (#1803)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.2.4 to 7.3.0.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v7.2.4...v7.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-04 01:23:07 -05:00
Barun Acharya
ea39f4ad88 refactor cli code (#1785)
* use template for commander instance in clitest

* remove unnecessary log

* use named export instead of default

* refactor cli code to another file to make it testable

* refactor cli.js into src/cli

* refactor

* refactor

* refactor

* refactor

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-02-03 23:29:06 -05:00
dependabot-preview[bot]
911651260a Bump @babel/core from 7.12.10 to 7.12.13 (#1801)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.10 to 7.12.13.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.13/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-03 19:34:40 -05:00
dependabot-preview[bot]
0fc3539f38 Bump @babel/plugin-proposal-object-rest-spread from 7.12.1 to 7.12.13 (#1802)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-object-rest-spread) from 7.12.1 to 7.12.13.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.13/packages/babel-plugin-proposal-object-rest-spread)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-02-03 19:28:40 -05:00
Vivek Singh
d9779f8bf4 stopped processing when camera access is not given and fixed the working of close button (#1797)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-01-29 07:39:05 -05:00
dependabot-preview[bot]
bd2187b2a0 Bump jspdf from 2.1.1 to 2.3.0 (#1794)
Bumps [jspdf](https://github.com/MrRio/jsPDF) from 2.1.1 to 2.3.0.
- [Release notes](https://github.com/MrRio/jsPDF/releases)
- [Changelog](https://github.com/MrRio/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/MrRio/jsPDF/compare/v2.1.1...v2.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-01-25 13:59:06 -05:00
Jeffrey Warren
e5ea6e5978 adjust gitpod settings to be able to run jest tests in gitpod (#1798)
* add xvfb to gitpod dockerfile to run jest tests in gitpod

* Update .gitpod.dockerfile

* jest running in gitpod, some timeouts
2021-01-25 13:53:17 -05:00
Vivek Singh
ffdba0b9a6 fixed unable to load version problem (#1789)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-01-25 10:22:39 -05:00
dependabot-preview[bot]
3ead0ee24c Bump ora from 5.1.0 to 5.3.0 (#1796)
Bumps [ora](https://github.com/sindresorhus/ora) from 5.1.0 to 5.3.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v5.1.0...v5.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-01-21 07:18:48 -05:00
dependabot-preview[bot]
729759e06a Bump geotiff from 1.0.0-beta.14 to 1.0.0-beta.16 (#1795)
Bumps [geotiff](https://github.com/geotiffjs/geotiff.js) from 1.0.0-beta.14 to 1.0.0-beta.16.
- [Release notes](https://github.com/geotiffjs/geotiff.js/releases)
- [Commits](https://github.com/geotiffjs/geotiff.js/compare/v1.0.0-beta.14...v1.0.0-beta.16)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-01-21 07:10:11 -05:00
dependabot-preview[bot]
04d2eca3c0 Bump compressorjs from 1.0.6 to 1.0.7
Bumps [compressorjs](https://github.com/fengyuanchen/compressorjs) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/fengyuanchen/compressorjs/releases)
- [Changelog](https://github.com/fengyuanchen/compressorjs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/fengyuanchen/compressorjs/compare/v1.0.6...v1.0.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-20 13:21:51 +00:00
dependabot-preview[bot]
64e6da3c41 Bump jasmine from 3.6.3 to 3.6.4 (#1793)
Bumps [jasmine](https://github.com/jasmine/jasmine-npm) from 3.6.3 to 3.6.4.
- [Release notes](https://github.com/jasmine/jasmine-npm/releases)
- [Commits](https://github.com/jasmine/jasmine-npm/compare/v3.6.3...v3.6.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-01-20 08:09:38 -05:00
dependabot-preview[bot]
ec2aa108c1 Bump gpu.js from 2.10.5 to 2.11.2 (#1790)
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.10.5 to 2.11.2.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits/2.11.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-01-20 01:57:45 -05:00
dependabot-preview[bot]
a3b4044a0b Bump looks-same from 7.2.3 to 7.2.4 (#1766)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.2.3 to 7.2.4.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v7.2.3...v7.2.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2021-01-19 11:19:26 -05:00
dependabot-preview[bot]
a47039a411 [Security] Bump node-notifier from 8.0.0 to 8.0.1
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1. **This update includes a security fix.**
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-19 15:59:14 +00:00
dependabot-preview[bot]
616932823d Bump @babel/core from 7.12.3 to 7.12.10 (#1779)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.3 to 7.12.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.10/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-01-19 10:53:36 -05:00
dependabot-preview[bot]
8730dd8136 [Security] Bump ini from 1.3.5 to 1.3.8
Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. **This update includes security fixes.**
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-19 13:45:55 +00:00
dependabot-preview[bot]
a1ca60a29d Bump buffer from 6.0.2 to 6.0.3 (#1771)
* Bump lint-staged from 10.5.1 to 10.5.3

Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.5.1 to 10.5.3.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.5.1...v10.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* Bump buffer from 6.0.2 to 6.0.3

Bumps [buffer](https://github.com/feross/buffer) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/feross/buffer/releases)
- [Commits](https://github.com/feross/buffer/compare/v6.0.2...v6.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-01-19 08:39:03 -05:00
dependabot-preview[bot]
0d7ab2bbda Bump lint-staged from 10.5.1 to 10.5.3
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.5.1 to 10.5.3.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.5.1...v10.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-19 13:31:45 +00:00
Jeffrey Warren
580a154f33 try moving to Github Actions from Travis for CI (#1783)
* try moving to Github Actions from Travis for CI

* npm install

* add apt-get prereqs

* Update continuous-integration.yml

* Update .github/workflows/continuous-integration.yml

Co-authored-by: Barun Acharya <47106543+daemon1024@users.noreply.github.com>

* use resemblejs in gif-tests

* trying `npm run setup`

* fix: use ubuntu latest for github actions

Co-authored-by: Barun Acharya <47106543+daemon1024@users.noreply.github.com>

* Update .github/workflows/continuous-integration.yml

* fix: try more changes

- fix: install `libcairo2-dev` explicitly with apt.
- fix: use Ubuntu 18.04

* fix<actions>: merge dependency installs in one command

* fix<actions>: include more dependencies

* GitHub actions running parallel (#1787)

* try running tests parallely

* setup composite actions

* Update continuous-integration.yml

* setup all jobs

* just install instead of setup

* trying ci without ubuntu package deps

* cache node modules in ci

* remove action.yml

* name change for brevity

* add recommended deps for tape-run

* xvfb-run --auto-servernum npm run core-tests

Co-authored-by: Barun Acharya <47106543+daemon1024@users.noreply.github.com>
Co-authored-by: daemon1024 <barun1024@gmail.com>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2021-01-19 07:48:12 -05:00
Jeffrey Warren
fc799bfa6a Add 0.05 step size for halftone rotation slider (#1777)
Fixes #1775
2020-12-05 12:58:28 -05:00
Jeffrey Warren
5a6d5560ff Add test for range step size for int (1) vs float (0.1) (#1776)
* Add test for range step size for int (1) vs float (0.1)

* Remove old default setting for integer

* fixed tests
2020-12-05 12:34:49 -05:00
Jeffrey Warren
cbaa0f0f6f Update index.html 2020-11-17 15:39:59 -05:00
dependabot-preview[bot]
ba34f100d0 Bump gpu.js from 2.10.4 to 2.10.5
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.10.4 to 2.10.5.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-13 17:24:31 +00:00
dependabot-preview[bot]
62c3cdb8bd Bump buffer from 5.7.0 to 6.0.2 (#1764)
Bumps [buffer](https://github.com/feross/buffer) from 5.7.0 to 6.0.2.
- [Release notes](https://github.com/feross/buffer/releases)
- [Commits](https://github.com/feross/buffer/compare/v5.7.0...v6.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-11-10 10:53:46 -05:00
dependabot-preview[bot]
2159d03e76 Bump jest from 26.6.2 to 26.6.3 (#1763)
Bumps [jest](https://github.com/facebook/jest) from 26.6.2 to 26.6.3.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v26.6.2...v26.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-11-05 01:25:46 -05:00
Rishabh Shukla
f0cb35a0aa Alpha masking module (#1546)
* Mask module added

* add mask module

* add test for alpha masking

* update Readme

Co-authored-by: h <f>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-11-03 11:18:49 -05:00
dependabot-preview[bot]
149e8d2150 Bump lint-staged from 10.5.0 to 10.5.1
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.5.0 to 10.5.1.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.5.0...v10.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-03 13:18:03 +00:00
dependabot-preview[bot]
127d417e40 Bump jest from 26.6.1 to 26.6.2
Bumps [jest](https://github.com/facebook/jest) from 26.6.1 to 26.6.2.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v26.6.1...v26.6.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-03 13:00:02 +00:00
dependabot-preview[bot]
8c57b2393f Bump jasmine from 3.6.1 to 3.6.3
Bumps [jasmine](https://github.com/jasmine/jasmine-npm) from 3.6.1 to 3.6.3.
- [Release notes](https://github.com/jasmine/jasmine-npm/releases)
- [Commits](https://github.com/jasmine/jasmine-npm/compare/v3.6.1...v3.6.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-03 12:30:57 +00:00
dependabot-preview[bot]
a9bb7c6834 Bump ora from 4.0.3 to 5.1.0 (#1760)
Bumps [ora](https://github.com/sindresorhus/ora) from 4.0.3 to 5.1.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v4.0.3...v5.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-11-03 07:08:39 -05:00
Josh Levinger
a8f8029a83 Upgrade picomatch so image-sequencer works in Safari (#1740)
* upgrade picomatch

for publiclab/image-sequencer#1738

* fix: remove picomatch from package.json

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-11-02 14:44:01 -05:00
dependabot-preview[bot]
3e91725bda Bump browserify from 16.5.0 to 17.0.0 (#1754)
Bumps [browserify](https://github.com/browserify/browserify) from 16.5.0 to 17.0.0.
- [Release notes](https://github.com/browserify/browserify/releases)
- [Changelog](https://github.com/browserify/browserify/blob/master/changelog.markdown)
- [Commits](https://github.com/browserify/browserify/compare/v16.5.0...v17.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-11-02 11:37:05 -05:00
dependabot-preview[bot]
b5135c716c Bump data-uri-to-buffer from 3.0.0 to 3.0.1 (#1755)
Bumps [data-uri-to-buffer](https://github.com/TooTallNate/node-data-uri-to-buffer) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/TooTallNate/node-data-uri-to-buffer/releases)
- [Commits](https://github.com/TooTallNate/node-data-uri-to-buffer/compare/3.0.0...3.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-11-02 11:27:38 -05:00
dependabot-preview[bot]
e2cd7b1950 Bump buffer from 5.6.0 to 5.7.0
Bumps [buffer](https://github.com/feross/buffer) from 5.6.0 to 5.7.0.
- [Release notes](https://github.com/feross/buffer/releases)
- [Commits](https://github.com/feross/buffer/compare/v5.6.0...v5.7.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-02 15:31:26 +00:00
dependabot-preview[bot]
4e9324b81e [Security] Bump acorn from 6.0.2 to 6.4.2
Bumps [acorn](https://github.com/acornjs/acorn) from 6.0.2 to 6.4.2. **This update includes security fixes.**
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.0.2...6.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-11-02 15:09:00 +00:00
Nirav Asher
1af80b325a New Shadow module (#1507)
* circular gradient module

* Shadow module added

* fixed minor documentation error

* fixed small errors

* added test for shadow module

* updated shadow module to receive x and y inputs

* final shadow module with two inputs

* fixed test for shadow module

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-11-02 09:53:30 -05:00
Harsh Khandeparkar
77a9f01e33 Change release issue template slightly (#1752)
* Update release_workflow.md

* Update release_workflow.md

* Update release_workflow.md
2020-11-02 00:18:04 -05:00
Aditya Zope
893bc108e0 Parse floating-point value from percentages (#1733)
* Parse floating-point value from percentages

* Add tests for resize module

* Add options' test for resize module

Co-authored-by: Aditya Zope <zope@Adityas-MacBook-Pro.local>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-11-02 00:08:36 -05:00
Rishabh Shukla
0622a0c21a Add support for transparent image in overlay module (#1606)
* add support for transparent image overlay

* replaced var for const/let

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-11-01 11:36:13 -05:00
dependabot-preview[bot]
67e11edcd8 Bump jspdf from 1.5.3 to 2.1.1 (#1737)
Bumps [jspdf](https://github.com/MrRio/jsPDF) from 1.5.3 to 2.1.1.
- [Release notes](https://github.com/MrRio/jsPDF/releases)
- [Changelog](https://github.com/MrRio/jsPDF/blob/master/RELEASE.md)
- [Commits](https://github.com/MrRio/jsPDF/compare/v1.5.3...v2.1.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-11-01 10:53:07 -05:00
dependabot-preview[bot]
195a54d355 Bump grunt from 1.1.0 to 1.3.0 (#1749)
Bumps [grunt](https://github.com/gruntjs/grunt) from 1.1.0 to 1.3.0.
- [Release notes](https://github.com/gruntjs/grunt/releases)
- [Changelog](https://github.com/gruntjs/grunt/blob/master/CHANGELOG)
- [Commits](https://github.com/gruntjs/grunt/compare/v1.1.0...v1.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-31 16:51:09 -04:00
dependabot-preview[bot]
0f1a8f922b Bump jasmine-spec-reporter from 4.2.1 to 6.0.0 (#1750)
Bumps [jasmine-spec-reporter](https://github.com/bcaudan/jasmine-spec-reporter) from 4.2.1 to 6.0.0.
- [Release notes](https://github.com/bcaudan/jasmine-spec-reporter/releases)
- [Changelog](https://github.com/bcaudan/jasmine-spec-reporter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bcaudan/jasmine-spec-reporter/compare/v4.2.1...v6.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-10-31 13:18:28 -04:00
dependabot-preview[bot]
0fe8c1e7a1 Bump @babel/core from 7.12.0 to 7.12.3 (#1748)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.12.0 to 7.12.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.3/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-10-31 07:59:13 -04:00
dependabot-preview[bot]
e10678e8d8 Bump pngquant-bin from 5.0.2 to 6.0.0
Bumps [pngquant-bin](https://github.com/imagemin/pngquant-bin) from 5.0.2 to 6.0.0.
- [Release notes](https://github.com/imagemin/pngquant-bin/releases)
- [Commits](https://github.com/imagemin/pngquant-bin/compare/v5.0.2...v6.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-30 20:11:51 +00:00
dependabot-preview[bot]
183b75373f Bump geotiff from 1.0.0-beta.13 to 1.0.0-beta.14 (#1745)
Bumps [geotiff](https://github.com/geotiffjs/geotiff.js) from 1.0.0-beta.13 to 1.0.0-beta.14.
- [Release notes](https://github.com/geotiffjs/geotiff.js/releases)
- [Commits](https://github.com/geotiffjs/geotiff.js/compare/v1.0.0-beta.13...v1.0.0-beta.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-30 16:04:50 -04:00
dependabot-preview[bot]
775378d8fd Bump lint-staged from 10.4.2 to 10.5.0 (#1746)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.4.2 to 10.5.0.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.4.2...v10.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-10-30 15:41:18 -04:00
dependabot-preview[bot]
4e3d9f97c0 Bump commander from 4.1.0 to 6.2.0 (#1744)
Bumps [commander](https://github.com/tj/commander.js) from 4.1.0 to 6.2.0.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v4.1.0...v6.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-30 11:19:04 -04:00
dependabot-preview[bot]
fddf2b6ed8 Bump jest from 26.1.0 to 26.6.1 (#1742)
Bumps [jest](https://github.com/facebook/jest) from 26.1.0 to 26.6.1.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v26.1.0...v26.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-30 11:07:07 -04:00
Barun Acharya
a5e3584ea8 adding tests for CLI functionality (#1718)
* test: add a basic cli test for savesequence

* refactor cli-test

* Run cli tests seperately

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-10-29 07:42:09 -04:00
dependabot-preview[bot]
a82bdea390 Bump looks-same from 7.2.2 to 7.2.3 (#1736)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.2.2 to 7.2.3.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v7.2.2...v7.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-28 16:57:47 -04:00
Harsh Khandeparkar
099e7e2e1d Scripts to update gh-pages (#1739)
* Create update-gh-pages

* fix: pull from stable branch instead of main

* fix: make script executable

* fix: add scripts/ to CODEOWNERS file

* fix: option to choose upstream branch

* feat: completely refactor the script

* docs<CONTRIBUTING>: document the scripts

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-28 16:47:57 -04:00
dependabot-preview[bot]
5408467800 Bump jsdom from 16.3.0 to 16.4.0 (#1735)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 16.3.0 to 16.4.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/16.3.0...16.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-28 16:35:29 -04:00
Jeffrey Warren
30c3fba933 Update and rename .github/ISSUE_TEMPLATE.md to .github/ISSUE_TEMPLATE/bug_report.md 2020-10-28 16:23:03 -04:00
Jeffrey Warren
cfd3750b68 Update release_workflow.md 2020-10-28 16:20:00 -04:00
Jeffrey Warren
fadaebcdb6 Update release_workflow.md 2020-10-28 16:18:45 -04:00
Jeffrey Warren
10f2739435 Create release_workflow.md 2020-10-28 16:16:34 -04:00
Jeffrey Warren
3caa033c8f Update demo.css to fix font links to League Spartan CDN via fontsource - (#1741)
https://cdn.jsdelivr.net/npm/fontsource-league-spartan@3.0.5/files/
2020-10-27 11:05:18 -04:00
Harsh Khandeparkar
14f13c300b fix: bump lockfile and sw.js versions (#1734) 2020-10-22 10:13:35 -04:00
Jeffrey Warren
a2d654321d Bump to v3.6.0 for new npm release (#1695)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-10-18 16:13:10 -04:00
dependabot-preview[bot]
ad2f63ce4f Bump jasmine-core from 3.5.0 to 3.6.0 (#1730)
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/main/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v3.5.0...v3.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-18 15:54:08 -04:00
dependabot-preview[bot]
82601ecbea Bump gpu.js from 2.9.5 to 2.10.4 (#1731)
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.9.5 to 2.10.4.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-18 11:16:03 -04:00
dependabot-preview[bot]
c750958add Bump lint-staged from 10.2.11 to 10.4.2 (#1732)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.2.11 to 10.4.2.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.2.11...v10.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-10-17 17:57:38 -04:00
Harsh Khandeparkar
e1c8a5f218 Edge Detect Horizontal Edges Got Fixed (#1696)
* fix: edge detect horizontal angle fixed

* test: fix edge detect tests

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-17 11:46:58 -04:00
Adam G
8c461bbeee Make the site responsive (#1382)
* Removed line 47 & 68, added line 154

* Line 61 removed inline styles from header

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-17 11:34:18 -04:00
dependabot-preview[bot]
11478ce421 Bump lodash from 4.17.19 to 4.17.20 (#1720)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.20.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.20)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-10-17 11:16:52 -04:00
dependabot-preview[bot]
fa02c9f1c4 Bump jsqr from 1.2.0 to 1.3.1
Bumps [jsqr](https://github.com/cozmo/jsQR) from 1.2.0 to 1.3.1.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-17 06:51:12 +00:00
Shazeb Ata
f4baebd7c7 Change dimension upon loading through camera (#1456)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-16 16:56:40 -04:00
dependabot-preview[bot]
d0172f91ff Bump @babel/plugin-proposal-object-rest-spread from 7.11.0 to 7.12.1 (#1726)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-object-rest-spread) from 7.11.0 to 7.12.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.1/packages/babel-plugin-proposal-object-rest-spread)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-10-16 11:16:42 -04:00
Shazeb Ata
c0cf8798a7 Hide ui on each draw (#1559)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-10-16 10:24:57 +05:30
Rishabh Shukla
d33afe09da refactored resize (#1562)
Co-authored-by: h <f>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-16 10:04:59 +05:30
Akshay Gupta
1713751728 Colorbar module default overlay shift fixed (#1542)
* Fixes #1538

* Fixes #1538

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-10-16 09:48:55 +05:30
Harsh Khandeparkar
a7993d5f7b Text Overlay Works (#1561)
Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
2020-10-16 08:55:11 +05:30
Mansi Sharma
31eaba8912 Updated config.yml according to plots2 file (#1566)
* Updated config.yml according to plots2 file

* Corrected according to suggestions

* minor change

* minor change

* minor change

* minor change

* minor change

* minor changes

Co-authored-by: sharmamansi <mansisharma785622gmail.com>
Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-10-16 01:20:53 +05:30
Naimish Rastogi
c372b7d950 VersionText color change (#1567)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-15 11:19:23 -04:00
dependabot-preview[bot]
765dbc5c9c Bump jasmine from 3.5.0 to 3.6.1 (#1723)
Bumps [jasmine](https://github.com/jasmine/jasmine-npm) from 3.5.0 to 3.6.1.
- [Release notes](https://github.com/jasmine/jasmine-npm/releases)
- [Commits](https://github.com/jasmine/jasmine-npm/compare/v3.5.0...v3.6.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-10-15 07:42:48 -04:00
Harsh Khandeparkar
8e3abcccd6 Create CODEOWNERS (#1719)
* Create CODEOWNERS

* Update .github/CODEOWNERS

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>

* Update .github/CODEOWNERS

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>

* Update .github/CODEOWNERS

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-14 19:47:56 -04:00
dependabot-preview[bot]
68a0995997 Bump @babel/core from 7.9.0 to 7.12.0 (#1721)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.9.0 to 7.12.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.12.0/packages/babel-core)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-14 19:05:04 -04:00
Jeffrey Warren
47fd8fe6db bump tape-run to ^8.0.0 (#1722) 2020-10-14 18:42:40 -04:00
dependabot-preview[bot]
2914aaef70 Bump jpegtran-bin from 4.0.0 to 5.0.2 (#1699)
Bumps [jpegtran-bin](https://github.com/imagemin/jpegtran-bin) from 4.0.0 to 5.0.2.
- [Release notes](https://github.com/imagemin/jpegtran-bin/releases)
- [Commits](https://github.com/imagemin/jpegtran-bin/compare/v4.0.0...v5.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-14 16:09:50 -04:00
dependabot-preview[bot]
e2dd5a7309 Bump imagemin-pngquant from 8.0.0 to 9.0.1 (#1715)
Bumps [imagemin-pngquant](https://github.com/imagemin/imagemin-pngquant) from 8.0.0 to 9.0.1.
- [Release notes](https://github.com/imagemin/imagemin-pngquant/releases)
- [Commits](https://github.com/imagemin/imagemin-pngquant/compare/v8.0.0...v9.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-10-14 16:02:20 -04:00
dependabot-preview[bot]
eb497e1a62 [Security] Bump bl from 1.2.2 to 1.2.3
Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3. **This update includes a security fix.**
- [Release notes](https://github.com/rvagg/bl/releases)
- [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-10-06 15:55:34 +00:00
bajajvinamr
8a929c4b4d Update defaultHtmlSequencerUi.js (#1712)
Fixed Module Selector dropdown showing error in console publiclab#1531

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-10-01 16:29:40 -04:00
Jeffrey Warren
b95af7672c Update README.md 2020-10-01 12:57:54 -04:00
dependabot-preview[bot]
eb5672c433 [Security] Bump decompress from 4.2.0 to 4.2.1
Bumps [decompress](https://github.com/kevva/decompress) from 4.2.0 to 4.2.1. **This update includes a security fix.**
- [Release notes](https://github.com/kevva/decompress/releases)
- [Commits](https://github.com/kevva/decompress/compare/v4.2.0...v4.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-09-21 21:51:45 +00:00
dependabot-preview[bot]
c0b9f88818 Bump lint-staged from 10.1.3 to 10.2.11
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.1.3 to 10.2.11.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.1.3...v10.2.11)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 23:31:58 +00:00
dependabot-preview[bot]
4810a3b975 Bump gpu.js from 2.9.4 to 2.9.5
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.9.4 to 2.9.5.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits/2.9.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-04 15:51:26 +00:00
dependabot-preview[bot]
07c6d1497a Bump lodash from 4.17.15 to 4.17.19 (#1697)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-08-04 11:15:24 -04:00
dependabot-preview[bot]
8ddf05f0bc Bump @babel/plugin-proposal-object-rest-spread from 7.8.3 to 7.11.0
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-object-rest-spread) from 7.8.3 to 7.11.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.11.0/packages/babel-plugin-proposal-object-rest-spread)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-04 03:19:53 +00:00
dependabot-preview[bot]
456a22a845 [Security] Bump elliptic from 6.4.1 to 6.5.3
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.4.1 to 6.5.3. **This update includes a security fix.**
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.4.1...v6.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-04 03:12:35 +00:00
dependabot-preview[bot]
740693b655 Bump geotiff from 1.0.0-beta.6 to 1.0.0-beta.13 (#1677)
Bumps [geotiff](https://github.com/geotiffjs/geotiff.js) from 1.0.0-beta.6 to 1.0.0-beta.13.
- [Release notes](https://github.com/geotiffjs/geotiff.js/releases)
- [Commits](https://github.com/geotiffjs/geotiff.js/compare/v1.0.0-beta.6...v1.0.0-beta.13)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-07-12 16:14:07 -04:00
Shazeb Ata
23ddf1fce0 Added test for Apply button (#1579)
* Added test for Apply button

* Refactored

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-07-12 16:03:10 -04:00
Jeffrey Warren
b7eb9cfc45 update gitpod badge URL due to referrer issues
https://github.com/gitpod-io/gitpod/issues/688
2020-07-11 13:26:59 -04:00
Yogesh Sharma
da9b167258 Updated Link (#1627)
Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-07-11 10:56:39 -04:00
dependabot-preview[bot]
3b6eac4a96 Bump gpu.js from 2.9.3 to 2.9.4
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.9.3 to 2.9.4.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-10 21:45:20 +00:00
dependabot-preview[bot]
8367f4bc26 Bump jsdom from 15.2.1 to 16.3.0 (#1691)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 15.2.1 to 16.3.0.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/15.2.1...16.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-07-10 14:50:53 -04:00
dependabot-preview[bot]
a5abbeaf76 Bump imagemin-jpegtran from 6.0.0 to 7.0.0
Bumps [imagemin-jpegtran](https://github.com/imagemin/imagemin-jpegtran) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/imagemin/imagemin-jpegtran/releases)
- [Commits](https://github.com/imagemin/imagemin-jpegtran/compare/v6.0.0...v7.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-07 21:23:59 +00:00
Jeffrey Warren
d55752827d Update .travis.yml 2020-07-07 18:58:58 +00:00
dependabot-preview[bot]
1658220198 Bump jest from 25.1.0 to 26.1.0
Bumps [jest](https://github.com/facebook/jest) from 25.1.0 to 26.1.0.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v25.1.0...v26.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-07-07 18:58:58 +00:00
Jeffrey Warren
54722a35f7 Update README.md (#1688) 2020-07-07 14:43:59 -04:00
Harsh Khandeparkar
eb381555c4 Edge Detect Fixed! (#1629)
* FIX!

* fix the test

* trigger travis

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-07-07 11:52:12 -04:00
Jeffrey Warren
917979267a Update .gitpod.yml to include gitpod dependencies in a mini dockerfile (#1685)
* Update .gitpod.yml

* Create .gitpod.dockerfile

* Update .gitpod.dockerfile

* Update .gitpod.dockerfile

* Update .gitpod.dockerfile

* Update .gitpod.dockerfile
2020-07-07 10:15:25 -04:00
dependabot-preview[bot]
fb303a8ca9 [Security] Bump websocket-extensions from 0.1.3 to 0.1.4 (#1671)
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. **This update includes a security fix.**
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-07-07 00:20:51 -04:00
Jeffrey Warren
102b82bd34 Split tests into separate Travis jobs with better labeling (#1684)
* Split tests into separate Travis jobs with better labeling

* format test browserification

* more descriptive labels

* combine grunt browserify of tests and the run of those tests
2020-07-07 00:03:02 -04:00
dependabot-preview[bot]
222d217d6d Bump tape-run from 6.0.1 to 7.0.0 (#1662)
Bumps [tape-run](https://github.com/juliangruber/tape-run) from 6.0.1 to 7.0.0.
- [Release notes](https://github.com/juliangruber/tape-run/releases)
- [Changelog](https://github.com/juliangruber/tape-run/blob/master/History.md)
- [Commits](https://github.com/juliangruber/tape-run/compare/v6.0.1...v7.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-07-06 11:50:29 -04:00
Jeffrey Warren
ef3afc00e2 .gitpod.yml - default branch prebuilds are on by default so removing
this also undoes #1680
2020-07-06 08:57:33 -04:00
Jeffrey Warren
325a5660d5 update gitpod conf to main branch? (#1680) 2020-07-05 18:22:46 -04:00
dependabot-preview[bot]
21a7dd4e4c Bump buffer from 5.4.3 to 5.6.0 (#1661)
Bumps [buffer](https://github.com/feross/buffer) from 5.4.3 to 5.6.0.
- [Release notes](https://github.com/feross/buffer/releases)
- [Commits](https://github.com/feross/buffer/compare/v5.4.3...v5.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-07-05 18:02:23 -04:00
Nisar Hassan Naqvi
feba2e72b7 simplify code contributions by fully automating the dev setup. (#1668)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-07-05 17:46:17 -04:00
Jeffrey Warren
1926c01fd6 color halftone and module test (#1678) 2020-07-05 17:00:53 -04:00
dependabot-preview[bot]
b05e1eb198 Bump grunt from 1.0.4 to 1.1.0 (#1660)
Bumps [grunt](https://github.com/gruntjs/grunt) from 1.0.4 to 1.1.0.
- [Release notes](https://github.com/gruntjs/grunt/releases)
- [Changelog](https://github.com/gruntjs/grunt/blob/master/CHANGELOG)
- [Commits](https://github.com/gruntjs/grunt/compare/v1.0.4...v1.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-07-05 16:42:01 -04:00
dependabot-preview[bot]
52d923dac5 [Security] Bump handlebars from 4.5.3 to 4.7.6 (#1670)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.5.3 to 4.7.6. **This update includes a security fix.**
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...v4.7.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-06-30 15:25:54 -04:00
dependabot-preview[bot]
0875df2bec Bump gpu.js from 2.6.6 to 2.9.3 (#1656) 2020-04-15 07:42:35 +00:00
dependabot-preview[bot]
e15d063a1a [Security] Bump ecstatic from 4.1.2 to 4.1.4 (#1655) 2020-04-15 07:01:04 +00:00
dependabot-preview[bot]
d431b836f7 Bump @babel/core from 7.8.3 to 7.9.0 (#1645) 2020-04-15 06:45:40 +00:00
dependabot-preview[bot]
6c615ed227 Bump lint-staged from 10.0.3 to 10.1.3
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.0.3 to 10.1.3.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.0.3...v10.1.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-14 21:00:35 +00:00
Deogle
600cce0be3 Removed all instances of mode: 'test' (#1599) 2020-01-31 10:58:12 -05:00
keshav234156
5f745ef4bd preview optimization (#1573)
Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-29 10:48:23 -05:00
dependabot-preview[bot]
28cedd72a6 Bump @babel/core from 7.7.7 to 7.8.3
Bumps [@babel/core](https://github.com/babel/babel) from 7.7.7 to 7.8.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.7.7...v7.8.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-28 20:19:21 +00:00
Nirav Asher
9260bc2278 circular gradient module (#1496)
* circular gradient module

* circular gradient option inside gradient module

* Added test for gradient module

* final shadow module with module test

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-28 15:02:06 -05:00
Harsh Khandeparkar
8c4c607f2c Fixed Setup Script Typo (#1588)
* Fix typo

* Update package.json

Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-28 14:31:30 -05:00
dependabot-preview[bot]
8483c07847 Bump lint-staged from 9.5.0 to 10.0.3
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.5.0 to 10.0.3.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.5.0...v10.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-28 17:30:21 +00:00
dependabot-preview[bot]
4bba811848 Bump @babel/plugin-syntax-object-rest-spread from 7.7.4 to 7.8.3
Bumps [@babel/plugin-syntax-object-rest-spread](https://github.com/babel/babel) from 7.7.4 to 7.8.3.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.7.4...v7.8.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-28 16:52:49 +00:00
Naman Aggarwal
166a0d894c Adding Test modules for GIF's (#1530)
* Test for GIF

* some cleanup

* Some cleanup

* Some code cleanup

* cleanup

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-01-28 11:01:41 -05:00
Naman Aggarwal
3ffea1f5e9 [FIXED]Draw rectangle's rectangle shinking down with every frame in gif's (#1535)
* Fix

* .

Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-28 10:52:40 -05:00
Shazeb Ata
79472baec4 Clear step (#1386)
* Added test clear_step

* Updated clear step test

* Changed name of clear step

* Changed name of clear step

* Added delete step

* Added Linebreaks

* Added clear and delete step

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-27 17:40:22 -05:00
dependabot-preview[bot]
70003521c6 Bump gpu.js from 2.6.2 to 2.6.6
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.6.2 to 2.6.6.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-27 22:24:36 +00:00
dependabot-preview[bot]
f6d53163b9 Bump tape from 4.12.1 to 4.13.0 (#1449) 2020-01-22 17:22:02 +00:00
dependabot-preview[bot]
19ae9262f2 Bump jest from 24.9.0 to 25.1.0 (#1556)
Bumps [jest](https://github.com/facebook/jest) from 24.9.0 to 25.1.0.
- [Release notes](https://github.com/facebook/jest/releases)
- [Changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/facebook/jest/compare/v24.9.0...v25.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-22 12:09:00 -05:00
Ove Sundal
2378a67895 remove redundant function (#1532)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-22 11:31:06 -05:00
dependabot-preview[bot]
ecaa3ecd13 Bump @babel/plugin-proposal-object-rest-spread from 7.7.7 to 7.8.3 (#1494) 2020-01-21 22:05:49 +00:00
Rishabh Shukla
2cd728b54c Fix minify Module (#1512)
* Fix minify Module

* fix minify module
2020-01-21 16:25:34 -05:00
Naman Aggarwal
40dc23bedd [FIXED] travis test not failing when module test fails (#1550)
* travis test error fix

* Updated PULL_REQUEST template

* code cleanup

* ..

* some minor changes

* some minor changes

* Trying to restrat the build

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
2020-01-21 16:22:46 -05:00
Rishabh Shukla
8b18d2d780 fix extraManipulation (#1551)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-21 14:53:32 -05:00
dependabot-preview[bot]
b6d07c035f Bump gpu.js from 2.4.8 to 2.6.2 (#1544)
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.4.8 to 2.6.2.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-21 14:32:42 -05:00
Arghadip Chakraborty
7c63bb53a4 Fixed issue #1528: UI Learn More Link Should Lead to the README (#1539)
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-21 12:58:54 -05:00
Olusola
5b92ba5dc5 Fixed paint bucket fill color error (#1519)
* fillColor getting correct color

* Fixed #1488

Corrected the multiplier from 256 to 255

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-21 12:44:06 -05:00
Naman Aggarwal
2b3e5a2915 Added options startingX and startingY in Add-Qr Module (#1520)
* Added options startingX and startingY in Add-Qr Module

* requeste changes

* Fixing Qr Code at the end when not fit in the image

Co-authored-by: Rishabh Shukla <42492389+blurry-x-face@users.noreply.github.com>
2020-01-18 19:48:52 -05:00
Shazeb Ata
2fba0d2074 Added url for canvas (#1533) 2020-01-18 10:47:34 -05:00
Vladimir Mikulic
afc903192c FIX: Histogram module selected value not displayed (#1510)
The histogram module values are "true" and "false".
jQuery would coerce them to Boolean true and false instead of String
"true" and "false" which would result in empty value being displayed.

Resolves #1295
2020-01-17 16:44:05 -05:00
Naman Aggarwal
c703836198 Draw Rectangle default values (#1443)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-17 16:43:09 -05:00
Rishabh Shukla
c22c6c70d0 Adding easier to use interface for blend module and different blend modes (#1453)
* Bump data-uri-to-buffer from 2.0.1 to 3.0.0

Bumps [data-uri-to-buffer](https://github.com/TooTallNate/node-data-uri-to-buffer) from 2.0.1 to 3.0.0.
- [Release notes](https://github.com/TooTallNate/node-data-uri-to-buffer/releases)
- [Commits](https://github.com/TooTallNate/node-data-uri-to-buffer/compare/2.0.1...3.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* add blend modes

* fix toCliString test

* add docs link for blend modes

* fix crop module

* undo last commit

* minor change

* change default to custom

* add docs link

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-17 15:47:47 -05:00
Rishabh Shukla
1fa8c6b8c1 Refactoring isGIF() as a utility function (#1511)
* refactor isGif

* refactor isGif

* fix isGif func

* Update isGif.js

* Update isGif.js
2020-01-17 15:27:05 -05:00
Rishabh Shukla
89fb3585ac Tests for checking image change upon change in options (#1490)
* add test for change in option for colormap

* add test for change in option for colormap

* add comments

* add few tests

* Add options change test for 14 more modules

* add test

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2020-01-17 15:00:13 -05:00
keshav234156
d1b9b8becc Fixes disabling of clicking after crop is deleted and added test for the cropUI (#1481)
* crop-ui

* crop-ui

* Added test

* Adding test

* improving comments

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 17:18:34 -05:00
keshav234156
1a0f4d4042 Blend new (#1499)
* fixes blend

* change info.json

* improve readablity and comments

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 17:00:13 -05:00
Naman Aggarwal
9a2f4c1d19 Fix for Dynamic module (#1451)
* ..

* fix Dynamic Module

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 16:26:52 -05:00
Rishabh Shukla
b8c7df760a Add ranged input for overlay module. (#1459)
* add ranged input for overlay module

* fix bug

* change input type to integer

* Add tests

* Add tests

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 15:07:35 -05:00
Naman Aggarwal
2736b481a4 Added aspect ratio module (#1454)
* Base file

* Added aspect ratio module

* Compatiable with Experimental GIF Manipulation

* some refactoring

* Changed the name from aspect-ratio to Constrained Crop

* cleanup

* Changes requested

* Added test module

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 14:40:30 -05:00
Naman Aggarwal
5ae545904d Fix Average module editing the UI from the source (#1469)
* Fix Average module editing the UI from the source

* requested changes

* Delete demo.js

* cleanup

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 14:16:51 -05:00
Rishabh Shukla
b0ddea012a Add test for import image (#1513)
* add test for import image

* add test for import image

* remove log

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 13:55:43 -05:00
Rishabh Shukla
94caefa2cd Contrast module now uses changePixel Method (#1482)
* contrast module uses changePixel Method

* change if block to Math function

* fix bug

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 12:47:55 -05:00
Oktawian Jurkiewicz
45c54bb9af crop default options changes (#1487)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 12:29:58 -05:00
Rishabh Shukla
c1c682c0a6 Fix color picker bug (#1465)
* fix color picker bug

* minor change

* change step to stepAll

* add test

* add comments to colorpicker UI test

* add space

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-16 12:23:36 -05:00
Shazeb Ata
423422a61f Remove Multiple Downloads (#1428)
* Removed event listeners

* Added Unbind

* Removed Event Listener

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-15 18:56:06 -05:00
Sanjana Nayar
cded94509b Updated defaultHtmlStepUi.js to add docs link in UI (#1506) 2020-01-15 16:22:32 -05:00
Rishabh Shukla
bfff7e7b99 fix crop module (#1463) 2020-01-13 17:36:53 -05:00
dependabot-preview[bot]
12c422a07b Bump gpu.js from 2.4.7 to 2.4.8
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.4.7 to 2.4.8.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/compare/2.4.7...2.4.8)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-12 17:28:12 +00:00
Harsh Khandeparkar
ea2069d7f6 [GCI] Experimental GIF Manipulation (#1404)
* wasmSuccess

* modules use wasmSuccess

* modules use wasmSuccess

* add the tooltip

* add GIF support

* fix imageDImensions function

* fix inputCoordinatesParser function

* show correct image dimensions

* show correct image dimensions

* don't allow save as PDF for GIFs

* fix QR module

* fix BlobAnalysis

* fix Blur

* fix Colorbar

* fix Crop

* fix crop defaults

* fix DrawRectangle

* fix EdgeDetect

* fix FlipImage

* fix Gradient

* fix Invert

* fix Overlay

* fix Resize

* fix Rotate

* fix TextOverlay

* fix parse input test

* make GIFs work in nodejs

* sample GIF test

* small change

* cleanup

* cleanup

* cleanup

* small fix

* small change

* handle errors

* proper error handling and fix tests

* cleanup

* try a fix

* try another fix

* fix module benchmarks

* try more fixes

* revert

* try fixing the tests

* fix overlay test

* add the gif tests

* remove unnecessary changes

* fix tests

* whoops

* add some docs

* inBrowser

* fix all module tests

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-11 12:05:10 -05:00
dependabot-preview[bot]
61b2d75383 Bump data-uri-to-buffer from 2.0.1 to 3.0.0 (#1437)
Bumps [data-uri-to-buffer](https://github.com/TooTallNate/node-data-uri-to-buffer) from 2.0.1 to 3.0.0.
- [Release notes](https://github.com/TooTallNate/node-data-uri-to-buffer/releases)
- [Commits](https://github.com/TooTallNate/node-data-uri-to-buffer/compare/2.0.1...3.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-09 16:05:56 -05:00
dependabot-preview[bot]
20f7d7ca2e Bump jsdom from 15.1.1 to 15.2.1 (#1438)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 15.1.1 to 15.2.1.
- [Release notes](https://github.com/jsdom/jsdom/releases)
- [Changelog](https://github.com/jsdom/jsdom/blob/master/Changelog.md)
- [Commits](https://github.com/jsdom/jsdom/compare/15.1.1...15.2.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-08 18:16:05 -05:00
dependabot-preview[bot]
9ef5d38084 Bump @babel/plugin-syntax-object-rest-spread from 7.2.0 to 7.7.4 (#1444)
Bumps [@babel/plugin-syntax-object-rest-spread](https://github.com/babel/babel) from 7.2.0 to 7.7.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.2.0...v7.7.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-08 16:56:41 -05:00
Rishabh Shukla
c453bbbd92 Fix Meta modules and add inputs to ndvi-colormap (#1432)
* fix meta module bug

* fix create meta module and add inputs to ndvi-colormap

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-08 16:14:50 -05:00
dependabot-preview[bot]
448848b2d1 Bump gpu.js from 2.4.6 to 2.4.7 (#1434)
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.4.6 to 2.4.7.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/compare/2.4.6...2.4.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-07 17:03:13 -05:00
dependabot-preview[bot]
9822da6a78 Bump ndarray from 1.0.18 to 1.0.19 (#1436)
Bumps [ndarray](https://github.com/mikolalysenko/ndarray) from 1.0.18 to 1.0.19.
- [Release notes](https://github.com/mikolalysenko/ndarray/releases)
- [Commits](https://github.com/mikolalysenko/ndarray/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-07 16:39:32 -05:00
Naman Aggarwal
d215b43a09 Fixing defaults in various modules (#1441)
* Fix AddQr

* Fix Threshold

* Fix ReplaceColor Modulr

* Fix Overlay Module

* Fix FlipImage Module

* fix Colorbar Module

* Fix colormap module

* fix overlay

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-07 16:18:45 -05:00
anthony-zhou
00ed0f148d Expand out offline app features for smoother cache clearing and version tracking (#1384)
* Add version number to bottom

* Get latest version number from GitHub

* Create versionManagement.js

Fetching the latest and local version number is now done through versionManagement.js

* Add popup to prompt for refresh when a new version is available

A new version is available whenever the sw.js file is changed.

* Add version number fixed in top right corner

* Fix Codeclimate issues

* Update versionManagement.js

* Update versionManagement.js

* Make update prompt appear at front of page

Changed z-index

* Delete unecessary code

* Create task to automatically update sw.js

Used grunt-text-replace

* Uninstall semver

* Add replace task to serve and production tasks

* Update demo.js

Make version statements more descriptive.

* Update versionManagement.js

Remove unused versionCompare function

* Change URL for getting latest version

Changed the URL for getting the latest NPM version to be based on the package.json file's attribute for "homepage".

* Update index.html

* Update demo.css

* Added explanatory comments

* Update versionManagement.js

* Update versionManagement.js

* Updates for readability

Changed single-line comments to multiline comments.

* Update versionManagement.js

* Update versionManagement.js

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-07 14:56:34 -05:00
dependabot-preview[bot]
ab793bcf4e Bump commander from 4.0.1 to 4.1.0 (#1435)
Bumps [commander](https://github.com/tj/commander.js) from 4.0.1 to 4.1.0.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/4.0.1...v4.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-07 12:02:23 -05:00
dependabot-preview[bot]
865e4bc268 Bump jasmine from 3.4.0 to 3.5.0 (#1433)
Bumps [jasmine](https://github.com/jasmine/jasmine-npm) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/jasmine/jasmine-npm/releases)
- [Commits](https://github.com/jasmine/jasmine-npm/compare/v3.4.0...v3.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-07 11:35:53 -05:00
Rishabh Shukla
6420bb05e8 fix meta module bug (#1426) 2020-01-06 16:26:35 -05:00
dependabot-preview[bot]
79d395bf24 Bump ora from 3.4.0 to 4.0.3 (#1415)
Bumps [ora](https://github.com/sindresorhus/ora) from 3.4.0 to 4.0.3.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v3.4.0...v4.0.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 13:59:57 -05:00
dependabot-preview[bot]
17ea0c8b44 Bump compressorjs from 1.0.5 to 1.0.6 (#1414)
Bumps [compressorjs](https://github.com/fengyuanchen/compressorjs) from 1.0.5 to 1.0.6.
- [Release notes](https://github.com/fengyuanchen/compressorjs/releases)
- [Changelog](https://github.com/fengyuanchen/compressorjs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/fengyuanchen/compressorjs/compare/v1.0.5...v1.0.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-06 13:48:26 -05:00
Shazeb Ata
81ef136b20 Change dimension upon loading an Image through UI (#1395)
* Change dimension upon loading an Image

* Refactored changedimension

* Refactored changedimension

* Added Comments

* Added description

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-06 13:38:48 -05:00
dependabot-preview[bot]
639eaf644f Bump readline-sync from 1.4.9 to 1.4.10 (#1206)
Bumps [readline-sync](https://github.com/anseki/readline-sync) from 1.4.9 to 1.4.10.
- [Release notes](https://github.com/anseki/readline-sync/releases)
- [Commits](https://github.com/anseki/readline-sync/compare/1.4.9...1.4.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 13:31:48 -05:00
dependabot-preview[bot]
a5da2ebc24 Bump @babel/plugin-proposal-object-rest-spread from 7.4.3 to 7.7.7 (#1372)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.4.3 to 7.7.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.4.3...v7.7.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 13:00:36 -05:00
dependabot-preview[bot]
6654e2a3f7 Bump jest-puppeteer from 4.3.0 to 4.4.0 (#1424)
Bumps [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer) from 4.3.0 to 4.4.0.
- [Release notes](https://github.com/smooth-code/jest-puppeteer/releases)
- [Changelog](https://github.com/smooth-code/jest-puppeteer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smooth-code/jest-puppeteer/compare/v4.3.0...v4.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-06 10:34:10 -05:00
dependabot-preview[bot]
7473a256e9 Bump looks-same from 7.2.1 to 7.2.2 (#1423)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.2.1 to 7.2.2.
- [Release notes](https://github.com/gemini-testing/looks-same/releases)
- [Changelog](https://github.com/gemini-testing/looks-same/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gemini-testing/looks-same/compare/v7.2.1...v7.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 10:07:51 -05:00
dependabot-preview[bot]
76e5eb85ce Bump imagemin from 7.0.0 to 7.0.1 (#1425)
Bumps [imagemin](https://github.com/imagemin/imagemin) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/imagemin/imagemin/releases)
- [Commits](https://github.com/imagemin/imagemin/compare/v7.0.0...v7.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-06 08:50:43 -05:00
Sparks
a8b6aac5b3 Update defaultHtmlStepUi.js (#1388)
Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-03 14:19:53 -05:00
dependabot-preview[bot]
d3b49ff187 Bump jasmine-core from 3.4.0 to 3.5.0 (#1408)
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/master/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v3.4.0...v3.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-03 14:16:13 -05:00
dependabot-preview[bot]
cd41d1e8d9 Bump qrcode from 1.4.1 to 1.4.4 (#1416)
Bumps [qrcode](https://github.com/soldair/node-qrcode) from 1.4.1 to 1.4.4.
- [Release notes](https://github.com/soldair/node-qrcode/releases)
- [Changelog](https://github.com/soldair/node-qrcode/blob/master/CHANGELOG.md)
- [Commits](https://github.com/soldair/node-qrcode/compare/v1.4.1...v1.4.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-03 13:01:26 -05:00
dependabot-preview[bot]
33d601fb58 Bump gpu.js from 2.3.1 to 2.4.6 (#1417)
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.3.1 to 2.4.6.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/compare/2.3.1...2.4.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-03 12:20:20 -05:00
dependabot-preview[bot]
4e96b7fb55 Bump commander from 3.0.1 to 4.0.1 (#1406)
Bumps [commander](https://github.com/tj/commander.js) from 3.0.1 to 4.0.1.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v3.0.1...4.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-02 17:48:26 -05:00
Shazeb Ata
12a78c5745 Created a new object instead of passing by reference (#1379)
* Creating copy of object

* Creating copy of object

* Create new object

Co-authored-by: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-02 15:46:50 -05:00
Naman Aggarwal
6ffba532c3 Fixed bug => Color Temperature showing black image when set on default. (#1401)
* fixed issue #1392

* required changes fix

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-02 13:43:03 -05:00
keshav234156
7905cc9252 fixing module test (#1410) 2020-01-02 12:53:50 -05:00
dependabot-preview[bot]
fd138ffb47 Bump tape from 4.11.0 to 4.12.1 (#1405)
Bumps [tape](https://github.com/substack/tape) from 4.11.0 to 4.12.1.
- [Release notes](https://github.com/substack/tape/releases)
- [Commits](https://github.com/substack/tape/compare/v4.11.0...v4.12.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-02 11:36:50 -05:00
dependabot-preview[bot]
0ceb354c56 Bump browserify from 16.2.3 to 16.5.0 (#1207)
Bumps [browserify](https://github.com/browserify/browserify) from 16.2.3 to 16.5.0.
- [Release notes](https://github.com/browserify/browserify/releases)
- [Changelog](https://github.com/browserify/browserify/blob/master/changelog.markdown)
- [Commits](https://github.com/browserify/browserify/compare/v16.2.3...v16.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-02 08:46:06 -05:00
dependabot-preview[bot]
48c65d3c64 Bump buffer from 5.4.2 to 5.4.3 (#1254)
Bumps [buffer](https://github.com/feross/buffer) from 5.4.2 to 5.4.3.
- [Release notes](https://github.com/feross/buffer/releases)
- [Commits](https://github.com/feross/buffer/compare/v5.4.2...v5.4.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-01 19:52:03 -05:00
dependabot-preview[bot]
4539f264b3 Bump lint-staged from 9.2.1 to 9.5.0 (#1308)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 9.2.1 to 9.5.0.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v9.2.1...v9.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-01 18:47:36 -05:00
dependabot-preview[bot]
b43cfc522f Bump jsqr from 1.1.1 to 1.2.0 (#1214)
Bumps [jsqr](https://github.com/cozmo/jsQR) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/cozmo/jsQR/releases)
- [Commits](https://github.com/cozmo/jsQR/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-01 16:37:57 -05:00
dependabot-preview[bot]
8d38088914 [Security] Bump handlebars from 4.1.2 to 4.5.3 (#1397)
Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.1.2 to 4.5.3. **This update includes a security fix.**
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/wycats/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.5.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-01 16:24:59 -05:00
Naman Aggarwal
772a56989f fix issue 1394 (#1399) 2020-01-01 15:04:53 -05:00
Srihari
13270a668c fix case (#1387) 2020-01-01 14:47:20 -05:00
Isaac Miti
cb47bf2341 Change the button to blue from green (#1380) 2020-01-01 14:41:18 -05:00
dependabot-preview[bot]
4097361599 Bump @babel/core from 7.5.5 to 7.7.7 (#1371)
Bumps [@babel/core](https://github.com/babel/babel) from 7.5.5 to 7.7.7.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.5.5...v7.7.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-01 13:46:58 -05:00
Harsh Khandeparkar
0bf178022d standardise comments (#1347) 2020-01-01 13:32:34 -05:00
Harsh Khandeparkar
51ce1c52f4 [GCI] Standardised Edge Detect module code comments (#1346)
* standardise comments

* more fixes

* fix

* Apply suggestions from code review

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-01 12:51:53 -05:00
Harsh Khandeparkar
1af9655bca [GCI] Standardised UI code comments (#1345)
* standardise comments

* fix some stuff

* A googol issues fixed

* Update examples/demo.js

* .

* .

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-01 12:39:17 -05:00
Harsh Khandeparkar
1db650cdd7 [GCI] Standardised UI util code comments (#1344)
* standardise comments

* small fix

Co-authored-by: Jeffrey Warren <jeff@unterbahn.com>
2020-01-01 12:26:41 -05:00
Veer Gadodia
d83703cf02 Update README.md (#1326) 2020-01-01 11:38:14 -05:00
Harsh Khandeparkar
c370a8b4ea Install GPU.js v2.3.1 (#1374)
* fix: Upgrade GPU.js to v2.3.0 and handle browserifying it

* fix?

* fiiix

* fix

* fix tests browserify

Co-authored-by: Robert Plummer <robertleeplummerjr@gmail.com>
2019-12-21 11:59:11 -05:00
Harsh Khandeparkar
6476b8d698 [GCI] Added Lightning Bolt for WASM accelerated modules (#1365)
* wasmSuccess

* modules use wasmSuccess

* modules use wasmSuccess

* add the tooltip
2019-12-19 18:45:42 -05:00
keshav234156
b7d5a98cdb seprated the title and radio group file (#1367) 2019-12-18 23:28:37 -05:00
Đoàn Ngọc Huân
2e94f20875 Update demo.css (#1368)
https://github.com/publiclab/image-sequencer/issues/1314
2019-12-18 13:30:18 -05:00
keshav234156
ed0f76c78d test for add step (#1366)
* test for add step

* adding relative path and testing with npm run test-ui(for testing in travis but it will abort previous test-ui)

* checking index.html

* checking index.html

* changing test location and reverting index.html

* remove console.log
2019-12-17 19:37:27 -05:00
Harsh Khandeparkar
4a86abbafd [GCI] InsertStep functionality added for loadImage step (#1360)
* add markuo

* add markupfix insertPreview

* fix insertPreview test

* make the new insertPreview work

* fix disabled

* small fix

* fix comments

* remove console log

* fix enabling/disabling of insert-step btn
2019-12-16 13:42:15 -05:00
Harsh Khandeparkar
426733f625 [GCI] Standardised Core code comments (#1343)
* standardise comments

* fix

* fixes

* add docs links

* remove extra .

* ., this and other changes
2019-12-16 12:56:03 -05:00
Harsh Khandeparkar
0ce2cf9492 [GCI] Standardised Blob Analysis module comments (#1351)
* fix comments

* Update src/modules/BlobAnalysis/BlobAnalysis.js

Fix double image

* Update src/modules/BlobAnalysis/BlobAnalysis.js

* . fix
2019-12-16 12:47:25 -05:00
Ryan10145
3d4025fd93 Disables Take a Photo Button and File Chooser While Camera is Active (#1357)
* Disables Other Buttons While Camera is Active

* Remove dropzone-text id from ImportImage UI
2019-12-16 11:53:32 -05:00
Sparks
76575b567a Dropdown 'Select a Module' fix (#1352)
* Update demo.js

* Codeclimate

* Update demo.js

* Code comments

* Comments codestyle

* Update demo.js
2019-12-12 11:53:18 -05:00
keshav234156
86dca0400e Allow saving onto Publiclab.org (#1353)
* Allow saving onto Publiclab.org

* success to primary

* fixing merge conflictx
2019-12-11 15:20:03 -05:00
anthony-zhou
5421a80fb3 Add Save as PDF option (#1349)
* Add Save as PDF option

* Edit coments for consistency

Edits follow the JSDoc guidelines. Comments begin with a capital letter and end with a period.
2019-12-11 13:23:13 -05:00
Vladimir Mikulic
bb4fc5b691 FIX: Dragzone overlapping (#1333)
* FIX: Dragzone overlapping

Changes:
- inline styles moved from ../ImportImage/Ui.js to demo.css
- minor code improvements

The change was necessary because in the old UI dragzone was overlapping
an image.

Resolves #1294

* FIX: Improve commit #ead4b932

Changes:
- rollback .dropzone input style
- add styles to  .import-image-zone input element

* FIX:  .import-image-zone input element width

Changes:
-  max-width increased to 120% on import-image-zone input element

* FIX: .import-image-zone max-width

Changes:
- rollback .import-image-zone input max-width to fit-content
- increase .import-image-zone max-width from 230px to 250px

* FIX: .import-image-zone input element max-width

Changes:
 - max-width set to 100%
2019-12-10 11:07:43 -05:00
Ryan10145
d371a0f2e4 Add Missing Modules to Documentation (#1325) 2019-12-10 11:02:07 -05:00
keshav234156
2459e53fda Fixes unexpected behavior of step panel dropdown (#1328)
* Fixes  dropdown

* Update defaultHtmlStepUi.js

* Update intermediateHtmlStepUi.js
2019-12-09 17:59:14 -05:00
keshav234156
032971d269 Fixes window error in Average module.Commented the test that were affecting other modules (#1330) 2019-12-09 17:52:01 -05:00
anthony-zhou
510fd7a934 Make "Add Step" button blue (#1331)
Changed the button's class from "btn-success" to "btn-primary."
2019-12-09 17:18:19 -05:00
Sasha Boginsky
5c76cb4012 Update CODE_OF_CONDUCT.md (#1248)
update to reflect the updates on 
https://publiclab.org/conduct Aug 28 2019, and also standardize format to match LDI, Mk, etc.
2019-12-09 16:58:29 -05:00
Rishabh Shukla
f1c94fd788 Display width and height of image at each step (#1309) 2019-11-28 14:42:25 -05:00
dependabot-preview[bot]
89626838e3 [Security] Bump https-proxy-agent from 2.2.1 to 2.2.4 (#1301)
Bumps [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) from 2.2.1 to 2.2.4. **This update includes security fixes.**
- [Release notes](https://github.com/TooTallNate/node-https-proxy-agent/releases)
- [Commits](https://github.com/TooTallNate/node-https-proxy-agent/compare/2.2.1...2.2.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-11-18 15:15:56 -05:00
VAIBHAV MATTA
cff82c998f Small Typo Error Corrected (#1278) 2019-10-29 22:45:14 +01:00
keshav234156
b1600af374 fixes insert-step functionality (#1266) 2019-10-28 19:21:43 +01:00
keshav234156
43e81c3847 fixes bugs in gamma-correction module (#1256)
* fixes gamma-correction module slider

* Update info.json
2019-10-07 12:03:00 -04:00
Samagra Gupta
44f5cb4e03 cursor change into pointer (#1259) 2019-10-01 14:23:19 -04:00
keshav234156
3eb741c6d9 rotate module (#1218)
* this PR solves the problem of clipping of the image while rotating

* a little clipping was still present .so made the changes

* Splitted into two files

* ommitted extra declared variables

* Update Module.js

* Update Rotate.js

* Update Rotate.js
2019-09-24 16:45:02 -04:00
duyquangnguyenhac
33f32251ec Document noise reduction module (#1189)
* Added documentation for noise reduction module

* Added fixed documentation for noise reduction module

* Update MODULES.md

* Minor Changes to Noise-Reduction description.

* Update docs/MODULES.md

Co-Authored-By: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>

* Move documentation to alphabetical order

* Update MODULES.md
2019-09-23 10:56:38 -04:00
dependabot-preview[bot]
5253e08d57 Bump gpu.js from 2.0.0-rc.26 to 2.0.0 (#1257)
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.0.0-rc.26 to 2.0.0.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/compare/2.0.0-rc.26...2.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-18 09:20:59 -04:00
keshav234156
d782c147c5 fixes add-QR and color-picker in draw-rectangle,grid-overlay (#1250) 2019-09-11 15:28:02 -04:00
Devesh Kaushik
339df8768d Updated CONTRIBUTION.md (#1231)
* Update Contribution.md

As directed by rexagod

* Update Contribution.md

added libxext-dev

* Update CONTRIBUTING.md

Co-Authored-By: Harsh Khandeparkar <34770591+HarshKhandeparkar@users.noreply.github.com>
2019-09-11 11:18:44 -04:00
dependabot-preview[bot]
4a0207bc27 Bump buffer from 5.4.0 to 5.4.2 (#1246)
Bumps [buffer](https://github.com/feross/buffer) from 5.4.0 to 5.4.2.
- [Release notes](https://github.com/feross/buffer/releases)
- [Commits](https://github.com/feross/buffer/compare/v5.4.0...v5.4.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-07 10:52:00 -04:00
dependabot-preview[bot]
9ad6bde18e Bump husky from 2.3.0 to 3.0.5 (#1243)
Bumps [husky](https://github.com/typicode/husky) from 2.3.0 to 3.0.5.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v2.3.0...v3.0.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-04 16:17:36 -04:00
dependabot-preview[bot]
740acaeec7 Bump gpu.js from 2.0.0-rc.25 to 2.0.0-rc.26 (#1228)
Bumps [gpu.js](https://github.com/gpujs/gpu.js) from 2.0.0-rc.25 to 2.0.0-rc.26.
- [Release notes](https://github.com/gpujs/gpu.js/releases)
- [Commits](https://github.com/gpujs/gpu.js/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-04 15:16:33 -04:00
dependabot-preview[bot]
256e1d65c7 [Security] Bump mixin-deep from 1.3.1 to 1.3.2 (#1234)
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2. **This update includes a security fix.**
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-03 14:06:03 -04:00
dependabot-preview[bot]
bab7573f4a Bump commander from 2.19.0 to 3.0.1 (#1244)
Bumps [commander](https://github.com/tj/commander.js) from 2.19.0 to 3.0.1.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v2.19.0...v3.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-09-03 13:58:19 -04:00
Jeffrey Warren
776cb42bd6 Revert extra test until complete 2019-09-01 16:14:52 -04:00
Jeffrey Warren
fb452f7788 add UI test for quick selector add step
re #1000
2019-09-01 16:09:49 -04:00
Tudor Anghelina
3741d679bd Update Module.js (#1090)
Added const $ = window.$; at line 19 inside extraManipulation(pixels)
2019-08-30 12:58:05 -04:00
Rishabh Shukla
1cc9fd1a50 Update Pull_Request.md (#1233)
* Update pull request template

* Update Pull_Request.md
2019-08-28 17:59:54 -04:00
keshav234156
6613af810c make select a module responsive (#1208) 2019-08-26 09:42:10 -04:00
dependabot-preview[bot]
1b3e95fdd9 Bump tape-run from 6.0.0 to 6.0.1 (#1222)
Bumps [tape-run](https://github.com/juliangruber/tape-run) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/juliangruber/tape-run/releases)
- [Changelog](https://github.com/juliangruber/tape-run/blob/master/History.md)
- [Commits](https://github.com/juliangruber/tape-run/compare/v6.0.0...v6.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-08-23 08:02:59 -04:00
242 changed files with 18176 additions and 4514 deletions

75
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,75 @@
# <-- DOCS FOR THIS FILE -->
# This is a comment.
# Each line is a file pattern followed by one or more owners.
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
# * @global-owner1 @global-owner2
# Order is important; the last matching pattern takes the most
# precedence. When someone opens a pull request that only
# modifies JS files, only @js-owner and not the global
# owner(s) will be requested for a review.
# *.js @js-owner
# You can also use email addresses if you prefer. They'll be
# used to look up users just like we do for commit author
# emails.
# *.go docs@example.com
# In this example, @doctocat owns any files in the build/logs
# directory at the root of the repository and any of its
# subdirectories.
# /build/logs/ @doctocat
# The `docs/*` pattern will match files like
# `docs/getting-started.md` but not further nested files like
# `docs/build-app/troubleshooting.md`.
# docs/* docs@example.com
# In this example, @octocat owns any file in an apps directory
# anywhere in your repository.
# apps/ @octocat
# In this example, @doctocat owns any file in the `/docs`
# directory in the root of your repository.
# /docs/ @doctocat
# <-- /DOCS FOR THIS FILE -->
# <-- COMMON TO ALL MAINTAINERS -->
/*.json @publiclab/is-maintainers
/*.md @publiclab/is-maintainers
/*.lock @ubliclab/is-maintainers
/Gruntfile.js @publiclab/is-maintainers
/.github/ @publiclab/is-maintainers
/scripts/ @publiclab/is-maintainers
# <-- /COMMON TO ALL MAINTAINERS -->
# <-- SPECIFIC MAINTAINERS -->
/index.js @publiclab/is-cli-maintainers
/src/cli/ @publiclab/is-cli-maintainers
/src/CliUtils.js @publiclab/is-cli-maintainers
/src/*.js @publiclab/is-core-maintainers
/src/*.json @publiclab/is-core-maintainers
/src/util/ @publiclab/is-core-maintainers
/test/core/* @publiclab/is-core-maintainers
/src/modules/ @publiclab/is-module-maintainers
/docs/ @publiclab/is-module-maintainers
/test/ @publiclab/is-tests-maintainers
/jest* @publiclab/is-tests-maintainers
/eslint* @publiclab/is-tests-maintainers
/travis* @publiclab/is-tests-maintainers
.travis.yml @publiclab/is-tests-maintainers
.gitpod* @publiclab/is-tests-maintainers
/gitpod* @publiclab/is-tests-maintainers
/examples/ @publiclab/is-ui-maintainers
/icons/ @publiclab/is-ui-maintainers
/test/ui-2/test/* @publiclab/is-ui-maintainers
/test/ui/spec/* @publiclab/is-ui-maintainers
# <-- /SPECIFIC MAINTAINERS -->

View File

@@ -1,3 +1,10 @@
---
name: Bug report 🐞
about: Help us identify and fix a bug!
title: ''
labels: bug
---
### Please describe the problem (or idea) ### Please describe the problem (or idea)
> What happened just before the problem occurred? Or what problem could this idea solve? > What happened just before the problem occurred? Or what problem could this idea solve?
@@ -10,13 +17,13 @@
### Please show us where to look ### Please show us where to look
https://beta.sequencer.publiclab.org Paste in a full URL, starting with:
> https://beta.sequencer.publiclab.org/
### What's your PublicLab.org username? If you can share a screenshot or a GIF that is EXTRA helpful! 💖
> This can help us diagnose the issue:
If you can see a version number in the upper right, please note that!
### Browser, version, and operating system ### Browser, version, and operating system

View File

@@ -0,0 +1,39 @@
---
name: New release checklist ✅
about: Coordinate steps to publish a new release
title: 'Checklist and coordination for v0.0.0 major/minor/patch release'
labels: release
assignees: '@publiclab/is-maintainers'
---
This template guides us through the steps of creating a new release, based on conversation and testing in [#1692](https://github.com/publiclab/image-sequencer/issues/1692).
Discuss with @publiclab/is-maintainers if anything is ambiguous!
<!-- NOTE: Change v0.0.0 to the appropriate release version -->
* [x] open an issue using the "release" template with this checklist with title `Checklist and coordination for v0.0.0 major/minor/patch release` (see [semantic versioning](https://docs.npmjs.com/about-semantic-versioning/))
* [ ] create a release [project](https://github.com/publiclab/image-sequencer/projects) from [this template](https://github.com/publiclab/image-sequencer/projects/5). You can copy a project from its menu.
* [ ] compile release notes below from corresponding [release project](https://github.com/publiclab/image-sequencer/projects).
* [ ] update version number in `examples/sw.js` (ex #1734) and `package.json` (ex #1695)
* [ ] finalize and merge to `main` branch (freeze merges to `main` branch until next step)
* [ ] merge, build and publish `/dist/` files to `stable` (merges to `main` branch can resume for next release)
* [ ] create a release on GitHub and use features description + release notes from below
* [ ] tag version number branch (i.e. `v0.0.0`)
* [ ] publish tagged branch to `npm`
* [ ] publish to live Github pages [demo](https://sequencer.publiclab.org) (with [bash script](https://github.com/publiclab/image-sequencer/pull/1703) from `/scripts/update-demo`) (from within GitPod works well)
* [ ] move anything necessary to next release project, i.e. <!-- Update this link -->https://github.com/publiclab/image-sequencer/projects/[insert project number]
* [ ] close this issue!
Noting we're now in this process in https://github.com/publiclab/image-sequencer/pull/1695 for `v3.6.0`.
****
### Release notes
Compile and edit release notes below, to be copied into the release description.
#### Added
#### Fixed
#### Changed

View File

@@ -2,15 +2,15 @@ Fixes #0000 (<=== Replace `0000` with the Issue Number)
Make sure these boxes are checked before your pull request (PR) is ready to be reviewed and merged. Thanks! Make sure these boxes are checked before your pull request (PR) is ready to be reviewed and merged. Thanks!
* [ ] tests pass -- look for a green checkbox ✔️ a few minutes after opening your PR -- or run tests locally with `npm test` * [ ] tests pass -- look for a green checkbox ✔️ a few minutes after opening your PR -- or run tests locally with `npm run test-all`
* [ ] code is in uniquely-named feature branch and has no merge conflicts * [ ] code is in uniquely-named feature branch and has no merge conflicts
* [ ] PR is descriptively titled * [ ] PR is descriptively titled
* [ ] ask `@publiclab/is-reviewers` for help, in a comment below * [ ] ask `@publiclab/is-reviewers` for help, in a comment below
* [ ] Insert-step functionality is working correct as expected.
> We're happy to help you get this ready -- don't be afraid to ask for help, and **don't be discouraged** if your tests fail at first! > We're happy to help you get this ready -- don't be afraid to ask for help, and **don't be discouraged** if your tests fail at first!
If tests do fail, click on the red `X` to learn why by reading the logs. If tests do fail, click on the red `X` to learn why by reading the logs.
Please be sure you've reviewed our contribution guidelines at https://publiclab.org/contributing-to-public-lab-software Please be sure you've reviewed our contribution guidelines at https://publiclab.org/contributing-to-public-lab-software
Please make sure to get at least two reviews before asking for merging the PR as that would make the PR more reliable on our part
Thanks! Thanks!

17
.github/config.yml vendored
View File

@@ -4,22 +4,27 @@
# Comment to be posted to on first time issues # Comment to be posted to on first time issues
newIssueWelcomeComment: | newIssueWelcomeComment: |
Thanks for opening your first issue here! Please follow the issue template to help us help you 👍🎉😄 Thanks for opening your first issue here! This space is [protected by our Code of Conduct](https://publiclab.org/conduct) - and we're here to help.
If you have screenshots to share demonstrating the issue, that's really helpful! 📸 You can [make a gif](https://www.cockos.com/licecap/) too! Please follow the issue template to help us help you 👍🎉😄
If you have screenshots to share demonstrating the issue, that's really helpful! 📸 You can [make a gif](https://www.cockos.com/licecap/) too!
Don't forget to join our [PublicLab Gitter channel](https://gitter.im/publiclab/publiclab) and our [ImageSequencer Gitter Channel](https://gitter.im/publiclab/image-sequencer) for some brainstorming discussions.
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
# Comment to be posted to on PRs from first time contributors in your repository # Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: | newPRWelcomeComment: |
Thanks for opening this pull request! Thanks for opening this pull request! This space is [protected by our Code of Conduct](https://publiclab.org/conduct).
There may be some errors, **but don't worry!** We're here to help! 👍🎉😄 There may be some errors, **but don't worry!** We're here to help! 👍🎉😄
Also please refer (https://github.com/publiclab/image-sequencer/blob/main/README.md) for installation help.
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
# Comment to be posted to on pull requests merged by a first time user # Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: | firstPRMergeComment: |
Congrats on merging your first pull request! 🙌🎉⚡️ Congrats on merging your first pull request! 🙌🎉⚡️
Your code will be published to https://beta.sequencer.publiclab.org in a day or two. Your code will be published to https://beta.sequencer.publiclab.org in a day or two. Please test out your work on this testing server and report back with a comment that all has gone well!
In the meantime, can you tell us your Twitter handle so we can thank you properly? In the meantime, can you tell us your Twitter handle so we can thank you properly also do join our weekly check-in to share your this week goal and the awesome work you did 😃.
Now that you've completed this, you can help someone else take their first step! Please find the link **pinned in the issue section**
Now that you've completed this, you can help someone else take their first step! Try looking at this list of `first-timers-only` issues, and see if someone else is waiting for feedback, or even stuck! 😕
People often get stuck at the same steps, so you might be able to help someone get unstuck, or help lead them to some documentation that'd help. Reach out and be encouraging and friendly! 😄 🎉
See: [Public Lab's coding community!](https://code.publiclab.org) See: [Public Lab's coding community!](https://code.publiclab.org)
# It is recommended to include as many gifs and emojis as possible # It is recommended to include as many gifs and emojis as possible

209
.github/workflows/tests.yml vendored Normal file
View File

@@ -0,0 +1,209 @@
name: tests
on: [pull_request]
jobs:
base-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: "Base istanbul/tape node tests"
run: npm test
benchmark-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: "Benchmark tests"
run: npm run benchmark
gif-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: "Gif tests"
run: npm run gif-test
browserify-core-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- run: sudo apt-get install xvfb
- name: "Browserify core tests and run"
run: grunt tests && xvfb-run --auto-servernum npm run core-tests
jsmine-ui-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: "Jasmine UI tests (mocked browser env)"
run: npm run test-ui
jest-ui-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: "jest-puppeteer UI tests (full browser env)"
run: npm run test-ui-2
cli-tests:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: "CLI tests"
run: npm run test-cli
grunt-build-test:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '12'
check-latest: true
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: "Grunt build test of dev environment"
run: grunt build
## Cache NPM folder
# cache:
# directories:
# - ~/.npm
# - ~/.cache

63
.gitpod.dockerfile Normal file
View File

@@ -0,0 +1,63 @@
FROM gitpod/workspace-full
USER root
RUN sudo apt-get update && apt-get install -y apt-transport-https \
&& sudo apt-get install -y \
xserver-xorg-dev \
libxext-dev \
build-essential \
libxi-dev \
libglew-dev \
pkg-config \
libglu1-mesa-dev \
freeglut3-dev \
mesa-common-dev \
x11-apps \
libice6 \
libsm6 \
libxaw7 \
libxft2 \
libxmu6 \
libxpm4 \
libxt6 \
x11-apps \
xbitmaps \
ca-certificates \
fonts-liberation \
libappindicator3-1 \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libgbm1 \
libgcc1 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
lsb-release \
wget \
xdg-utils \
xvfb \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/*

18
.gitpod.yml Normal file
View File

@@ -0,0 +1,18 @@
image:
file: .gitpod.dockerfile
tasks:
- init: npm run setup
command: npm start
ports:
- port: 3000
onOpen: open-preview
github:
prebuilds:
branches: true
pullRequests: true
pullRequestsFromForks: true
addCheck: true
addComment: true
addBadge: false
addLabel: false

View File

@@ -1,8 +1,8 @@
sudo: required sudo: required
language: node_js language: node_js
node_js: node_js:
- '8'
- '10' - '10'
- '12'
env: env:
- CXX=g++-4.8 - CXX=g++-4.8
before_script: before_script:
@@ -10,10 +10,24 @@ before_script:
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
- chmod +x ./cc-test-reporter - chmod +x ./cc-test-reporter
- ./cc-test-reporter before-build - ./cc-test-reporter before-build
script: jobs:
- npm test include:
- npm run test-ui - name: "Base istanbul/tape node tests"
- grunt build script: npm test
- name: "Benchmark tests"
script: npm run benchmark
- name: "Gif tests"
script: npm run gif-test
- name: "Browserify core tests and run"
script: grunt tests && npm run core-tests
- name: "Jasmine UI tests (mocked browser env)"
script: npm run test-ui
- name: "jest-puppeteer UI tests (full browser env)"
script: npm run test-ui-2
- name: "CLI tests"
script: npm run test-cli
- name: "Grunt build test of dev environment"
script: grunt build
after_success: after_success:
- bash <(curl -s https://codecov.io/bash) - bash <(curl -s https://codecov.io/bash)
after_script: after_script:

View File

@@ -1,114 +1,11 @@
This document was copied from its home at https://publiclab.org/conduct on October 12, 2017. See that page if you would like to submit your concerns in a safe, completely anonymous way, and to learn more about this document.
****
# Public Lab Code of Conduct # Public Lab Code of Conduct
_Public Lab, PO Box 426113, Cambridge, MA 02142_ _Public Lab, 55 Cromwell Street, 1C, Providence, RI 02907_
We are coming together with an intent to care for ourselves and one another. We want to nurture a compassionate democratic culture where responsibility is shared. We -- visitors, community members, community moderators, staff, organizers, sponsors, and all others -- hold ourselves accountable to the same values regardless of position or experience. For this to work for everybody, individual decisions will not be allowed to run counter to the welfare of other people. This community aspires to be a respectful place both during online and in-person interactions so that all people are able to fully participate with their dignity intact. This document is a piece of the culture we're creating. We are coming together with an intent to care for ourselves and one another as we produce knowledge in pursuit of environmental justice. For this to work for everybody, individual decisions will not be allowed to run counter to the welfare of other people. We—visitors, community members, community moderators, staff, organizers, sponsors, and all othershold ourselves accountable to the same values regardless of position or experience. This community aspires to be a respectful place both during online and in-person interactions so that all people are able to fully participate with their dignity intact. This document is a piece of the culture we're creating.
This code of conduct applies to all spaces managed by the Public Lab community and non-profit, both online and in person. It provides a clear set of practical guidelines for events led by organizers and community members, multi-day events such as Barnraisings, and online venues such as the website, comment threads on software platforms, chatrooms, our mailing lists, the issue tracker, and any other forums created by Public Lab which the community uses for communication. For interactions with additional groups, see our Partnership Guidelines at https://publiclab.org/partners.
This code of conduct applies to all spaces managed by the Public Lab community and non-profit, both online and in person. It was written by the Conduct Committee (formed in 2015 during Public Labs annual conference “The Barnraising”) and facilitated by staff to provide a clear set of practical guidelines for multi-day events such as Barnraisings, events led by organizers and community members, and online venues such as the website, comment threads on software platforms, chatrooms, our mailing lists, the issue tracker, and any other forums created by Public Lab which the community uses for communication. To read the full Code of Conduct and learn how to contact the Conduct Committee or the Moderators group, see:
https://publiclab.org/conduct
## We come from all kinds of backgrounds
Our community is best when we fully invite and include participants from a wide range of backgrounds. We specifically design spaces to be welcoming and accessible to newcomers and folks from underrepresented groups. Public Lab is dedicated to providing a harassment-free, safe, and inclusive experience for everyone, regardless of personal and professional background, gender, gender identity and expression, style of clothing, sexual orientation, dis-/ability, physical appearance, body size, race, class, age, or religion. Public Lab resists and rejects: racism, sexism, ableism, ageism, homophobia, transphobia, body shaming, religion shaming, “geekier-than-thou” shaming, education bias, the shaming of people nursing children, and the dismissal or bullying of children or adults.
## We do not tolerate harassment or shaming
While we operate under the assumption that all people involved with Public Lab subscribe to the basic understanding laid out above, we take these issues very seriously and think they should, in general, be taken seriously. Therefore, individuals who violate this Code both in and outside of Public Lab spaces may affect their ability to participate in Public Lab ranging from temporarily being placed into online moderation to, as a last resort, expulsion from the community. If you have any questions about our commitment to this framework and/or if you are unsure about aspects of it, email conduct@publiclab.org and we will do our best to provide clarification.
## How It Works
Sometimes things go wrong. When a situation is uncomfortable, hurtful, exclusionary, or upsetting, there is a problem that should be addressed. This code of conduct is an effort to maintain a safe space for everyone, and to talk about what might happen if that space is compromised. Please see additional guidelines below for community behavior on how we expect people to interact with one another.
### Two helpful groups
__Conduct Committee (ConductCom)__: If at any time you experience something that you are not comfortable with, you may contact the Conduct Committee. As established during the 2015 Annual Barnraising, the following individuals are on the Conduct Committee: Klie Kliebert, Carla Green, Nick Shapiro, and Shannon Dosemagen, the executive director of the Public Lab nonprofit.
If you would like to have a confidential conversation, connect with ConductCom in person or email via [conduct@publiclab.org](mailto:conduct@publiclab.org). A minimum of two committee members will confer and respond as swiftly as possible. If you would prefer to speak privately with a representative of the nonprofit, please contact the executive director directly either in person or by email: [shannon@publiclab.org.](mailto:conduct@publiclab.org)
To submit a report anonymously for review by ConductCom, go online via phone or computer to our anonymous “contact” app, located at [http://bit.ly/PLReport](http://bit.ly/PLReport). This contact app will be monitored daily at 8am CST during in-person events like Barnraisings and weekly at all other times. During multi-day in-person events hosted by the Public Lab non-profit, there will also be a physical suggestion box available. This box will be monitored throughout the event and can also be used to let us know if you need us to check on an anonymous online submission sooner.
__Moderators Group:__ The moderators group is responsible for addressing immediate moderation issues that arise during online violations of the code over email lists and Public Lab community websites, as well as approving first-time posts and generally handling spam. Instructions on how to become a moderator, and, if youve been placed in moderation how to begin the process of getting out of moderation can be found at: https://publiclab.org/wiki/moderation.
****
## A Culture of Empathy
We begin interactions by acknowledging that we are part of a community with complementary goals. Different views are allowed to respectfully coexist in the same space. When something's happened and someone is uncomfortable, our first choice is to work through it. Endeavor to listen and appropriately adjust your behavior if someone approaches you privately with a request that you apologize or publicly requests that you stop an ongoing presentation. If someone questions your words, actions or motives, or "calls you out", hear their feedback and respond respectfully. Its okay to not understand why something is hurtful or causes discomfort, as long as you approach it respectfully, with empathy. Repeating hurtful behavior after it has been addressed is disrespectful and is not allowed. Doing so will result in removal and subsequent banning from in-person events and being placed into moderation in online spaces.
### The first rule of engaging with others is consent
During in-person gatherings, consent is important to highlight because the negotiation of consent can be subtle, and its easy to miss each others non-verbal cues, resulting in miscommunication and/or offense. During online interactions, consent can be even harder to distinguish.
We make guesses or assessments of consent (willingness, welcome, invitation) all the time. Then we stay open to signs that the consent isn't there. Handshakes are a clear example of consent: someone offers a hand, and you take it if you want to shake it. A friendly smile might indicate consent to start a conversation. It might not. We learn that in the interaction. Sometimes we ask directly. We are open to making mistakes, and learning from them. The more we learn to be empathetic and see other people, the more we're able to talk about consent.
Before you engage with someone on any level, be sure you have their consent. If your indications aren't being heard, you can also ask for help from other folks, especially Conduct Committee members and staff of the non-profit: "They aren't taking the hint. Will you help?" Turning a blind eye to hurtful interactions can be as bad for our community as the exchange itself. If you witness something, it's your responsibility to say something. This is how we keep each other accountable, encourage empathy, and keep our community safe.
## Guidelines for in-person community behavior
Do | Dont
----------- | -----------
Respectfully share what method works best for you, while giving others space to think differently and contribute other ideas | Disparage entire groups/sets of people for their beliefs or methods
Ask permission to take pictures of and post about others on social media (see Media Consent, above)| Upload photos, tag or mention others online without their consent
Speak your own narrative, from your own unique culture | Caricature the cultural expressions of groups you are not a member of
Model inclusionary expertise - if others in the group appear to be “lost”, slow down; stop and ask for input | Present information in a way / at a level that no one else in the room can understand, with no attempt to include others in the discussion
Create events that are all-ages appropriate | Use language that excludes youth and their experiences as vital contributors
Give everyone a chance to talk, only interrupting if absolutely necessary - for example, Code of Conduct violations | Repeatedly disrupt a discussion
Stop, listen and ask for clarification if someone perceives your behavior or presentation as violating the Code of Conduct | Ignore others request to stop potentially harmful behavior, even if it was an accident
Cultivate a sense of humor based on other subjects, such as word play (especially puns!) | Joke using words related to actual or insulting descriptions of people
Use words that accurately describe the situation - For example, “The wind was ridiculously strong!” instead of “The wind was crazy!” | Use disability and mental/emotional health terminology to describe a situation metaphorically, especially if the phrasing is meant as an insult
Only discuss someone elses lifestyle practices if they invite you to a conversation on the topic | Make unwelcomed comments regarding a persons lifestyle practices, including those related to food, health, parenting, relationships, and employment
Ask someone before you hug them; keep your hands/body to yourself, even when joking, unless the other person has given verbal consent | Initiate physical contact or simulate physical contact without consent
Disengage and find another activity if someone did not invite you and is not engaging with you | Violate personal space by continuing your physical presence into private spaces without consent
Exercise the right to talk about your own identity if you want to, or not if you dont want to | Deliberately “out” any aspect of a persons identity without their consent
Use the pronouns people have specified for themselves | Purposely misgender someone (ie, refusing to use their correct gender pronouns) after they have told you their correct pronouns
## Additional guidelines for online community behavior
Online modes of interaction involve large numbers of people without the helpful presence of gestural, expression, and tonal cues regarding consent. Because of this, respectful and self-aware online conduct is both especially important and difficult. Our community has evolved specific guidelines for online interactions.
_If someone violates these guidelines, someone from the Moderators group will place them into moderation by changing that persons posting permission on the relevant list, on the website, or both._
Our triple notification standard for moderation means a point person from the Moderators group will:
1. e-mail the person directly with a brief explanation of what was violated,
2. send a summary email to the rest of the moderators group,
3. if it happened on a public list (vs a website), notify the list that one of our members has been placed into moderation with a brief explanation of what is not tolerated.
If you wish to begin the process of getting out of moderation, respond to the email sent to you from [moderators@publiclab.org](mailto:moderators@publiclab.org). The Moderators group has the option to involve ConductCom.
Do | Dont
-------|--------
Stay on topic to make long threads easier to follow |Send spurious one-line responses that effectively "spam" hundreds of people and lower the overall content quality of a conversation. (Exception: expressions of appreciation and encouragement!)
Start a new thread to help others follow along. Important if your response starts to significantly diverge from the original topic | Respond with off-topic information making it hard for the large group of readers to follow along
Write short and literal subject lines to help the readers of the list manage the volume of communication | Humor and euphemisms in subject lines are easily misunderstood, although enthusiasm is welcome!
Mind your tone. We are not having this conversation in person, so it is all the more important to maintain a tone of respect | Write in aggressive tone, disrespectful tone, mocking tone, off-color tone. Note: writing in all caps is regarded as shouting
## Media Consent
* ALWAYS check with parents about posting anything with minors.
* Never post the names of minors in conjunction with their photo.
* During multi-day events like Barnraisings most people will have signed media releases. Those who havent will be responsible for placing stickers on their nametags, and/or raising their hands in the moment to alert photographers to move them out of frame.
* For events where people have not signed blanket media release forms, the photographer is responsible for letting the room know that you are taking photos that will be posted online. Pay special attention to the presence of minors and their parent's wishes.
## Addendum for all staff
Staff are bound by their Employment Handbook, you must reference it. Additionally:
* Direct problems that come up among community members to the Conduct Committee.
* When organizing events, circulate access information regarding wheelchair-accessible ADA bathrooms, non-gendered bathrooms, the presence of stairs or curb ramps in the parking lot, et cetera.
* During events that you are attending in person, solve accessibility issues by making sure attendees know where bathrooms are located and can access them by wheelchair without being obstructed by things like chairs, kites, contraptions, or cords.
* Watch for people feeling left out and include them.

View File

@@ -5,7 +5,7 @@ Happily accepting pull requests; to edit the core library, modify files in `./sr
On ARM based devices, the `gl` module may require some libraries to be re-installed: On ARM based devices, the `gl` module may require some libraries to be re-installed:
`sudo apt-get install -y build-essential libxi-dev libglu1-mesa-dev libglew-dev pkg-config` -- see https://github.com/stackgl/headless-gl#ubuntudebian for more. `sudo apt-get install -y build-essential xserver-xorg-dev libxext-dev libxi-dev libglu1-mesa-dev libglew-dev pkg-config` -- see https://github.com/stackgl/headless-gl#ubuntudebian for more.
Most contribution (we imagine) would be in the form of API-compatible modules, which need not be directly included. Most contribution (we imagine) would be in the form of API-compatible modules, which need not be directly included.
@@ -17,6 +17,7 @@ Most contribution (we imagine) would be in the form of API-compatible modules, w
* [Ideas](#Contribution-ideas) * [Ideas](#Contribution-ideas)
* [Grunt Tasks](#grunt-tasks) * [Grunt Tasks](#grunt-tasks)
* [UI Helper Methods](#ui-helper-methods) * [UI Helper Methods](#ui-helper-methods)
* [Scripts](#scripts)
**** ****
@@ -374,7 +375,7 @@ module.exports =
We are now using `eslint` and `husky` to help lint and format our code each time we commit. Eslint defines coding standards and helps in cleaning up the code. To run eslint for checking errors globally or within a specific file run: We are now using `eslint` and `husky` to help lint and format our code each time we commit. Eslint defines coding standards and helps in cleaning up the code. To run eslint for checking errors globally or within a specific file run:
``` ```
npx eslint . npx eslint .
npx eslint <file path> npx eslint <file path>
``` ```
@@ -412,15 +413,15 @@ The following command is used for running the tasks: `grunt [task-name]`. Here `
The method returns a scoped `jQuery` object which only searches for elements inside a given scope (a DOM element). The method returns a scoped `jQuery` object which only searches for elements inside a given scope (a DOM element).
To use the method, To use the method,
* import the `scopeSelector` and `scopeSelectorAll` methods from `lib/scopeQuery.js` * import the `scopeSelector` and `scopeSelectorAll` methods from `lib/scopeQuery.js`
* call the methods with scope as a parameter * call the methods with scope as a parameter
```js ```js
var scopeQuery = require('./scopeQuery'); var scopeQuery = require('./scopeQuery');
var $step = scopeQuery.scopeSelector(scope), var $step = scopeQuery.scopeSelector(scope),
$stepAll = scopeQuery.scopeSelectorAll(scope); $stepAll = scopeQuery.scopeSelectorAll(scope);
``` ```
This will return an object with a constructor which returns a `jQuery` object (from inside the scope) but with new `elem` and `elemAll` methods. This will return an object with a constructor which returns a `jQuery` object (from inside the scope) but with new `elem` and `elemAll` methods.
@@ -433,7 +434,7 @@ This will return an object with a constructor which returns a `jQuery` object (f
#### Example #### Example
```js ```js
//The scope is a div element with id=“container“ and there are three divs in it //The scope is a div element with id=“container“ and there are three divs in it
//with ids „1“, „2“, and „3“, and all of them have a „child“ class attribute //with ids „1“, „2“, and „3“, and all of them have a „child“ class attribute
var $step = require('./scopeQuery').scopeSelector(document.getElementById('container')); var $step = require('./scopeQuery').scopeSelector(document.getElementById('container'));
@@ -458,3 +459,23 @@ The following code can be used
$step('query').show().hide(); $step('query').show().hide();
$stepAll('q2').show().hide(); $stepAll('q2').show().hide();
``` ```
## Scripts
The following shell scripts are present in the `scripts/` directory.
- `update-gh-pages`: This script can be used to update the `gh-pages` branch of this repo or a fork.
This script is not meant to be used directly as it runs in the current working directory.
If you run it on your primary local clone, it can **delete** the local changes. This script is made to be used in a github action
or in a temporary directory via another script, such as `update-demo`.
Arguments:
1. Repo(to use as upstream) url in the form username/repo (default: publiclab/image-sequencer) NOTE: Github only
2. Branch to pull from eg: main or stable (default: stable)
3. CNAME URL (default: none)
4. Set the fourth argument to anything to bypass the warning. You will have to set this argument if you want to run this script in another script without needing
user interaction, such as in a github action.
- `update-demo`: A safe, interactive script that can be used to update the `gh-pages` branch of any image-sequencer fork.
This script is safe to use directly because it separately clones the repo in a temporary directory.
Arguments: None since it is a an *interactive* script, ie it asks the user for input.

View File

@@ -2,6 +2,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-contrib-uglify-es'); grunt.loadNpmTasks('grunt-contrib-uglify-es');
grunt.loadNpmTasks('grunt-browser-sync'); grunt.loadNpmTasks('grunt-browser-sync');
grunt.loadNpmTasks('grunt-text-replace');
require('matchdep') require('matchdep')
.filterDev('grunt-*') .filterDev('grunt-*')
@@ -21,6 +22,11 @@ module.exports = function(grunt) {
}, },
browserify: { browserify: {
options: {
alias: {
'gpu.js': './node_modules/gpu.js/src/index.js'
}
},
core: { core: {
src: ['src/ImageSequencer.js'], src: ['src/ImageSequencer.js'],
dest: 'dist/image-sequencer.js' dest: 'dist/image-sequencer.js'
@@ -36,6 +42,28 @@ module.exports = function(grunt) {
produi: { produi: {
src: ['examples/demo.js'], src: ['examples/demo.js'],
dest: 'dist/image-sequencer-ui.brow.js' dest: 'dist/image-sequencer-ui.brow.js'
},
tests: {
src: ['test/core/sequencer/meta-modules.js',
'test/core/sequencer/image-sequencer.js',
'test/core/sequencer/chain.js',
'test/core/sequencer/replace.js',
'test/core/sequencer/import-export.js',
'test/core/sequencer/run.js',
'test/core/sequencer/dynamic-imports.js',
'test/core/util/*.js'],
dest: './output/core-tests.js'
}
},
replace: {
version: {
src: ['examples/sw.js'],
overwrite: true,
replacements: [{
from: /image-sequencer-static-v.*/g,
to: "image-sequencer-static-v<%= pkg.version %>';"
}]
} }
}, },
@@ -69,8 +97,10 @@ module.exports = function(grunt) {
/* Default (development): Watch files and build on change. */ /* Default (development): Watch files and build on change. */
grunt.registerTask('default', ['watch']); grunt.registerTask('default', ['watch']);
grunt.registerTask('build', ['browserify:core', 'browserify:ui', 'uglify:core', 'uglify:ui']); grunt.registerTask('build', ['browserify:core', 'browserify:ui', 'replace:version', 'uglify:core', 'uglify:ui']);
grunt.registerTask('serve', ['browserify:core', 'browserify:ui', 'browserSync', 'watch']); grunt.registerTask('serve', ['browserify:core', 'browserify:ui', 'replace:version', 'browserSync', 'watch']);
grunt.registerTask('compile', ['browserify:core', 'browserify:ui']); grunt.registerTask('compile', ['browserify:core', 'browserify:ui']);
grunt.registerTask('production', ['browserify:prodcore', 'browserify:produi', 'uglify:prodcore', 'uglify:produi']); grunt.registerTask('production', ['browserify:prodcore', 'browserify:produi', 'replace:version', 'uglify:prodcore', 'uglify:produi']);
grunt.registerTask('tests', ['browserify:tests']);
}; };

View File

@@ -1,13 +1,19 @@
Image Sequencer Image Sequencer
==== ====
[![Code of Conduct](https://img.shields.io/badge/code-of%20conduct-green.svg)](https://publiclab.org/conduct)
[![npm version](https://badge.fury.io/js/image-sequencer.svg)](https://badge.fury.io/js/image-sequencer)
[![Build Status](https://travis-ci.org/publiclab/image-sequencer.svg?branch=master)](https://travis-ci.org/publiclab/image-sequencer) [![Maintainability](https://api.codeclimate.com/v1/badges/5906996dd2e90aca6398/maintainability)](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) [![Codecov](https://img.shields.io/codecov/c/github/publiclab/image-sequencer.svg?logo=codecov)](https://codecov.io/gh/publiclab/image-sequencer) [![Build Status](https://travis-ci.org/publiclab/image-sequencer.svg?branch=master)](https://travis-ci.org/publiclab/image-sequencer) [![Maintainability](https://api.codeclimate.com/v1/badges/5906996dd2e90aca6398/maintainability)](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) [![Codecov](https://img.shields.io/codecov/c/github/publiclab/image-sequencer.svg?logo=codecov)](https://codecov.io/gh/publiclab/image-sequencer)
[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/publiclab/image-sequencer/)
- **Latest Stable Demo**: https://sequencer.publiclab.org - **Latest Stable Demo**: https://sequencer.publiclab.org
- **Latest Beta Demo**: https://beta.sequencer.publiclab.org - **Latest Beta Demo**: https://beta.sequencer.publiclab.org
- **Stable Branch**: https://github.com/publiclab/image-sequencer/tree/stable/ - **Stable Branch**: https://github.com/publiclab/image-sequencer/tree/stable/
Begin running (and contributing to) this codebase immediately with [GitPod](https://gitpod.io) (this also opens the latest `main` branch code):
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/publiclab/image-sequencer)
## Why ## Why
Image Sequencer is different from other image processing systems because it's _non-destructive_: instead of modifying the original image, it **creates a new image at each step in a sequence**. This is because it: Image Sequencer is different from other image processing systems because it's _non-destructive_: instead of modifying the original image, it **creates a new image at each step in a sequence**. This is because it:
@@ -71,6 +77,12 @@ In case of a port conflict please run the following
npm i -g http-server ; http-server -p 3000 npm i -g http-server ; http-server -p 3000
``` ```
### Online one-click setup for contributing
Contribute to ImageSequencer using a fully featured online development environment that will automatically: clone the repo, install the dependencies and start the webserver.
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/from-referrer/)
### Browser ### Browser
Just include [image-sequencer.min.js](https://github.com/publiclab/image-sequencer/blob/stable/dist/image-sequencer.min.js) in the Head section of your web page. See the [demo here](https://sequencer.publiclab.org)! Just include [image-sequencer.min.js](https://github.com/publiclab/image-sequencer/blob/stable/dist/image-sequencer.min.js) in the Head section of your web page. See the [demo here](https://sequencer.publiclab.org)!
@@ -242,7 +254,7 @@ If only one module is to be added, `modules` is simply the name of the module.
If multiple images are to be added, `modules` is an array, which holds the names of modules If multiple images are to be added, `modules` is an array, which holds the names of modules
to be added, in that particular order. to be added, in that particular order.
optional_otions is just an optional parameter, in object form, which you might optional_options is just an optional parameter, in object form, which you might
want to provide to the modules. want to provide to the modules.
A variety of syntaxes are supported by Image Sequencer to add multiple steps and configurations quickly for module chaining. The project supports the string syntax, designed to be compact and URL friendly, and JSON, for handling more complex sequences. This can be achieved by passing strings to `sequencer.addStep()`: A variety of syntaxes are supported by Image Sequencer to add multiple steps and configurations quickly for module chaining. The project supports the string syntax, designed to be compact and URL friendly, and JSON, for handling more complex sequences. This can be achieved by passing strings to `sequencer.addStep()`:
@@ -598,4 +610,17 @@ let sequencer = ImageSequencer() // also for wasm mode i.e. default mode
let sequencer = ImageSequencer({useWasm:false}) //for non-wasm mode let sequencer = ImageSequencer({useWasm:false}) //for non-wasm mode
``` ```
## Experimental GIF processing support
ImageSequencer currently can process GIFs but only for most of the modules. Every frame of the GIF is manipulated sequentially (parallel processing would be preferable in the future).
The final frames are then converted back to a GIF but in the process, the time duration of each frame is lost and defaults to `0.1s`.
Modules that do not work:
1. ColorBar (Will get fixed upon fixing overlay as this is a meta module which uses overlay)
2. FisheyeGL
3. Overlay
4. Blend
5. Histogram
6. WebGL Distort

View File

@@ -8,39 +8,44 @@ List of Module Documentations
3. [Blend](#blend-module) 3. [Blend](#blend-module)
4. [Blur](#blur-module) 4. [Blur](#blur-module)
5. [Brightness](#brightness-module) 5. [Brightness](#brightness-module)
6. [Channel](#channel-module) 6. [Canvas-Resize](#canvas-resize-module)
7. [Colorbar](#colorbar-module) 7. [Channel](#channel-module)
8. [Colormap](#colormap-module) 8. [Colorbar](#colorbar-module)
9. [ColorTemperature](#color-temperature) 9. [Colormap](#colormap-module)
10. [Contrast](#contrast-module) 10. [ColorTemperature](#color-temperature)
11. [Convolution](#convolution-module) 11. [Contrast](#contrast-module)
12. [Crop](#crop-module) 12. [Convolution](#convolution-module)
13. [DecodeQr](#decodeQr-module) 13. [Crop](#crop-module)
14. [Dither](#dither-module) 14. [DecodeQr](#decodeQr-module)
15. [DrawRectangle](#draw-rectangle-module) 15. [Dither](#dither-module)
16. [Dynamic](#dynamic-module) 16. [DrawRectangle](#draw-rectangle-module)
17. [Edge-Detect](#edge-detect-module) 17. [Dynamic](#dynamic-module)
18. [FisheyeGl](#fisheyeGl-module) 18. [Edge-Detect](#edge-detect-module)
19. [FlipImage](#flipimage-module) 19. [Exposure](#exposure-module)
20. [Gamma-Correction](#gamma-correction-module) 20. [FisheyeGl](#fisheyeGl-module)
21. [Gradient](#gradient-module) 21. [FlipImage](#flipimage-module)
22. [Grid-Overlay](#grid-overlay) 22. [Gamma-Correction](#gamma-correction-module)
23. [Histogram](#histogram-module) 23. [Gradient](#gradient-module)
24. [Import-image](#import-image-module) 24. [Grid-Overlay](#grid-overlay)
25. [Invert](#invert-module) 25. [Histogram](#histogram-module)
26. [MinifyImage](#minify-image) 26. [Import-image](#import-image-module)
27. [Ndvi](#ndvi-module) 27. [Invert](#invert-module)
28. [Ndvi-Colormap](#ndvi-colormap-module) 28. [MinifyImage](#minify-image)
29. [Overlay](#overlay-module) 29. [Ndvi](#ndvi-module)
30. [PaintBucket](#paint-bucket-module) 30. [Ndvi-Colormap](#ndvi-colormap-module)
31. [ReplaceColor](#replacecolor-module) 31. [NoiseReduction](#noise-reduction)
32. [Resize](#resize-module) 32. [Overlay](#overlay-module)
33. [Rotate](#rotate-module) 33. [PaintBucket](#paint-bucket-module)
34. [Saturation](#saturation-module) 34. [ReplaceColor](#replacecolor-module)
35. [Segmented-Colormap](#segmented-colormap-module) 35. [Resize](#resize-module)
36. [Text-Overlay](#text-overlay) 36. [Rotate](#rotate-module)
37. [Threshold](#threshold) 37. [Saturation](#saturation-module)
38. [Tint](#tint) 38. [Segmented-Colormap](#segmented-colormap-module)
39. [Text-Overlay](#text-overlay)
40. [Threshold](#threshold)
41. [Tint](#tint)
42. [WebGL-Distort](#webgl-distort-module)
43. [White-Balance](#white-balance-module)
## add-qr-module ## add-qr-module
@@ -73,7 +78,8 @@ This module is used for averaging all the pixels of the image.
## blend-module ## blend-module
This module is used for blending two images . This module is used for blending two images. For More info read: _[wiki](https://en.wikipedia.org/wiki/Blend_modes)_
#### Usage #### Usage
```js ```js
@@ -83,8 +89,12 @@ This module is used for blending two images .
``` ```
where `options` is an object with the following properties: where `options` is an object with the following properties:
* offset: step of image with which current image is to be blended(Two steps back is -2, three steps back is -3 etc; default -2) * offset: step of image with which current image is to be blended(Two steps back is -2, three steps back is -3 etc; default -2)
* func: function used to blend two images (default : function(r1, g1, b1, a1, r2, g2, b2, a2) { return [ r1, g2, b2, a2 ] }) * blendMode: Blending mode to use for blending two images by default it uses the given function
* func: function used to blend two images (default : function(r1, g1, b1, a1, r2, g2, b2, a2) { return [ r1, g2, b2, a2 ] })
[More info for different blend modes can be found here](http://docs.gimp.org/en/gimp-concepts-layer-modes.html)
## Blob Analysis ## Blob Analysis
@@ -130,6 +140,24 @@ where `options` is an object with the following property:
* brightness : brightness of the image in percentage (0 to 100; default 100) * brightness : brightness of the image in percentage (0 to 100; default 100)
## canvas-resize-module
This module is used for resizing the canvas of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('canvas-resize',options)
.run()
```
where `options` is an object with the following property:
* width: final width of the canvas (default 1000)
* height: final height of the canvas (default 1000)
* x: x-coordinate of the top left of the image on the canvas (default 500)
* y: y-coordinate of the top left of the image on the canvas (default 500)
## channel-module ## channel-module
This module is used for forming a grayscale image by applying one of the three primary colors. This module is used for forming a grayscale image by applying one of the three primary colors.
@@ -326,6 +354,21 @@ where `options` is an object with the following properties:
* lowThresholdratio : Lower Threshold Ratio ( default : 0.2) * lowThresholdratio : Lower Threshold Ratio ( default : 0.2)
## exposure-module
This module is used for changing the exposure of the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('exposure',options)
.run()
```
where `options` is an object with the following property:
* exposure: exposure value for the new image (-3 to 4; default 1)
## fisheyeGl-module ## fisheyeGl-module
This module is used for correcting Fisheye or Lens Distortion This module is used for correcting Fisheye or Lens Distortion
@@ -488,6 +531,21 @@ This module is used for demonstrating ndvi and colormap properties consecutively
``` ```
## Noise-Reduction
Noise in an image are atypical pixels that are not representing the color or the exposure of the scene correctly. This Noise Reduction module reduces the noise in the image by using either median filtering or mean filtering techniques to change the RGB value of the pixels to create a smoother and fuller image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('noise-reduction',options)
.run()
```
where `options` is an object with the property `method`. `options.method` can be:
* Median Filtering: Set the RGB value of the pixel to the median RGB pixel value of all adjacent pixels (maximum 8 adjacent pixels and itself)
* Mean Filtering: Set the RGB value of the pixel to the mean RGB pixel value of all adjacent pixels (maximum 8 adjacent pixels and itself)
## overlay-module ## overlay-module
This module is used for overlaying an Image over another . This module is used for overlaying an Image over another .
@@ -651,3 +709,38 @@ It adds color tint to an image
where `options` is an object with the following property: where `options` is an object with the following property:
* color : RGB values seperated by a space (default "0 0 255") * color : RGB values seperated by a space (default "0 0 255")
* factor : amount of tint (default 0.5) * factor : amount of tint (default 0.5)
## webgl-distort-module
This module is used for transforming the perspective of images based on corner coordinates.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('webgl-distort',options)
.run()
```
where `options` is an object with the following property:
* nw: top-left corner x and y coordinates separated by a comma (default "0,100")
* ne: top-right corner x and y coordinates separated by a comma (default "1023,-50")
* se: bottom-right corner x and y coordinates separated by a comma (default "1223,867")
* sw: bottom-left corner x and y coordinates separated by a comma (default "100,767")
## white-balance-module
This module is used for rendering neutral colors of an image correctly based on the whitest pixel in the image.
#### Usage
```js
sequencer.loadImage('PATH')
.addSteps('white-balance',options)
.run()
```
where `options` is an object with the following property:
* red: red component of the whitest pixel (default 255)
* green: green component of the whitest pixel (default 255)
* blue: blue component of the whitest pixel (default 255)

View File

@@ -1,12 +1,8 @@
/* https://github.com/theleagueof/league-spartan */ /* https://github.com/theleagueof/league-spartan */
@font-face { @font-face {
font-family: 'League Spartan'; font-family: 'League Spartan';
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot'); src: url('https://cdn.jsdelivr.net/npm/fontsource-league-spartan@3/files/league-spartan-latin-600-normal.woff2') format('woff2'),
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot?#iefix') format('embedded-opentype'), url('https://cdn.jsdelivr.net/npm/fontsource-league-spartan@3/files/league-spartan-latin-600-normal.woff') format('woff');
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.woff2') format('woff2'),
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.woff') format('woff'),
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.ttf') format('truetype'),
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.svg#league_spartanbold') format('svg');
font-weight: bold; font-weight: bold;
font-style: normal; font-style: normal;
} }
@@ -33,7 +29,7 @@ body > .container-fluid {
.center-align { .center-align {
display: flex; display: flex;
justify-content: center; justify-content: left;
text-align:center; text-align:center;
} }
@@ -46,6 +42,10 @@ body > .container-fluid {
margin-right: 20px; margin-right: 20px;
} }
.mouse {
cursor: pointer !important;
}
.nomargin { .nomargin {
margin: 0 !important; margin: 0 !important;
} }
@@ -63,14 +63,25 @@ body > .container-fluid {
color: #444; color: #444;
} }
.hover {
background: #eee;
}
.dropzone input { .dropzone input {
max-width: 100%; max-width: 100%;
} }
.import-image-zone {
margin: 10px auto 30px auto;
max-width: 250px;
min-width: 230px;
}
.import-image-zone input {
max-width: 100%;
}
.hover {
border: 4px dashed #888888;
background: #F0F0F0;
}
.step { .step {
margin-bottom: 20px; margin-bottom: 20px;
} }
@@ -103,7 +114,10 @@ body > .container-fluid {
} }
#add-step-btn{ #add-step-btn{
margin-left: 10px; width: 100%
}
.selectize-input {
width: 100%;
} }
#addStep .labels { #addStep .labels {
@@ -137,10 +151,16 @@ body > .container-fluid {
margin: 0px 0px 0px 10px; margin: 0px 0px 0px 10px;
width: 250px; width: 250px;
} }
@media(max-width: 768px) {
#dropzone {
margin: 0 0% 30px;
}
}
#dwnld { #dwnld {
max-width: 500px; max-width: 500px;
margin: 20px auto; margin: 20px auto;
margin-left: 5px;
} }
#gif_element { #gif_element {
@@ -244,13 +264,14 @@ a.name-header{
} }
.step-column{ .step-column{
display:flex; display:flex;
align-content: center; align-content: center;
justify-content: center; justify-content: center;
} }
.trash-container button.btn-xs { .trash-container button.btn-xs {
margin-top: -5px !important; position: relative;
bottom: 7px;
} }
.toggleIcon { .toggleIcon {
@@ -267,12 +288,110 @@ a.name-header{
width:100%; width:100%;
} }
.save-button{ .save-button{
margin-top:20px; margin-top:20px;
margin-bottom:0px; margin-bottom:0px;
align:center; align:center;
width:100%; width:100%;
} }
.toggle { .toggle {
cursor: default; cursor: default;
} }
.general-tooltip:hover{
text-decoration: none;
}
.general-tooltip:focus{
outline: none;
}
.general-tooltip:focus-within{
outline: none;
}
.general-tooltip{
position: relative;
bottom: 7px;
font-size: 16px;
color: #444;
}
#version-number-text {
text-align: center;
padding-top: 100px;
color: gray;
}
#version-number-top-right {
position: fixed;
right: 2%;
top: 5%;
color: gray;
}
/* Non float rightward alignment*/
.right {
margin-left: auto;
display: block;
}
#update-prompt-modal,.notify-box {
visibility: hidden;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 8px;
padding: 16px;
position: fixed;
z-index: 1000;
left: 10%;
top: 30px;
}
#update-prompt-modal {
width: 30vw;
margin: 0.2rem;
}
.notify-box {
width:34vw;
padding:18px;
border-radius:8px;
margin-left:0.8rem;
text-align:left;
color:#333;
background:#c3c3c3;
}
/* Bootstrap class for display none remove it after updating to version v4 */
.d-none {
display:none;
}
/* Bootstrap class for display block remove it after updating to version v4 */
.d-block {
display:block;
}
#update-prompt-modal.show,.notify-box {
visibility: visible;
-webkit-animation: fadein 0.5s;
animation: fadein 0.5s;
}
@-webkit-keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

View File

@@ -3,12 +3,48 @@ var defaultHtmlSequencerUi = require('./lib/defaultHtmlSequencerUi.js'),
intermediateHtmlStepUi = require('./lib/intermediateHtmlStepUi.js'), intermediateHtmlStepUi = require('./lib/intermediateHtmlStepUi.js'),
DefaultHtmlStepUi = require('./lib/defaultHtmlStepUi.js'), DefaultHtmlStepUi = require('./lib/defaultHtmlStepUi.js'),
urlHash = require('./lib/urlHash.js'), urlHash = require('./lib/urlHash.js'),
insertPreview = require('./lib/insertPreview.js'); insertPreview = require('./lib/insertPreview.js'),
versionManagement = require('./lib/versionManagement.js'),
isGIF = require('../src/util/isGif');
window.onload = function () { window.onload = function () {
sequencer = ImageSequencer(); sequencer = ImageSequencer(); // Set the global sequencer variable
options = {
sortField: 'text',
openOnFocus: false,
onInitialize: function () {
this.$control.on('click', () => {
this.ignoreFocusOpen = true;
setTimeout(() => {
// Trigger onFocus and open dropdown.
this.ignoreFocusOpen = false;
}, 50);
});
},
// Open dropdown after timeout of onClick.
onFocus: function () {
if (!this.ignoreFocusOpen) {
this.open();
}
}
};
function refreshOptions() { versionManagement.getLatestVersionNumber(function(versionNumber) {
console.log('The latest NPM version number for Image Sequencer (from GitHub) is v' + versionNumber);
});
console.log('The local version number for Image Sequencer is v' + versionManagement.getLocalVersionNumber());
function displayVersionNumber() {
$('#version-number-text').text('Image Sequencer v' + versionManagement.getLocalVersionNumber());
$('#version-number-top-right').text('v' + versionManagement.getLocalVersionNumber());
}
displayVersionNumber();
function refreshOptions(options) {
// Default options if parameter is empty.
if (options == undefined) options = { sortField: 'text' };
// Load information of all modules (Name, Inputs, Outputs) // Load information of all modules (Name, Inputs, Outputs)
var modulesInfo = sequencer.modulesInfo(); var modulesInfo = sequencer.modulesInfo();
@@ -24,15 +60,16 @@ window.onload = function () {
} }
// Null option // Null option
addStepSelect.append('<option value="" disabled selected>Select a Module</option>'); addStepSelect.append('<option value="" disabled selected>Select a Module</option>');
addStepSelect.selectize({ addStepSelect.selectize(options);
sortField: 'text'
});
} }
refreshOptions(); refreshOptions(options);
$(window).on('scroll', scrollFunction); $(window).on('scroll', scrollFunction);
function scrollFunction() { /**
* @description Method to toggle the scroll-up arrow.
*/
function scrollFunction(A, B) {
var shouldDisplay = $('body').scrollTop() > 20 || $(':root').scrollTop() > 20; var shouldDisplay = $('body').scrollTop() > 20 || $(':root').scrollTop() > 20;
$('#move-up').css({ $('#move-up').css({
@@ -40,7 +77,9 @@ window.onload = function () {
}); });
} }
/**
* @description Method to scroll to the top of the page.
*/
function topFunction() { function topFunction() {
$('body').animate({scrollTop: 0}); $('body').animate({scrollTop: 0});
$(':root').animate({scrollTop: 0}); $(':root').animate({scrollTop: 0});
@@ -55,7 +94,7 @@ window.onload = function () {
// UI for the overall demo: // UI for the overall demo:
var ui = defaultHtmlSequencerUi(sequencer); var ui = defaultHtmlSequencerUi(sequencer);
// find any `src` parameters in URL hash and attempt to source image from them and run the sequencer // Load image data from URL `src` parameter.
if (urlHash.getUrlHashParameter('src')) { if (urlHash.getUrlHashParameter('src')) {
sequencer.loadImage(urlHash.getUrlHashParameter('src'), ui.onLoad); sequencer.loadImage(urlHash.getUrlHashParameter('src'), ui.onLoad);
} else { } else {
@@ -65,25 +104,33 @@ window.onload = function () {
var resetSequence = function () { var resetSequence = function () {
var r = confirm('Do you want to reset the sequence?'); var r = confirm('Do you want to reset the sequence?');
if (r) if (r)
window.location = '/'; {
window.location.hash = '';
location.reload();
}
}; };
$('#addStep select').on('change', ui.selectNewStepUi); $('#addStep select').on('change', ui.selectNewStepUi);
$('#addStep #add-step-btn').on('click', ui.addStepUi); $('#addStep #add-step-btn').on('click', ui.addStepUi);
$('#resetButton').on('click', resetSequence); $('#resetButton').on('click', resetSequence);
//Module button radio selection // Module Selector quick buttons click handler.
$('.radio-group .radio').on('click', function () { $('.radio-group .radio').on('click', function () {
$(this).parent().find('.radio').removeClass('selected'); $(this).parent().find('.radio').removeClass('selected');
$(this).addClass('selected'); $(this).addClass('selected');
newStep = $(this).attr('data-value'); newStep = $(this).attr('data-value');
//$("#addStep option[value=" + newStep + "]").attr('selected', 'selected');
$('#addStep select').val(newStep); $('#addStep select').val(newStep);
ui.selectNewStepUi(newStep); ui.selectNewStepUi(newStep);
ui.addStepUi(newStep); ui.addStepUi(newStep);
$(this).removeClass('selected'); $(this).removeClass('selected');
}); });
/**
* @method displayMessageOnSaveSequence
* @description When a sequence is saved to a browser, notification is displayed.
* @returns {Null}
*/
function displayMessageOnSaveSequence() { function displayMessageOnSaveSequence() {
$('.savesequencemsg').fadeIn(); $('.savesequencemsg').fadeIn();
setTimeout(function () { setTimeout(function () {
@@ -103,7 +150,7 @@ window.onload = function () {
} }
} }
$('#saveButton').on('click', function () { $('#saveButton').on('click', function () {
// different handlers triggered for different dropdown options // Different handlers triggered for different dropdown options.
let dropDownValue = $('#selectSaveOption option:selected').val(); let dropDownValue = $('#selectSaveOption option:selected').val();
@@ -115,14 +162,18 @@ window.onload = function () {
} }
else if (dropDownValue == 'save-seq') { else if (dropDownValue == 'save-seq') {
saveSequence(); saveSequence();
} else if(dropDownValue == 'save-pdf') {
savePDF(getLastImage());
}
else if (dropDownValue == 'save-to-publiclab.org' ){
SaveToPubliclab();
} }
}); });
let isWorkingOnGifGeneration = false; let isWorkingOnGifGeneration = false;
$('.js-view-as-gif').on('click', function (event) { $('.js-view-as-gif').on('click', function (event) { // GIF generation and display
/* Prevent user from triggering generation multiple times*/ if (isWorkingOnGifGeneration) return; // Prevent multiple button clicks
if (isWorkingOnGifGeneration) return;
isWorkingOnGifGeneration = true; isWorkingOnGifGeneration = true;
@@ -131,12 +182,12 @@ window.onload = function () {
button.innerHTML = '<i class="fa fa-circle-o-notch fa-spin"></i>'; button.innerHTML = '<i class="fa fa-circle-o-notch fa-spin"></i>';
try { try {
/* Get gif resources of previous steps */ // Get GIF resources from previous steps
let options = getGifResources(); let options = getGifResources();
gifshot.createGIF(options, function (obj) { // gif generation gifshot.createGIF(options, function (obj) { // GIF generation
if (!obj.error) { if (!obj.error) {
// Final gif encoded with base64 format // Final GIF encoded with base64 format
var image = obj.image; var image = obj.image;
var animatedImage = document.createElement('img'); var animatedImage = document.createElement('img');
@@ -146,9 +197,7 @@ window.onload = function () {
let modal = $('#js-download-gif-modal'); let modal = $('#js-download-gif-modal');
$('#js-download-as-gif-button').one('click', function () { $('#js-download-as-gif-button').one('click', function () {
// Trigger download downloadGif(image); // Trigger GIF download
downloadGif(image);
// Close modal
modal.modal('hide'); modal.modal('hide');
}); });
@@ -160,7 +209,6 @@ window.onload = function () {
// Insert image // Insert image
gifContainer.appendChild(animatedImage); gifContainer.appendChild(animatedImage);
// Open modal // Open modal
modal.modal(); modal.modal();
@@ -179,16 +227,16 @@ window.onload = function () {
}); });
function getGifResources() { function getGifResources() {
/* Returns an object with specific gif options */ // Returns an object with specific gif options
let imgs = document.getElementsByClassName('step-thumbnail'); let imgs = document.getElementsByClassName('step-thumbnail');
var imgSrcs = []; var imgSrcs = [];
// Pushes image sources of all the modules in dom // Pushes image sources of all the modules in the DOM
for (var i = 0; i < imgs.length; i++) { for (var i = 0; i < imgs.length; i++) {
imgSrcs.push(imgs[i].src); imgSrcs.push(imgs[i].src);
} }
var options = { // gif frame options var options = { // GIF frame options
'gifWidth': imgs[0].width, 'gifWidth': imgs[0].width,
'gifHeight': imgs[0].height, 'gifHeight': imgs[0].height,
'images': imgSrcs, 'images': imgSrcs,
@@ -207,11 +255,64 @@ window.onload = function () {
}); });
} }
function downloadGif(image) { /**
download(image, 'index.gif', 'image/gif');// downloadjs library function * Get the data URL for the last image in the sequence.
* @return {string} The data URL for the last image in the sequence.
*/
function getLastImage() {
// Get the image from the last step.
let imgs = document.getElementsByClassName('step-thumbnail');
let lastStepImage = imgs[imgs.length - 1];
return lastStepImage.getAttribute('src');
} }
// image selection and drag/drop handling from examples/lib/imageSelection.js /**
* Download the given image URL as a PDF file.
* @param {string} imageDataURL - The data URL for the image.
*/
function savePDF(imageDataURL) {
sequencer.getImageDimensions(imageDataURL, function(dimensions) {
if (isGIF(imageDataURL)) {
// Get the dimensions of the image.
let pageWidth = dimensions.width;
let pageHeight = dimensions.height;
// Create a new pdf with the same dimensions as the image.
const pdf = new jsPDF({
orientation: pageHeight > pageWidth ? 'portrait' : 'landscape',
unit: 'px',
format: [pageHeight, pageWidth]
});
// Add the image to the pdf with dimensions equal to the internal dimensions of the page.
pdf.addImage(imageDataURL, 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight());
// Save the pdf with the filename specified here:
pdf.save('index.pdf');
}
else console.log('GIFs cannot be converted to PDF');
});
}
function downloadGif(image) {
download(image, 'index.gif', 'image/gif'); // Downloadjs library function
}
function SaveToPubliclab() {
function postToPL(imgSrc) {
var uniq = Date.now();
$('body').append('<form method="post" id="postToPL' + uniq + '" action="https://publiclab.org/post" target="postToPLWindow"><input type="hidden" name="datauri_main_image" /></form>');
f = $('#postToPL' + uniq)[0];
f.datauri_main_image.value = imgSrc;
window.open('', 'postToPLWindow');
f.submit();
}
postToPL($('img')[sequencer.steps.length - 1].src);
}
// Image selection and drag/drop handling from examples/lib/imageSelection.js
sequencer.setInputStep({ sequencer.setInputStep({
dropZoneSelector: '#dropzone', dropZoneSelector: '#dropzone',
fileInputSelector: '#fileInput', fileInputSelector: '#fileInput',
@@ -226,8 +327,9 @@ window.onload = function () {
step.options.step.imgElement.src = reader.result; step.options.step.imgElement.src = reader.result;
else else
step.imgElement.src = reader.result; step.imgElement.src = reader.result;
insertPreview.updatePreviews(reader.result, '#addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src, '.insertDiv'); insertPreview.updatePreviews(reader.result, document.querySelector('#addStep'));
DefaultHtmlStepUi(sequencer).updateDimensions(step);
}, },
onTakePhoto: function (url) { onTakePhoto: function (url) {
var step = sequencer.steps[0]; var step = sequencer.steps[0];
@@ -237,16 +339,16 @@ window.onload = function () {
step.options.step.imgElement.src = url; step.options.step.imgElement.src = url;
else else
step.imgElement.src = url; step.imgElement.src = url;
insertPreview.updatePreviews(url, '#addStep'); insertPreview.updatePreviews(url, document.querySelector('#addStep'));
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src, '.insertDiv'); DefaultHtmlStepUi(sequencer).updateDimensions(step);
} }
}); });
setupCache(); setupCache();
if (urlHash.getUrlHashParameter('src')) { if (urlHash.getUrlHashParameter('src')) { // Gets the sequence from the URL
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'), '#addStep'); insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'), document.querySelector('#addStep'));
} else { } else {
insertPreview.updatePreviews('images/tulips.png', '#addStep'); insertPreview.updatePreviews('images/tulips.png', document.querySelector('#addStep'));
} }
}; };

View File

@@ -33,9 +33,12 @@
<script src="../node_modules/gifshot/dist/gifshot.min.js" type="text/javascript"></script> <script src="../node_modules/gifshot/dist/gifshot.min.js" type="text/javascript"></script>
<!-- Download.js for large files --> <!-- Download.js for large files -->
<script src="../node_modules/downloadjs/download.min.js" type="text/javascript" /> <script src="../node_modules/downloadjs/download.min.js" type="text/javascript" ></script>
<script src="lib/scrollToTop.js"></script> <!-- jspdf to enable save image as pdf -->
<script src="../node_modules/jspdf/dist/jspdf.min.js" type="text/javascript" ></script>
<!-- <script src="lib/scrollToTop.js"></script> -->
<script src="../node_modules/selectize/dist/js/standalone/selectize.min.js"></script> <script src="../node_modules/selectize/dist/js/standalone/selectize.min.js"></script>
</head> </head>
@@ -53,6 +56,17 @@
<link href="./selectize.default.css" rel="stylesheet"> <link href="./selectize.default.css" rel="stylesheet">
<link rel="stylesheet" href="demo.css"> <link rel="stylesheet" href="demo.css">
<div id="update-prompt-modal">A new version of image sequencer is available. Click <a href="#" id="reload">here</a> to update.</div>
<div class="notify-box d-none">
<strong>Failed To Load Image</strong>
<button type="button" class="ml-2 mb-1 close" id="close-popup"><span>&times;</span></button>
<div class="notify-msg">
Can not Load Image Due to CORS Error Learn more about this
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors" target="_blank">here</a>
</div>
</div>
<div class="container-fluid"> <div class="container-fluid">
<header class="text-center"> <header class="text-center">
@@ -70,10 +84,11 @@
</a> </a>
by <a href="https://publiclab.org" title="Publiclab Website"><i class="fa fa-globe"></i> Publiclab</a> by <a href="https://publiclab.org" title="Publiclab Website"><i class="fa fa-globe"></i> Publiclab</a>
</p> </p>
<span id="version-number-top-right"></span>
</header> </header>
<div id="dropzone" class="dropzone"> <div id="dropzone" class="dropzone">
<p> <p id="dropzone-text">
<i>Select or drag in an image to start!</i> <i>Select or drag in an image to start!</i>
</p> </p>
<center> <center>
@@ -139,16 +154,16 @@
<p>Crop</p> <p>Crop</p>
</div> </div>
</div> </div>
<div class="row center-align"> <div class="row justify-content-center">
<div class="col-md-8"> <div class="col-lg-8">
<select id="selectStep"> <select id="selectStep" class="text-center">
<!-- The default null selection has been appended manually in demo.js <!-- The default null selection has been appended manually in demo.js
This is because the options in select are overritten when options are appended.--> This is because the options in select are overritten when options are appended.-->
</select> </select>
</div> </div>
<div class="col-md-4"> <div class="col-lg-4">
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button></div> <button class="btn btn-primary btn-lg" name="add" id="add-step-btn">Add Step</button></div>
</div> </div>
<div class="row center-align"> <div class="row center-align">
<button id="resetButton" class="btn btn-default btn-lg" <button id="resetButton" class="btn btn-default btn-lg"
@@ -187,11 +202,13 @@
<div class="panel-body"> <div class="panel-body">
<div style="text-align:center;"> <div style="text-align:center;">
<h2 style="margin-top:20px">Save</h2> <h2 style="margin-top:20px">Save</h2>
<select class="form-control input-md" id="selectSaveOption" style="margin-top:20px"> <select class="form-control input-md mouse" id="selectSaveOption" style="margin-top:20px">
<option value="save-image">Save as PNG</option> <option value="save-image">Save as PNG</option>
<option value="save-gif">Save as GIF (all steps)</option> <option value="save-gif">Save as GIF (all steps)</option>
<option value="save-pdf">Save as PDF</option>
<option value="save-seq">Save sequence</option> <option value="save-seq">Save sequence</option>
<option value="save-seq-string">Save sequence string</option> <option value="save-seq-string">Save sequence string</option>
<option value="save-to-publiclab.org">Save to PublicLab.org</option>>
</select> </select>
<p><button id="saveButton" class="btn btn-primary btn-lg save-button">Save</button></p> <p><button id="saveButton" class="btn btn-primary btn-lg save-button">Save</button></p>
<p><button class="btn btn-default btn-lg js-view-as-gif" id="gif">Preview GIF</button></p> <p><button class="btn btn-default btn-lg js-view-as-gif" id="gif">Preview GIF</button></p>
@@ -210,7 +227,7 @@
<h2>Need Help?</h2> <h2>Need Help?</h2>
<p> <p>
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer/issues">Ask a question</a> <a class="btn btn-default" href="https://github.com/publiclab/image-sequencer/issues">Ask a question</a>
<a class="btn btn-default" href="https://publiclab.org/chat">Ask in our chatroom</a> <a class="btn btn-default" href="https://gitter.im/publiclab/image-sequencer" target="_blank">Ask in our chatroom </a>
</p> </p>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
@@ -223,6 +240,9 @@
</p> </p>
</div> </div>
</div> </div>
<div class="row">
<p id="version-number-text">Loading Version Number</p>
</div>
</footer> </footer>
<button id="move-up"><i class="fa fa-arrow-circle-o-up"></i></button> <button id="move-up"><i class="fa fa-arrow-circle-o-up"></i></button>

View File

@@ -1,18 +1,71 @@
var setupCache = function() { var setupCache = function() {
let newWorker; // When sw.js is changed, this is the new service worker generated.
// Toggle a CSS class to display a popup prompting the user to fetch a new version.
function showUpdateModal() {
$('#update-prompt-modal').addClass('show');
}
/**
* When a new service worker has been loaded, the button in the update prompt
* modal should trigger the skipWaiting event to replace the current
* service worker with the new one.
*/
$('#reload').on('click', function() {
newWorker.postMessage({ action: 'skipWaiting' });
});
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
// Register the service worker.
navigator.serviceWorker.register('sw.js', { scope: '/examples/' }) navigator.serviceWorker.register('sw.js', { scope: '/examples/' })
.then(function(registration) { .then(function(registration) {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => { return new Promise(function(resolve,reject){
console.log(installingWorker);
if (installingWorker.state === 'installed') { registration.addEventListener('updatefound', () => {
location.reload(); // When sw.js has been changed, get a reference to the new service worker.
} newWorker = registration.installing;
};
console.log('Registration successful, scope is:', registration.scope); if(!newWorker){
}) return reject(new Error('error in installing service worker'));
.catch(function(error) { }
console.log('Service worker registration failed, error:', error);
newWorker.addEventListener('statechange', () => {
// Check if service worker state has changed.
switch(newWorker.state) {
case 'installed':
if(navigator.serviceWorker.controller) {
// New service worker available; prompt the user to update.
showUpdateModal();
$('#reload').on('click',(e) => {
e.preventDefault();
console.log('New Service Worker Installed Successfully');
location.reload();
return resolve();
})
}
// No updates available; do nothing.
break;
case 'redundant':
return reject(new Error('installing new service worker now became redundant'));
}
})
})
})
}).catch(err => {
console.log('Failed In Registering Service Worker: ',err);
});
/**
* This is the event listener for when the service worker updates.
* When the service worker updates, reload the page.
*/
let refreshing;
navigator.serviceWorker.addEventListener('controllerchange', function() {
if(refreshing) return;
window.location.reload();
refreshing = true;
}); });
} }
@@ -24,16 +77,22 @@ var setupCache = function() {
}); });
} }
$('#clear-cache').click(function() { const clearCache = () => {
if ('serviceWorker' in navigator) { if ('serviceWorker' in navigator) {
caches.keys().then(function(cacheNames) { return caches.keys()
cacheNames.forEach(function(cacheName) { .then(function(cache) {
caches.delete(cacheName); return Promise.all(cache.map(function(cacheItem) {
}); return caches.delete(cacheItem);
}));
}); });
} }
}
$('#clear-cache').click(function() {
clearCache();
location.reload(); location.reload();
}); });
}; };
module.exports = setupCache; module.exports = setupCache;

View File

@@ -1,4 +1,5 @@
var urlHash = require('./urlHash.js'); var urlHash = require('./urlHash.js');
insertPreview = require('./insertPreview.js');
function DefaultHtmlSequencerUi(_sequencer, options) { function DefaultHtmlSequencerUi(_sequencer, options) {
options = options || {}; options = options || {};
@@ -27,12 +28,17 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
function selectNewStepUi() { function selectNewStepUi() {
var m = $(addStepSel + ' select').val(); var m = $(addStepSel + ' select').val();
if(!m) m = arguments[0]; if(!m) m = arguments[0];
$(addStepSel + ' .info').html(_sequencer.modulesInfo(m).description); else $(addStepSel + ' .info').html(_sequencer.modulesInfo(m).description);
$(addStepSel + ' #add-step-btn').prop('disabled', false); $(addStepSel + ' #add-step-btn').prop('disabled', false);
} }
function removeStepUi() { function removeStepUi() {
var index = $(removeStepSel).index(this) + 1; var index = $(removeStepSel).index(this) + 1;
// If last step is removed.
if(sequencer.steps.length==index+1){
console.log("inside")
insertPreview.updatePreviews(sequencer.steps[index-1].output.src, document.querySelector('#addStep'));
}
sequencer.removeSteps(index).run({ index: index - 1 }); sequencer.removeSteps(index).run({ index: index - 1 });
// remove from URL hash too // remove from URL hash too
urlHash.setUrlHashParameter('steps', sequencer.toString()); urlHash.setUrlHashParameter('steps', sequencer.toString());
@@ -41,7 +47,12 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
} }
function addStepUi() { function addStepUi() {
if ($(addStepSel + ' select').val() == 'none') return;
if ($(addStepSel + ' select').val() == ''){
alert('Please Select a Step to Proceed');
return;
}
var newStepName; var newStepName;
if(typeof arguments[0] !== 'string') if(typeof arguments[0] !== 'string')
newStepName = $(addStepSel + ' select option').html().toLowerCase().split(' ').join('-'); newStepName = $(addStepSel + ' select option').html().toLowerCase().split(' ').join('-');

View File

@@ -11,29 +11,38 @@
const intermediateHtmlStepUi = require('./intermediateHtmlStepUi.js'), const intermediateHtmlStepUi = require('./intermediateHtmlStepUi.js'),
urlHash = require('./urlHash.js'), urlHash = require('./urlHash.js'),
_ = require('lodash'), _ = require('lodash'),
insertPreview = require('./insertPreview.js');
mapHtmlTypes = require('./mapHtmltypes'), mapHtmlTypes = require('./mapHtmltypes'),
scopeQuery = require('./scopeQuery'); scopeQuery = require('./scopeQuery'),
isGIF = require('../../src/util/isGif');
function DefaultHtmlStepUi(_sequencer, options) { function DefaultHtmlStepUi(_sequencer, options) {
let $step, $stepAll;
options = options || {}; options = options || {};
var stepsEl = options.stepsEl || document.querySelector('#steps'); var stepsEl = options.stepsEl || document.querySelector('#steps');
var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep'; var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep';
function onSetup(step, stepOptions) { function onSetup(step, stepOptions) {
if (step.options && step.options.description) if (step.options && step.options.description)
step.description = step.options.description; step.description = step.options.description;
let stepDocsLink = '';
if (step.moduleInfo) stepDocsLink = step.moduleInfo['docs-link'] || '';
step.ui = step.ui = // Basic UI markup for the step
'\ '\
<div class="container-fluid step-container">\ <div class="container-fluid step-container">\
<div class="panel panel-default">\ <div class="panel panel-default">\
<div class="panel-heading">\ <div class="panel-heading">\
<div class="trash-container pull-right"></div>\ <div class="trash-container pull-right">\
<a type="button" target="_blank" href="https://developer.mozilla.org/en-US/docs/WebAssembly" style="display: none;" class="btn btn-link general-tooltip wasm-tooltip" data-toggle="tooltip" data-html="true" data-original-title="<div style=\'text-align: center\'><p>This step is Web Assembly accelerated. Click to Read More</div>">\
<i class="fa fa-bolt"></i>\
</a>\
<button type="button" class="btn btn-link ' + step.name + ' general-tooltip dimension-tooltip" data-toggle="tooltip" data-html="true" data-original-title="">\
<i class="fa fa-info-circle"></i>\
</button>\
</div>\
<h3 class="panel-title">' + <h3 class="panel-title">' +
'<span class="toggle">' + step.name + ' <span class="caret toggleIcon rotated"></span>\ '<span class="toggle mouse">' + step.name + ' <span class="caret toggleIcon rotated"></span>\
<span class="load-spin pull-right" style="display:none;padding:1px 8px;"><i class="fa fa-circle-o-notch fa-spin"></i></span>\ <span class="load-spin pull-right" style="display:none;padding:1px 8px;"><i class="fa fa-circle-o-notch fa-spin"></i></span>\
</h3>\ </h3>\
</div>\ </div>\
@@ -42,7 +51,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
<div class="row step">\ <div class="row step">\
<div class="col-md-4 details container-fluid">\ <div class="col-md-4 details container-fluid">\
<div class="cal collapse in"><p>' + <div class="cal collapse in"><p>' +
'<i>' + (step.description || '') + '</i>' + '<a href="' + stepDocsLink + '">' + (step.description || '') + '</a>' +
'</p></div>\ '</p></div>\
</div>\ </div>\
<div class="col-md-8 cal collapse in step-column">\ <div class="col-md-8 cal collapse in step-column">\
@@ -59,7 +68,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
</div>'; </div>';
var tools = var tools =
'<div class="trash">\ '<div class="trash" style="display: inline-block">\
<button confirm="Are you sure?" class="remove btn btn-default btn-xs">\ <button confirm="Are you sure?" class="remove btn btn-default btn-xs">\
<i class="fa fa-trash"></i>\ <i class="fa fa-trash"></i>\
</button>\ </button>\
@@ -68,21 +77,20 @@ function DefaultHtmlStepUi(_sequencer, options) {
var util = intermediateHtmlStepUi(_sequencer, step); var util = intermediateHtmlStepUi(_sequencer, step);
var parser = new DOMParser(); var parser = new DOMParser();
step.ui = parser.parseFromString(step.ui, 'text/html'); step.ui = parser.parseFromString(step.ui, 'text/html'); // Convert the markup string to a DOM node.
step.ui = step.ui.querySelector('div.container-fluid'); step.ui = step.ui.querySelector('div.container-fluid');
$step = scopeQuery.scopeSelector(step.ui); step.$step = scopeQuery.scopeSelector(step.ui); // Shorthand methods for scoped DOM queries. Read the docs [CONTRIBUTING.md](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md) for more info.
$stepAll = scopeQuery.scopeSelectorAll(step.ui); step.$stepAll = scopeQuery.scopeSelectorAll(step.ui);
step.ui.$step = $step; let {$step, $stepAll} = step;
step.ui.$stepAll = $stepAll;
step.linkElements = step.ui.querySelectorAll('a'); step.linkElements = step.ui.querySelectorAll('a'); // All the anchor tags in the step UI
step.imgElement = $step('a img.img-thumbnail')[0]; step.imgElement = $step('a img.img-thumbnail')[0]; // The output image
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) { if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
var inputs = _sequencer.modulesInfo(step.name).inputs; var inputs = _sequencer.modulesInfo(step.name).inputs;
var outputs = _sequencer.modulesInfo(step.name).outputs; var outputs = _sequencer.modulesInfo(step.name).outputs;
var merged = Object.assign(inputs, outputs); // combine outputs w inputs var merged = Object.assign(inputs, outputs); // Combine outputs with inputs
for (var paramName in merged) { for (var paramName in merged) {
var isInput = inputs.hasOwnProperty(paramName); var isInput = inputs.hasOwnProperty(paramName);
@@ -102,10 +110,10 @@ function DefaultHtmlStepUi(_sequencer, options) {
else { else {
let paramVal = step.options[paramName] || inputDesc.default; let paramVal = step.options[paramName] || inputDesc.default;
if (inputDesc.id == 'color-picker') { // separate input field for color-picker if (inputDesc.id == 'color-picker') { // Separate input field for color-picker
html += html +=
'<div id="color-picker" class="input-group colorpicker-component">' + '<div id="color-picker" class="input-group colorpicker-component">' +
'<input class="form-control target" type="' + '<input class="form-control color-picker-target" type="' +
inputDesc.type + inputDesc.type +
'" name="' + '" name="' +
paramName + paramName +
@@ -113,7 +121,14 @@ function DefaultHtmlStepUi(_sequencer, options) {
paramVal + '">' + '<span class="input-group-addon"><i></i></span>' + paramVal + '">' + '<span class="input-group-addon"><i></i></span>' +
'</div>'; '</div>';
} }
else { // use this if the the field isn't color-picker else if(inputDesc.type === 'button'){
html = '<div><button name="' + paramName + '" type="' + inputDesc.type + '" >\
<i class="fa fa-crosshairs"></i></button>\
<span>click to select coordinates</span>\
</div>';
}
else { // Non color-picker input types and other than a button
html = html =
'<input class="form-control target" type="' + '<input class="form-control target" type="' +
inputDesc.type + inputDesc.type +
@@ -123,7 +138,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
paramVal + paramVal +
'" placeholder ="' + '" placeholder ="' +
(inputDesc.placeholder || ''); (inputDesc.placeholder || '');
if (inputDesc.type.toLowerCase() == 'range') { if (inputDesc.type.toLowerCase() == 'range') {
html += html +=
'"min="' + '"min="' +
@@ -131,7 +146,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
'"max="' + '"max="' +
inputDesc.max + inputDesc.max +
'"step="' + '"step="' +
(inputDesc.step ? inputDesc.step : 1) + '">' + '<span>' + paramVal + '</span>'; inputDesc.step + '">' + '<span>' + paramVal + '</span>';
} }
else html += '">'; else html += '">';
@@ -155,10 +170,10 @@ function DefaultHtmlStepUi(_sequencer, options) {
</div>'; </div>';
$step('div.details').append(div); $step('div.details').append(div);
} }
$step('div.panel-footer').append( $step('div.panel-footer').append( // Save button
'<div class="cal collapse in"><button type="submit" class="btn btn-sm btn-default btn-save" disabled = "true" >Apply</button> <small style="padding-top:2px;">Press apply to see changes</small></div>' '<div class="cal collapse in"><button type="submit" class="btn btn-sm btn-default btn-save" disabled = "true" >Apply</button> <small style="padding-top:2px;">Press apply to see changes</small></div>'
); );
$step('div.panel-footer').prepend( $step('div.panel-footer').prepend( // Markup for tools: download and insert step buttons
'<button class="pull-right btn btn-default btn-sm insert-step" >\ '<button class="pull-right btn btn-default btn-sm insert-step" >\
<span class="insert-text"><i class="fa fa-plus"></i> Insert Step</span><span class="no-insert-text" style="display:none">Close</span></button>\ <span class="insert-text"><i class="fa fa-plus"></i> Insert Step</span><span class="no-insert-text" style="display:none">Close</span></button>\
<button class="pull-right btn btn-default btn-sm download-btn" style="margin-right:2px" >\ <button class="pull-right btn btn-default btn-sm download-btn" style="margin-right:2px" >\
@@ -173,9 +188,10 @@ function DefaultHtmlStepUi(_sequencer, options) {
parser.parseFromString(tools, 'text/html').querySelector('div') parser.parseFromString(tools, 'text/html').querySelector('div')
); );
$stepAll('.remove').on('click', function() {notify('Step Removed', 'remove-notification');}); $stepAll('.remove').on('click', function() {notify('Step Removed', 'remove-notification');}); // Notification on removal of a step
$stepAll('.insert-step').on('click', function() { util.insertStep(step.ID); }); $step('.insert-step').on('click', function() { util.insertStep(step.ID); }); // Insert a step in between the sequence
// Insert the step's UI in the right place // Insert the step's UI in the right place
if (stepOptions.index == _sequencer.steps.length) { if (stepOptions.index == _sequencer.steps.length) {
stepsEl.appendChild(step.ui); stepsEl.appendChild(step.ui);
$('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true); $('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true);
@@ -185,16 +201,30 @@ function DefaultHtmlStepUi(_sequencer, options) {
else { else {
stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]); stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]);
} }
// Enable the load-image insert-step button when there are steps after load-image
// The logical operator is `> 0` because the number of steps is found before adding the step, actual logic is `steps.length + 1 > 1` which is later simplified.
if (_sequencer.steps.length > 0) $('#load-image .insert-step').prop('disabled', false);
else $('#load-image .insert-step').prop('disabled', true);
} }
else { else {
$('#load-image').append(step.ui); $('#load-image').append(step.ui); // Default UI without extra tools for the first step(load image)
$step('div.panel-footer').prepend( `
<button class="right btn btn-default btn-sm insert-step" disabled="true">
<span class="insert-text"><i class="fa fa-plus"></i> Insert Step</span>
<span class="no-insert-text" style="display:none">Close</span>
</button>`
);
$step('.insert-step').on('click', function() { util.insertStep(step.ID); });
} }
$step('.toggle').on('click', () => { $step('.toggle').on('click', () => { // Step container dropdown
$step('.toggleIcon').toggleClass('rotated'); $step('.toggleIcon').toggleClass('rotated');
$stepAll('.cal').collapse('toggle'); $stepAll('.cal').collapse('toggle');
}); });
$(step.imgElement).on('mousemove', _.debounce(() => imageHover(step), 150)); $(step.imgElement).on('mousemove', _.debounce(() => imageHover(step), 150)); // Shows the pixel coordinates on hover
$(step.imgElement).on('click', (e) => {e.preventDefault(); }); $(step.imgElement).on('click', (e) => {e.preventDefault(); });
$stepAll('#color-picker').colorpicker(); $stepAll('#color-picker').colorpicker();
@@ -211,15 +241,23 @@ function DefaultHtmlStepUi(_sequencer, options) {
}); });
_sequencer.run({ index: step.index - 1 }); _sequencer.run({ index: step.index - 1 });
// modify the url hash // Modify the URL hash
urlHash.setUrlHashParameter('steps', _sequencer.toString()); urlHash.setUrlHashParameter('steps', _sequencer.toString());
// disable the save button // Disable the save button
$step('.btn-save').prop('disabled', true); $step('.btn-save').prop('disabled', true);
optionsChanged = false; optionsChanged = false;
changedInputs = 0; changedInputs = 0;
} }
} }
/**
* @method handleInputValueChange
* @description Enables the save button on input change
* @param {*} currentValue The current value of the input
* @param {*} initValue The initial/old value of the input
* @param {Boolean} hasChangedBefore Whether the input was changed before
* @returns {Boolean} True if the value has changed
*/
function handleInputValueChange(currentValue, initValue, hasChangedBefore) { function handleInputValueChange(currentValue, initValue, hasChangedBefore) {
var inputChanged = !(isNaN(initValue) || isNaN(currentValue) ? currentValue === initValue : currentValue - initValue === 0); var inputChanged = !(isNaN(initValue) || isNaN(currentValue) ? currentValue === initValue : currentValue - initValue === 0);
changedInputs += hasChangedBefore ? inputChanged ? 0 : -1 : inputChanged ? 1 : 0; changedInputs += hasChangedBefore ? inputChanged ? 0 : -1 : inputChanged ? 1 : 0;
@@ -250,6 +288,21 @@ function DefaultHtmlStepUi(_sequencer, options) {
}); });
}); });
$stepAll('.color-picker-target').each(function(i, input) {
$(input)
.data('initValue', $(input).val())
.data('hasChangedBefore', false)
.on('input change', function() {
$(this)
.data('hasChangedBefore',
handleInputValueChange(
$(this).val(),
$(this).data('initValue'),
$(this).data('hasChangedBefore')
)
);
});
});
$('input[type="range"]').on('input', function() { $('input[type="range"]').on('input', function() {
@@ -258,17 +311,20 @@ function DefaultHtmlStepUi(_sequencer, options) {
} }
function onDraw() { function onDraw({$step, $stepAll}) {
$step('.load').show(); $step('.load').show();
$step('img').hide(); $step('img').hide();
$stepAll('.load-spin').show(); $stepAll('.load-spin').show();
} }
function onComplete(step) { function onComplete(step) {
let {$step, $stepAll} = step;
$step('img').show(); $step('img').show();
$stepAll('.load-spin').hide(); $stepAll('.load-spin').hide();
$step('.load').hide(); $step('.load').hide();
$stepAll('.download-btn').off('click');
step.imgElement.src = (step.name == 'load-image') ? step.output.src : step.output; step.imgElement.src = (step.name == 'load-image') ? step.output.src : step.output;
var imgthumbnail = $step('.img-thumbnail').getDomElem(); var imgthumbnail = $step('.img-thumbnail').getDomElem();
for (let index = 0; index < step.linkElements.length; index++) { for (let index = 0; index < step.linkElements.length; index++) {
@@ -276,28 +332,35 @@ function DefaultHtmlStepUi(_sequencer, options) {
step.linkElements[index].href = step.imgElement.src; step.linkElements[index].href = step.imgElement.src;
} }
// TODO: use a generalized version of this // TODO: use a generalized version of this.
function fileExtension(output) { function fileExtension(output) {
return output.split('/')[1].split(';')[0]; return output.split('/')[1].split(';')[0];
} }
$stepAll('.download-btn').on('click', () => { $stepAll('.download-btn').on('click', () => {
for (let index = 0; index < step.linkElements.length; index++){ function dataURLtoBlob(dataurl) {
let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
var element = document.createElement('a'); bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
element.setAttribute('href', step.linkElements[index].href); while(n--){
element.setAttribute('download', step.name + '.' + fileExtension(step.imgElement.src)); u8arr[n] = bstr.charCodeAt(n);
element.style.display = 'none'; }
document.body.appendChild(element); return new Blob([u8arr], {type:mime});
element.click();
document.body.removeChild(element);
} }
var element = document.createElement('a');
element.setAttribute('download', step.name + '.' + fileExtension(step.imgElement.src));
element.style.display = 'none';
document.body.appendChild(element);
var blob = dataURLtoBlob(step.output);
var objurl = URL.createObjectURL(blob);
element.setAttribute('href', objurl);
element.click();
}); });
// fill inputs with stored step options // Fill inputs with stored step options
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) { if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
var inputs = _sequencer.modulesInfo(step.name).inputs; var inputs = _sequencer.modulesInfo(step.name).inputs;
var outputs = _sequencer.modulesInfo(step.name).outputs; var outputs = _sequencer.modulesInfo(step.name).outputs;
@@ -309,7 +372,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
.data('initValue', step.options[i]); .data('initValue', step.options[i]);
if (inputs[i].type.toLowerCase() === 'select') if (inputs[i].type.toLowerCase() === 'select')
$step('div[name="' + i + '"] select') $step('div[name="' + i + '"] select')
.val(step.options[i]) .val(String(step.options[i]))
.data('initValue', step.options[i]); .data('initValue', step.options[i]);
} }
} }
@@ -319,12 +382,58 @@ function DefaultHtmlStepUi(_sequencer, options) {
.val(step[i]); .val(step[i]);
} }
} }
$(function () {
$('[data-toggle="tooltip"]').tooltip();
updateDimensions(step);
});
if (step.name === 'load-image') insertPreview.updatePreviews(step.output.src, document.querySelector('#addStep'));
else insertPreview.updatePreviews(step.output, document.querySelector('#addStep'));
// Handle the wasm bolt display
if (step.useWasm) {
if (step.wasmSuccess) $step('.wasm-tooltip').fadeIn();
else $step('.wasm-tooltip').fadeOut();
}
else $step('.wasm-tooltip').fadeOut();
}
/**
* @description Updates Dimension of the image
* @param {Object} step - Current Step
* @returns {void}
*
*/
function updateDimensions(step){
_sequencer.getImageDimensions(step.imgElement.src, function (dim) {
step.ui.querySelector('.' + step.name).attributes['data-original-title'].value = `<div style="text-align: center"><p>Image Width: ${dim.width}<br>Image Height: ${dim.height}</br>${isGIF(step.output) ? `Frames: ${dim.frames}` : ''}</div>`;
});
} }
/**
* @method imageHover
* @description Handler to display image coordinates on hover.
* @param {Object} step Current step variable
* @returns {Null}
*/
function imageHover(step){ function imageHover(step){
var img = $(step.imgElement); var img = $(step.imgElement);
let customXCoord = '20'; //default x coordinate
let customYCoord = '20'; //default y coordinate
const customButton = $('button[name="Custom-Coordinates"]');
img.click(function(e) {
customXCoord = e.offsetX;
customYCoord = e.offsetY;
customButton.click(function() {
$('input[name="x"]').val(customXCoord);
$('input[name="y"]').val(customYCoord);
})
});
img.mousemove(function(e) { img.mousemove(function(e) {
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
canvas.width = img.width(); canvas.width = img.width();
@@ -343,27 +452,42 @@ function DefaultHtmlStepUi(_sequencer, options) {
function onRemove(step) { function onRemove(step) {
step.ui.remove(); step.ui.remove();
$('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true); $('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true);
$('div[class*=imgareaselect-]').remove();
// Enable the load-image insert-step button when there are steps after load-image
// The logical operator is `> 2` because the number of steps is found before removing the step, actual logic is `steps.length - 1 > 1` which is later simplified.
if (_sequencer.steps.length - 1 > 1) $('#load-image .insert-step').prop('disabled', false);
else $('#load-image .insert-step').prop('disabled', true);
$(step.imgElement).imgAreaSelect({
remove: true
});
} }
function getPreview() { function getPreview() {
return step.imgElement; return step.imgElement;
} }
/**
* @method notify
* @description General purpose DOM toast notification
* @param {String} msg Message to be displayed
* @param {String} id A unique identifier for the notification
* @returns {Null}
*/
function notify(msg, id){ function notify(msg, id){
if ($('#' + id).length == 0) { if ($('#' + id).length == 0) {
var notification = document.createElement('span'); var notification = document.createElement('span');
notification.innerHTML = ' <i class="fa fa-info-circle" aria-hidden="true"></i> ' + msg ; notification.innerHTML = ' <i class="fa fa-info-circle" aria-hidden="true"></i> ' + msg ;
notification.id = id; notification.id = id;
notification.classList.add('notification'); notification.classList.add('notification');
$('body').append(notification); $('body').append(notification);
} }
$('#' + id).fadeIn(500).delay(200).fadeOut(500); $('#' + id).fadeIn(500).delay(200).fadeOut(500);
} }
return { return {
getPreview: getPreview, getPreview: getPreview,
onSetup: onSetup, onSetup: onSetup,
@@ -371,7 +495,8 @@ function DefaultHtmlStepUi(_sequencer, options) {
onRemove: onRemove, onRemove: onRemove,
onDraw: onDraw, onDraw: onDraw,
notify: notify, notify: notify,
imageHover: imageHover imageHover: imageHover,
updateDimensions: updateDimensions
}; };
} }

View File

@@ -1,5 +1,5 @@
function generatePreview(previewStepName, customValues, path, selector) { // Generate downscaled preview images for quick buttons.
function generatePreview(previewStepName, customValues, path, DomNode) {
var previewSequencer = ImageSequencer(); var previewSequencer = ImageSequencer();
function insertPreview(src) { function insertPreview(src) {
var img = document.createElement('img'); var img = document.createElement('img');
@@ -8,9 +8,10 @@ function generatePreview(previewStepName, customValues, path, selector) {
img.src = src; img.src = src;
$(img).css('max-width', '200%'); $(img).css('max-width', '200%');
$(img).css('transform', 'translateX(-20%)'); $(img).css('transform', 'translateX(-20%)');
$(selector + ' .radio-group').find('div').each(function() { $(DomNode.querySelector('.radio-group')).find('.radio').each(function() {
if ($(this).find('div').attr('data-value') === previewStepName) { if ($(this).attr('data-value') === previewStepName) {
$(this).find('div').append(img); $(this).find('img').remove();
$(this).append(img);
} }
}); });
} }
@@ -29,8 +30,8 @@ function generatePreview(previewStepName, customValues, path, selector) {
previewSequencer.loadImage(path, loadPreview); previewSequencer.loadImage(path, loadPreview);
} }
function updatePreviews(src, selector) { function updatePreviews(src, DomNode) {
$(selector + ' img').remove(); $(DomNode).find('img').remove();
var previewSequencerSteps = { var previewSequencerSteps = {
'resize': '125%', 'resize': '125%',
@@ -41,19 +42,20 @@ function updatePreviews(src, selector) {
'crop': { 'crop': {
'x': 0, 'x': 0,
'y': 0, 'y': 0,
'w': '(50%)', 'w': '50%',
'h': '(50%)', 'h': '50%',
'noUI': true 'noUI': true
} }
}; };
var img = new Image(); var img = new Image();
img.onload = function(){ img.onload = function(){
var height = img.height; var height = img.height;
var width = img.width; var width = img.width;
let percentage = (80 / height) * 100; //take the min resize value that fits the preview area => (new-width/orig_ht) - '80 as the preview area has 80*80 dimension let percentage = (80 / height) * 100; // Take the min resize value that fits the preview area => (new-width/orig_ht) - '80 as the preview area has 80*80 dimension.
percentage = Math.max((80 / width) * 100, percentage); // make sure that one dimension doesn't resize greater, leading distorting preview-area fitting percentage = Math.max((80 / width) * 100, percentage); // Make sure that one dimension doesn't resize greater, leading distorting preview-area fitting.
percentage = Math.ceil(percentage); percentage = Math.ceil(percentage);
var sequencer = ImageSequencer(); var sequencer = ImageSequencer();
@@ -62,7 +64,7 @@ function updatePreviews(src, selector) {
this.addSteps('resize', {['resize']: percentage + '%'}); this.addSteps('resize', {['resize']: percentage + '%'});
this.run((src)=>{ this.run((src)=>{
Object.keys(previewSequencerSteps).forEach(function (step, index) { Object.keys(previewSequencerSteps).forEach(function (step, index) {
generatePreview(step, Object.values(previewSequencerSteps)[index], src, selector); generatePreview(step, Object.values(previewSequencerSteps)[index], src, DomNode);
}); });
}); });
}); });
@@ -74,4 +76,4 @@ function updatePreviews(src, selector) {
module.exports = { module.exports = {
generatePreview : generatePreview, generatePreview : generatePreview,
updatePreviews : updatePreviews updatePreviews : updatePreviews
}; };

View File

@@ -1,8 +1,17 @@
var urlHash = require('./urlHash.js'), var urlHash = require('./urlHash.js'),
insertPreview = require('./insertPreview.js'); insertPreview = require('./insertPreview.js');
/**
* @method IntermediateHtmlStepUi
* @description Inserts a module selector in between the current sequence
* @param {Object} _sequencer Sequencer instance
* @param {Object} step Current step variable
* @param {Object} options Optional options Object
* @returns {Object} Object containing the insertStep function
*/
function IntermediateHtmlStepUi(_sequencer, step, options) { function IntermediateHtmlStepUi(_sequencer, step, options) {
function stepUI() { function stepUI() {
// Basic markup for the selector
return '<div class="row insertDiv collapse">\ return '<div class="row insertDiv collapse">\
<section class="panel panel-primary .insert-step">\ <section class="panel panel-primary .insert-step">\
<button class="btn btn-default close-insert-box"><i class="fa fa-times" aria-hidden="true"></i> Close</button>\ <button class="btn btn-default close-insert-box"><i class="fa fa-times" aria-hidden="true"></i> Close</button>\
@@ -55,7 +64,7 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
</select>\ </select>\
<div>\ <div>\
<div class="col-md-4">\ <div class="col-md-4">\
<button class="btn btn-success btn-lg insert-save-btn add-step-btn" name="add">Add Step</button>\ <button class="btn btn-primary btn-lg insert-save-btn add-step-btn" name="add">Add Step</button>\
<div>\ <div>\
</div>\ </div>\
</div>\ </div>\
@@ -64,15 +73,13 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
</div>'; </div>';
} }
/**
function selectNewStepUi($step) { * @method toggleDiv
var insertSelect = $step('.insert-step-select'); * @description Toggles the module selector dropdown.
var m = insertSelect.val(); * @param {Object} $step $step util function
$step('.insertDiv .info').html(_sequencer.modulesInfo(m).description); * @param {Fucntion} callback Optional callback function
$step('.insertDiv .add-step-btn').prop('disabled', false); * @returns {Null}
} */
var toggleDiv = function($step, callback = function(){}){ var toggleDiv = function($step, callback = function(){}){
$step('.insertDiv').collapse('toggle'); $step('.insertDiv').collapse('toggle');
if ($step('.insert-text').css('display') != 'none'){ if ($step('.insert-text').css('display') != 'none'){
@@ -83,13 +90,19 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
} }
}; };
/**
* @method insertStep
* @description Handler to insert selected module in the sequence
* @returns {Null}
*/
insertStep = function (id) { insertStep = function (id) {
const $step = step.ui.$step, const $step = step.$step,
$stepAll = step.ui.$stepAll; $stepAll = step.$stepAll;
var modulesInfo = _sequencer.modulesInfo(); var modulesInfo = _sequencer.modulesInfo();
var parser = new DOMParser(); var parser = new DOMParser();
var addStepUI = stepUI(); var addStepUI = stepUI();
addStepUI = parser.parseFromString(addStepUI, 'text/html').querySelector('div'); addStepUI = parser.parseFromString(addStepUI, 'text/html').querySelector('div');
if ($step('.insertDiv').length > 0){ if ($step('.insertDiv').length > 0){
toggleDiv($step); toggleDiv($step);
} }
@@ -100,60 +113,56 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
addStepUI addStepUI
); );
toggleDiv($step, function(){ toggleDiv($step, function(){
insertPreview.updatePreviews(step.output, '.insertDiv'); if (step.name === 'load-image') insertPreview.updatePreviews(step.output.src, $step('.insertDiv').getDomElem());
else insertPreview.updatePreviews(step.output, $step('.insertDiv').getDomElem());
}); });
} }
$step('.insertDiv .close-insert-box').off('click').on('click', function(){toggleDiv(function(){});});
$step('.insertDiv .close-insert-box').off('click').on('click', function(){
toggleDiv($step);
$step('.insertDiv').removeClass('insertDiv');
});
var insertStepSelect = $step('.insert-step-select'); var insertStepSelect = $step('.insert-step-select');
insertStepSelect.html(''); insertStepSelect.html('');
// Add modules to the insertStep dropdown // Add modules to the insertStep dropdown
for (var m in modulesInfo) { for (var m in modulesInfo) {
if (modulesInfo[m] !== undefined) if (modulesInfo[m] && modulesInfo[m].name)
insertStepSelect.append( insertStepSelect.append(
'<option value="' + m + '">' + modulesInfo[m].name + '</option>' '<option value="' + m + '">' + modulesInfo[m].name + '</option>'
); );
} }
insertStepSelect.selectize({ insertStepSelect.selectize({
sortField: 'text' sortField: 'text'
}); });
$step('.inserDiv .add-step-btn').prop('disabled', true);
$('.insertDiv .radio-group .radio').on('click', function () {
insertStepSelect.append('<option value="" disabled selected>Select a Module</option>'); var newStepName = $(this).attr('data-value'); // Get the name of the module to be inserted
$step('.insertDiv .radio-group .radio').on('click', function () { id = $($step('.insertDiv').parents()[3]).prevAll().length;
$(this).parent().find('.radio').removeClass('selected'); insert(id, $step, newStepName); // Insert the selected module
$(this).addClass('selected');
newStep = $(this).attr('data-value');
$step('.insert-step-select').val(newStep);
selectNewStepUi($step);
insert(id, $step);
$(this).removeClass('selected');
}); });
insertStepSelect.on('change', () => {selectNewStepUi($step);});
$step('.insertDiv .add-step-btn').on('click', function () { insert(id, $step); }); $step('.insertDiv .add-step-btn').on('click', function () {
var newStepName = insertStepSelect.val();
id = $($step('.insertDiv').parents()[3]).prevAll().length;
insert(id, $step, newStepName); });
}; };
function insert(id, $step) { /**
* @method insert
options = options || {}; * @description Inserts the specified step at the specified index in the sequence
var insertStepSelect = $step('.insert-step-select'); * @param {Number} id Index of the step
if (insertStepSelect.val() == 'none') return; * @param {Function} $step $step util function
* @param {String} newStepName Name of the new step
var newStepName = insertStepSelect.val(); */
function insert(id, $step, newStepName) {
toggleDiv($step); toggleDiv($step);
var sequenceLength = 1; $step('.insertDiv').removeClass('insertDiv');
if (sequencer.sequences[newStepName]) { _sequencer.insertSteps(id + 1, newStepName).run({ index: id });
sequenceLength = sequencer.sequences[newStepName].length;
} else if (sequencer.modules[newStepName][1]['length']) {
sequenceLength = sequencer.modules[newStepName][1]['length'];
}
_sequencer
.insertSteps(id + 1, newStepName).run({ index: id });
// add to URL hash too
urlHash.setUrlHashParameter('steps', _sequencer.toString()); urlHash.setUrlHashParameter('steps', _sequencer.toString());
} }
return { return {
@@ -161,4 +170,3 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
}; };
} }
module.exports = IntermediateHtmlStepUi; module.exports = IntermediateHtmlStepUi;

View File

@@ -1,8 +1,13 @@
/**
* @description Maps module input types to their respective html <input> tag types.
* @param {Object} inputInfo Object containing the type and optionally min/max for range type inputs.
*/
function mapHtmlTypes(inputInfo){ function mapHtmlTypes(inputInfo){
var htmlType; var htmlType;
switch(inputInfo.type.toLowerCase()){ switch(inputInfo.type.toLowerCase()){
case 'integer': case 'integer':
htmlType = inputInfo.min != undefined ? 'range' : 'number'; htmlType = inputInfo.min != undefined ? 'range' : 'number';
if (htmlType === 'range') inputInfo.step = inputInfo.step || 1; // default range step size for integer
break; break;
case 'string': case 'string':
htmlType = 'text'; htmlType = 'text';
@@ -15,14 +20,18 @@ function mapHtmlTypes(inputInfo){
break; break;
case 'float': case 'float':
htmlType = inputInfo.min != undefined ? 'range' : 'text'; htmlType = inputInfo.min != undefined ? 'range' : 'text';
if (htmlType === 'range') inputInfo.step = inputInfo.step || 0.1; // default range step size for float
break;
case 'coordinate-input':
htmlType = 'button';
break; break;
default: default:
htmlType = 'text'; htmlType = 'text';
break; break;
} }
var response = inputInfo; var response = Object.assign({}, inputInfo);
response.type = htmlType; response.type = htmlType;
return response; return response;
} }
module.exports = mapHtmlTypes; module.exports = mapHtmlTypes;

View File

@@ -1,6 +1,7 @@
/** /**
* @method $scope * @method $scope
* @param {"DOMNode"} scope A DOM Node as the scope * @param {"DOMNode"} scope A DOM Node as the scope
* @returns {Function} Constructor for the scopeSelector Object.
*/ */
function $scope(scope) { function $scope(scope) {
return function(queryString){ return function(queryString){
@@ -24,6 +25,7 @@ function $scope(scope) {
/** /**
* @method $scopeAll * @method $scopeAll
* @param {"DOMNode"} scope A DOM Node as the scope * @param {"DOMNode"} scope A DOM Node as the scope
* @returns {Function} Constructor for the scopeSelectorAll Object.
*/ */
function $scopeAll(scope){ function $scopeAll(scope){
return function(queryString){ return function(queryString){
@@ -47,7 +49,8 @@ function $scopeAll(scope){
/** /**
* @method scopeSelector * @method scopeSelector
* @description A scoped jQuery selector * @description A scoped jQuery selector
* @param {"DOMNode"} scope DOM Node as the scope * @param {"DOMNode"} scope A DOM Node as the scope
* @returns {Function}
*/ */
function scopeSelector(scope){ function scopeSelector(scope){
return $scope(scope); return $scope(scope);
@@ -56,7 +59,8 @@ function scopeSelector(scope){
/** /**
* @method scopeSelectorAll * @method scopeSelectorAll
* @description A scoped jQuery multiple selector * @description A scoped jQuery multiple selector
* @param {"DOMNode} scope DOM Node as the scope * @param {"DOMNode} scope A DOM Node as the scope
* @returns {Function}
*/ */
function scopeSelectorAll(scope){ function scopeSelectorAll(scope){
return $scopeAll(scope); return $scopeAll(scope);

View File

@@ -0,0 +1,43 @@
/**
* Functions for getting version information.
* Note: these functions are not used by the service worker to check for updates;
* the service worker updates whenever sw.js has changed.
* sw.js is changed when grunt replace:version is run. This task is run during
* grunt build, serve, and productions tasks.
*/
const package = require('../../package.json');
/**
* Get the current version number from package.json on the homepage.
* @param {function} callback The function that uses the version number.
*/
function getLatestVersionNumber(callback) {
// Get the homepage reference from the local package.json.
var homepage = package.homepage;
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
var response = JSON.parse(this.responseText);
var latestVersionNumber = response.version;
// Do something with the version number using a callback function.
if (callback)
callback(latestVersionNumber);
}
}
// Get the package.json file from online using a GET request.
request.open("GET", homepage + "/package.json", true);
request.send();
}
// Get the version number from the local package.json file.
function getLocalVersionNumber() {
return package.version;
}
module.exports = {
getLatestVersionNumber,
getLocalVersionNumber
}

34
examples/offline.html Normal file
View File

@@ -0,0 +1,34 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Error 502 | Bad Gateway</title>
<style>
body{
background-color:#d3d3d3;
}
p {
font-size:20px;
}
main {
display: flex;
flex-direction:column;
text-align: center;
justify-content: center;
}
a {
text-decoration: none;
color:blue;
}
</style>
</head>
<body>
<main>
<p>Error 502: something went wrong.</p>
<p>It seems that you are not connected to internet.<br>Please try after some time.</p>
<a href="/">Go To Home Page</a>
</main>
</body>
</html>

View File

@@ -1,7 +1,14 @@
const staticCacheName = 'image-sequencer-static-v3'; const staticCacheName = 'image-sequencer-static-v3.6.0';
self.addEventListener('install', function(e) {
self.addEventListener('install', event => { e.waitUntil(
console.log('Attempting to install service worker'); caches.open(staticCacheName).then(function(cache) {
console.log('Attempting to install service worker');
return cache.addAll([
'/',
'/examples/offline.html'
]);
})
);
}); });
self.addEventListener('activate', function(e) { self.addEventListener('activate', function(e) {
@@ -22,14 +29,33 @@ self.addEventListener('activate', function(e) {
self.addEventListener('fetch', function(event) { self.addEventListener('fetch', function(event) {
event.respondWith( event.respondWith(
caches.open(staticCacheName).then(function(cache) { // Try to fetch the latest data first.
return cache.match(event.request).then(function (response) { fetch(event.request)
return response || fetch(event.request).then(function(response) { .then(function(response) {
if(event.request.method == 'GET') return caches.open(staticCacheName)
cache.put(event.request, response.clone()); .then(function(cache) {
return response; if(event.request.method == 'GET'){
cache.put(event.request.url, response.clone());
}
return response;
})
})
.catch(function(err) {
// Now the request has been failed so show cached data.
return caches.match(event.request).then(function(res){
if (res === undefined) {
// Display offline page
return caches.match('offline.html');
}
return res;
}); });
});
}) })
); )
});
// When the update modal sends a 'skipWaiting' message, call the skipWaiting method.
self.addEventListener('message', function(event) {
if(event.data.action === 'skipWaiting') {
self.skipWaiting();
}
}); });

View File

@@ -1,89 +1,5 @@
#!/usr/bin/env node #!/usr/bin/env node
require('./src/ImageSequencer'); var cli = require('./src/cli');
sequencer = ImageSequencer({ ui: true });
var fs = require('fs');
var program = require('commander');
var utils = require('./src/CliUtils');
var saveSequence = require('./src/cli/saveSequence.js'); cli(process.argv);
var installModule = require('./src/cli/installModule.js');
var sequencerSteps = require('./src/cli/sequencerSteps.js');
function exit(message) {
console.error(message);
process.exit(1);
}
program
.version('0.1.0')
.option('-i, --image [PATH/URL]', 'Input image URL')
.option('-s, --step [step-name]', 'Name of the step to be added.')
.option('-o, --output [PATH]', 'Directory where output will be stored.')
.option('-b, --basic', 'Basic mode outputs only final image')
.option('-c, --config [Object]', 'Options for the step')
.option('--save-sequence [string]', 'Name space separated with Stringified sequence')
.option('--install-module [string]', 'Module name space seaprated npm package name')
.parse(process.argv);
if (program.saveSequence) saveSequence(program, sequencer);
else if (program.installModule) installModule(program, sequencer);
else {
// Parse step into an array to allow for multiple steps.
if (!program.step) exit('No steps passed');
program.step = program.step.split(' ');
// User must input an image.
if (!program.image) exit('Can\'t read file.');
// User must input an image.
fs.access(program.image, function(err) {
if (err) exit('Can\'t read file.');
});
// User must input a step. If steps exist, check that every step is a valid step.
if (!program.step || !(utils.validateSteps(program.step, sequencer)))
exit('Please ensure all steps are valid.');
// If there's no user defined output directory, select a default directory.
program.output = program.output || './output/';
// Set sequencer to log module outputs, if any.
sequencer.setUI({
onComplete: function(step) {
// Get information of outputs.
step.info = sequencer.modulesInfo(step.name);
for (var output in step.info.outputs) {
console.log('[' + program.step + ']: ' + output + ' = ' + step[output]);
}
},
notify: function(msg) {
console.log('\x1b[36m%s\x1b[0m', '🌟 ' + msg);
}
});
// Finally, if everything is alright, load the image, add the steps and run the sequencer.
sequencer.loadImages(program.image, function() {
console.warn(
'\x1b[33m%s\x1b[0m',
'Please wait \n output directory generated will be empty until the execution is complete'
);
//Generate the Output Directory
var outputFilename = program.output.split('/').slice(-1)[0];
if (outputFilename.includes('.')) {
// user did give an output filename we have to remove it from dir
program.output = program.output.split('/').slice(0, -1).join('/');
}
else {
outputFilename = null;
}
sequencerSteps(program, sequencer, outputFilename);
});
}

12
jest-puppeteer.config.js Normal file
View File

@@ -0,0 +1,12 @@
module.exports = {
launch: {
args: ['--no-sandbox', '--disable-setuid-sandbox'], // https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
headless: process.env.HEADLESS !== 'false',
},
server: {
command: 'grunt serve',
port:3000,
launchTimeout: 5000000,
},
};

6
jest.config.js Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
preset: 'jest-puppeteer',
testRegex: './*\\.test\\.js$',
verbose: true,
};

10678
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,19 @@
{ {
"name": "image-sequencer", "name": "image-sequencer",
"version": "3.5.1", "version": "3.6.0",
"description": "A modular JavaScript image manipulation library modeled on a storyboard.", "description": "A modular JavaScript image manipulation library modeled on a storyboard.",
"main": "src/ImageSequencer.js", "main": "src/ImageSequencer.js",
"scripts": { "scripts": {
"debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert", "debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert",
"test": "TEST=true istanbul cover tape test/core/*.js test/core/ui/user-interface.js test/core/modules/*.js | tap-spec; node test/core/sequencer/benchmark.js; browserify test/core/sequencer/meta-modules.js test/core/sequencer/image-sequencer.js test/core/sequencer/chain.js test/core/sequencer/replace.js test/core/sequencer/import-export.js test/core/sequencer/run.js test/core/sequencer/dynamic-imports.js test/core/util/*.js | tape-run --render=\"tap-spec\"", "test": "TEST=true istanbul cover tape test/core/*.js test/core/ui/user-interface.js test/core/modules/*.js | tap-spec;",
"benchmark": "node test/core/sequencer/benchmark.js | tap-spec;",
"gif-test": "node test/core/gifs/gif-test.js | tap-spec;",
"core-tests": "cat ./output/core-tests.js | tape-run --render=\"tap-spec\"",
"test-all": "npm run test && npm run benchmark && npm run gif-test && grunt tests && npm run core-tests",
"test-ui": "node node_modules/jasmine/bin/jasmine test/ui/spec/*.js", "test-ui": "node node_modules/jasmine/bin/jasmine test/ui/spec/*.js",
"setup": "npm i && npm i -g grunt grunt-cli && grunt build", "test-ui-2": "node ./node_modules/.bin/jest",
"test-cli": "node test/cli/*.js | tap-spec",
"setup": "npm i && npm i -g grunt grunt-cli && npm rebuild --build-from-source && grunt build",
"start": "grunt serve" "start": "grunt serve"
}, },
"lint-staged": { "lint-staged": {
@@ -32,38 +38,41 @@
"dependencies": { "dependencies": {
"atob": "^2.1.2", "atob": "^2.1.2",
"base64-img": "^1.0.4", "base64-img": "^1.0.4",
"bootstrap": "~3.4.0", "bootstrap": "^3.4.1",
"bootstrap-colorpicker": "^2.5.3", "bootstrap-colorpicker": "^2.5.3",
"buffer": "~5.4.0", "buffer": "~6.0.2",
"commander": "^2.11.0", "commander": "^7.0.0",
"compressorjs": "^1.0.5", "compressorjs": "^1.0.5",
"data-uri-to-buffer": "^2.0.0", "data-uri-to-buffer": "^3.0.0",
"downloadjs": "^1.4.7", "downloadjs": "^1.4.7",
"eslint": "^6.1.0", "eslint": "^6.1.0",
"expr-eval": "^2.0.2",
"fisheyegl": "^0.1.2", "fisheyegl": "^0.1.2",
"font-awesome": "~4.7.0", "font-awesome": "~4.7.0",
"geotiff": "^1.0.0-beta.6", "geotiff": "^1.0.0-beta.6",
"get-pixels": "~3.3.0", "get-pixels": "~3.3.0",
"gifshot": "^0.4.5", "gifshot": "^0.4.5",
"glfx": "0.0.4", "glfx": "0.0.4",
"gpu.js": "^2.0.0-rc.12", "gpu.js": "^2.3.1",
"image-sequencer-invert": "^1.0.0", "image-sequencer-invert": "^1.0.0",
"imagejs": "0.0.9", "imagejs": "0.0.9",
"imagemin": "^7.0.0", "imagemin": "^7.0.1",
"imagemin-jpegtran": "^6.0.0", "imagemin-jpegtran": "^7.0.0",
"imagemin-pngquant": "^8.0.0", "imagemin-pngquant": "^9.0.1",
"imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2", "imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2",
"istanbul": "^0.4.5", "istanbul": "^0.4.5",
"jasmine": "^3.4.0", "jasmine": "^3.4.0",
"jpegtran-bin": "^5.0.2",
"jquery": "^3.3.1", "jquery": "^3.3.1",
"jsdom": "^15.0.0", "jsdom": "^16.3.0",
"jspdf": "^2.1.1",
"jsqr": "^1.1.1", "jsqr": "^1.1.1",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"matcher-core": "git@github.com:publiclab/matcher-core.git#matcher-node",
"ndarray": "^1.0.18", "ndarray": "^1.0.18",
"opencv.js": "^1.2.1", "opencv.js": "^1.2.1",
"ora": "^3.0.0", "ora": "^5.1.0",
"pace": "0.0.4", "pace": "0.0.4",
"pngquant-bin": "^6.0.0",
"puppeteer": "^1.14.0", "puppeteer": "^1.14.0",
"qrcode": "^1.3.3", "qrcode": "^1.3.3",
"readline-sync": "^1.4.7", "readline-sync": "^1.4.7",
@@ -78,7 +87,7 @@
"@babel/plugin-proposal-object-rest-spread": "^7.4.3", "@babel/plugin-proposal-object-rest-spread": "^7.4.3",
"@babel/plugin-syntax-object-rest-spread": "^7.2.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
"babelify": "^10.0.0", "babelify": "^10.0.0",
"browserify": "16.2.3", "browserify": "17.0.0",
"eslint": "^6.1.0", "eslint": "^6.1.0",
"grunt": "^1.0.3", "grunt": "^1.0.3",
"grunt-browser-sync": "^2.2.0", "grunt-browser-sync": "^2.2.0",
@@ -86,18 +95,22 @@
"grunt-contrib-concat": "^1.0.1", "grunt-contrib-concat": "^1.0.1",
"grunt-contrib-uglify-es": "^3.3.0", "grunt-contrib-uglify-es": "^3.3.0",
"grunt-contrib-watch": "^1.1.0", "grunt-contrib-watch": "^1.1.0",
"husky": "^2.2.0", "grunt-text-replace": "^0.4.0",
"husky": "^3.0.5",
"image-filter-core": "~2.0.2", "image-filter-core": "~2.0.2",
"image-filter-threshold": "~2.0.1", "image-filter-threshold": "~2.0.1",
"jasmine-core": "^3.3.0", "jasmine-core": "^3.3.0",
"jasmine-jquery": "^2.1.1", "jasmine-jquery": "^2.1.1",
"jasmine-spec-reporter": "^4.2.1", "jasmine-spec-reporter": "^6.0.0",
"lint-staged": "^9.1.0", "jest": "^26.1.0",
"jest-puppeteer": "^4.3.0",
"lint-staged": "^10.0.3",
"looks-same": "^7.0.0", "looks-same": "^7.0.0",
"matchdep": "^2.0.0", "matchdep": "^2.0.0",
"resemblejs": "^3.2.5",
"tap-spec": "^5.0.0", "tap-spec": "^5.0.0",
"tape": "^4.9.2", "tape": "^5.2.0",
"tape-run": "^6.0.0", "tape-run": "^8.0.0",
"uglify-es": "^3.3.7" "uglify-es": "^3.3.7"
}, },
"husky": { "husky": {

26
scripts/update-demo Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
scriptsDir=$(realpath $(dirname $0))
echo -ne "Enter the repo to push to in the form username/repo (required): "
read -e pushRepo
echo -ne "Enter repo URL to pull from (upstream) in the form username/repo (default: publiclab/image-sequencer): "
read -e repoInput
echo -ne "Enter branch name (default: stable): "
read -e branchInput
echo -ne "Enter CNAME URL(default: none): "
read -e cnameUrlInput
tempDir=$(mktemp -d)
pushd $tempDir > /dev/null
git clone https://github.com/$pushRepo
pushd image-sequencer > /dev/null
$scriptsDir/update-gh-pages "$repoInput" "$branchInput" "$cnameUrlInput" "no warn"
popd > /dev/null
popd > /dev/null

117
scripts/update-gh-pages Executable file
View File

@@ -0,0 +1,117 @@
#!/bin/bash
set -e # So that nothing wrong is published
warn() {
echo -e "\033[1;31m
------IMPORTANT------
THIS SCRIPT IS NOT MEANT TO BE USED DIRECTLY, PLEASE NEWLY CLONE THE REPO IN A SEPARATE DIRECTORY AND USE THE SCRIPT THERE.
USING THIS SCRIPT IN YOUR MAIN CLONE MAY DELETE YOUR LOCAL CHANGES.
This script is made to be reusable: If you want to manually update the demo, \
use the interactive script \`update-demo\`. This script can also be used in a github action.
You can set the 4th argument to anything to bypass this warning. \
Setting the 4th argument means that the first 3 arguments are also set which means that you know what you are doing (I assume).
------IMPORTANT------
\033[0m"
echo -ne "Do you still want to continue? [Y/n]: "
read -e yN
case $yN in
[yY][eE][sS] | [yY])
;;
*)
exit 0
;;
esac
}
# --- Constants ---
deps="jquery bootstrap imgareaselect gifshot downloadjs selectize font-awesome bootstrap-colorpicker jspdf opencv.js/opencv.js" # A list of node_module dependencies to force commit
# --- Constants ---
# --- Arguments ---
# $1: Repo(to use as upstream) url in the form username/repo (default: publiclab/image-sequencer) NOTE: Github only
# $2: Branch to pull from eg: main or stable (default: stable)
# $3: CNAME URL (default: none)
# $4: Set the fourth argument to anything to bypass the warning.
if [[ "$1" != "" ]];
then
repo=$1
else
repo="publiclab/image-sequencer"
fi
if [[ "$2" != "" ]];
then
branch=$2
else
branch="stable"
fi
if [[ "$3" != "" ]];
then
CNAMEURL=$3
else
CNAMEURL=""
fi
# --- Arguments ---
# --- Main Script ---
if [[ "$4" == "" ]]; # Set a 4th argument to anything to bypass this warning.
then
warn
fi
git checkout gh-pages
git remote add upstream https://github.com/$repo
git fetch upstream
git reset --hard upstream/$branch
echo -e "Running setup script."
npm run setup
echo -e "Building dist files."
grunt production
if [ ! -f CNAME ];
then
echo -e "Creating CNAME"
touch CNAME
fi
echo $CNAMEURL > CNAME
echo -e "Removing unnecessary files."
rm -R docs/
rm -R test/
rm CONTRIBUTING.md
rm index.js
echo -e "Copying important files from src/"
cp src/ui/prepareDynamic.js prepareDynamic.js
echo "Removing src/"
rm -R src/
mkdir -p src/ui/
mv prepareDynamic.js src/ui/prepareDynamic.js
echo -e "git add dist and node_modules dependencies."
git add .
for dep in $deps; # Force add node_modules dependencies
do
git add -f node_modules/$dep
done
git add -f dist/image-sequencer.js
git add -f dist/image-sequencer-ui.js
echo -e "committing and pusing."
git commit --no-verify -m "update"
git push -f
exit 0
# --- Main Script ---

View File

@@ -2,6 +2,11 @@ if (typeof window !== 'undefined') { isBrowser = true; }
else { var isBrowser = false; } else { var isBrowser = false; }
require('./util/getStep.js'); require('./util/getStep.js');
/**
* @method ImageSequencer
* @param {Object|Float32Array} options Optional options
* @returns {Object}
*/
ImageSequencer = function ImageSequencer(options) { ImageSequencer = function ImageSequencer(options) {
var str = require('./Strings.js')(this.steps, modulesInfo, addSteps, copy); var str = require('./Strings.js')(this.steps, modulesInfo, addSteps, copy);
@@ -14,6 +19,12 @@ ImageSequencer = function ImageSequencer(options) {
return Object.prototype.toString.call(object).split(' ')[1].slice(0, -1); return Object.prototype.toString.call(object).split(' ')[1].slice(0, -1);
} }
/**
* @method log
* @description Logs colored messages to the console using ASCII color codes
* @param {String} color ASCII color code
* @param {String} msg Message to be logged to the console
*/
function log(color, msg) { function log(color, msg) {
if (options.ui != 'none') { if (options.ui != 'none') {
if (arguments.length == 1) console.log(arguments[0]); if (arguments.length == 1) console.log(arguments[0]);
@@ -21,6 +32,12 @@ ImageSequencer = function ImageSequencer(options) {
} }
} }
/**
* @method copy
* @description Returns a clone of the input object.
* @param {Object|Float32Array} a The Object/Array to be cloned
* @returns {Object|Float32Array}
*/
function copy(a) { function copy(a) {
if (!typeof (a) == 'object') return a; if (!typeof (a) == 'object') return a;
if (objTypeOf(a) == 'Array') return a.slice(); if (objTypeOf(a) == 'Array') return a.slice();
@@ -53,10 +70,10 @@ ImageSequencer = function ImageSequencer(options) {
for (o in sequencer) { for (o in sequencer) {
modules[o] = sequencer[o]; modules[o] = sequencer[o];
} }
sequences = JSON.parse(window.localStorage.getItem('sequences')); sequences = JSON.parse(window.localStorage.getItem('sequences')); // Get saved sequences from localStorage
if (!sequences) { if (!sequences) {
sequences = {}; sequences = {};
window.localStorage.setItem('sequences', JSON.stringify(sequences)); window.localStorage.setItem('sequences', JSON.stringify(sequences)); // Set the localStorage entry as an empty Object by default
} }
} }
@@ -64,11 +81,16 @@ ImageSequencer = function ImageSequencer(options) {
// if (options.imageSelect || options.inBrowser) addStep('image-select'); // if (options.imageSelect || options.inBrowser) addStep('image-select');
// else if (options.imageUrl) loadImage(imageUrl); // else if (options.imageUrl) loadImage(imageUrl);
/**
* @method addSteps
* @description Adds one of more steps to the sequence.
* @return {Object}
*/
function addSteps() { function addSteps() {
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer; var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
var args = []; var args = [];
var json_q = {}; var json_q = {};
for (var arg in arguments) { args.push(copy(arguments[arg])); } for (var arg in arguments) { args.push(copy(arguments[arg])); } // Get all the module names from the arguments
json_q = formatInput.call(this_, args, '+'); json_q = formatInput.call(this_, args, '+');
inputlog.push({ method: 'addSteps', json_q: copy(json_q) }); inputlog.push({ method: 'addSteps', json_q: copy(json_q) });
@@ -77,17 +99,28 @@ ImageSequencer = function ImageSequencer(options) {
return this; return this;
} }
/**
* @method removeStep
* @description Removes the step at the specified index from the sequence.
* @param {Object} ref ImageSequencer instance
* @param {Number} index Index of the step to be removed
* @returns {Null}
*/
function removeStep(ref, index) { function removeStep(ref, index) {
//remove the step from images[image].steps and redraw remaining images // Remove the step from images[image].steps and redraw remaining images
if (index > 0) { if (index > 0) {
//var this_ = (this.name == "ImageSequencer") ? this : this.sequencer; // var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
thisStep = ref.steps[index]; thisStep = ref.steps[index];
thisStep.UI.onRemove(thisStep.options.step); thisStep.UI.onRemove(thisStep.options.step);
ref.steps.splice(index, 1); ref.steps.splice(index, 1);
} }
//tell the UI a step has been removed
} }
/**
* @method removeSteps
* @description Removes one or more steps from the sequence
* @returns {Object}
*/
function removeSteps() { function removeSteps() {
var indices; var indices;
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer; var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
@@ -103,6 +136,11 @@ ImageSequencer = function ImageSequencer(options) {
return this; return this;
} }
/**
* @method insertSteps
* @description Inserts steps at the specified index
* @returns {Object}
*/
function insertSteps() { function insertSteps() {
var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer; var this_ = (this.name == 'ImageSequencer') ? this : this.sequencer;
var args = []; var args = [];
@@ -118,8 +156,11 @@ ImageSequencer = function ImageSequencer(options) {
return this; return this;
} }
// Config is an object which contains the runtime configuration like progress bar /**
// information and index from which the sequencer should run * @method run
* @param {Object} config Object which contains the runtime configuration like progress bar information and index from which the sequencer should run.
* @returns {Boolean}
*/
function run(config) { function run(config) {
var progressObj, index = 0; var progressObj, index = 0;
config = config || { mode: 'no-arg' }; config = config || { mode: 'no-arg' };
@@ -137,7 +178,7 @@ ImageSequencer = function ImageSequencer(options) {
var callback = function() { }; var callback = function() { };
for (var arg in args) for (var arg in args)
if (objTypeOf(args[arg]) == 'Function') if (objTypeOf(args[arg]) == 'Function')
callback = args.splice(arg, 1)[0]; //callback is formed callback = args.splice(arg, 1)[0]; // Callback is formed
var json_q = formatInput.call(this_, args, 'r'); var json_q = formatInput.call(this_, args, 'r');
@@ -146,6 +187,11 @@ ImageSequencer = function ImageSequencer(options) {
return true; return true;
} }
/**
* @method loadImages
* @description Loads an image via dataURL or normal URL. Read the docs(https://github.com/publiclab/image-sequencer/blob/main/README.md) for more info.
* @returns {Null}
*/
function loadImages() { function loadImages() {
var args = []; var args = [];
var prevSteps = this.getSteps().slice(1).map(step=>step.options.name); var prevSteps = this.getSteps().slice(1).map(step=>step.options.name);
@@ -182,17 +228,35 @@ ImageSequencer = function ImageSequencer(options) {
} }
/**
* @method replaceImage
* @description Replaces the current image in the sequencer
* @param {String} selector DOM selector string for the image input
* @param {*} steps Current steps Object
* @param {Object} options
* @returns {*}
*/
function replaceImage(selector, steps, options) { function replaceImage(selector, steps, options) {
options = options || {}; options = options || {};
options.callback = options.callback || function() { }; options.callback = options.callback || function() { };
return require('./ReplaceImage')(this, selector, steps, options); return require('./ReplaceImage')(this, selector, steps, options);
} }
//returns the steps added /**
* @method getSteps
* @description Returns the current sequence of steps
* @returns {Object}
*/
function getSteps(){ function getSteps(){
return this.steps; return this.steps;
} }
/**
* @method setUI
* @description To set up a UI for ImageSequencer via different callback methods. Read the docs(https://github.com/publiclab/image-sequencer/blob/main/README.md) for more info.
* @param {Object} UI Object containing UI callback methods. Read the docs(https://github.com/publiclab/image-sequencer/blob/main/README.md) for more info.
* @returns {Null}
*/
function setUI(UI) { function setUI(UI) {
this.events = require('./ui/UserInterface')(UI); this.events = require('./ui/UserInterface')(UI);
} }
@@ -201,6 +265,12 @@ ImageSequencer = function ImageSequencer(options) {
return require('./ExportBin')(dir, this, basic, filename); return require('./ExportBin')(dir, this, basic, filename);
}; };
/**
* @method modulesInfo
* @description Returns information about the given module or all the available modules
* @param {String} name Module name
* @returns {Object}
*/
function modulesInfo(name) { function modulesInfo(name) {
var modulesdata = {}; var modulesdata = {};
if (name == 'load-image') return {}; if (name == 'load-image') return {};
@@ -222,23 +292,30 @@ ImageSequencer = function ImageSequencer(options) {
return modulesdata; return modulesdata;
} }
/**
* @method loadNewModule
* @description Adds a new local module to sequencer. Read the docs(https://github.com/publiclab/image-sequencer/blob/main/README.md) for mode info.
* @param {String} name Name of the new module
* @param {Object} options An Object containing path and info about the new module.
* @returns {Object}
*/
function loadNewModule(name, options) { function loadNewModule(name, options) {
if (!options) { if (!options) {
return this; return this;
} else if (Array.isArray(options)) { } else if (Array.isArray(options)) {
// contains the array of module and info // Contains the array of module and info
this.modules[name] = options; this.modules[name] = options;
} else if (options.func && options.info) { } else if (options.func && options.info) {
// passed in options object // Passed in options object
this.modules[name] = [ this.modules[name] = [
options.func, options.info options.func, options.info
]; ];
} else if (options.path && !this.inBrowser) { } else if (options.path && !this.inBrowser) {
// load from path(only in node) // Load from path(only in node)
const module = [ const module = [
require(`${options.path}/Module.js`), require(`${options.path}/Module.js`),
require(`${options.path}/info.json`) require(`${options.path}/info.json`)
@@ -248,6 +325,13 @@ ImageSequencer = function ImageSequencer(options) {
return this; return this;
} }
/**
* @method saveNewModule
* @description Saves a new local module to ImageSequencer
* @param {String} name Name of the new module
* @param {String} path Path to the new module
* @returns {Null}
*/
function saveNewModule(name, path) { function saveNewModule(name, path) {
if (options.inBrowser) { if (options.inBrowser) {
// Not for browser context // Not for browser context
@@ -258,6 +342,13 @@ ImageSequencer = function ImageSequencer(options) {
fs.writeFileSync('./src/Modules.js', mods); fs.writeFileSync('./src/Modules.js', mods);
} }
/**
* @method saveSequence
* @description Saves a sequence on the browser localStorage.
* @param {String} name Name for the sequence
* @param {String} sequenceString Sequence data as a string
* @returns {Null}
*/
function saveSequence(name, sequenceString) { // 4. save sequence function saveSequence(name, sequenceString) { // 4. save sequence
const sequence = str.stringToJSON(sequenceString); const sequence = str.stringToJSON(sequenceString);
// Save the given sequence string as a module // Save the given sequence string as a module
@@ -276,7 +367,7 @@ ImageSequencer = function ImageSequencer(options) {
} }
function loadModules() { function loadModules() {
// This function loads the modules and saved sequences // loadModules function loads the modules and saved sequences.
this.modules = require('./Modules'); this.modules = require('./Modules');
if (options.inBrowser) if (options.inBrowser)
this.sequences = JSON.parse(window.localStorage.getItem('sequences')); this.sequences = JSON.parse(window.localStorage.getItem('sequences'));
@@ -286,7 +377,7 @@ ImageSequencer = function ImageSequencer(options) {
return { return {
//literals and objects // Literals and objects
name: 'ImageSequencer', name: 'ImageSequencer',
options: options, options: options,
inputlog: inputlog, inputlog: inputlog,
@@ -296,7 +387,7 @@ ImageSequencer = function ImageSequencer(options) {
steps: steps, steps: steps,
image: image, image: image,
//user functions // User functions
loadImages: loadImages, loadImages: loadImages,
loadImage: loadImages, loadImage: loadImages,
addSteps: addSteps, addSteps: addSteps,
@@ -325,10 +416,11 @@ ImageSequencer = function ImageSequencer(options) {
loadModules: loadModules, loadModules: loadModules,
getSteps:getSteps, getSteps:getSteps,
//other functions // Other functions
log: log, log: log,
objTypeOf: objTypeOf, objTypeOf: objTypeOf,
copy: copy, copy: copy,
getImageDimensions: require('./util/getImageDimensions'),
setInputStep: require('./ui/SetInputStep')(sequencer) setInputStep: require('./ui/SetInputStep')(sequencer)
}; };

View File

@@ -11,8 +11,10 @@ module.exports = {
'canvas-resize': require('./modules/CanvasResize'), 'canvas-resize': require('./modules/CanvasResize'),
'channel': require('./modules/Channel'), 'channel': require('./modules/Channel'),
'colorbar': require('./modules/Colorbar'), 'colorbar': require('./modules/Colorbar'),
'color-halftone': require('./modules/ColorHalftone'),
'color-temperature': require('./modules/ColorTemperature'), 'color-temperature': require('./modules/ColorTemperature'),
'colormap': require('./modules/Colormap'), 'colormap': require('./modules/Colormap'),
'constrained-crop': require('./modules/ConstrainedCrop'),
'contrast': require('./modules/Contrast'), 'contrast': require('./modules/Contrast'),
'convolution': require('./modules/Convolution'), 'convolution': require('./modules/Convolution'),
'crop': require('./modules/Crop'), 'crop': require('./modules/Crop'),
@@ -29,9 +31,11 @@ module.exports = {
'gradient': require('./modules/Gradient'), 'gradient': require('./modules/Gradient'),
'grid-overlay': require('./modules/GridOverlay'), 'grid-overlay': require('./modules/GridOverlay'),
'import-image': require('./modules/ImportImage'), 'import-image': require('./modules/ImportImage'),
'mask': require('./modules/Mask'),
'minify-image': require('./modules/MinifyImage'), 'minify-image': require('./modules/MinifyImage'),
'invert': require('image-sequencer-invert'), // 'invert': require('image-sequencer-invert'), this code imports the invert module from a different repository altogether (using a require statement)
'matcher': require('./modules/Matcher'), // Which is a powerful feature of ImageSequencer, the modules are independent of the rest of the library's source.
'invert': require('./modules/Invert'),
'ndvi': require('./modules/Ndvi'), 'ndvi': require('./modules/Ndvi'),
'ndvi-colormap': require('./modules/NdviColormap'), 'ndvi-colormap': require('./modules/NdviColormap'),
'noise-reduction': require('./modules/NoiseReduction'), 'noise-reduction': require('./modules/NoiseReduction'),
@@ -41,6 +45,7 @@ module.exports = {
'resize': require('./modules/Resize'), 'resize': require('./modules/Resize'),
'rotate': require('./modules/Rotate'), 'rotate': require('./modules/Rotate'),
'saturation': require('./modules/Saturation'), 'saturation': require('./modules/Saturation'),
'shadow': require('./modules/Shadow'),
'text-overlay': require('./modules/TextOverlay'), 'text-overlay': require('./modules/TextOverlay'),
'threshold': require('./modules/Threshold'), 'threshold': require('./modules/Threshold'),
'tint': require('./modules/Tint'), 'tint': require('./modules/Tint'),

View File

@@ -45,6 +45,8 @@ function Run(ref, json_q, callback, ind, progressObj) {
// This output is accessible by UI // This output is accessible by UI
ref.steps[i].options.step.output = ref.steps[i].output.src; ref.steps[i].options.step.output = ref.steps[i].output.src;
ref.steps[i].options.step.wasmSuccess = ref.steps[i].output.wasmSuccess || false;
ref.steps[i].options.step.useWasm = ref.steps[i].output.useWasm || false;
// Tell UI that step has been drawn. // Tell UI that step has been drawn.
ref.steps[i].UI.onComplete(ref.steps[i].options.step); ref.steps[i].UI.onComplete(ref.steps[i].options.step);

102
src/cli/index.js Normal file
View File

@@ -0,0 +1,102 @@
require('../ImageSequencer');
sequencer = ImageSequencer({ ui: true });
var fs = require('fs');
var { Command } = require('commander');
var utils = require('../CliUtils');
var saveSequence = require('./saveSequence.js');
var installModule = require('./installModule.js');
var sequencerSteps = require('./sequencerSteps.js');
function exit(message) {
console.error(message);
process.exit(1);
}
function executeSteps(program) {
// Set sequencer to log module outputs, if any.
sequencer.setUI({
onComplete: function (step) {
// Get information of outputs.
step.info = sequencer.modulesInfo(step.name);
for (var output in step.info.outputs) {
console.log('[' + program.step + ']: ' + output + ' = ' + step[output]);
}
},
notify: function (msg) {
console.log('\x1b[36m%s\x1b[0m', '🌟 ' + msg);
},
});
// Finally, if everything is alright, load the image, add the steps and run the sequencer.
sequencer.loadImages(program.image, function () {
console.warn(
'\x1b[33m%s\x1b[0m',
'Please wait \n output directory generated will be empty until the execution is complete'
);
//Generate the Output Directory
var outputFilename = program.output.split('/').slice(-1)[0];
if (outputFilename.includes('.')) {
// user did give an output filename we have to remove it from dir
program.output = program.output.split('/').slice(0, -1).join('/');
} else {
outputFilename = null;
}
sequencerSteps(program, sequencer, outputFilename);
});
}
function parseSteps(program) {
// Parse step into an array to allow for multiple steps.
if (!program.step) exit('No steps passed');
program.step = program.step.split(' ');
// User must input an image.
if (!program.image) exit('Can\'t read file.');
// User must input an image.
fs.access(program.image, function (err) {
if (err) exit('Can\'t read file.');
});
// User must input a step. If steps exist, check that every step is a valid step.
if (!program.step || !utils.validateSteps(program.step, sequencer))
exit('Please ensure all steps are valid.');
// If there's no user defined output directory, select a default directory.
program.output = program.output || './output/';
executeSteps(program);
}
function cli(args) {
let program = new Command();
program
.version('0.1.0')
.option('-i, --image [PATH/URL]', 'Input image URL')
.option('-s, --step [step-name]', 'Name of the step to be added.')
.option('-o, --output [PATH]', 'Directory where output will be stored.')
.option('-b, --basic', 'Basic mode outputs only final image')
.option('-c, --config [Object]', 'Options for the step')
.option(
'--save-sequence [string]',
'Name space separated with Stringified sequence'
)
.option(
'--install-module [string]',
'Module name space seaprated npm package name'
)
.parse(args);
const options = program.opts();
if (options.saveSequence) saveSequence(options, sequencer);
else if (options.installModule) installModule(options, sequencer);
else parseSteps(options);
}
module.exports = cli;

View File

@@ -1,46 +1,58 @@
const _ = require('lodash'),
parseCornerCoordinateInputs = require('../../util/ParseInputCoordinates');
module.exports = function AddQR(options, UI) { module.exports = function AddQR(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json')); var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.size = options.size || defaults.size;
options.qrCodeString = options.qrCodeString || 'https://github.com/publiclab/image-sequencer';
var output; var output;
getPixels = require('get-pixels'); getPixels = require('get-pixels');
function draw(input, callback, progressObj) { function draw(input, callback, progressObj) {
options.size = Number(options.size || defaults.size);
options.qrCodeString = options.qrCodeString || defaults.qrCodeString;
options.startingX = options.startingX || defaults.startingX;
options.startingY = options.startingY || defaults.startingY;
progressObj.stop(true); progressObj.stop(true);
progressObj.overrideFlag = true; progressObj.overrideFlag = true;
var step = this; var step = this;
return getPixels(input.src, function(err, oldPixels) { function extraManipulation(pixels, setRenderState, generateOutput) {
function changePixel(r, g, b, a) { let iw = pixels.shape[0], // Width of Original Image
return [r, g, b, a]; ih = pixels.shape[1]; // Height of Original Image
} const oldPixels = _.cloneDeep(pixels);
setRenderState(false); // Prevent rendering of final output image until extraManipulation completes.
function extraManipulation(pixels, generateOutput) { // Parse the inputs.
if (err) { parseCornerCoordinateInputs({iw, ih},
console.log(err); {
return; startingX: { valInp: options.startingX, type: 'horizontal'},
} startingY: { valInp: options.startingY, type: 'vertical' },
require('./QR')(options, pixels, oldPixels, generateOutput); }, function(opt, cord){
} options.startingX = Math.floor(cord.startingX.valInp);
function output(image, datauri, mimetype) { options.startingY = Math.floor(cord.startingY.valInp);
step.output = { src: datauri, format: mimetype }; });
}
return require('../_nomodule/PixelManipulation.js')(input, { require('./QR')(options, pixels, oldPixels, () => {
output: output, setRenderState(true); // Allow rendering in the callback.
ui: options.step.ui, generateOutput();
changePixel: changePixel,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
}); });
}); }
function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
} }
return { return {

View File

@@ -1,44 +1,37 @@
module.exports = exports = function (options, pixels, oldPixels, callback) { const pixelSetter = require('../../util/pixelSetter.js'),
const pixelSetter = require('../../util/pixelSetter.js'); getPixels = require('get-pixels'),
QRCode = require('qrcode');
module.exports = exports = function (options, pixels, oldPixels, cb) {
var QRCode = require('qrcode'); QRCode.toDataURL(options.qrCodeString, {width: options.size, scale: 1}, function (error, url) {
QRCode.toDataURL(options.qrCodeString, function (err, url) {
var getPixels = require('get-pixels');
getPixels(url, function (err, qrPixels) { getPixels(url, function (err, qrPixels) {
if (err) { if (err) {
console.log('Bad image path', image); console.log('get-pixels error: ', err);
} }
var imagejs = require('imagejs'); const width = oldPixels.shape[0],
var bitmap = new imagejs.Bitmap({ width: qrPixels.shape[0], height: qrPixels.shape[1] });
bitmap._data.data = qrPixels.data;
var resized = bitmap.resize({
width: options.size, height: options.size,
algorithm: 'bicubicInterpolation'
});
qrPixels.data = resized._data.data;
qrPixels.shape = [options.size, options.size, 4];
qrPixels.stride[1] = 4 * options.size;
var width = oldPixels.shape[0],
height = oldPixels.shape[1]; height = oldPixels.shape[1];
var xe = width - options.size,
ye = height - options.size;
for (var m = 0; m < width; m++) {
for (var n = 0; n < height; n++) {
if (m >= xe && n >= ye) {
pixelSetter(m, n, [qrPixels.get(m - xe, n - ye, 0), qrPixels.get(m - xe, n - ye, 1), qrPixels.get(m - xe, n - ye, 2), qrPixels.get(m - xe, n - ye, 3)], pixels);
}
else { const xe = Math.min(options.startingX, width - options.size), // Starting pixel coordinates
pixelSetter(m, n, [qrPixels.get(m, n, 0), qrPixels.get(m, n, 1), qrPixels.get(m, n, 2), qrPixels.get(m, n, 3)], pixels); ye = Math.min(options.startingY, height - options.size);
}
for (let x = xe; x < Math.min(xe + options.size, width); x++) {
for (let y = ye; y < Math.min(ye + options.size, height); y++) {
pixelSetter(
x,
y,
[
qrPixels.get(x - xe, y - ye, 0),
qrPixels.get(x - xe, y - ye, 1),
qrPixels.get(x - xe, y - ye, 2),
qrPixels.get(x - xe, y - ye, 3)
],
pixels
);
} }
} }
callback();
if(cb) cb();
}); });
}); });
}; };

View File

@@ -12,6 +12,16 @@
"type": "string", "type": "string",
"desc": "input string to generate QR code", "desc": "input string to generate QR code",
"default": "https://github.com/publiclab/image-sequencer" "default": "https://github.com/publiclab/image-sequencer"
},
"startingX": {
"type": "string",
"desc": "X-position (measured from left) from where QR starts",
"default": "0"
},
"startingY": {
"type": "string",
"desc": "Y-position (measured from top) from where QR starts",
"default": "0"
} }
}, },
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#add-qr-module" "docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#add-qr-module"

View File

@@ -42,23 +42,19 @@ module.exports = function Average(options, UI) {
// report back and store average in metadata: // report back and store average in metadata:
options.step.metadata.averages = sum; options.step.metadata.averages = sum;
// TODO: refactor into a new "display()" method as per https://github.com/publiclab/image-sequencer/issues/242 if (options.step.average === undefined) options.step.average = '';
if (options.step.inBrowser && options.step.ui) $(options.step.ui).find('.details').append('<p><b>Averages</b> (r, g, b, a): ' + sum.join(', ') + '</p>'); options.step.average += 'rgba(' + sum.join(', ') + ')';
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = {
src: datauri,
format: mimetype
};
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
ui: options.step.ui, ui: options.step.ui,
inBrowser: options.inBrowser,
extraManipulation: extraManipulation, extraManipulation: extraManipulation,
format: input.format, format: input.format,
image: options.image, image: options.image,

View File

@@ -3,5 +3,11 @@
"description": "Average all pixel color", "description": "Average all pixel color",
"inputs": { "inputs": {
}, },
"outputs": {
"average": {
"type": "string",
"desc": "The average value of all the pixels."
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#average-module" "docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#average-module"
} }

View File

@@ -1,9 +1,10 @@
module.exports = function Dynamic(options, UI, util) { module.exports = function Blend(options, UI, util) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json')); var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.func = options.func || defaults.blend; options.func = options.blend || defaults.blend;
options.offset = options.offset || defaults.offset; options.offset = options.offset || defaults.offset;
options.blendMode = options.blendMode || defaults.blendMode;
var output; var output;
@@ -15,9 +16,6 @@ module.exports = function Dynamic(options, UI, util) {
var step = this; var step = this;
// convert to runnable code:
if (typeof options.func === 'string') eval('options.func = ' + options.func);
var getPixels = require('get-pixels'); var getPixels = require('get-pixels');
// convert offset as string to int // convert offset as string to int
@@ -32,26 +30,83 @@ module.exports = function Dynamic(options, UI, util) {
callback(); callback();
} }
// see http://docs.gimp.org/en/gimp-concepts-layer-modes.html for other blend modes
const multiply_mode = function (i, m) {
return ~~( (i * m) / 255 );
};
const divide_mode = function (i, m) {
return ~~( (256 * i) / (m + 1) );
};
const overlay_mode = function (i, m) {
return ~~( (i / 255) * (i + ((2 * m) / 255) * (255 - i)) );
};
const screen_mode = function (i, m) {
return ~~( 255 - ((255 - m) * (255 - i)) / 255 );
};
const sof_light_mode = function (i, m) {
var Rs = screen_mode(i, m);
return ~~( ((((255 - i) * m) + Rs) * i) / 255 );
};
const color_dodge = function (i, m) {
return ~~( (256 * i) / (255 - m + 1) );
};
const burn_mode = function (i, m) {
return ~~( 255 - (256 * (255 - i)) / (m + 1));
};
const grain_extract_mode = function (i, m) {
return ~~( i - m + 128 );
};
const grain_merge_mode = function (i, m) {
return ~~( i + m - 128 );
};
getPixels(priorStep.output.src, function(err, pixels) { getPixels(priorStep.output.src, function(err, pixels) {
options.firstImagePixels = pixels; options.firstImagePixels = pixels;
// Convert to runnable code.
if (typeof options.func === 'string') eval('options.func = ' + options.func);
function changePixel(r2, g2, b2, a2, x, y) { function changePixel(r2, g2, b2, a2, x, y) {
// blend! // blend!
let p = options.firstImagePixels; let p = options.firstImagePixels;
return options.func( let r1 = p.get(x, y, 0),
r2, g2, b2, a2, g1 = p.get(x, y, 1),
p.get(x, y, 0), b1 = p.get(x, y, 2),
p.get(x, y, 1), a1 = p.get(x, y, 3);
p.get(x, y, 2),
p.get(x, y, 3) const blends = {
); 'Color Dodge': () => [color_dodge(r2, r1), color_dodge(g2, g1), color_dodge(b2, b1), 255],
'Multiply': () => [multiply_mode(r2, r1), multiply_mode(g2, g1), multiply_mode(b2, b1), multiply_mode(a2, a1)],
'Divide': () => [divide_mode(r2, r1), divide_mode(g2, g1), divide_mode(b2, b1), 255],
'Overlay': () => [overlay_mode(r2, r1), overlay_mode(g2, g1), overlay_mode(b2, b1), 255],
'Screen': () => [screen_mode(r2, r1), screen_mode(g2, g1), screen_mode(b2, b1), 255],
'Soft Light': () => [sof_light_mode(r2, r1), sof_light_mode(g2, g1), sof_light_mode(b2, b1), 255],
'Color Burn': () => [burn_mode(r2, r1), burn_mode(g2, g1), burn_mode(b2, b1), 255],
'Grain Extract': () => [grain_extract_mode(r2, r1), grain_extract_mode(g2, g1), grain_extract_mode(b2, b1), 255],
'Grain Merge': () => [grain_merge_mode(r2, r1), grain_merge_mode(g2, g1), grain_merge_mode(b2, b1), 255]
};
if(options.blendMode == 'custom')
return options.func(
r2, g2, b2, a2, r1, g1, b1, a1
);
else {
return blends[options.blendMode]();
}
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
// run PixelManipulatin on second image's pixels // run PixelManipulatin on second image's pixels

View File

@@ -1,17 +1,34 @@
{ {
"name": "blend", "name": "blend",
"description": "Blend two chosen image steps with the given function. Defaults to using the red channel from image 1 and the green and blue and alpha channels of image 2. Easier to use interfaces coming soon!", "description": "Blend two chosen image steps with the given function. Defaults to using the red channel from image 1 and the green and blue and alpha channels of image 2.",
"inputs": { "inputs": {
"offset": { "offset": {
"type": "integer", "type": "integer",
"desc": "Choose which image to blend the current image with. Two steps back is -2, three steps back is -3 etc.", "desc": "Choose which image to blend the current image with. Two steps back is -2, three steps back is -3 etc.",
"default": -2 "default": -2
}, },
"blendMode": {
"type": "select",
"desc": "Name of the Blend Mode to use",
"default": "custom",
"values": [
"custom",
"Multiply",
"Divide",
"Overlay",
"Screen",
"Soft Light",
"Color Burn",
"Color Dodge",
"Grain Extract",
"Grain Merge"
]
},
"blend": { "blend": {
"type": "string", "type": "string",
"desc": "Function to use to blend the two images.", "desc": "Function to use to blend the two images.",
"default": "function(r1, g1, b1, a1, r2, g2, b2, a2) { return [ r1, g2, b2, a2 ] }" "default": "function(r1, g1, b1, a1, r2, g2, b2, a2, x, y) { return [ r2, g2, b2, a2 ] }"
} }
}, },
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blend-module" "docs-link": "https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blend-module"
} }

View File

@@ -1,17 +1,10 @@
module.exports = function(pixels, options, priorStep){ module.exports = function(pixels){
var $ = require('jquery'); // to make Blob-analysis work for node.js
var img = $(priorStep.imgElement);
if(Object.keys(img).length === 0){
img = $(priorStep.options.step.imgElement);
}
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
canvas.width = pixels.shape[0]; canvas.width = pixels.shape[0];
canvas.height = pixels.shape[1]; canvas.height = pixels.shape[1];
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.drawImage(img[0], 0, 0); ctx.putImageData(new ImageData(new Uint8ClampedArray(pixels.data), pixels.shape[0], pixels.shape[1]), 0, 0);
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
@@ -25,26 +18,26 @@ module.exports = function(pixels, options, priorStep){
let unknown = new cv.Mat(); let unknown = new cv.Mat();
let markers = new cv.Mat(); let markers = new cv.Mat();
// gray and threshold image // Gray and Threshold the image
cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0); cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0);
cv.threshold(gray, gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU); cv.threshold(gray, gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU);
// get background // Get background
let M = cv.Mat.ones(3, 3, cv.CV_8U); let M = cv.Mat.ones(3, 3, cv.CV_8U);
cv.erode(gray, gray, M); cv.erode(gray, gray, M);
cv.dilate(gray, opening, M); cv.dilate(gray, opening, M);
cv.dilate(opening, imageBg, M, new cv.Point(-1, -1), 3); cv.dilate(opening, imageBg, M, new cv.Point(-1, -1), 3);
// distance transform // Distance transform
cv.distanceTransform(opening, distTrans, cv.DIST_L2, 5); cv.distanceTransform(opening, distTrans, cv.DIST_L2, 5);
cv.normalize(distTrans, distTrans, 1, 0, cv.NORM_INF); cv.normalize(distTrans, distTrans, 1, 0, cv.NORM_INF);
// get foreground // Get foreground
cv.threshold(distTrans, imageFg, 0.7 * 1, 255, cv.THRESH_BINARY); cv.threshold(distTrans, imageFg, 0.7 * 1, 255, cv.THRESH_BINARY);
imageFg.convertTo(imageFg, cv.CV_8U, 1, 0); imageFg.convertTo(imageFg, cv.CV_8U, 1, 0);
cv.subtract(imageBg, imageFg, unknown); cv.subtract(imageBg, imageFg, unknown);
// get connected components markers // Get connected components markers
cv.connectedComponents(imageFg, markers); cv.connectedComponents(imageFg, markers);
for (let i = 0; i < markers.rows; i++) { for (let i = 0; i < markers.rows; i++) {
for (let j = 0; j < markers.cols; j++) { for (let j = 0; j < markers.cols; j++) {
@@ -58,13 +51,13 @@ module.exports = function(pixels, options, priorStep){
cv.cvtColor(src, src, cv.COLOR_RGBA2RGB, 0); cv.cvtColor(src, src, cv.COLOR_RGBA2RGB, 0);
cv.watershed(src, markers); cv.watershed(src, markers);
// draw barriers // Grow barriers
for (let i = 0; i < markers.rows; i++) { for (let i = 0; i < markers.rows; i++) {
for (let j = 0; j < markers.cols; j++) { for (let j = 0; j < markers.cols; j++) {
if (markers.intPtr(i, j)[0] == -1) { if (markers.intPtr(i, j)[0] == -1) {
src.ucharPtr(i, j)[0] = 255; // R src.ucharPtr(i, j)[0] = 255; // Red
src.ucharPtr(i, j)[1] = 0; // G src.ucharPtr(i, j)[1] = 0; // Green
src.ucharPtr(i, j)[2] = 0; // B src.ucharPtr(i, j)[2] = 0; // Blue
} }
} }
} }
@@ -78,4 +71,4 @@ module.exports = function(pixels, options, priorStep){
pixels.data = myImageData.data; pixels.data = myImageData.data;
return pixels; return pixels;
}; };

View File

@@ -10,17 +10,14 @@ module.exports = function BlobAnalysis(options, UI){
var step = this; var step = this;
var priorStep = this.getStep(-1); // get the previous step to process it
function extraManipulation(pixels){ function extraManipulation(pixels){
pixels = require('./BlobAnalysis')(pixels, options, priorStep); pixels = require('./BlobAnalysis')(pixels);
return pixels; return pixels;
} }
function output(image, datauri, mimetype){ function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
step.output = { src: datauri, format: mimetype};
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
@@ -40,4 +37,4 @@ module.exports = function BlobAnalysis(options, UI){
output: output, output: output,
UI: UI UI: UI
}; };
}; };

View File

@@ -2,5 +2,6 @@
"name": "Blob Analysis", "name": "Blob Analysis",
"description": "Blob/Region identification for microscopic images.", "description": "Blob/Region identification for microscopic images.",
"inputs": {}, "inputs": {},
"requires": ["webgl", "browser"],
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blob-analysis" "docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#blob-analysis"
} }

View File

@@ -1,8 +1,36 @@
// Generates a 5x5 Gaussian kernel
function kernelGenerator(sigma = 1) {
let kernel = [],
sum = 0;
if (sigma == 0) sigma += 0.05;
const s = 2 * Math.pow(sigma, 2);
for (let y = -2; y <= 2; y++) {
kernel.push([]);
for (let x = -2; x <= 2; x++) {
let r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
kernel[y + 2].push(Math.exp(-(r / s)));
sum += kernel[y + 2][x + 2];
}
}
for (let x = 0; x < 5; x++){
for (let y = 0; y < 5; y++){
kernel[y][x] = (kernel[y][x] / sum);
}
}
return kernel;
}
module.exports = exports = function(pixels, blur) { module.exports = exports = function(pixels, blur) {
const pixelSetter = require('../../util/pixelSetter.js'); const pixelSetter = require('../../util/pixelSetter.js');
let kernel = kernelGenerator(blur), let kernel = kernelGenerator(blur), // Generate the Gaussian kernel based on the sigma input.
pixs = { pixs = { // Separates the rgb channel pixels to convolve on the GPU.
r: [], r: [],
g: [], g: [],
b: [], b: [],
@@ -20,46 +48,18 @@ module.exports = exports = function(pixels, blur) {
} }
} }
const convolve = require('../_nomodule/gpuUtils').convolve; const convolve = require('../_nomodule/gpuUtils').convolve; // GPU convolution function.
const conPix = convolve([pixs.r, pixs.g, pixs.b], kernel); const conPix = convolve([pixs.r, pixs.g, pixs.b], kernel); // Convolves the pixels (all channels separately) on the GPU.
for (let y = 0; y < pixels.shape[1]; y++){ for (let y = 0; y < pixels.shape[1]; y++){
for (let x = 0; x < pixels.shape[0]; x++){ for (let x = 0; x < pixels.shape[0]; x++){
var pixelvalue = [Math.max(0, Math.min(conPix[0][y][x], 255)), var pixelvalue = [Math.max(0, Math.min(conPix[0][y][x], 255)),
Math.max(0, Math.min(conPix[1][y][x], 255)), Math.max(0, Math.min(conPix[1][y][x], 255)),
Math.max(0, Math.min(conPix[2][y][x], 255))]; Math.max(0, Math.min(conPix[2][y][x], 255))];
pixelSetter(x, y, pixelvalue, pixels); pixelSetter(x, y, pixelvalue, pixels); // Sets the image pixels according to the blurred values.
} }
} }
return pixels; return pixels;
};
//Generates a 5x5 Gaussian kernel
function kernelGenerator(sigma = 1) {
let kernel = [],
sum = 0;
if (sigma == 0) sigma += 0.05;
const s = 2 * Math.pow(sigma, 2);
for (let y = -2; y <= 2; y++) {
kernel.push([]);
for (let x = -2; x <= 2; x++) {
let r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
kernel[y + 2].push(Math.exp(-(r / s)));
sum += kernel[y + 2][x + 2];
}
}
for (let x = 0; x < 5; x++){
for (let y = 0; y < 5; y++){
kernel[y][x] = (kernel[y][x] / sum);
}
}
return kernel;
}
};

View File

@@ -20,16 +20,14 @@ module.exports = function Blur(options, UI) {
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
ui: options.step.ui, ui: options.step.ui,
inBrowser: options.inBrowser,
extraManipulation: extraManipulation, extraManipulation: extraManipulation,
format: input.format, format: input.format,
image: options.image, image: options.image,

View File

@@ -31,11 +31,8 @@ module.exports = function Brightness(options, UI) {
return [r, g, b, a]; return [r, g, b, a];
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -35,11 +35,8 @@ module.exports = function canvasResize(options, UI) {
return newPixels; return newPixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -22,5 +22,6 @@
"desc": "Y-cord of the top left corner of the image on the canvas", "desc": "Y-cord of the top left corner of the image on the canvas",
"default": 500 "default": 500
} }
} },
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#canvas-resize-module"
} }

View File

@@ -22,11 +22,8 @@ module.exports = function Channel(options, UI) {
if (options.channel === 'blue') return [0, 0, b, a]; if (options.channel === 'blue') return [0, 0, b, a];
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accesible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -0,0 +1,135 @@
/*
* Generate halftone versions of CMYK channels and blend them with varying rotations as in analog print color separation processes.
* Simulates a CMYK halftone rendering of the image by multiplying pixel values with a four rotated 2D sine wave patterns, one each for cyan, magenta, yellow, and black.
* http://evanw.github.io/glfx.js/docs/#colorHalftone
*/
module.exports = function ColorHalftone(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
var fx = require('glfx');
var dataURItoBlob = function dataURItoBlob(dataURI) {
// convert base64/URLEncoded data component to raw binary data held in a string
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to a typed array
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], { type: mimeString });
};
var canvasToBlobUrl = function canvasToBlobUrl(canvas) {
var blob = dataURItoBlob(canvas.toDataURL('image/png'));
return window.URL.createObjectURL(blob);
};
var colorHalftone = function colorHalftone(id, options, download) {
// try to create a WebGL canvas (will fail if WebGL isn't supported)
try {
var canvas = fx.canvas(1500, 1500);
} catch (e) {
alert(e);
return;
}
// convert the image to a texture
var imageEl = document.getElementById(id);
var image = new Image();
image.onload = function() {
var texture = canvas.texture(image);
canvas.draw(texture,
image.width, // * ratio,
image.height// * ratio
);
canvas.colorHalftone(
image.width / 2,
image.height / 2,
parseFloat(options.angle),
parseFloat(options.size)
).update();
var burl = canvasToBlobUrl(canvas);
if (download) {
window.open(burl);
} else { // replace the image
// keep non-blob version in case we have to fall back:
// image.src = canvas.toDataURL('image/png');
// window.location = canvas.toDataURL('image/png');
imageEl.src = burl;
}
};
$(image).hide();
image.src = imageEl.src;
};
function draw(input, callback) {
var step = this;
options.angle = options.angle || defaults.angle;
options.size = options.size || defaults.size;
if (!options.inBrowser) {
// this.output = input;
// callback();
require('../_nomodule/gl-context')(input, callback, step, options);
}
else {
var image = document.createElement('img');
image.onload = () => {
colorHalftone(
'img',
options
);
image.onload = () => {
var canvas = document.createElement('canvas');
canvas.width = image.naturalWidth; // or 'width' if you want a special/scaled size
canvas.height = image.naturalHeight; // or 'height' if you want a special/scaled size
canvas.getContext('2d').drawImage(image, 0, 0);
step.output = { src: canvas.toDataURL('image/png'), format: 'png' };
image.remove();
callback();
};
};
image.src = input.src;
image.id = 'img';
document.body.appendChild(image);
}
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};

View File

@@ -1,4 +1,4 @@
module.exports = [ module.exports = [
require('./Module'), require('./Module'),
require('./info.json') require('./info.json')
]; ];

View File

@@ -0,0 +1,23 @@
{
"name": "color-halftone",
"requires": ["webgl"],
"description": "Generate halftone versions of CMYK channels and blend them with varying rotations as in analog print color separation processes.",
"inputs": {
"angle": {
"type": "float",
"desc": "angle of rotation of the halftone patterns in radians",
"default": "0.25",
"min": "0",
"max": "1.57",
"step": "0.05"
},
"size": {
"type": "integer",
"desc": "the diameter of a dot in pixels",
"default": "4",
"min": "3",
"max": "20"
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#color-halftone-module"
}

View File

@@ -1,12 +1,15 @@
module.exports = function ColorTemperature(options, UI) { module.exports = function ColorTemperature(options, UI) {
const pixelSetter = require('../../util/pixelSetter.js'); const pixelSetter = require('../../util/pixelSetter.js');
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output; var output;
function draw(input, callback, progressObj) { function draw(input, callback, progressObj) {
options.temperature = (options.temperature > '40000') ? '40000' : options.temperature; options.temperature = options.temperature || defaults.temperature;
options.temperature = (options.temperature > 40000) ? 40000 : options.temperature;
options.temperature = (options.temperature < 0) ? 0 : options.temperature;
progressObj.stop(true); progressObj.stop(true);
progressObj.overrideFlag = true; progressObj.overrideFlag = true;
@@ -52,10 +55,8 @@ module.exports = function ColorTemperature(options, UI) {
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -1,12 +1,12 @@
module.exports = require('../../util/createMetaModule.js')( module.exports = require('../../util/createMetaModule.js')(
function mapFunction(options) { function mapFunction(options) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
// return steps with options: // return steps with options:
return [ return [
{ 'name': 'gradient', 'options': {} }, { 'name': 'gradient', 'options': {} },
{ 'name': 'colormap', 'options': { colormap: options.colormap } }, { 'name': 'colormap', 'options': { colormap: options.colormap || defaults.colormap } },
{ 'name': 'crop', 'options': { 'y': 0, 'h': options.h } }, { 'name': 'crop', 'options': { 'y': 0, 'w': '100%', 'h': options.h || defaults.h } },
{ 'name': 'overlay', 'options': { 'x': options.x, 'y': options.y, 'offset': -4 } } { 'name': 'overlay', 'options': { 'x': options.x || defaults.x, 'y': options.y || defaults.y, 'offset': -4 } }
]; ];
}, { }, {
infoJson: require('./info.json') infoJson: require('./info.json')

View File

@@ -12,7 +12,8 @@
*/ */
module.exports = function Colormap(value, options) { module.exports = function Colormap(value, options) {
options.colormap = options.colormap || colormaps.default; var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.colormap = options.colormap || defaults.colormap;
// if a lookup table is provided as an array: // if a lookup table is provided as an array:
if(typeof(options.colormap) == 'object') if(typeof(options.colormap) == 'object')
colormapFunction = colormap(options.colormap); colormapFunction = colormap(options.colormap);

View File

@@ -16,12 +16,10 @@ module.exports = function Colormap(options, UI) {
return [res[0], res[1], res[2], 255]; return [res[0], res[1], res[2], 255];
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
ui: options.step.ui, ui: options.step.ui,

View File

@@ -0,0 +1,56 @@
/*
* Crops an Image on the basis of the ratio provided
*/
module.exports = function ConstrainedCrop(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input, callback) {
var step = this,
startingX = Number(options.startingX || defaults.startingX),
startingY = Number(options.startingY || defaults.startingY),
aspectRatio = (options.aspectRatio || defaults.aspectRatio).split(':'),
widthRatio = Number(aspectRatio[0]),
heightRatio = Number(aspectRatio[1]);
function extraManipulation(pixels) {
var width = pixels.shape[0],
height = pixels.shape[1];
var endX, endY;
if(((width - startingX) / widthRatio) * heightRatio <= (height - startingY)) {
endX = width;
endY = (((width - startingX) / widthRatio) * heightRatio) + startingY;
}
else {
endX = (((height - startingY) / heightRatio) * widthRatio) + startingX;
endY = height;
}
const newPixels = require('../Crop/Crop')(pixels, {'x': startingX, 'y': startingY, 'w': endX - startingX, 'h': endY - startingY}, function() {
});
return newPixels;
}
function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
}
return require('../_nomodule/PixelManipulation')(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};

View File

@@ -0,0 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];

View File

@@ -0,0 +1,23 @@
{
"name": "constrained-crop",
"description": "Crops an image in a particular aspect-ratio",
"inputs": {
"startingX": {
"type": "integer",
"desc": "X-position (measured from left) from where cropping starts",
"default": 0
},
"startingY": {
"type": "integer",
"desc": "Y-position (measured from top) from where cropping starts",
"default": 0
},
"aspectRatio":{
"type": "string",
"desc": "Enter aspect ratio in following format width:height",
"default": "1:1"
}
},
"docs-link":""
}

View File

@@ -1,30 +0,0 @@
var _ = require('lodash');
const pixelSetter = require('../../util/pixelSetter.js');
module.exports = exports = function(pixels, contrast) {
let oldpix = _.cloneDeep(pixels);
contrast = Number(contrast);
if (contrast < -100) contrast = -100;
if (contrast > 100) contrast = 100;
contrast = (100.0 + contrast) / 100.0;
contrast *= contrast;
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
var rgbarray = [oldpix.get(i, j, 0) / 255.0, oldpix.get(i, j, 1) / 255.0, oldpix.get(i, j, 2) / 255.0];
for(var idx = 0;idx < 3;idx++){
rgbarray[idx] -= 0.5;
rgbarray[idx] *= contrast;
rgbarray[idx] += 0.5;
rgbarray[idx] *= 255;
if (rgbarray[idx] < 0) rgbarray[idx] = 0;
if (rgbarray[idx] > 255) rgbarray[idx] = 255;
}
pixelSetter(i, j, rgbarray, pixels);
}
}
return pixels;
};

View File

@@ -15,25 +15,41 @@ module.exports = function Contrast(options, UI) {
var step = this; var step = this;
function extraManipulation(pixels) { let contrast = options.contrast;
pixels = require('./Contrast')(pixels, options.contrast);
return pixels; contrast = Number(contrast);
if (contrast < -100) contrast = -100;
if (contrast > 100) contrast = 100;
contrast = (100.0 + contrast) / 100.0;
contrast *= contrast;
function changeContrast(p){
p -= 0.5;
p *= contrast;
p += 0.5;
p *= 255;
p = Math.max(0, p);
p = Math.min(p, 255);
return p;
} }
function output(image, datauri, mimetype) { function changePixel(r, g, b, a) {
// This output is accessible by Image Sequencer return [changeContrast(r / 255), changeContrast(g / 255), changeContrast(b / 255), a];
step.output = { src: datauri, format: mimetype }; }
function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
ui: options.step.ui, ui: options.step.ui,
extraManipulation: extraManipulation, changePixel: changePixel,
format: input.format, format: input.format,
image: options.image, image: options.image,
callback: callback, callback: callback,
inBrowser: options.inBrowser,
useWasm:options.useWasm useWasm:options.useWasm
}); });

View File

@@ -19,10 +19,8 @@ module.exports = function Convolution(options, UI) {
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
@@ -31,6 +29,7 @@ module.exports = function Convolution(options, UI) {
extraManipulation: extraManipulation, extraManipulation: extraManipulation,
format: input.format, format: input.format,
image: options.image, image: options.image,
inBrowser: options.inBrowser,
callback: callback, callback: callback,
useWasm:options.useWasm useWasm:options.useWasm
}); });

View File

@@ -1,61 +1,71 @@
module.exports = function Crop(input, options, callback) { const ndarray = require('ndarray'),
pixelSetter = require('../../util/pixelSetter'),
parseCornerCoordinateInputs = require('../../util/ParseInputCoordinates');
module.exports = function Crop(pixels, options, cb) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json')); var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var getPixels = require('get-pixels'), options.x = options.x || defaults.x;
savePixels = require('save-pixels'); options.y = options.y || defaults.y;
options.x = parseInt(options.x) || defaults.x; options.w = options.w || defaults.w;
options.y = parseInt(options.y) || defaults.y; options.h = options.h || defaults.h;
getPixels(input.src, function(err, pixels){ options.backgroundColor = options.backgroundColor || defaults.backgroundColor;
options.w = parseInt(options.w) || Math.floor(pixels.shape[0]);
options.h = parseInt(options.h) || Math.floor(pixels.shape[1]);
options.backgroundColor = options.backgroundColor || defaults.backgroundColor;
var ox = options.x;
var oy = options.y;
var w = options.w;
var h = options.h;
var iw = pixels.shape[0]; //Width of Original Image
var ih = pixels.shape[1]; //Height of Original Image
var backgroundArray = [];
backgroundColor = options.backgroundColor.substring(options.backgroundColor.indexOf('(') + 1, options.backgroundColor.length - 1); // extract only the values from rgba(_,_,_,_)
backgroundColor = backgroundColor.split(',');
for(var i = 0; i < w ; i++){
backgroundArray = backgroundArray.concat([backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]]);
}
// var newarray = new Uint8Array(4*w*h);
var array = [];
for (var n = oy; n < oy + h; n++) {
var offsetValue = 4 * w * n;
if(n < ih){
var start = n * 4 * iw + ox * 4;
var end = n * 4 * iw + ox * 4 + 4 * w;
var pushArray = Array.from(pixels.data.slice(start, end ));
array.push.apply(array, pushArray);
} else {
array.push.apply(array, backgroundArray);
}
}
var newarray = Uint8Array.from(array);
pixels.data = newarray;
pixels.shape = [w, h, 4];
pixels.stride[1] = 4 * w;
options.format = input.format; const bg = options.backgroundColor.replace('rgba', '').replace('(', '').replace(')', '').split(',');
var chunks = []; let iw = pixels.shape[0], // Width of Original Image
var totalLength = 0; ih = pixels.shape[1], // Height of Original Image
var r = savePixels(pixels, options.format); offsetX,
offsetY,
w,
h;
r.on('data', function(chunk){ // Parse the inputs
totalLength += chunk.length; parseCornerCoordinateInputs({iw, ih},
chunks.push(chunk); {
x: { valInp: options.x, type: 'horizontal' },
y: { valInp: options.y, type: 'vertical' },
w: { valInp: options.w, type: 'horizontal' },
h: { valInp: options.h, type: 'vertical' },
}, function (opt, coord) {
offsetX = Math.floor(coord.x.valInp);
offsetY = Math.floor(coord.y.valInp);
w = Math.floor(coord.w.valInp);
h = Math.floor(coord.h.valInp);
}); });
r.on('end', function(){ const newPixels = new ndarray([], [w, h, 4]);
var data = Buffer.concat(chunks, totalLength).toString('base64');
var datauri = 'data:image/' + options.format + ';base64,' + data; for (let x = 0; x < w; x++) {
callback(datauri, options.format); for (let y = 0; y < h; y++) {
}); pixelSetter(x, y, bg, newPixels); // Set the background color
}); }
}
for (
let x = 0;
x < Math.min(w - 1, offsetX + iw - 1);
x++
) {
for (
let y = 0;
y < Math.min(h - 1, offsetY + ih - 1);
y++
) {
const inputImgX = x + offsetX,
inputImgY = y + offsetY;
pixelSetter(x, y, [
pixels.get(inputImgX, inputImgY, 0),
pixels.get(inputImgX, inputImgY, 1),
pixels.get(inputImgX, inputImgY, 2),
pixels.get(inputImgX, inputImgY, 3)
], newPixels); // Set the background color
}
}
if (cb) cb();
return newPixels;
}; };

View File

@@ -1,3 +1,4 @@
const pixelManipulation = require('../_nomodule/PixelManipulation');
/* /*
* Image Cropping module * Image Cropping module
* Usage: * Usage:
@@ -26,54 +27,39 @@ module.exports = function CropModule(options, UI) {
var step = this; var step = this;
// save the input image;
// TODO: this should be moved to module API to persist the input image
options.step.input = input.src; options.step.input = input.src;
var parseCornerCoordinateInputs = require('../../util/ParseInputCoordinates');
//parse the inputs // We should do this via event/listener:
parseCornerCoordinateInputs(options, { if (ui && ui.hide) ui.hide();
src: input.src,
x: { valInp: options.x, type: 'horizontal' },
y: { valInp: options.y, type: 'vertical' }, function extraManipulation(pixels) {
w: { valInp: options.w, type: 'horizontal' }, const newPixels = require('./Crop')(pixels, options, function() {
h: { valInp: options.h, type: 'vertical' },
}, function (options, coord) { // Start custom UI setup (draggable UI)
options.x = parseInt(coord.x.valInp); // Only once we have an input image
options.y = parseInt(coord.y.valInp); if (setupComplete === false && options.step.inBrowser && !options.noUI) {
options.w = coord.w.valInp; setupComplete = true;
options.h = coord.h.valInp; ui.setup();
}
});
return newPixels;
}
function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
}
return pixelManipulation(input, {
output: output,
ui: options.step.ui,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
}); });
require('./Crop')(input, options, function (out, format) {
// This output is accessible to Image Sequencer
step.output = {
src: out,
format: format
};
// This output is accessible to the UI
options.step.output = out;
// Tell the UI that the step has been drawn
UI.onComplete(options.step);
// we should do this via event/listener:
if (ui && ui.hide) ui.hide();
// start custom UI setup (draggable UI)
// only once we have an input image
if (setupComplete === false && options.step.inBrowser && !options.noUI) {
setupComplete = true;
ui.setup();
}
// Tell Image Sequencer that step has been drawn
callback();
});
} }
return { return {

View File

@@ -59,12 +59,6 @@ module.exports = function CropModuleUi(step, ui) {
]; ];
} }
function remove() {
$(imgEl()).imgAreaSelect({
remove: true
});
}
function hide() { function hide() {
// then hide the draggable UI // then hide the draggable UI
$(imgEl()).imgAreaSelect({ $(imgEl()).imgAreaSelect({
@@ -92,7 +86,6 @@ module.exports = function CropModuleUi(step, ui) {
return { return {
setup: setup, setup: setup,
remove: remove,
hide: hide hide: hide
}; };
}; };

View File

@@ -16,12 +16,12 @@
"w": { "w": {
"type": "string", "type": "string",
"desc": "Width of crop", "desc": "Width of crop",
"default": "(50%)" "default": "100%"
}, },
"h": { "h": {
"type": "string", "type": "string",
"desc": "Height of crop", "desc": "Height of crop",
"default": "(50%)" "default": "100%"
}, },
"backgroundColor": { "backgroundColor": {
"type": "text", "type": "text",

View File

@@ -28,18 +28,16 @@ module.exports = function DoNothing(options, UI) {
options.step.qrval = (decoded) ? decoded.data : 'undefined'; options.step.qrval = (decoded) ? decoded.data : 'undefined';
}); });
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
// This output is accessible by Image Sequencer step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
step.output = {
src: datauri,
format: mimetype
};
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
ui: options.step.ui, ui: options.step.ui,
format: input.format, format: input.format,
image: options.image, image: options.image,
inBrowser: options.inBrowser,
callback: callback, callback: callback,
useWasm:options.useWasm useWasm:options.useWasm
}); });

View File

@@ -15,10 +15,8 @@ module.exports = function Dither(options, UI) {
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
// This output is accessible by Image Sequencer step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
@@ -27,6 +25,7 @@ module.exports = function Dither(options, UI) {
extraManipulation: extraManipulation, extraManipulation: extraManipulation,
format: input.format, format: input.format,
image: options.image, image: options.image,
inBrowser: options.inBrowser,
callback: callback, callback: callback,
useWasm:options.useWasm useWasm:options.useWasm
}); });

View File

@@ -4,22 +4,24 @@ module.exports = exports = function(pixels, options){
options.startingX = options.startingX || defaults.startingX; options.startingX = options.startingX || defaults.startingX;
options.startingY = options.startingY || defaults.startingY; options.startingY = options.startingY || defaults.startingY;
var ox = Number(options.startingX), var ox = Number(options.startingX),
oy = Number(options.startingY), oy = Number(options.startingY),
iw = pixels.shape[0], iw = pixels.shape[0],
ih = pixels.shape[1], ih = pixels.shape[1],
thickness = Number(options.thickness) || defaults.thickness, thickness = Number(options.thickness) || defaults.thickness,
ex = options.endX = Number(options.endX) - thickness || iw - 1, ex = Number(options.endX || defaults.endX) - thickness || iw - 1,
ey = options.endY = Number(options.endY) - thickness || ih - 1, ey = Number(options.endY || defaults.endY) - thickness || ih - 1,
color = options.color || defaults.color; color = options.color || defaults.color;
color = color.substring(color.indexOf('(') + 1, color.length - 1); // extract only the values from rgba(_,_,_,_)
color = color.substring(color.indexOf('(') + 1, color.length - 1); // Extract only the values from rgba(_,_,_,_)
color = color.split(','); color = color.split(',');
var drawSide = function(startX, startY, endX, endY){ var drawSide = function(startX, startY, endX, endY){
for (var n = startX; n <= endX + thickness; n++){ for (var n = startX; n <= endX + thickness; n++){
for (var k = startY; k <= endY + thickness; k++){ for (var k = startY; k <= endY + thickness; k++){
pixelSetter(n, k, color, pixels); //to remove 4th channel - pixels.set(n, k, 3, color[3]); pixelSetter(n, k, [color[0], color[1], color[2]], pixels); // To remove 4th channel - pixels.set(n, k, 3, color[3]);
} }
} }
}; };

View File

@@ -19,10 +19,8 @@ module.exports = function DrawRectangle(options, UI) {
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
@@ -32,6 +30,7 @@ module.exports = function DrawRectangle(options, UI) {
extraManipulation: extraManipulation, extraManipulation: extraManipulation,
format: input.format, format: input.format,
image: options.image, image: options.image,
inBrowser: options.inBrowser,
callback: callback, callback: callback,
useWasm:options.useWasm useWasm:options.useWasm
}); });

View File

@@ -17,13 +17,13 @@
"endX":{ "endX":{
"type": "integer", "type": "integer",
"desc": "last x position of the rectangle", "desc": "last x position of the rectangle",
"default": "width" "default": 10
}, },
"endY":{ "endY":{
"type": "integer", "type": "integer",
"desc": "last y position of the rectangle", "desc": "last y position of the rectangle",
"default": "height" "default": 10
}, },
"thickness":{ "thickness":{

View File

@@ -1,5 +1,5 @@
module.exports = function Dynamic(options, UI) { module.exports = function Dynamic(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output; var output;
// This function is called on every draw. // This function is called on every draw.
@@ -10,24 +10,24 @@ module.exports = function Dynamic(options, UI) {
var step = this; var step = this;
// start with monochrome, but if options.red, options.green, and options.blue are set, accept them too options.red = options.red || defaults.red;
options.monochrome = options.monochrome || '(R+G+B)/3'; options.blue = options.blue || defaults.blue;
options.green = options.green || defaults.green;
const Parser = require('expr-eval').Parser;
function generator(expression) { function generator(expression) {
var func = 'f = function (r, g, b, a) { var R = r, G = g, B = b, A = a;'; let expr = Parser.parse('R = r; G = g; B = b; A = a; ' + expression);
func = func + 'return '; return expr.toJSFunction("r,g,b,a,R,G,B,A");
func = func + expression + '}';
var f;
eval(func);
return f;
} }
var channels = ['red', 'green', 'blue', 'alpha']; var channels = ['red', 'green', 'blue', 'alpha'];
channels.forEach(function(channel) { channels.forEach(function(channel) {
if (options.hasOwnProperty(channel)) options[channel + '_function'] = generator(options[channel]); if (channel === 'alpha'){
else if (channel === 'alpha') options['alpha_function'] = function() { return 255; }; options['alpha_function'] = function() { return 255; };
else options[channel + '_function'] = generator(options.monochrome); } else {
options[channel + '_function'] = generator(options[channel]);
}
}); });
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -71,12 +71,10 @@ module.exports = function Dynamic(options, UI) {
} }
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {
output: output, output: output,
ui: options.step.ui, ui: options.step.ui,

View File

@@ -16,11 +16,6 @@
"type": "string", "type": "string",
"desc": "Expression to return for blue channel with R, G, B, and A inputs", "desc": "Expression to return for blue channel with R, G, B, and A inputs",
"default": "b" "default": "b"
},
"monochrome (fallback)": {
"type": "string",
"desc": "Expression to return with R, G, B, and A inputs; fallback for other channels if none provided",
"default": "r + g + b"
} }
}, },
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#dynamic-module" "docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#dynamic-module"

View File

@@ -1,6 +1,8 @@
// Define kernels for the sobel filter // Read More: https://en.wikipedia.org/wiki/Canny_edge_detector
const pixelSetter = require('../../util/pixelSetter.js'); const pixelSetter = require('../../util/pixelSetter.js');
// Define kernels for the sobel filter.
const kernelx = [ const kernelx = [
[-1, 0, 1], [-1, 0, 1],
[-2, 0, 2], [-2, 0, 2],
@@ -12,16 +14,14 @@ const kernelx = [
[ 1, 2, 1] [ 1, 2, 1]
]; ];
let pixelsToBeSupressed = [];
module.exports = function(pixels, highThresholdRatio, lowThresholdRatio, useHysteresis) { module.exports = function(pixels, highThresholdRatio, lowThresholdRatio, useHysteresis) {
let angles = [], grads = [], strongEdgePixels = [], weakEdgePixels = []; let angles = [], grads = [], strongEdgePixels = [], weakEdgePixels = [], pixelsToBeSupressed = [];
for (var x = 0; x < pixels.shape[0]; x++) { for (var x = 0; x < pixels.shape[0]; x++) {
grads.push([]); grads.push([]);
angles.push([]); angles.push([]);
for (var y = 0; y < pixels.shape[1]; y++) { for (var y = 0; y < pixels.shape[1]; y++) {
var result = sobelFilter( var result = sobelFilter( // Convolves the sobel filter on every pixel
pixels, pixels,
x, x,
y y
@@ -32,28 +32,47 @@ module.exports = function(pixels, highThresholdRatio, lowThresholdRatio, useHyst
angles.slice(-1)[0].push(result.angle); angles.slice(-1)[0].push(result.angle);
} }
} }
nonMaxSupress(pixels, grads, angles); nonMaxSupress(pixels, grads, angles, pixelsToBeSupressed); // Non Maximum Suppression: Filter fine edges.
doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels); doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels, pixelsToBeSupressed); // Double Threshold: Categorizes edges into strong and weak edges based on two thresholds.
if(useHysteresis.toLowerCase() == 'true') hysteresis(strongEdgePixels, weakEdgePixels); if(useHysteresis.toLowerCase() == 'true') hysteresis(strongEdgePixels, weakEdgePixels); // Optional Hysteresis (very slow) to minimize edges generated due to noise.
strongEdgePixels.forEach(pixel => preserve(pixels, pixel)); strongEdgePixels.forEach(pixel => preserve(pixels, pixel)); // Makes the strong edges White.
weakEdgePixels.forEach(pixel => supress(pixels, pixel)); weakEdgePixels.forEach(pixel => supress(pixels, pixel)); // Makes the weak edges black(bg color) after filtering.
pixelsToBeSupressed.forEach(pixel => supress(pixels, pixel)); pixelsToBeSupressed.forEach(pixel => supress(pixels, pixel)); // Makes the rest of the image black.
return pixels; return pixels;
}; };
/**
* @method supress
* @description Supresses (fills with background color) the specified (non-edge)pixel.
* @param {Object} pixels ndarry of pixels
* @param {Float32Array} pixel Pixel coordinates
* @returns {Null}
*/
function supress(pixels, pixel) { function supress(pixels, pixel) {
pixelSetter(pixel[0], pixel[1], [0, 0, 0, 255], pixels); pixelSetter(pixel[0], pixel[1], [0, 0, 0, 255], pixels);
} }
/**
* @method preserve
* @description Preserve the specified pixel(of an edge).
* @param {Object} pixels ndarray of pixels
* @param {*} pixel Pixel coordinates
* @returns {Null}
*/
function preserve(pixels, pixel) { function preserve(pixels, pixel) {
pixelSetter(pixel[0], pixel[1], [255, 255, 255, 255], pixels); pixelSetter(pixel[0], pixel[1], [255, 255, 255, 255], pixels);
} }
// sobelFilter function that convolves sobel kernel over every pixel /**
* @method sobelFiler
* @description Runs the sobel filter on the specified and neighbouring pixels.
* @param {Object} pixels ndarray of pixels
* @param {Number} x x-coordinate of the pixel
* @param {Number} y y-coordinate of the pixel
* @returns {Object} Object containing the gradient and angle.
*/
function sobelFilter(pixels, x, y) { function sobelFilter(pixels, x, y) {
let val = pixels.get(x, y, 0), let val = pixels.get(x, y, 0),
gradX = 0.0, gradX = 0.0,
@@ -65,8 +84,8 @@ function sobelFilter(pixels, x, y) {
let xn = x + a - 1, let xn = x + a - 1,
yn = y + b - 1; yn = y + b - 1;
if (isOutOfBounds(pixels, xn, yn)) { if (isOutOfBounds(pixels, xn, yn)) { // Fallback for coordinates which lie outside the image.
gradX += pixels.get(xn + 1, yn + 1, 0) * kernelx[a][b]; gradX += pixels.get(xn + 1, yn + 1, 0) * kernelx[a][b]; // Fallback to nearest pixel
gradY += pixels.get(xn + 1, yn + 1, 0) * kernely[a][b]; gradY += pixels.get(xn + 1, yn + 1, 0) * kernely[a][b];
} }
else { else {
@@ -84,11 +103,20 @@ function sobelFilter(pixels, x, y) {
}; };
} }
/**
* @method categorizeAngle
* @description Categorizes the given angle into 4 catagories according to the Category Map given below.
* @param {Number} angle Angle in degrees
* @returns {Number} Category number of the given angle
*/
function categorizeAngle(angle){ function categorizeAngle(angle){
if ((angle >= -22.5 && angle <= 22.5) || (angle < -157.5 && angle >= -180)) return 1; const pi = Math.PI;
else if ((angle >= 22.5 && angle <= 67.5) || (angle < -112.5 && angle >= -157.5)) return 2; angle = angle > 0 ? angle : pi - Math.abs(angle); // Diagonally flip the angle if it is negative (since edge remains the same)
else if ((angle >= 67.5 && angle <= 112.5) || (angle < -67.5 && angle >= -112.5)) return 3;
else if ((angle >= 112.5 && angle <= 157.5) || (angle < -22.5 && angle >= -67.5)) return 4; if (angle <= pi / 8 || angle > 7 * pi / 8) return 1;
else if (angle > pi / 8 && angle <= 3 * pi / 8) return 2;
else if (angle > 3 * pi / 8 && angle <= 5 * pi / 8) return 3;
else if (angle > 5 * pi / 8 && angle <= 7 * pi / 8) return 4;
/* Category Map /* Category Map
* 1 => E-W * 1 => E-W
@@ -98,33 +126,39 @@ function categorizeAngle(angle){
*/ */
} }
/**
* @method isOutOfBounds
* @description Checks whether the given coordinates lie outside the bounds of the image. Used for error handling in convolution.
* @param {Object} pixels ndarray of pixels
* @param {*} x x-coordinate of the pixel
* @param {*} y y-coordinate of the pixel
* @returns {Boolean} True if the given coordinates are out of bounds.
*/
function isOutOfBounds(pixels, x, y){ function isOutOfBounds(pixels, x, y){
return ((x < 0) || (y < 0) || (x >= pixels.shape[0]) || (y >= pixels.shape[1])); return ((x < 0) || (y < 0) || (x >= pixels.shape[0]) || (y >= pixels.shape[1]));
} }
const removeElem = (arr = [], elem) => { const removeElem = (arr = [], elem) => { // Removes the specified element from the given array.
return arr = arr.filter((arrelem) => { return arr = arr.filter((arrelem) => {
return arrelem !== elem; return arrelem !== elem;
}); });
}; };
// Non Maximum Supression without interpolation // Non Maximum Supression without interpolation.
function nonMaxSupress(pixels, grads, angles) { function nonMaxSupress(pixels, grads, angles, pixelsToBeSupressed) {
angles = angles.map((arr) => arr.map(convertToDegrees));
for (let x = 0; x < pixels.shape[0]; x++) { for (let x = 0; x < pixels.shape[0]; x++) {
for (let y = 0; y < pixels.shape[1]; y++) { for (let y = 0; y < pixels.shape[1]; y++) {
let angleCategory = categorizeAngle(angles[x][y]); let angleCategory = categorizeAngle(angles[x][y]);
if (!isOutOfBounds(pixels, x - 1, y - 1) && !isOutOfBounds(pixels, x + 1, y + 1)){ if (!isOutOfBounds(pixels, x - 1, y - 1) && !isOutOfBounds(pixels, x + 1, y + 1)){
switch (angleCategory){ switch (angleCategory){ // Non maximum suppression according to angle category
case 1: case 1:
if (!((grads[x][y] >= grads[x][y + 1]) && (grads[x][y] >= grads[x][y - 1]))) { if (!((grads[x][y] >= grads[x][y + 1]) && (grads[x][y] >= grads[x][y - 1]))) {
pixelsToBeSupressed.push([x, y]); pixelsToBeSupressed.push([x, y]);
} }
break; break;
case 2: case 2:
if (!((grads[x][y] >= grads[x + 1][y + 1]) && (grads[x][y] >= grads[x - 1][y - 1]))){ if (!((grads[x][y] >= grads[x + 1][y + 1]) && (grads[x][y] >= grads[x - 1][y - 1]))){
pixelsToBeSupressed.push([x, y]); pixelsToBeSupressed.push([x, y]);
@@ -147,17 +181,15 @@ function nonMaxSupress(pixels, grads, angles) {
} }
} }
} }
// Converts radians to degrees
var convertToDegrees = radians => (radians * 180) / Math.PI;
// Finds the max value in a 2d array like grads // Finds the max value in a 2d array like grads.
var findMaxInMatrix = arr => Math.max(...arr.map(el => el.map(val => val ? val : 0)).map(el => Math.max(...el))); var findMaxInMatrix = arr => Math.max(...arr.map(el => el.map(val => val ? val : 0)).map(el => Math.max(...el)));
// Applies the double threshold to the image // Applies the double threshold to the image.
function doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels) { function doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels, pixelsToBeSupressed) {
const highThreshold = findMaxInMatrix(grads) * highThresholdRatio, const highThreshold = findMaxInMatrix(grads) * highThresholdRatio, // High Threshold relative to the strongest edge
lowThreshold = highThreshold * lowThresholdRatio; lowThreshold = highThreshold * lowThresholdRatio; // Low threshold relative to high threshold
for (let x = 0; x < pixels.shape[0]; x++) { for (let x = 0; x < pixels.shape[0]; x++) {
for (let y = 0; y < pixels.shape[1]; y++) { for (let y = 0; y < pixels.shape[1]; y++) {
@@ -178,6 +210,12 @@ function doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, s
} }
} }
/**
* @method hysteresis
* @description Filters weak edge pixels that are not connected to a strong edge pixel.
* @param {Float32array} strongEdgePixels 2D array of strong edge pixel coordinates
* @param {*} weakEdgePixels 2D array of weak edge pixel coordinated
*/
function hysteresis(strongEdgePixels, weakEdgePixels){ function hysteresis(strongEdgePixels, weakEdgePixels){
strongEdgePixels.forEach(pixel => { strongEdgePixels.forEach(pixel => {
let x = pixel[0], let x = pixel[0],

View File

@@ -1,5 +1,8 @@
const Blur = require('../Blur/Blur');
/* /*
* Detect Edges in an Image * Detect Edges in an Image
* Uses Canny method for the same
* Read more: https://en.wikipedia.org/wiki/Canny_edge_detector
*/ */
module.exports = function edgeDetect(options, UI) { module.exports = function edgeDetect(options, UI) {
@@ -13,48 +16,36 @@ module.exports = function edgeDetect(options, UI) {
// The function which is called on every draw. // The function which is called on every draw.
function draw(input, callback, progressObj) { function draw(input, callback, progressObj) {
progressObj.stop(true); progressObj.stop(true);
progressObj.overrideFlag = true; progressObj.overrideFlag = true;
var step = this; var step = this;
// Blur the image // Makes the image greyscale
const internalSequencer = ImageSequencer({ inBrowser: false, ui: false }); function changePixel(r, g, b, a) {
return internalSequencer.loadImage(input.src, function() { return [(r + g + b) / 3, (r + g + b) / 3, (r + g + b) / 3, a];
internalSequencer.importJSON([{ 'name': 'blur', 'options': { blur: options.blur } }]); }
return internalSequencer.run(function onCallback(internalOutput) {
require('get-pixels')(internalOutput, function(err, blurPixels) {
if (err) {
return;
}
// Extra Manipulation function used as an enveloper for applying gaussian blur and Convolution // Extra Manipulation function used as an enveloper for applying gaussian blur and Convolution
function changePixel(r, g, b, a) { function extraManipulation(pixels) {
return [(r + g + b) / 3, (r + g + b) / 3, (r + g + b) / 3, a]; const blurPixels = Blur(pixels, options.blur);
} return require('./EdgeUtils')(blurPixels, options.highThresholdRatio, options.lowThresholdRatio, options.hysteresis);
}
function extraManipulation() { function output(image, datauri, mimetype, wasmSuccess) {
return require('./EdgeUtils')(blurPixels, options.highThresholdRatio, options.lowThresholdRatio, options.hysteresis); step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
} }
function output(image, datauri, mimetype) { return require('../_nomodule/PixelManipulation.js')(input, {
step.output = { src: datauri, format: mimetype }; output: output,
} ui: options.step.ui,
changePixel: changePixel,
return require('../_nomodule/PixelManipulation.js')(input, { extraManipulation: extraManipulation,
output: output, format: input.format,
ui: options.step.ui, image: options.image,
changePixel: changePixel, inBrowser: options.inBrowser,
extraManipulation: extraManipulation, callback: callback,
format: input.format, useWasm: options.useWasm
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm: options.useWasm
});
});
});
}); });
} }
@@ -64,4 +55,4 @@ module.exports = function edgeDetect(options, UI) {
output: output, output: output,
UI: UI UI: UI
}; };
}; };

View File

@@ -1,6 +1,6 @@
{ {
"name": "edge-detect", "name": "edge-detect",
"description": "This module detects edges using the Canny method, which first Gaussian blurs the image to reduce noise (amount of blur configurable in settings as `options.blur`), then applies a number of steps to highlight edges, resulting in a greyscale image where the brighter the pixel, the stronger the detected edge.<a href='https://en.wikipedia.org/wiki/Canny_edge_detector'> Read more. </a>", "description": "Edge Detect module detects edges using the Canny method, which first blurs the image to reduce noise (amount of blur configurable in settings as `options.blur`), then applies a number of steps to highlight edges, resulting in a greyscale image where the brighter the pixel, the stronger the detected edge. [Read more](https://en.wikipedia.org/wiki/Canny_edge_detector)",
"inputs": { "inputs": {
"blur": { "blur": {
"type": "float", "type": "float",

View File

@@ -24,11 +24,8 @@ module.exports = function Exposure(options, UI) {
return [r, g, b, a]; return [r, g, b, a];
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -11,5 +11,5 @@
"step": 0.05 "step": 0.05
} }
}, },
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md" "docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#exposure-module"
} }

View File

@@ -1,11 +1,12 @@
const _ = require('lodash');
/* /*
* Flip the image on vertical/horizontal axis. * Flip the image on vertical/horizontal axis.
*/ */
module.exports = function FlipImage(options, UI) { module.exports = function FlipImage(options, UI) {
options.Axis = options.Axis || require('./info.json').inputs.Axis.default; var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.Axis = options.Axis || defaults.Axis;
var output, let output;
getPixels = require('get-pixels');
function draw(input, callback, progressObj) { function draw(input, callback, progressObj) {
@@ -14,34 +15,30 @@ module.exports = function FlipImage(options, UI) {
var step = this; var step = this;
return getPixels(input.src, function(err, oldPixels) { function changePixel(r, g, b, a) {
function changePixel(r, g, b, a) { return [r, g, b, a];
return [r, g, b, a]; }
} function extraManipulation(pixels) {
function extraManipulation(pixels) { const oldPixels = _.cloneDeep(pixels);
if (err) {
console.log(err);
return;
}
return require('./flipImage')(oldPixels, pixels, options.Axis);
}
function output(image, datauri, mimetype) {
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, { return require('./flipImage')(oldPixels, pixels, options.Axis);
output: output, }
ui: options.step.ui,
changePixel: changePixel, function output(image, datauri, mimetype, wasmSuccess) {
extraManipulation: extraManipulation, step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
format: input.format, }
image: options.image,
inBrowser: options.inBrowser, return require('../_nomodule/PixelManipulation.js')(input, {
callback: callback, output: output,
useWasm:options.useWasm ui: options.step.ui,
}); changePixel: changePixel,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
}); });
} }
return { return {

View File

@@ -10,8 +10,7 @@ module.exports = function Gamma(options, UI) {
var step = this; var step = this;
var defaults = require('./../../util/getDefaults.js')(require('./info.json')), var defaults = require('./../../util/getDefaults.js')(require('./info.json')),
adjustment = options.adjustment || defaults.adjustment; val = options.adjustment || defaults.adjustment;
var val = adjustment / defaults.adjustment;
function changePixel(r, g, b, a) { function changePixel(r, g, b, a) {
@@ -22,10 +21,8 @@ module.exports = function Gamma(options, UI) {
return [r, g, b, a]; return [r, g, b, a];
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -5,9 +5,10 @@
"adjustment": { "adjustment": {
"type": "float", "type": "float",
"desc": "gamma correction (inverse of actual gamma factor) for the new image", "desc": "gamma correction (inverse of actual gamma factor) for the new image",
"default": 0.2, "default": 0.5,
"min": 2, "min": 0,
"max": 1 "max": 5,
"step": 0.1
} }
}, },
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#gamma-correction-module" "docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#gamma-correction-module"

View File

@@ -1,55 +1,57 @@
module.exports = function Invert(options, UI) { const pixelSetter = require('../../util/pixelSetter.js'),
const pixelSetter = require('../../util/pixelSetter.js'); pixelManipulation = require('../_nomodule/PixelManipulation');
module.exports = function Gradient(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.gradientType = options.gradientType || defaults.gradientType;
var output; var output;
// The function which is called on every draw. // The function which is called on every draw.
function draw(input, callback) { function draw(input, callback) {
var getPixels = require('get-pixels');
var savePixels = require('save-pixels');
var step = this; var step = this;
getPixels(input.src, function(err, pixels) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
}
if (err) { function extraManipulation(pixels) {
console.log('Bad Image path'); const [w, h] = pixels.shape;
return; if (options.gradientType === 'linear') {
} for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
var width = pixels.shape[0]; let val = (i / w) * 255;
for (var i = 0; i < pixels.shape[0]; i++) { pixelSetter(i, j, [val, val, val, 255], pixels);
for (var j = 0; j < pixels.shape[1]; j++) { }
let val = (i / width) * 255; }
pixelSetter(i, j, [val, val, val, 255], pixels); }
else {
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
var distX = Math.abs(w / 2 - i);
var distY = Math.abs(h / 2 - j);
var distance = Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2));
val = 255 * (distance / pixels.shape[0]);
pixelSetter(i, j, [val, val, val, 255], pixels);
}
} }
} }
var chunks = [];
var totalLength = 0;
var r = savePixels(pixels, input.format, { quality: 100 });
r.on('data', function(chunk) { return pixels;
totalLength += chunk.length; }
chunks.push(chunk);
});
r.on('end', function() { return pixelManipulation(input, {
var data = Buffer.concat(chunks, totalLength).toString('base64'); output,
var datauri = 'data:image/' + input.format + ';base64,' + data; extraManipulation,
output(input.image, datauri, input.format); callback,
callback(); format: input.format,
}); image: options.image,
inBrowser: options.inBrowser,
useWasm:options.useWasm
}); });
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
} }
return { return {

View File

@@ -1,6 +1,13 @@
{ {
"name": "gradient", "name": "gradient",
"description": "Gives a gradient of the image", "description": "Gives a gradient of the image",
"inputs": {}, "inputs": {
"gradientType": {
"type": "select",
"desc": "Choose between linear or circular gradient",
"default": "linear",
"values": ["linear", "circular"]
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#gradient-module" "docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#gradient-module"
} }

View File

@@ -2,11 +2,11 @@ module.exports = exports = function(pixels, options){
var defaults = require('./../../util/getDefaults.js')(require('./info.json')); var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
const pixelSetter = require('../../util/pixelSetter.js'); const pixelSetter = require('../../util/pixelSetter.js');
if(Number(options.x)==0){ if(Number(options.x) == 0){
options.x = 1; options.x = 1;
} }
if( Number(options.y)==0) { if( Number(options.y) == 0) {
options.y =1; options.y = 1;
} }
options.x = Math.abs(Number(options.x)) || defaults.x; options.x = Math.abs(Number(options.x)) || defaults.x;
@@ -17,14 +17,14 @@ module.exports = exports = function(pixels, options){
for(var x = 0; x < pixels.shape[0]; x += options.x){ for(var x = 0; x < pixels.shape[0]; x += options.x){
for(var y = 0 ; y < pixels.shape[1]; y++){ for(var y = 0 ; y < pixels.shape[1]; y++){
pixelSetter(x, y, color, pixels); // to remove 4th channel - pixels.set(x, y, 3, color[3]); pixelSetter(x, y, [color[0], color[1], color[2]], pixels); // to remove 4th channel - pixels.set(x, y, 3, color[3]);
} }
} }
for(var y = 0; y < pixels.shape[1]; y += options.y){ for(var y = 0; y < pixels.shape[1]; y += options.y){
for(var x = 0 ; x < pixels.shape[0]; x++){ for(var x = 0 ; x < pixels.shape[0]; x++){
pixelSetter(x, y, color, pixels); // to remove 4th channel - pixels.set(x, y, 3, color[3]); pixelSetter(x, y, [color[0], color[1], color[2]], pixels); // to remove 4th channel - pixels.set(x, y, 3, color[3]);
} }
} }

View File

@@ -15,11 +15,8 @@ module.exports = function GridOverlay(options, UI) {
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accesible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -11,7 +11,7 @@ module.exports = function Channel(options, UI) {
const pixelSetter = require('../../util/pixelSetter.js'); const pixelSetter = require('../../util/pixelSetter.js');
options.gradient = options.gradient || defaults.gradient; options.gradient = options.gradient || defaults.gradient;
options.gradient = JSON.parse(options.gradient); options.gradient = String(JSON.parse(options.gradient));
progressObj.stop(true); progressObj.stop(true);
progressObj.overrideFlag = true; progressObj.overrideFlag = true;
@@ -63,11 +63,8 @@ module.exports = function Channel(options, UI) {
return pixels; return pixels;
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accesible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return require('../_nomodule/PixelManipulation.js')(input, { return require('../_nomodule/PixelManipulation.js')(input, {

View File

@@ -8,7 +8,7 @@ module.exports = function ImportImageModuleUi(step, ui) {
// add a file input listener // add a file input listener
var dropZone = '\ var dropZone = '\
<div class="dropzone" style="padding: 30px;margin: 10px 20% 30px;border: 4px dashed #ccc;border-radius: 8px;text-align: center;color: #444;" id="' + dropzoneId + '">\ <div class="dropzone import-image-zone" id="' + dropzoneId + '">\
<p>\ <p>\
<i>Select or drag in an image to overlay.</i>\ <i>Select or drag in an image to overlay.</i>\
</p>\ </p>\

View File

@@ -1,3 +1,4 @@
const pixelManipulation = require('../_nomodule/PixelManipulation');
/* /*
* Invert the image * Invert the image
*/ */
@@ -17,14 +18,11 @@ function Invert(options, UI) {
return [255 - r, 255 - g, 255 - b, a]; return [255 - r, 255 - g, 255 - b, a];
} }
function output(image, datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
} }
return input.pixelManipulation({ return pixelManipulation(input, {
output: output, output: output,
changePixel: changePixel, changePixel: changePixel,
format: input.format, format: input.format,
@@ -43,10 +41,4 @@ function Invert(options, UI) {
UI: UI UI: UI
}; };
} }
var info = { module.exports = Invert;
'name': 'invert',
'description': 'Inverts the image.',
'inputs': {
}
};
module.exports = [Invert, info];

View File

@@ -0,0 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];

View File

@@ -0,0 +1,82 @@
module.exports = function Mask(options, UI, util) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.offset = options.offset || defaults.offset;
options.resize = options.resize || defaults.resize;
var output;
// This function is called on every draw.
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
var getPixels = require('get-pixels');
// convert offset as string to int
if (typeof options.offset === 'string')
options.offset = parseInt(options.offset);
// save first image's pixels
var priorStep = this.getStep(options.offset);
if (priorStep.output === undefined) {
this.output = input;
UI.notify('Offset Unavailable', 'offset-notification');
callback();
}
const alpha_masking = function(c, a) {
return (a * c + (255 - a) * c) / 255;
};
const internalSequencer = ImageSequencer({ inBrowser: false, ui: false });
internalSequencer.loadImage(priorStep.output.src, function() {
internalSequencer.importJSON([{ 'name': 'resize', 'options': { resize: options.resize } }]);
internalSequencer.run(function onCallback(internalOutput) {
getPixels(internalOutput, function(err, pixels) {
options.firstImagePixels = pixels;
function changePixel(r2, g2, b2, a2, x, y) {
let p = options.firstImagePixels;
let r1 = p.get(x, y, 0),
g1 = p.get(x, y, 1),
b1 = p.get(x, y, 2),
a1 = p.get(x, y, 3);
return [alpha_masking(r1, a2), alpha_masking(g1, a2), alpha_masking(b1, a2)];
}
function output(image, datauri, mimetype, wasmSuccess) {
step.output = {
src: datauri,
format: mimetype,
wasmSuccess,
useWasm: options.useWasm
};
}
// run PixelManipulatin on second image's pixels
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
ui: options.step.ui,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm: options.useWasm
});
});
});
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
};

View File

@@ -0,0 +1,4 @@
module.exports = [
require('./Module'),
require('./info.json')
];

View File

@@ -0,0 +1,18 @@
{
"name": "mask",
"description": "Masks two images according to their Alpha values",
"inputs": {
"offset": {
"type": "integer",
"desc": "Choose which image to mask the current image with. Two steps back is -2, three steps back is -3 etc.",
"default": -2
},
"resize": {
"type": "string",
"desc": "Percentage value by which first image is to be resized",
"default": "125%"
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md"
}

View File

@@ -1,63 +0,0 @@
/*
* Match the images
*/
function Match(options, UI) {
var output, points;
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
global.XY = [
options.imageX || defaults.imageX,
options.imageY || defaults.imageY
];
const core = require('matcher-core');
core(function(err, out, code){
points = JSON.parse(out.trim());
});
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
function changePixel(r, g, b, a, x, y) {
for(var i = 0; i < 500; i++){
if(Math.abs(points[i].x - x) <= 10 && Math.abs(points[i].y - y) <= 10){
return [0, 255, 0];
}
}
return [r, g, b, a];
}
function output(image, datauri, mimetype) {
step.output = { src: datauri, format: mimetype };
}
return input.pixelManipulation({
output: output,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback,
useWasm:options.useWasm
});
}
return {
options: options,
draw: draw,
output: output,
UI: UI
};
}
module.exports = Match;

View File

@@ -1,15 +0,0 @@
{
"name": "matcher-core",
"description": "Pattern-mining module for detecting key-points in images",
"url": "https://github.com/publiclab/matcher-core.git",
"inputs": {
"imageX": {
"type": "text",
"default": ""
},
"imageY": {
"type": "text",
"default": ""
}
}
}

View File

@@ -49,7 +49,7 @@ module.exports = function MinifyImage(options, UI) {
reader.readAsDataURL(result); reader.readAsDataURL(result);
reader.onloadend = function () { reader.onloadend = function () {
base64data = reader.result; base64data = reader.result;
output(base64data, input.format); output(null, base64data, input.format, false);
if (callback) callback(); if (callback) callback();
return; return;
}; };
@@ -76,19 +76,14 @@ module.exports = function MinifyImage(options, UI) {
}); });
var destPath = __dirname + '/results/test.' + input.format; var destPath = __dirname + '/results/test.' + input.format;
var data = base64Img.base64Sync(destPath); var data = base64Img.base64Sync(destPath);
output(data, input.format); output(null, data, input.format, false);
if (callback) callback(); if (callback) callback();
})(); })().catch(e => console.log(e));
} }
function output(datauri, mimetype) { function output(image, datauri, mimetype, wasmSuccess) {
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
// This output is accessible by Image Sequencer
step.output = {
src: datauri,
format: mimetype
};
} }
} }
return { return {

Some files were not shown because too many files have changed in this diff Show More