Compare commits

...

53 Commits

Author SHA1 Message Date
Jeffrey Warren
e562cae6a0 Update .codecov.yml 2019-04-15 17:09:50 -05:00
Jeffrey Warren
40c91483ab Add codecov comments 2019-04-15 16:32:36 -05:00
Harsh Khandeparkar
3772f78f51 1000 contributions PR (#1008)
* Update PULL_REQUEST_TEMPLATE.md

* changes
2019-04-15 16:24:29 -05:00
Slytherin
6ba604550b Add codecov (#1014) 2019-04-15 15:58:58 -05:00
Harsh Khandeparkar
2f86dcb0c8 Fixed Service Worker (#976)
* Update cache.js

* Update cache.js

* Create sw.js

* Delete sw.js
2019-04-15 12:38:39 -05:00
dependabot[bot]
fd981634fa Bump commander from 2.19.0 to 2.20.0 (#980)
Bumps [commander](https://github.com/tj/commander.js) from 2.19.0 to 2.20.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/v2.19.0...v2.20.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 12:33:00 -05:00
dependabot[bot]
142464bb8b Bump ora from 3.2.0 to 3.4.0 (#981)
Bumps [ora](https://github.com/sindresorhus/ora) from 3.2.0 to 3.4.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v3.2.0...v3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 12:32:09 -05:00
dependabot[bot]
78d9cd91e7 Bump jasmine-core from 3.3.0 to 3.4.0 (#986)
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 3.3.0 to 3.4.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.3.0...v3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-15 09:18:26 -05:00
Vibhor Gupta
e22eacf666 Add: white balance module (#1011)
* WIP

* added white balance and renamed temperature module

* import defaults

* white balance module test
2019-04-15 07:21:39 -05:00
Varun Gupta
c3e8c3fb74 Gl puppeteer (#1007)
* add geotiff

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* now running gl using localhost fixes #216

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* modularize api and fix tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* finishing up

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add docs

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fixes

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* fix benchmark.js

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-04-14 10:50:26 -05:00
aashna27
4e43c9123a Fixes Text-Overlay (#1004) 2019-04-12 10:11:00 -04:00
dependabot[bot]
914a172f5d Bump jquery from 3.3.1 to 3.4.0 (#1001)
Bumps [jquery](https://github.com/jquery/jquery) from 3.3.1 to 3.4.0.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Commits](https://github.com/jquery/jquery/compare/3.3.1...3.4.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-04-11 04:42:32 -04:00
Lohitha
e4ddb04601 Add spinner while gif is generating (#991)
fixes #843
2019-04-08 19:47:26 -04:00
Harshith pabbati
edcc253029 fixed the bug (#999) 2019-04-08 08:26:39 -04:00
Terrence
51a38fe3cf More Modules option removed. Placeholder text added (#996)
* More Modules option removed. Placeholder text added

* 'A' changed to 'a' in placeholder text

* Update examples/lib/intermediateHtmlStepUi.js

Suggested update

Co-Authored-By: teisenhower <47988669+teisenhower@users.noreply.github.com>
2019-04-07 13:12:18 -04:00
Varun Gupta
e4e4548c09 add canvas resize module (#994)
* add canvas resize module

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* add tests

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-04-07 12:41:14 -04:00
Vajean Stan
7cf96df1ee Removed redundant parameters in ImageSequencer.js (#967)
* Removed redundant parameters in ImageSequencer.js

* Re-added loadImages, deleted loadImage

* Left both loadImage and loadImages in

I think I need more details to the last phrase in the instructions, telling me to remove the export of loadImages, I tried deleting that line and cannot pass the test.
2019-04-05 18:03:04 -04:00
Harsh Khandeparkar
2a0eff41f4 Fix insert step and allow "closing" it (#655)
* update dist

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

dist update

Revert "dist update"

This reverts commit 9ee2a987e8f978961656ae8f71f6e6702bbbd30d.

* fix insert step button

* add icon

* add dist

* use normal functions

* use normal functions

* no lag

* changes

* changes

* changes

* Update intermediateHtmlStepUi.js

* toggleDiv global

- Globalised toggleDiv
- toggleDiv has default callback which does nothing.
2019-04-05 15:08:42 -04:00
Harsh Khandeparkar
b95728f95c Create fto-template.md (#977)
* Create fto-template.md

* Create first-timers.yml
2019-04-05 14:42:34 -04:00
Harshith pabbati
d63aab79a6 Added doc for grid-overlay (#983) 2019-04-05 14:37:17 -04:00
Harshith pabbati
0e7323efa9 Grid-Overlay module. (#974)
* Grid-Overlay module

* Added the X and Y for inputs
2019-04-03 08:46:57 -04:00
Harshith pabbati
1de170c978 made few changes to css (#975) 2019-04-02 09:37:39 -04:00
Jeffrey Warren
9a666a2f06 add maintainability badge from codeclimate 2019-04-01 14:33:02 -04:00
Harshith pabbati
985c67847e Changes to make the insert-step disable at the first step (#968) 2019-04-01 10:36:45 -04:00
Jeffrey Warren
690c126f41 ui-tweaks (#960) 2019-03-30 12:47:56 -04:00
Harshith pabbati
bc1151c340 Made it to work (#958) 2019-03-29 18:21:01 -04:00
Jeffrey Warren
32268c54df remove container class from step div (#956) 2019-03-28 21:35:10 -04:00
dependabot[bot]
12df02a0fd Bump jsdom from 13.2.0 to 14.0.0 (#845)
Bumps [jsdom](https://github.com/jsdom/jsdom) from 13.2.0 to 14.0.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/13.2.0...14.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-28 21:32:05 -04:00
MichaelLin250
a51644963a TRYING SO HARD TO FIX IT (#950) 2019-03-28 21:29:41 -04:00
Harshith pabbati
9f524615a5 Bootstrap panel (#942)
* Bootstrap panel

* Indentation.

* css tidying

* more tweaks
2019-03-28 20:59:21 -04:00
aashna27
8ad171ee56 Tests added (#943) 2019-03-27 07:49:42 -04:00
vaari gupta
a8757a888a Improved Footer (#904)
* improved footer

* corrected Footer

* Delete image-sequencer-ui.js

* Delete image-sequencer-ui.min.js

* Delete image-sequencer.js

* Delete image-sequencer.min.js
2019-03-26 18:33:48 -04:00
Harsh Khandeparkar
24fb83a565 Delete image-sequencer-ui.js (#941)
* Delete image-sequencer-ui.js

* fix link
2019-03-25 16:53:06 -04:00
aashna27
60cfcb4d30 Added Text Overlay module (#917) 2019-03-25 15:58:02 -04:00
Jeffrey Warren
488bbd86da Rearrange buttons in UI (#936) 2019-03-25 15:57:18 -04:00
Harsh Khandeparkar
a923f48c87 gitignore dist and update links (#908)
* Update .gitignore

* Delete image-sequencer-ui.min.js

* Delete image-sequencer.js

* Delete image-sequencer.min.js

* Update README.md

* Update README.md

* Update CONTRIBUTING.md

* Update .npmignore

* Update README.md

* Update .npmignore

* Update CONTRIBUTING.md
2019-03-25 15:55:34 -04:00
dependabot[bot]
15e93f09bd Bump grunt from 1.0.3 to 1.0.4 (#939)
Bumps [grunt](https://github.com/gruntjs/grunt) from 1.0.3 to 1.0.4.
- [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.3...v1.0.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 11:01:52 -04:00
dependabot[bot]
eb12d061ee Bump looks-same from 7.1.1 to 7.2.0 (#940)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.1.1 to 7.2.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/commits/v7.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-25 11:01:42 -04:00
Harsh Khandeparkar
95efe812c3 Rename White balance to ColorTemperature (#931)
* Update and rename src/modules/WhiteBalance/Module.js to src/modules/ColorTemperature/Module.js

* Rename src/modules/WhiteBalance/index.js to src/modules/ColorTemperature/index.js

* Update and rename src/modules/WhiteBalance/info.json to src/modules/ColorTemperature/info.json

* Update Modules.js

* Update MODULES.md

* Update MODULES.md

* Update Module.js

* Update info.json
2019-03-25 10:11:55 -04:00
rohithGoudM
9be102e1dd Fixed Unresponsive Select Step Box (#927)
* The cursor changes to pointer when hovered over select element

* Cursor to pointer changes added to demo.css

* adding csrtoptr class directly to dist file

* small bug in ui fixed through bootstrap

* small bug in ui fixed through bootstrap

* Fixed unresponsive bug in ui with bootstrap

* all changes have been deleted regarding the cursor bug. only unresponsive bug has been solved
2019-03-25 10:11:09 -04:00
Jeffrey Warren
b0a00a71d3 Update diagram (#921) 2019-03-24 12:08:57 -04:00
dependabot[bot]
001ad61954 Bump looks-same from 7.1.0 to 7.1.1 (#907)
Bumps [looks-same](https://github.com/gemini-testing/looks-same) from 7.1.0 to 7.1.1.
- [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/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2019-03-22 19:21:12 -04:00
Jeffrey Warren
ca8b7ecb95 Update CONTRIBUTING.md 2019-03-22 14:37:22 -04:00
Harshith pabbati
33dcb5794f clear cache offline button (#910) 2019-03-21 18:51:36 -04:00
Harshith pabbati
9ffd60c707 Seo tags for google search (#914)
* Seo tags for google search

* changes

* changes
2019-03-21 16:50:24 -04:00
Harsh Khandeparkar
32bd372139 Minify JS for production (#897)
* Create prod.js

* Delete prod.js

* add production task

* add grunt tasks to contributing file

* add default task.
2019-03-20 23:19:18 -04:00
Slytherin
bae2013243 Fixed quick buttons issue (#905) 2019-03-20 17:21:57 -04:00
Varun Gupta
cb53efbe21 redid import-image and fix ExportBin fixes #899 (#900)
* redid import-image and fix ExportBin fixes #899

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>

* 3.0.1

* bypass import-image

Signed-off-by: tech4GT <varun.gupta1798@gmail.com>
2019-03-20 13:53:02 -04:00
MAYANK CHHIPA
21ff486618 Add Dropdown Transitions (#881)
* Add Dropdown Transitions

* Add Dropdown Transitions

* Update defaultHtmlStepUi.js

* Add Dropdown Transitions

* Add Dropdown Transitions

* Add Dropdown Transitions
2019-03-19 15:28:05 -04:00
Harsh Khandeparkar
951afdbc4f add grunt build to setup script (#895) 2019-03-19 11:50:09 -04:00
aashna27
709df84cb2 Corrected view (#867) 2019-03-19 11:41:39 -04:00
Harsh Khandeparkar
f852730d98 Is Nightly Completed (#893)
* beta demo

* config.yml

* Update config.yml

* Update ISSUE_TEMPLATE.md

* Update package.json

* mistake

* mistake
2019-03-19 10:25:06 -04:00
Vibhor Gupta
e5cf6a311f Add: Exposure Module (#721)
* exposure module

* requested changes

* update module
2019-03-19 08:02:28 -04:00
69 changed files with 1970 additions and 92750 deletions

11
.codecov.yml Normal file
View File

@@ -0,0 +1,11 @@
comment:
layout: "reach, diff, flags, files"
behavior: default
require_changes: false # if true: only post the comment if coverage changes
require_base: no # [yes :: must have a base report to post]
require_head: yes # [yes :: must have a head report to post]
branches: null # branch names that can post comment
coverage:
status:
project: off
patch: off

View File

@@ -10,7 +10,7 @@
### Please show us where to look
http://sequencer.publiclab.org...
https://beta.sequencer.publiclab.org
### What's your PublicLab.org username?

View File

@@ -1,4 +1,4 @@
Fixes #[Add issue number here.]
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!

2
.github/config.yml vendored
View File

@@ -17,7 +17,7 @@ newPRWelcomeComment: |
# Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: |
Congrats on merging your first pull request! 🙌🎉⚡️
Your code will likely be published to https://sequencer.publiclab.org in the next few days.
Your code will be published to https://beta.sequencer.publiclab.org in a day or two.
In the meantime, can you tell us your Twitter handle so we can thank you properly?
Now that you've completed this, you can help someone else take their first step!
See: [Public Lab's coding community!](https://code.publiclab.org)

12
.github/first-timers.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# You can change the labels to suit your needs if "first-timers-only" is not what you are looking for.
# These are some examples.
labels:
- first-timers-only
- help wanted
#If you would like to add your own template for the issue, add an .md file to your .github folder
template: .github/fto-template.md
# You can create the issue in a different repo than where the problem is. Just make sure you installed the bot on the configured repository.
# The issue will link back to the original repository where the contribution will be made.
#repository: repo-name

51
.github/fto-template.md vendored Normal file
View File

@@ -0,0 +1,51 @@
Hi, this is a [first-timers-only issue](https://code.publiclab.org/#r=all). This means we've worked to make it more legible to folks who either **haven't contributed to our codebase before, or even folks who haven't contributed to open source before**.
If that's you, we're interested in helping you take the first step and can answer questions and help you out as you do. Note that we're especially interested in contributions from people from groups underrepresented in free and open source software!
We know that the process of creating a pull request is the biggest barrier for new contributors. This issue is for you 💝
If you have contributed before, **consider leaving this one for someone new**, and looking through our general [help wanted](https://github.com/publiclab/image-sequencer/labels/help-wanted) issues. Thanks!
### 🤔 What you will need to know.
Nothing. This issue is meant to welcome you to Open Source :) We are happy to walk you through the process.
### 📋 Step by Step
- [ ] 🙋 **Claim this issue**: Comment below. If someone else has claimed it, ask if they've opened a pull request already and if they're stuck -- maybe you can help them solve a problem or move it along!
- [ ] 📝 **Update** the file [$FILENAME]($BRANCH_URL) in the `$REPO` repository (press the little pen Icon) and edit the line as shown below.
[See this page](https://code.publiclab.org/#r=all) for some help in taking your first steps!
Below is a "diff" showing in red (and a `-`) which lines to remove, and in green (and a `+`) which lines to add:
```diff
$DIFF
```
- [ ] 💾 **Commit** your changes
- [ ] 🔀 **Start a Pull Request**. There are two ways how you can start a pull request:
1. If you are familiar with the terminal or would like to learn it, [here is a great tutorial](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) on how to send a pull request using the terminal.
2. You can also [edit files directly in your browser](https://help.github.com/articles/editing-files-in-your-repository/) and open a pull request from there.
- [ ] 🏁 **Done** Ask in comments for a review :)
### Please keep us updated
💬⏰ - We encourage contributors to be respectful to the community and provide an update **within a week** of claiming a first-timers-only issue. We're happy to keep it assigned to you as long as you need if you update us with a request for more time or help, but if we don't see any activity a week after you claim it we may reassign it to give someone else a chance. Thank you in advance!
If this happens to you, don't sweat it! Grab another open issue.
### Is someone else already working on this?
🔗- We encourage contributors to link to the original issue in their pull request so all users can easily see if someone's already started on it.
👥- **If someone seems stuck, offer them some help!** Otherwise, [take a look at some other issues you can help with](https://code.publiclab.org/#r=all). Thanks!
### 🤔❓ Questions?
Leave a comment below!

6
.gitignore vendored
View File

@@ -27,6 +27,10 @@ build/Release
node_modules
node_modules/*
# Dist Files
dist/*
dist
# Optional npm cache directory
.npm
@@ -45,4 +49,4 @@ test/core/modules/test_outputs/*
node_modules/
node_modules/*
test_outputs
/test_outputs
/test_outputs

View File

@@ -37,6 +37,8 @@ test.js
output.txt
output/
examples/
icons/

View File

@@ -15,6 +15,8 @@ script:
- npm test
- npm run test-ui
- grunt build
after_success:
- bash <(curl -s https://codecov.io/bash)
after_script:
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
addons:

View File

@@ -11,6 +11,7 @@ Most contribution (we imagine) would be in the form of API-compatible modules, w
* [Contributing Modules](#contributing-modules)
* [Info File](#info-file)
* [Ideas](#Contribution-ideas)
* [Grunt Tasks](#grunt-tasks)
****
@@ -26,7 +27,7 @@ If you find a bug please list it here, and help us develop Image Sequencer by [o
## Contributing modules
Most contributions can happen in modules, rather than to core library code. Modules and their [corresponding info files](#info-file) are included into the library in this file: https://github.com/publiclab/image-sequencer/blob/master/src/Modules.js#L5-L7
Most contributions can happen in modules, rather than to core library code. Modules and their [corresponding info files](#info-file) are included into the library in this file: https://github.com/publiclab/image-sequencer/blob/main/src/Modules.js#L5-L7
Module names, descriptions, and parameters are set in the `info.json` file -- [see below](#info-file).
@@ -62,6 +63,8 @@ Image Sequencer modules are designed to be run either in the browser or in a Nod
https://github.com/tech4gt/image-sequencer
### Browser/node compatibility
If you wish to offer a module without browser-compatibility, please indicate this in the returned `info` object as:
module.exports = [
@@ -108,7 +111,20 @@ function ModuleName(options,UI) {
// load a standard info.json file.
];
```
### Running a browser-only module in node
If your module has browser specific code or you are consuming a dependency which does the `gl-context` api. We designed this api especially for webl based modules but since it runs the module in a headless browser, ti supports all browser specific APIs.
The api must be used in the following format
```js
var step = this;
if (!options.inBrowser) {
require('../_nomodule/gl-context')(input, callback, step, options);
}
else {
/* Browser specific code */
}
```
### options
@@ -139,7 +155,7 @@ input = {
pixelManipulation: "general purpose pixel manipulation API, see https://github.com/publiclab/image-sequencer/blob/master/src/modules/_nomodule/PixelManipulation.js"
}
```
For example usage for pixelManipulation see https://github.com/publiclab/image-sequencer/blob/master/src/modules/Invert/Module.js
For example usage of pixelManipulation see https://github.com/publiclab/image-sequencer/blob/main/src/modules/Invert/Module.js
**The module is included in the browser inside a script tag and since the code runs directly in the browser if any other module is required apart from the apis available on the input object, it should be either bundled with the module code and imported in es6 format or the module code must be browserified before distribution for browser**
@@ -261,9 +277,9 @@ The `progressObj` parameter of `draw()` is not consumed unless a custom progress
### Module example
See existing module `green-channel` for an example: https://github.com/publiclab/image-sequencer/tree/master/src/modules/GreenChannel/Module.js
See existing module `channel` for an example: https://github.com/publiclab/image-sequencer/blob/main/src/modules/Channel/Module.js
The `green-channel` module is included into the core modules here: https://github.com/publiclab/image-sequencer/blob/master/src/Modules.js#L5-L7
The `channel` module is included into the core modules here: https://github.com/publiclab/image-sequencer/blob/main/src/Modules.js#L5-L7
For help integrating, please open an issue.
@@ -345,4 +361,17 @@ module.exports =
}
}
});
```
```
## Grunt Tasks
This repository has different grunt tasks for different uses. The source code is in the [Gruntfile](https://github.com/publiclab/image-sequencer/blob/main/Gruntfile.js).
The following command is used for running the tasks: `grunt [task-name]`. Here `[task-name]` should be replaced by the name of the task to be run. To run the default task run `grunt` without any options.
#### Tasks
1. **compile**: Compiles/Browserifies the dist files in `/dist/image-sequencer.js` and `/dist/image-sequencer-ui.js`.
2. **build**: Compiles the files as in the **compile** task and minifies/uglifies dist files in `/dist/image-sequencer.min.js` and `/dist/image-sequencer-ui.min.js`.
3. **watch**: Checks for any changes in the source code and runs the **compile** task if any changes are found.
4. **serve**: Compiles the dist files as in the **compile** task and starts a local server on `localhost:3000` to host the demo site in `/examples/` directory. Also runs the **watch** task.
5. **production**: Compiles and minifies dist files in `/dist/image-sequencer.js` and `/dist/image-sequencer-ui.js` without the `.min.js` extension to include minified files in the demo site. This script should only be used in production mode while deploying.
6. **default**: Runs the **watch** task as default.

View File

@@ -15,8 +15,8 @@ module.exports = function(grunt) {
livereload: true
},
source: {
files: ["src/**/*", "Gruntfile.js", "examples/lib/*","examples/demo.js"],
tasks: ["browserify"]
files: ["src/**/*", "Gruntfile.js", "examples/lib/*", "examples/demo.js"],
tasks: ["compile"]
}
},
@@ -24,10 +24,18 @@ module.exports = function(grunt) {
core: {
src: ["src/ImageSequencer.js"],
dest: "dist/image-sequencer.js"
},
},
ui: {
src: ["examples/demo.js"],
dest: "dist/image-sequencer-ui.js"
},
prodcore: {
src: ["src/ImageSequencer.js"],
dest: "dist/image-sequencer.brow.js"
},
produi: {
src: ["examples/demo.js"],
dest: "dist/image-sequencer-ui.brow.js"
}
},
@@ -39,6 +47,14 @@ module.exports = function(grunt) {
ui: {
src: ['dist/image-sequencer-ui.js'],
dest: 'dist/image-sequencer-ui.min.js'
},
prodcore: {
src: ["dist/image-sequencer.brow.js"],
dest: "dist/image-sequencer.js"
},
produi: {
src: ["dist/image-sequencer-ui.brow.js"],
dest: "dist/image-sequencer-ui.js"
}
},
browserSync: {
@@ -53,7 +69,8 @@ module.exports = function(grunt) {
/* Default (development): Watch files and build on change. */
grunt.registerTask("default", ["watch"]);
grunt.registerTask("build", ["browserify", "uglify"]);
grunt.registerTask("serve", ["browserify", "browserSync", "watch"]);
grunt.registerTask("compile", ["browserify"]);
grunt.registerTask("build", ["browserify:core", "browserify:ui", "uglify:core", "uglify:ui"]);
grunt.registerTask("serve", ["browserify:core", "browserify:ui", "browserSync", "watch"]);
grunt.registerTask("compile", ["browserify:core", "browserify:ui"]);
grunt.registerTask("production", ["browserify:prodcore", "browserify:produi", "uglify:prodcore", "uglify:produi"]);
};

View File

@@ -1,7 +1,12 @@
Image Sequencer
====
[![Build Status](https://travis-ci.org/publiclab/image-sequencer.svg?branch=master)](https://travis-ci.org/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)
- **Latest Stable Demo**: https://sequencer.publiclab.org
- **Latest Beta Demo**: https://beta.sequencer.publiclab.org
- **Stable Branch**: https://github.com/publiclab/image-sequencer/tree/stable/
## Why
@@ -14,9 +19,9 @@ Image Sequencer is different from other image processing systems because it's _n
The following diagrams attempt to explain how the applications various components interconnect:
![general diagram](https://i.imgur.com/S3Dou2M.jpg)
![general diagram](https://publiclab.org/i/30547.png?s=o)
![workflow diagram](https://raw.githubusercontent.com/publiclab/image-sequencer/master/examples/images/diagram-workflows.png)
![workflow diagram](https://raw.githubusercontent.com/publiclab/image-sequencer/main/examples/images/diagram-workflows.png)
It also for prototypes other related ideas:
@@ -24,15 +29,17 @@ It also for prototypes other related ideas:
* test-based image processing -- the ability to create a sequence of steps that do the same task as other image processing tools, provable with example before/after images to compare with
* logging each step -- to produce an evidentiary record of modifications to an original image
* cascading changes -- change an earlier step's settings, and see those changes affect later steps
* "small modules" -- based extensibility: see [Contributing](https://github.com/publiclab/image-sequencer/blob/master/CONTRIBUTING.md)
* "small modules" -- based extensibility: see [Contributing](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md)
## Examples
* [Simple Demo](https://publiclab.github.io/image-sequencer/)
* [Simple Demo](https://sequencer.publiclab.org)
* [Latest Beta Demo](https://beta.sequencer.publiclab.org)
A diagram of this running 5 steps on a single sample image may help explain how it works:
![example workflow](https://raw.githubusercontent.com/publiclab/image-sequencer/master/examples/images/diagram-6-steps.png)
![example workflow](https://raw.githubusercontent.com/publiclab/image-sequencer/main/examples/images/diagram-6-steps.png)
## Jump to:
@@ -43,8 +50,8 @@ A diagram of this running 5 steps on a single sample image may help explain how
* [Method Chaining](#method-chaining)
* [Multiple Images](#multiple-images)
* [Creating a User Interface](#creating-a-user-interface)
* [Contributing](https://github.com/publiclab/image-sequencer/blob/master/CONTRIBUTING.md)
* [Submit a Module](https://github.com/publiclab/image-sequencer/blob/master/CONTRIBUTING.md#contributing-modules)
* [Contributing](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md)
* [Submit a Module](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md#contributing-modules)
* [Get Demo Bookmarklet](https://publiclab.org/w/imagesequencerbookmarklet)
## Installation
@@ -52,12 +59,12 @@ A diagram of this running 5 steps on a single sample image may help explain how
This library conveniently works in the browser, in Node, and on the command line (CLI).
### Unix based platforms
You can set up a local environment to test the UI with `sudo npm run setup` followed by `npm start`
You can set up a local environment to test the UI with `npm run setup` followed by `npm start`.
### Windows
Our npm scripts do not support windows shells, please run the following snippet in PowerShell.
```powershell
npm i ; npm i -g grunt grunt-cli ; grunt serve
npm i ; npm i -g grunt grunt-cli ; grunt build; grunt serve
```
In case of a port conflict please run the following
```powershell
@@ -66,12 +73,12 @@ npm i -g http-server ; http-server -p 3000
### Browser
Just include [image-sequencer.js](https://publiclab.github.io/image-sequencer/dist/image-sequencer.js) in the Head section of your web page. See the [demo here](https://publiclab.github.io/image-sequencer/)!
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)!
### Node (via NPM)
(You must have NPM for this)
Add `image-sequencer` to your list of dependencies and run `$ npm install`
Add `image-sequencer` to your list of dependencies and run `npm install`
### CLI

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

73614
dist/image-sequencer.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -37,7 +37,8 @@ List of Module Documentations
32. [Saturation](#saturation-module)
33. [Threshold](#threshold)
34. [Tint](#tint)
35. [WhiteBalance](#white-balance)
35. [ColorTemperature](#color-temperature)
36. [Grid-Overlay](#grid-overlay)
## crop-module
@@ -571,17 +572,32 @@ where `options` is an object with the following property:
* factor : amount of tint (default 0.5)
## White Balance
## Color Temperature
This Change the colour balance of the image by adjusting the colour temperature.
This changes the color temperature of the image.
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('white-balance',options)
.addSteps('color-temperature',options)
.run()
```
where `options` is an object with the following property:
* temperature : temperature between 0 - 40,000 kelvin (default 6000)
## Grid Overlay
This adds the grid over an image.
## Usage
```js
sequencer.loadImage('PATH')
.addSteps('grid-overlay',options)
.run()
```
where `options` is an object with the following property:
* options.x : The value at which the grid line should start in x-axis.
* options.y : The value at which the grid line should start in y-axis.
* color : Color for the grid on the image.

View File

@@ -1,14 +1,14 @@
/* https://github.com/theleagueof/league-spartan */
@font-face {
font-family: 'League Spartan';
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot');
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot?#iefix') format('embedded-opentype'),
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-style: normal;
font-family: 'League Spartan';
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot');
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot?#iefix') format('embedded-opentype'),
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-style: normal;
}
body {
@@ -18,11 +18,19 @@ body {
background: #f8f8fa;
}
footer {
margin-top: 40px;
}
h1 {
font-family: 'League Spartan';
color: #445;
}
body > .container,
body > .container-fluid {
}
.center-align {
display: flex;
justify-content: center;
@@ -71,17 +79,6 @@ h1 {
margin-bottom: 20px;
}
.details {
border-top: 3px solid #444;
padding-left: 6px;
}
.details h3 {
font-family: monospace;
margin-top: 12px;
font-size: 1.3em;
}
.det {
padding: 10px 16px;
text-decoration: italic;
@@ -100,11 +97,6 @@ h1 {
color: #444;
}
.load-spin{
position: absolute;
right: 0px;
}
#addStep {
max-width: 500px;
margin: 20px auto;
@@ -159,19 +151,19 @@ h1 {
}
#move-up {
position: fixed;
bottom: 50px;
right: 40px;
z-index: 550;
display: none;
background:transparent;
border:none;
position: fixed;
bottom: 50px;
right: 40px;
z-index: 550;
display: none;
background:transparent;
border:none;
}
#move-up i {
font-size:60px;
opacity:0.7;
color:#BABABA;
font-size:60px;
opacity:0.7;
color:#BABABA;
}
.btn-circle{
@@ -208,7 +200,7 @@ h1 {
.savesequencemsg{
display: none;
text-align: center;
}
}
.notification {
background-color: #808b96;
@@ -251,14 +243,32 @@ a.name-header{
color: #445;
}
.step-column{
display:flex;
flex-direction:row;
align-items:center;
.step-column{
display:flex;
align-content: center;
justify-content: center;
}
.step-image{
width:100%;
display:flex;
flex-direction:column;
align-items:center;
.trash-container button.btn-xs {
margin-top: -5px !important;
}
.toggleIcon {
transition: transform 0.2s;
}
.rotated {
transform: rotate(180deg);
}
#gif{
margin-left:0px;
margin-top:5px;
width:100%;
}
.save-button{
margin-top:20px;
margin-bottom:0px;
align:center;
width:100%;
}

View File

@@ -23,7 +23,7 @@ window.onload = function() {
);
}
// Null option
addStepSelect.append('<option value="none" disabled selected>More modules...</option>');
addStepSelect.append('<option value="" disabled selected>Select a Module</option>');
addStepSelect.selectize({
sortField: 'text'
});
@@ -79,8 +79,8 @@ window.onload = function() {
newStep = $(this).attr('data-value');
//$("#addStep option[value=" + newStep + "]").attr('selected', 'selected');
$("#addStep select").val(newStep);
ui.selectNewStepUi();
ui.addStepUi();
ui.selectNewStepUi(newStep);
ui.addStepUi(newStep);
$(this).removeClass('selected');
});
@@ -118,7 +118,7 @@ window.onload = function() {
var button = event.target;
button.disabled = true;
button.innerHTML='<i class="fa fa-circle-o-notch fa-spin"></i>'
try {
// Select all images from previous steps
@@ -170,6 +170,7 @@ window.onload = function() {
modal.modal();
button.disabled = false;
button.innerHTML = 'View GIF';
isWorkingOnGifGeneration = false;
}
});
@@ -177,6 +178,7 @@ window.onload = function() {
catch (e) {
console.error(e);
button.disabled = false;
button.innerHTML = 'View GIF';
isWorkingOnGifGeneration = false;
}
@@ -197,8 +199,8 @@ window.onload = function() {
step.options.step.imgElement.src = reader.result;
else
step.imgElement.src = reader.result;
insertPreview.updatePreviews(reader.result,'addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src,'insertStep');
insertPreview.updatePreviews(reader.result,'#addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src,'.insertDiv');
},
onTakePhoto: function (url) {
var step = sequencer.steps[0];
@@ -208,16 +210,16 @@ window.onload = function() {
step.options.step.imgElement.src = url;
else
step.imgElement.src = url;
insertPreview.updatePreviews(url,'addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src,'insertStep');
insertPreview.updatePreviews(url,'#addStep');
insertPreview.updatePreviews(sequencer.steps[0].imgElement.src,'.insertDiv');
}
});
setupCache();
if (urlHash.getUrlHashParameter('src')) {
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'),'addStep');
insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'),'#addStep');
} else {
insertPreview.updatePreviews("images/tulips.png",'addStep');
insertPreview.updatePreviews("images/tulips.png",'#addStep');
}
};
};

View File

@@ -2,7 +2,6 @@
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -10,6 +9,11 @@
<meta name="theme-color" content="#428bca">
<link rel="icon" sizes="192x192" href="../icons/ic_192.png">
<link rel="manifest" href="manifest.json">
<!--Adding meta Tag for search engine optimisation-->
<meta property="og:description" content="A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original image, it creates a new image at each step in a sequence.">
<meta property="og:site_name" content="sequencer.publiclab.org">
<meta property="og:url" content="https://sequencer.publiclab.org">
<meta property="og:title" content="Image Sequencer">
<title>Image Sequencer</title>
@@ -29,7 +33,6 @@
<script src="../node_modules/selectize/dist/js/standalone/selectize.min.js"></script>
</head>
<body>
<link href="../node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
@@ -124,12 +127,16 @@
<p>Crop</p>
</div>
</div>
<div class="center-align">
<div class="row center-align">
<div class="col-md-8">
<select id="selectStep" >
<!-- The default null selection has been appended manually in demo.js
This is because the options in select are overritten when options are appended.-->
</select>
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button>
</div>
<div class="col-md-4">
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button></div>
</div>
<div class="row center-align">
<button id="resetButton" class="btn btn-default btn-lg" style=" margin: 20px 35px 0px 35px; width:100%;">Clear All Steps</button>
@@ -138,39 +145,26 @@
</div>
</section>
<section id="sequence-actions" class="panel">
<div class="panel-body">
<div class="row center-align">
<!--<button class="btn btn-primary btn-block btn-lg" name="save-sequence" id="save-seq">Save Sequence</button> -->
<!--<button class="btn btn-primary btn-block btn-lg" id="download-btn" name="download" style="display: block; margin: 0px 10px 0px 0px; width: 250px;">Download PNG</button> -->
<button class="btn btn-primary btn-block btn-lg js-view-as-gif" id="gif" style="margin: 0px 35px 0px 35px;width:100%;">View GIF</button>
</div>
<div class="modal fade" id="js-download-gif-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Your gif is ready</h4>
</div>
<div class="modal-body">
<div id="js-download-modal-gif-container">
<!-- Gif should appear here -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Done</button>
<button id="js-download-as-gif-button" class="btn btn-primary">Download</button>
</div>
<div class="modal fade" id="js-download-gif-modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Your gif is ready</h4>
</div>
<div class="modal-body">
<div id="js-download-modal-gif-container">
<!-- Gif should appear here -->
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Done</button>
<button id="js-download-as-gif-button" class="btn btn-primary">Download</button>
</div>
</div>
</div>
</section>
</div>
</div>
<div class="col-sm-4">
@@ -179,14 +173,14 @@
<div class="panel-body">
<div style="text-align:center;">
<h2 style="margin-top:20px">Save</h2>
<p>Or click ARROW to save the entire sequence as a workflow for future use.</p>
<select class="form-control input-md" id="selectSaveOption" style="margin-top:20px">
<option>Save as PNG</option>
<option>Save as GIF (all steps)</option>
<option>Save sequence</option>
<option>Save sequence string</option>
</select>
<button id="saveButton" class="btn btn-primary btn-lg" style="margin-top:20px; margin-bottom:0px;align:center; width:100%;">Save</button>
<select class="form-control input-md" id="selectSaveOption" style="margin-top:20px">
<option>Save as PNG</option>
<option>Save as GIF (all steps)</option>
<option>Save sequence</option>
<option>Save sequence string</option>
</select>
<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>
</div>
</div>
</div>
@@ -195,24 +189,22 @@
</div>
<footer>
<hr style="margin:20px;"><center><a class="color:grey;" id="clear-cache">Clear offline cache</a></center>
<hr style="margin:20px;"><center><button class="btn btn-default btn-sm" id="clear-cache">Clear offline cache</button></center>
<div class="row">
<div class="col-md-6">
<h2>Need Help?</h2>
<p>
Post a link to this and ask help from other community members on <a href="https://github.com/publiclab/image-sequencer/issues/new">Github Issues</a>
</p>
<p>
<a class="btn btn-primary" href="https://gitter.im/publiclab/publiclab">Ask a question on Gitter</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>
</p>
</div>
<div class="col-md-6">
<h2>Improve this tool</h2>
<p>
This is an open source toolkit which you can help add to and improve on <a href="https://github.com/publiclab/image-sequencer/">Github</a>
This is an open source toolkit which you can help improve on Github
</p>
<p>
<a class="btn btn-primary" href="https://github.com/publiclab/image-sequencer">View the code &raquo;</a>
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer">View the code &raquo;</a>
</p>
</div>
</div>

View File

@@ -36,4 +36,4 @@ var setupCache = function() {
});
}
module.exports = setupCache;
module.exports = setupCache;

View File

@@ -26,6 +26,7 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
function selectNewStepUi() {
var m = $(addStepSel + " select").val();
if(!m) m = arguments[0];
$(addStepSel + " .info").html(_sequencer.modulesInfo(m).description);
$(addStepSel + " #add-step-btn").prop("disabled", false);
}
@@ -43,6 +44,8 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
if ($(addStepSel + " select").val() == "none") return;
var newStepName = $(addStepSel + " select").val();
if(!newStepName) newStepName = arguments[0]
/*
* after adding the step we run the sequencer from defined step

View File

@@ -25,46 +25,50 @@ function DefaultHtmlStepUi(_sequencer, options) {
step.ui =
'\
<div class="container">\
<div class="row step" style="display:flex">\
<form class="input-form">\
<div class="col-md-4 details" style="flex:1">\
<h3>\
<span class = "toggle">' +step.name + ' <i class="fa fa-caret-up toggleIcon" aria-hidden="true"></i></span>' +
'<span class="load-spin" style="display:none;"><i class="fa fa-circle-o-notch fa-spin"></i></span>' +
'</h3><div class="cal"><p><i>"'+
(step.description || "") +
'</i></p></div>\
</div>\
</form>\
<div class="col-md-8 cal step-column">\
<div class="load" style="display:none;"><i class="fa fa-circle-o-notch fa-spin"></i></div>\
<div class="step-image">\
<a><img alt="" class="img-thumbnail step-thumbnail"/></a>\
</div>\
</div>\
</div>\
</div>\
</div>';
<div class="container-fluid step-container">\
<div class="panel panel-default">\
<div class="panel-heading">\
<div class="trash-container pull-right"></div>\
<h3 class="panel-title">' +
'<span class="toggle">' +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>\
</h3>\
</div>\
<form class="input-form">\
<div class="panel-body cal collapse in">\
<div class="row step">\
<div class="col-md-4 details container-fluid">\
<div class="cal collapse in"><p>' +
'<i>' + (step.description || "") + '</i>' +
'</p></div>\
</div>\
<div class="col-md-8 cal collapse in step-column">\
<div class="load load-spin" style="display:none;"><i class="fa fa-circle-o-notch fa-spin"></i></div>\
<div class="step-image">\
<a class="cal collapse in"><img class="img-thumbnail step-thumbnail"/></a>\
</div>\
</div>\
</div>\
</div>\
<div class="panel-footer cal collapse in"></div>\
</form>\
</div>\
</div>';
var tools =
'<div class="cal"><div class="tools btn-group">\
<button confirm="Are you sure?" class="remove btn btn btn-default">\
<i class="fa fa-trash"></i>\
</button>\
<button class="btn insert-step" style="margin-left:10px;border-radius:6px;background-color:#fff;border:solid #bababa 1.1px;" >\
<i class="fa fa-plus"></i> Add\
</button>\
</div>\
'<div class="trash">\
<button confirm="Are you sure?" class="remove btn btn-default btn-xs">\
<i class="fa fa-trash"></i>\
</button>\
</div>';
var util = intermediateHtmlStepUi(_sequencer, step);
var parser = new DOMParser();
step.ui = parser.parseFromString(step.ui, "text/html");
step.ui = step.ui.querySelector("div.container");
step.ui = step.ui.querySelector("div.container-fluid");
step.linkElements = step.ui.querySelectorAll("a");
step.imgElement = step.ui.querySelector("a img");
step.imgElement = step.ui.querySelector("a img.img-thumbnail");
if (_sequencer.modulesInfo().hasOwnProperty(step.name)) {
var inputs = _sequencer.modulesInfo(step.name).inputs;
@@ -113,7 +117,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
div.setAttribute("name", paramName);
var description = inputs[paramName].desc || paramName;
div.innerHTML =
"<div class='det cal'>\
"<div class='det cal collapse in'>\
<label for='" +
paramName +
"'>" +
@@ -125,29 +129,30 @@ function DefaultHtmlStepUi(_sequencer, options) {
</div>";
step.ui.querySelector("div.details").appendChild(div);
}
$(step.ui.querySelector("div.details")).append(
'<div class="cal"><p><button type="submit" class="btn btn-default btn-save" disabled = "true" >Apply</button><span> Press apply to see changes</span></p></div>'
$(step.ui.querySelector("div.panel-footer")).append(
'<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.ui.querySelector("div.panel-footer")).prepend(
'<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>'
);
}
if (step.name != "load-image") {
step.ui
.querySelector("div.details")
.appendChild(
.querySelector("div.trash-container")
.prepend(
parser.parseFromString(tools, "text/html").querySelector("div")
);
$(step.ui.querySelectorAll(".remove")).on('click', function() {notify('Step Removed','remove-notification')});
$(step.ui.querySelectorAll(".insert-step")).on('click', function() { util.insertStep(step.ID) });
$(step.ui.querySelectorAll(".insert-step")).on('click', function() { util.insertStep(step.ID) });
// Insert the step's UI in the right place
if (stepOptions.index == _sequencer.steps.length) {
stepsEl.appendChild(step.ui);
$("#steps .container:nth-last-child(1) .insert-step").prop('disabled',true);
if($("#steps .container:nth-last-child(2)"))
$("#steps .container:nth-last-child(2) .insert-step").prop('disabled',false);
$("#steps .step-container:nth-last-child(1) .insert-step").prop('disabled',true);
if($("#steps .step-container:nth-last-child(2)"))
$("#steps .step-container:nth-last-child(2) .insert-step").prop('disabled',false);
} else {
stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]);
}
@@ -156,8 +161,8 @@ function DefaultHtmlStepUi(_sequencer, options) {
$("#load-image").append(step.ui);
}
$(step.ui.querySelector(".toggle")).on("click", () => {
$(step.ui.querySelector('.toggleIcon')).toggleClass('fa-caret-up').toggleClass('fa-caret-down');
$(step.ui.querySelectorAll(".cal")).toggleClass("collapse");
$(step.ui.querySelector('.toggleIcon')).toggleClass('rotated');
$(step.ui.querySelectorAll(".cal")).collapse('toggle');
});
$(step.imgElement).on("mousemove", _.debounce(() => imageHover(step), 150));
@@ -225,16 +230,13 @@ function DefaultHtmlStepUi(_sequencer, options) {
function onDraw(step) {
$(step.ui.querySelector(".load")).show();
$(step.ui.querySelector("img")).hide();
if( $(step.ui.querySelector(".toggleIcon")).hasClass("fa-caret-down") )
{
$(step.ui.querySelector(".load-spin")).show();
}
$(step.ui.querySelectorAll(".load-spin")).show();
}
function onComplete(step) {
$(step.ui.querySelector(".load")).hide();
$(step.ui.querySelector("img")).show();
$(step.ui.querySelector(".load-spin")).hide();
$(step.ui.querySelectorAll(".load-spin")).hide();
$(step.ui.querySelector(".load")).hide();
step.imgElement.src = (step.name == "load-image") ? step.output.src : step.output;
var imgthumbnail = step.ui.querySelector(".img-thumbnail");
@@ -299,7 +301,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
function onRemove(step) {
step.ui.remove();
$("#steps .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();
}
@@ -319,7 +321,8 @@ function DefaultHtmlStepUi(_sequencer, options) {
$('#'+id).fadeIn(500).delay(200).fadeOut(500);
}
return {
getPreview: getPreview,
onSetup: onSetup,

View File

@@ -8,7 +8,7 @@ function generatePreview(previewStepName, customValues, path, selector) {
img.src = src;
$(img).css("max-width", "200%");
$(img).css("transform", "translateX(-20%)");
var stepDiv = $('#'+selector+' .row').find('div').each(function() {
$(selector + ' .radio-group').find('div').each(function() {
if ($(this).find('div').attr('data-value') === previewStepName) {
$(this).find('div').append(img);
}
@@ -27,7 +27,7 @@ function generatePreview(previewStepName, customValues, path, selector) {
}
function updatePreviews(src, selector) {
$('#'+selector+' img').remove();
$(selector+' img').remove();
var previewSequencerSteps = {
"resize": "125%",

View File

@@ -3,81 +3,109 @@ var urlHash = require('./urlHash.js'),
function IntermediateHtmlStepUi(_sequencer, step, options) {
function stepUI() {
return '<div class="row insertDiv">\
<div class="col-md-6 col-md-offset-2" style="margin-top:5%">\
<section id="insertStep" class="panel panel-primary">\
<div class="form-inline">\
<div class="panel-body">\
<p class="info">Select a new module to add to your sequence.</p>\
<div class="row center-align radio-group">\
<div>\
<div class="radio" data-value="resize">\
<i class="fa fa-arrows-alt fa-4x i-over"></i>\
</div>\
<p>Resize</p>\
return '<div class="row insertDiv collapse">\
<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>\
<div class="form-inline">\
<div class="panel-body">\
<p class="info">Select a new module to add to your sequence.</p>\
<div class="row center-align radio-group">\
<div>\
<div class="radio" data-value="resize">\
<i class="fa fa-arrows-alt fa-4x i-over"></i>\
</div>\
<p>Resize</p>\
</div>\
<div>\
<div class="radio" data-value="brightness">\
<i class="fa fa-sun-o fa-4x i-over"></i>\
</div>\
<p>Brightness</p>\
</div>\
<div>\
<div class="radio" data-value="contrast">\
<i class="fa fa-adjust fa-4x i-over"></i>\
</div>\
<p>Contrast</p>\
</div>\
<div>\
<div class="radio" data-value="saturation">\
<i class="fa fa-tint fa-4x i-over i-small"></i>\
</div>\
<p>Saturation</p>\
</div>\
<div>\
<div class="radio" data-value="rotate">\
<i class="fa fa-rotate-right fa-4x i-over"></i>\
</div>\
<p>Rotate</p>\
</div>\
<div>\
<div class="radio" data-value="crop">\
<i class="fa fa-crop fa-4x i-over"></i>\
</div>\
<p>Crop</p>\
</div>\
</div>\
<div>\
<div class="radio" data-value="brightness">\
<i class="fa fa-sun-o fa-4x i-over"></i>\
</div>\
<p>Brightness</p>\
<div class="row center-align">\
<div class="col-md-8">\
<select class="insert-step-select">\
<!-- The default null selection has been appended manually in demo.js\
This is because the options in select are overritten when options are appended.-->\
</select>\
<div>\
<div class="col-md-4">\
<button class="btn btn-success btn-lg insert-save-btn add-step-btn" name="add">Add Step</button>\
<div>\
</div>\
<div>\
<div class="radio" data-value="contrast">\
<i class="fa fa-adjust fa-4x i-over"></i>\
</div>\
<p>Contrast</p>\
</div>\
<div>\
<div class="radio" data-value="saturation">\
<i class="fa fa-tint fa-4x i-over i-small"></i>\
</div>\
<p>Saturation</p>\
</div>\
<div>\
<div class="radio" data-value="rotate">\
<i class="fa fa-rotate-right fa-4x i-over"></i>\
</div>\
<p>Rotate</p>\
</div>\
<div>\
<div class="radio" data-value="crop">\
<i class="fa fa-crop fa-4x i-over"></i>\
</div>\
<p>Crop</p>\
</div>\
</div>\
<div class="center-align">\
<select class="form-control input-lg" id="selectStep">\
<!-- The default null selection has been appended manually in demo.js\
This is because the options in select are overritten when options are appended.-->\
</select>\
<button class="btn btn-success btn-lg" name="add" id="add-step-btn">Add Step</button>\
</div>\
</div>\
</div>\
</section>\
</section>\
</div>';
}
function selectNewStepUi() {
var m = $("#insertStep select").val();
$("#insertStep .info").html(_sequencer.modulesInfo(m).description);
$("#insertStep #add-step-btn").prop("disabled", false);
var insertSelect = $(step.ui.querySelector('.insert-step-select'))
var m = insertSelect.val();
$(step.ui.querySelector('.insertDiv .info')).html(_sequencer.modulesInfo(m).description);
$(step.ui.querySelector('.insertDiv .add-step-btn')).prop("disabled", false);
}
var toggleDiv = function(callback = function(){}){
$(step.ui.querySelector('.insertDiv')).collapse('toggle');
if ($(step.ui.querySelector('.insert-text')).css('display') != "none"){
$(step.ui.querySelector('.insert-text')).fadeToggle(200, function(){$(step.ui.querySelector('.no-insert-text')).fadeToggle(200, callback)})
}
else {
$(step.ui.querySelector('.no-insert-text')).fadeToggle(200, function(){$(step.ui.querySelector('.insert-text')).fadeToggle(200, callback)})
}
}
insertStep = function (id) {
var modulesInfo = _sequencer.modulesInfo();
var parser = new DOMParser();
var addStepUI = stepUI();
addStepUI = parser.parseFromString(addStepUI, "text/html").querySelector("div")
step.ui
if ($(step.ui.querySelector('.insertDiv')).length > 0){
toggleDiv();
}
else {
step.ui
.querySelector("div.step")
.insertAdjacentElement('afterend',
addStepUI
);
insertPreview.updatePreviews(step.output,'insertStep');
var insertStepSelect = $("#insertStep select");
toggleDiv(function(){
insertPreview.updatePreviews(step.output, '.insertDiv');
});
}
$(step.ui.querySelector('.insertDiv .close-insert-box')).off('click').on('click', function(){toggleDiv(function(){})});
var insertStepSelect = $(step.ui.querySelector('.insert-step-select'));
insertStepSelect.html("");
// Add modules to the insertStep dropdown
for (var m in modulesInfo) {
@@ -86,33 +114,33 @@ function IntermediateHtmlStepUi(_sequencer, step, options) {
'<option value="' + m + '">' + modulesInfo[m].name + "</option>"
);
}
$('#insertStep #add-step-btn').selectize({
insertStepSelect.selectize({
sortField: 'text'
});
$('#insertStep #add-step-btn').prop('disabled', true);
insertStepSelect.append('<option value="none" disabled selected>More modules...</option>');
$('#insertStep .radio-group .radio').on("click", function () {
$(step.ui.querySelector('.inserDiv .add-step-btn')).prop('disabled', true);
insertStepSelect.append('<option value="" disabled selected>Select a Module</option>');
$(step.ui.querySelector('.insertDiv .radio-group .radio')).on("click", function () {
$(this).parent().find('.radio').removeClass('selected');
$(this).addClass('selected');
newStep = $(this).attr('data-value');
insertStepSelect.val(newStep);
$(step.ui.querySelector('.insert-step-select')).val(newStep);
selectNewStepUi();
insert(id);
$(this).removeClass('selected');
});
$(step.ui.querySelector("#insertStep select")).on('change', selectNewStepUi);
$(step.ui.querySelector("#insertStep #add-step-btn")).on('click', function () { insert(id) });
insertStepSelect.on('change', selectNewStepUi);
$(step.ui.querySelector('.insertDiv .add-step-btn')).on('click', function () { insert(id) });
}
function insert(id) {
options = options || {};
var insertStepSelect = $("#insertStep select");
var insertStepSelect = $(step.ui.querySelector('.insert-step-select'));
if (insertStepSelect.val() == "none") return;
var newStepName = insertStepSelect.val()
$('div .insertDiv').remove();
toggleDiv();
var sequenceLength = 1;
if (sequencer.sequences[newStepName]) {
sequenceLength = sequencer.sequences[newStepName].length;

View File

@@ -32,4 +32,4 @@ self.addEventListener('fetch', function(event) {
});
})
);
});
});

1076
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,13 @@
{
"name": "image-sequencer",
"version": "3.0.0",
"version": "3.0.1",
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
"main": "src/ImageSequencer.js",
"scripts": {
"debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert",
"test": "TEST=true tape test/core/*.js test/core/ui/user-interface.js test/core/modules/QR.js | tap-spec; browserify test/core/modules/image-sequencer.js test/core/modules/chain.js test/core/modules/meta-modules.js test/core/modules/replace.js test/core/modules/import-export.js test/core/modules/run.js test/core/modules/dynamic-imports.js test/core/util/parse-input.js test/core/modules/benchmark.js| tape-run --render=\"tap-spec\"",
"test": "TEST=true istanbul cover tape test/core/*.js test/core/ui/user-interface.js test/core/modules/canvas-resize.js test/core/modules/QR.js | tap-spec; browserify test/core/modules/image-sequencer.js test/core/modules/chain.js test/core/modules/meta-modules.js test/core/modules/replace.js test/core/modules/import-export.js test/core/modules/run.js test/core/modules/dynamic-imports.js test/core/util/parse-input.js test/core/modules/benchmark.js| tape-run --render=\"tap-spec\"",
"test-ui": "jasmine test/spec/*.js",
"setup": "npm i && npm i -g grunt grunt-cli",
"setup": "npm i && npm i -g grunt grunt-cli && grunt build",
"start": "grunt serve"
},
"repository": {
@@ -31,18 +31,22 @@
"downloadjs": "^1.4.7",
"fisheyegl": "^0.1.2",
"font-awesome": "~4.7.0",
"geotiff": "^1.0.0-beta.6",
"get-pixels": "~3.3.0",
"gifshot": "^0.4.5",
"image-sequencer-invert": "^1.0.0",
"imagejs": "0.0.9",
"imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2",
"istanbul": "^0.4.5",
"jquery": "^3.3.1",
"jsdom": "^13.1.0",
"jsdom": "^14.0.0",
"jsqr": "^1.1.1",
"lodash": "^4.17.11",
"ndarray": "^1.0.18",
"ndarray-gaussian-filter": "^1.0.0",
"ora": "^3.0.0",
"pace": "0.0.4",
"puppeteer": "^1.14.0",
"qrcode": "^1.3.3",
"readline-sync": "^1.4.7",
"save-pixels": "~2.3.4",
@@ -70,7 +74,7 @@
"tape-run": "^5.0.0",
"uglify-es": "^3.3.7"
},
"homepage": "https://github.com/publiclab/image-sequencer",
"homepage": "https://sequencer.publiclab.org",
"bin": {
"sequencer": "./index.js"
}

View File

@@ -32,11 +32,11 @@ module.exports = function ExportBin(dir = "./output/", ref, basic, filename) {
if (err) console.error(err)
});
if (filename && basic) {
var steps = ref.steps;
var datauri = steps.slice(-1)[0].output.src;
var ext = steps.slice(-1)[0].output.format;
var buffer = require('data-uri-to-buffer')(datauri);
fs.writeFile(dir + filename, buffer, function() { });
var steps = ref.steps;
var datauri = steps.slice(-1)[0].output.src;
var ext = steps.slice(-1)[0].output.format;
var buffer = require('data-uri-to-buffer')(datauri);
fs.writeFile(dir + filename, buffer, function() { });
}
else {
getDirectories(dir, function(dirs) {
@@ -48,21 +48,21 @@ module.exports = function ExportBin(dir = "./output/", ref, basic, filename) {
}
fs.mkdir(dir + 'sequencer' + num, function() {
var root = dir + 'sequencer' + num + '/';
var steps = ref.steps;
if (basic) {
var datauri = steps.slice(-1)[0].output.src;
var ext = steps.slice(-1)[0].output.format;
var steps = ref.steps;
if (basic) {
var datauri = steps.slice(-1)[0].output.src;
var ext = steps.slice(-1)[0].output.format;
var buffer = require('data-uri-to-buffer')(datauri);
fs.writeFile(root + "image" + "_" + (steps.length - 1) + "." + ext, buffer, function() { });
}
else {
for (var i in steps) {
var datauri = steps[i].output.src;
var ext = steps[i].output.format;
var buffer = require('data-uri-to-buffer')(datauri);
fs.writeFile(root + image + "_" + (steps.length - 1) + "." + ext, buffer, function() { });
}
else {
for (var i in steps) {
var datauri = steps[i].output.src;
var ext = steps[i].output.format;
var buffer = require('data-uri-to-buffer')(datauri);
fs.writeFile(root + image + "_" + i + "." + ext, buffer, function() { });
}
fs.writeFile(root + "image" + "_" + i + "." + ext, buffer, function() { });
}
}
});
});
}

View File

@@ -87,7 +87,7 @@ ImageSequencer = function ImageSequencer(options) {
//tell the UI a step has been removed
}
function removeSteps(index) {
function removeSteps() {
var indices;
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
var args = [];
@@ -102,7 +102,7 @@ ImageSequencer = function ImageSequencer(options) {
return this;
}
function insertSteps(image, index, name, o) {
function insertSteps() {
var this_ = (this.name == "ImageSequencer") ? this : this.sequencer;
var args = []
for (var arg in arguments) args.push(arguments[arg]);
@@ -119,7 +119,7 @@ ImageSequencer = function ImageSequencer(options) {
// Config is an object which contains the runtime configuration like progress bar
// information and index from which the sequencer should run
function run(config, t_image, t_from) {
function run(config) {
var progressObj, index = 0;
config = config || { mode: 'no-arg' };
if (config.index) index = config.index;

View File

@@ -7,8 +7,10 @@ module.exports = {
'blend': require('./modules/Blend'),
'blur': require('./modules/Blur'),
'brightness': require('./modules/Brightness'),
'canvas-resize': require('./modules/CanvasResize'),
'channel': require('./modules/Channel'),
'colorbar': require('./modules/Colorbar'),
'color-temperature': require('./modules/ColorTemperature'),
'colormap': require('./modules/Colormap'),
'contrast': require('./modules/Contrast'),
'convolution': require('./modules/Convolution'),
@@ -18,22 +20,25 @@ module.exports = {
'draw-rectangle': require('./modules/DrawRectangle'),
'dynamic': require('./modules/Dynamic'),
'edge-detect': require('./modules/EdgeDetect'),
'exposure': require('./modules/Exposure'),
'flip-image': require('./modules/FlipImage'),
'fisheye-gl': require('./modules/FisheyeGl'),
'histogram': require('./modules/Histogram'),
'gamma-correction': require('./modules/GammaCorrection'),
'gradient': require('./modules/Gradient'),
'grid-overlay': require('./modules/GridOverlay'),
'import-image': require('./modules/ImportImage'),
'invert': require('image-sequencer-invert'),
'ndvi': require('./modules/Ndvi'),
'ndvi-colormap': require('./modules/NdviColormap'),
'paint-bucket': require('./modules/PaintBucket'),
'overlay': require('./modules/Overlay'),
'replace-color':require('./modules/ReplaceColor'),
'replace-color': require('./modules/ReplaceColor'),
'resize': require('./modules/Resize'),
'rotate': require('./modules/Rotate'),
'saturation': require('./modules/Saturation'),
'text-overlay': require('./modules/TextOverlay'),
'threshold': require('./modules/Threshold'),
'tint': require('./modules/Tint'),
'white-balance': require('./modules/WhiteBalance')
}
}

View File

@@ -0,0 +1,63 @@
/*
* Changes the Canvas Size
*/
module.exports = function canvasResize(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input, callback, progressObj) {
options.width = options.width || defaults.width;
options.height = options.height || defaults.height;
options.x = options.x || defaults.x;
options.y = options.y || defaults.y;
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
function extraManipulation(pixels) {
let newPixels = require('ndarray')(new Uint8Array(4 * options.width * options.height).fill(255), [options.width, options.height, 4]);
let iMax = options.width - options.x,
jMax = options.height - options.y;
for (let i = 0; i < iMax && i < pixels.shape[0]; i++) {
for (let j = 0; j < jMax && j < pixels.shape[1]; j++) {
let x = i + options.x, y = j + options.y;
newPixels.set(x, y, 0, pixels.get(i, j, 0));
newPixels.set(x, y, 1, pixels.get(i, j, 1));
newPixels.set(x, y, 2, pixels.get(i, j, 2));
newPixels.set(x, y, 3, pixels.get(i, j, 3));
}
}
return newPixels;
}
function output(image, datauri, mimetype) {
// This output is accessible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
}
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,26 @@
{
"name": "Resize Canvas",
"description": "This module resizes the canvas and overlays the ouput of the previous step at given location",
"inputs": {
"width": {
"type": "integer",
"desc": "Final width of the canvas",
"default": 1000
},
"height": {
"type": "integer",
"desc": "Final height of the canvas",
"default": 1000
},
"x": {
"type": "integer",
"desc": "X-cord of the top left corner of the image on the canvas",
"default": 500
},
"y": {
"type": "float",
"desc": "Y-cord of the top left corner of the image on the canvas",
"default": 500
}
}
}

View File

@@ -0,0 +1,81 @@
module.exports = function ColorTemperature(options, UI) {
var output;
function draw(input, callback, progressObj) {
options.temperature = (options.temperature > "40000") ? "40000" : options.temperature
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
function extraManipulation(pixels) {
let temp = parseInt(options.temperature)
temp /= 100
let r, g, b;
if (temp <= 66) {
r = 255;
g = Math.min(Math.max(99.4708025861 * Math.log(temp) - 161.1195681661, 0), 255);
} else {
r = Math.min(Math.max(329.698727446 * Math.pow(temp - 60, -0.1332047592), 0), 255);
g = Math.min(Math.max(288.1221695283 * Math.pow(temp - 60, -0.0755148492), 0), 255);
}
if (temp >= 66) {
b = 255;
} else if (temp <= 19) {
b = 0;
} else {
b = temp - 10;
b = Math.min(Math.max(138.5177312231 * Math.log(b) - 305.0447927307, 0), 255);
}
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
r_data = pixels.get(i, j, 0)
r_new_data = (255 / r) * r_data
pixels.set(i, j, 0, r_new_data)
g_data = pixels.get(i, j, 1)
g_new_data = (255 / g) * g_data
pixels.set(i, j, 1, g_new_data)
b_data = pixels.get(i, j, 2)
b_new_data = (255 / b) * b_data
pixels.set(i, j, 2, b_new_data)
}
}
return pixels
}
function output(image, datauri, mimetype) {
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
}
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,12 @@
{
"name": "Color Temperature",
"description": "Changes the color temperature of the image.",
"inputs": {
"temperature": {
"type": "integer",
"desc": "Temperature between 0 - 40,000 Kelvin",
"default": 6000
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#color-temperature"
}

View File

@@ -7,7 +7,7 @@ module.exports = function edgeDetect(options, UI) {
options.blur = options.blur || defaults.blur;
options.highThresholdRatio = options.highThresholdRatio || defaults.highThresholdRatio;
options.lowThresholdRatio = options.lowThresholdRatio || defaults.lowThresholdRatio;
options.hystereis = options.hysteresis || defaults.hysteresis;
options.hysteresis = options.hysteresis || defaults.hysteresis;
var output;
@@ -27,7 +27,7 @@ module.exports = function edgeDetect(options, UI) {
function extraManipulation(pixels) {
pixels = require('ndarray-gaussian-filter')(pixels, options.blur);
pixels = require('./EdgeUtils')(pixels, options.highThresholdRatio, options.lowThresholdRatio, options.hystereis);
pixels = require('./EdgeUtils')(pixels, options.highThresholdRatio, options.lowThresholdRatio, options.hysteresis);
return pixels;
}

View File

@@ -0,0 +1,50 @@
/*
* Changes the Image Exposure
*/
module.exports = function Exposure(options,UI){
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
var output;
function draw(input,callback,progressObj){
options.exposure = options.exposure || defaults.exposure
var exposure = Math.pow(2, options.exposure);
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
function changePixel(r, g, b, a){
r = Math.min(255, r*exposure)
g = Math.min(255, g*exposure)
b = Math.min(255, b*exposure)
return [r, g, b, a]
}
function output(image,datauri,mimetype){
// This output is accessible by Image Sequencer
step.output = {src:datauri,format:mimetype};
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
changePixel: changePixel,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
}
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,15 @@
{
"name": "Exposure",
"description": "Change the exposure of the image by given exposure value",
"inputs": {
"exposure": {
"type": "float",
"desc": "exposure value for the new image",
"default": 1,
"min": -3,
"max": 4,
"step": 0.05
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md"
}

View File

@@ -1,26 +1,25 @@
/*
* Resolves Fisheye Effect
*/
module.exports = function DoNothing(options,UI) {
* Resolves Fisheye Effect
*/
module.exports = function DoNothing(options, UI) {
var output;
require('fisheyegl');
var gl = require('fisheyegl');
function draw(input,callback) {
function draw(input, callback) {
var step = this;
if (!options.inBrowser) { // This module is only for browser
this.output = input;
callback();
if (!options.inBrowser) {
require('../_nomodule/gl-context')(input, callback, step, options);
}
else {
// Create a canvas, if it doesn't already exist.
if (!document.querySelector('#image-sequencer-canvas')) {
var canvas = document.createElement('canvas');
canvas.style.display = "none";
canvas.setAttribute('id','image-sequencer-canvas');
canvas.setAttribute('id', 'image-sequencer-canvas');
document.body.append(canvas);
}
else var canvas = document.querySelector('#image-sequencer-canvas');
@@ -48,10 +47,10 @@ module.exports = function DoNothing(options,UI) {
distorter.fov.y = options.y;
// generate fisheyegl output
distorter.setImage(input.src,function(){
distorter.setImage(input.src, function() {
// this output is accessible to Image Sequencer
step.output = {src: canvas.toDataURL(), format: input.format};
step.output = { src: canvas.toDataURL(), format: input.format };
// Tell Image Sequencer and UI that step has been drawn
callback();

View File

@@ -0,0 +1,36 @@
module.exports = exports = function(pixels, options,priorstep){
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.color = options.color || defaults.color;
options.x = options.x || defaults.x;
options.y = options.y || defaults.y;
var img = $(priorstep.imgElement);
if(Object.keys(img).length === 0){
img = $(priorstep.options.step.imgElement);
}
var canvas = document.createElement("canvas");
canvas.width = pixels.shape[0]; //img.width();
canvas.height = pixels.shape[1]; //img.height();
var ctx = canvas.getContext('2d');
ctx.drawImage(img[0], 0, 0);
var p=2;
function drawBoard(){
for (var x = 0; x <= canvas.width; x+=options.x) {
ctx.moveTo(0.5 + x + p, p);
ctx.lineTo(0.5 + x + p, canvas.height + p);
}
for (var y = 0; y <= canvas.height; y+=options.y) {
ctx.moveTo(p, 0.5 + y + p);
ctx.lineTo(canvas.width + p, 0.5 + y + p);
}
ctx.strokeStyle = options.color;
ctx.stroke();
}
drawBoard();
var myImageData = ctx.getImageData(0,0,canvas.width,canvas.height);
pixels.data = myImageData.data
return pixels;
}

View File

@@ -0,0 +1,50 @@
module.exports = function GridOverlay(options,UI) {
var output;
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
if (!options.step.inBrowser) { // This module is only for browser
this.output = input;
callback();
}
else{
var priorStep = this.getStep(-1); // get the previous step to add text onto it.
function extraManipulation(pixels) {
//if (options.step.inBrowser)
pixels = require('./GridOverlay')(pixels, options,priorStep);
return pixels
}
function output(image, datauri, mimetype) {
// This output is accesible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
}
}
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,31 @@
{
"name": "GridOverlay",
"description": "Overlays a grid over an Image",
"inputs": {
"x": {
"type": "integer",
"desc": "X-position (measured from left) from where grid starts",
"default": 100
},
"y": {
"type": "integer",
"desc": "Y-position (measured from top) from where grid starts",
"default": 100
},
"color": {
"type": "select",
"desc": "Select the color for the grid.",
"default": "black",
"values": [
"black",
"blue",
"green",
"red",
"white",
"pink",
"orange"
]
}
},
"only": "browser"
}

View File

@@ -9,10 +9,9 @@
module.exports = function ImportImageModule(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.imageUrl = options.url || defaults.url;
options.imageUrl = options.inBrowser ? (options.url || defaults.url) : "./examples/images/monarch.png";
var output,
imgObj = new Image();
var output;
// we should get UI to return the image thumbnail so we can attach our own UI extensions
@@ -27,32 +26,17 @@ module.exports = function ImportImageModule(options, UI) {
var step = this;
if (!options.inBrowser) { // This module is only for browser
this.output = input;
step.metadata = step.metadata || {};
// TODO: develop a standard API method for saving each input state,
// for reference in future steps (for blending, for example)
step.metadata.input = input;
// options.format = require('../../util/GetFormat')(options.imageUrl);
var helper = ImageSequencer({ inBrowser: options.inBrowser, ui: false });
helper.loadImages(options.imageUrl, () => {
step.output = helper.steps[0].output;
callback();
} else {
step.metadata = step.metadata || {};
// TODO: develop a standard API method for saving each input state,
// for reference in future steps (for blending, for example)
step.metadata.input = input;
function onLoad() {
// This output is accessible to Image Sequencer
step.output = {
src: imgObj.src,
format: options.format
}
// Tell Image Sequencer that step has been drawn
callback();
}
options.format = require('../../util/GetFormat')(options.imageUrl);
imgObj.onload = onLoad;
imgObj.src = options.imageUrl;
}
});
}
return {

View File

@@ -0,0 +1,51 @@
module.exports = function TextOverlay(options,UI) {
var output;
function draw(input, callback, progressObj) {
progressObj.stop(true);
progressObj.overrideFlag = true;
var step = this;
if (!options.step.inBrowser) { // This module is only for browser
this.output = input;
callback();
}
else{
var priorStep = this.getStep(-1); // get the previous step to add text onto it.
function extraManipulation(pixels) {
//if (options.step.inBrowser)
pixels = require('./TextOverlay')(pixels, options,priorStep);
return pixels
}
function output(image, datauri, mimetype) {
// This output is accesible by Image Sequencer
step.output = { src: datauri, format: mimetype };
}
return require('../_nomodule/PixelManipulation.js')(input, {
output: output,
extraManipulation: extraManipulation,
format: input.format,
image: options.image,
inBrowser: options.inBrowser,
callback: callback
});
}
}
return {
options: options,
draw: draw,
output: output,
UI: UI
}
}

View File

@@ -0,0 +1,27 @@
module.exports = exports = function(pixels, options,priorstep){
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.text = options.text || defaults.text;
options.x = options.x || defaults.x;
options.y = options.y || defaults.y;
options.font = options.font || defaults.font;
options.color = options.color || defaults.color;
options.size = options.size || defaults.size;
var img = $(priorstep.imgElement);
if(Object.keys(img).length === 0){
img = $(priorstep.options.step.imgElement);
}
var canvas = document.createElement("canvas");
canvas.width = pixels.shape[0]; //img.width();
canvas.height = pixels.shape[1]; //img.height();
var ctx = canvas.getContext('2d');
ctx.drawImage(img[0], 0, 0);
ctx.fillStyle = options.color;
ctx.font = options.size +"px " + options.font;
ctx.fillText(options.text, options.x, options.y);
var myImageData = ctx.getImageData(0,0,canvas.width,canvas.height);
pixels.data = myImageData.data
return pixels;
}

View File

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

View File

@@ -0,0 +1,53 @@
{
"name": "Text-Overlay",
"description": "Overlay text on image.",
"inputs": {
"text": {
"type": "string",
"desc": "Enter the text to overlay.",
"default": "Lorem ipsum"
},
"x": {
"type": "integer",
"desc": "Starting text horizontal position.",
"default": "20"
},
"y": {
"type": "integer",
"desc": "Starting text vertical position.",
"default": "20"
},
"font": {
"type": "select",
"desc": "Select the font style.",
"default": "serif",
"values": [
"serif",
"arial",
"times",
"courier",
"Montserrat"
]
},
"color": {
"type": "select",
"desc": "Select the text color.",
"default": "black",
"values": [
"black",
"blue",
"green",
"red",
"white",
"pink",
"orange"
]
},
"size": {
"type" : "integer",
"desc": "Enter the font size in pixels.",
"default": "12"
}
},
"only": "browser"
}

View File

@@ -1,11 +1,15 @@
module.exports = function Balance(options, UI) {
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
options.red = options.red || defaults.red
options.green = options.green || defaults.green
options.blue = options.blue || defaults.blue
var output;
function draw(input, callback, progressObj) {
options.temperature = (options.temperature > "40000") ? "40000" : options.temperature
progressObj.stop(true);
progressObj.overrideFlag = true;
@@ -13,43 +17,16 @@ module.exports = function Balance(options, UI) {
function extraManipulation(pixels) {
let temp = parseInt(options.temperature)
temp /= 100
var i = 0
var red_factor = 255/options.red
var green_factor = 255/options.green
var blue_factor = 255/options.blue
let r, g, b;
if (temp <= 66) {
r = 255;
g = Math.min(Math.max(99.4708025861 * Math.log(temp) - 161.1195681661, 0), 255);
} else {
r = Math.min(Math.max(329.698727446 * Math.pow(temp - 60, -0.1332047592), 0), 255);
g = Math.min(Math.max(288.1221695283 * Math.pow(temp - 60, -0.0755148492), 0), 255);
}
if (temp >= 66) {
b = 255;
} else if (temp <= 19) {
b = 0;
} else {
b = temp - 10;
b = Math.min(Math.max(138.5177312231 * Math.log(b) - 305.0447927307, 0), 255);
}
for (let i = 0; i < pixels.shape[0]; i++) {
for (let j = 0; j < pixels.shape[1]; j++) {
r_data = pixels.get(i, j, 0)
r_new_data = (255 / r) * r_data
pixels.set(i, j, 0, r_new_data)
g_data = pixels.get(i, j, 1)
g_new_data = (255 / g) * g_data
pixels.set(i, j, 1, g_new_data)
b_data = pixels.get(i, j, 2)
b_new_data = (255 / b) * b_data
pixels.set(i, j, 2, b_new_data)
}
while (i < pixels.data.length) {
pixels.data[i] = Math.min(255, pixels.data[i]*red_factor)
pixels.data[i+1] = Math.min(255, pixels.data[i+1]*green_factor)
pixels.data[i+2] = Math.min(255, pixels.data[i+2]*blue_factor)
i+=4
}
return pixels

View File

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

View File

@@ -1,11 +1,21 @@
{
"name": "White Balance",
"description": "Change the colour balance of the image by adjusting the colour temperature.",
"description": "Render neutral colours correctly based on the whitest pixel in the image.",
"inputs": {
"temperature": {
"red": {
"type": "integer",
"desc": "Temperature between 0 - 40,000 Kelvin",
"default": 6000
"desc": "Red component of the whitest pixel ",
"default": 255
},
"green": {
"type": "integer",
"desc": "Green component of the whitest pixel ",
"default": 255
},
"blue": {
"type": "integer",
"desc": "Blue component of the whitest pixel ",
"default": 255
}
},
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#white-balance"

View File

@@ -69,32 +69,32 @@ module.exports = function PixelManipulation(image, options) {
}
// perform any extra operations on the entire array:
var res;
if (options.extraManipulation) res = options.extraManipulation(pixels,generateOutput);
if (options.extraManipulation) res = options.extraManipulation(pixels, generateOutput);
// there may be a more efficient means to encode an image object,
// but node modules and their documentation are essentially arcane on this point
function generateOutput(){
function generateOutput() {
var chunks = [];
var totalLength = 0;
var r = savePixels(pixels, options.format, { quality: 100 });
var totalLength = 0;
r.on("data", function(chunk) {
totalLength += chunk.length;
chunks.push(chunk);
});
var r = savePixels(pixels, options.format, { quality: 100 });
r.on("end", function() {
var data = Buffer.concat(chunks, totalLength).toString("base64");
var datauri = "data:image/" + options.format + ";base64," + data;
if (options.output)
options.output(options.image, datauri, options.format);
if (options.callback) options.callback();
});
r.on("data", function(chunk) {
totalLength += chunk.length;
chunks.push(chunk);
});
r.on("end", function() {
var data = Buffer.concat(chunks, totalLength).toString("base64");
var datauri = "data:image/" + options.format + ";base64," + data;
if (options.output)
options.output(options.image, datauri, options.format);
if (options.callback) options.callback();
});
}
if(res){
pixels=res;
if (res) {
pixels = res;
generateOutput();
}
else if(!options.extraManipulation) generateOutput();
else if (!options.extraManipulation) generateOutput();
});
};

View File

@@ -0,0 +1,37 @@
module.exports = function runInBrowserContext(input, callback, step, options) {
// to ignore this from getting browserified
const puppeteer = eval('require')('puppeteer');
//Stripped down version of options which is serializable
var minOptions = require("lodash").cloneDeep(options);
minOptions.step = options.step.name;
var obj = { input: input, modOptions: minOptions }
puppeteer.launch().then(function(browser) {
browser.newPage().then(page => {
/* Maybe there is a better way to this, loading the page coz localstorage API
is not available otherwise */
page.goto("https://google.com").then(() => {
page.addScriptTag({ path: require('path').join(__dirname, '../../../dist/image-sequencer.js') }).then(() => {
page.evaluate((options) => {
return new Promise((resolve, reject) => {
var sequencer = ImageSequencer();
sequencer.loadImage(options.input.src);
sequencer.addSteps(options.modOptions.step, options.modOptions);
sequencer.run(function cb(out) {
resolve(sequencer.steps[1].output.src)
});
})
}, obj).then(el => {
browser.close().then(() => {
step.output = { src: el, format: input.format };
callback();
});
});
})
});
});
});
}

View File

@@ -14,13 +14,13 @@ function LoadImage(ref, name, src, main_callback) {
callback(datauri, step);
}
else if (!ref.options.inBrowser && !!src.match(/^https?:\/\//i)) {
require( src.match(/^(https?):\/\//i)[1] ).get(src,function(res){
require(src.match(/^(https?):\/\//i)[1]).get(src, function(res) {
var data = '';
var contentType = res.headers['content-type'];
res.setEncoding('base64');
res.on('data',function(chunk) {data += chunk;});
res.on('end',function() {
callback("data:"+contentType+";base64,"+data, step);
res.on('data', function(chunk) { data += chunk; });
res.on('end', function() {
callback("data:" + contentType + ";base64," + data, step);
});
});
}
@@ -32,10 +32,10 @@ function LoadImage(ref, name, src, main_callback) {
image.onload = function() {
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
context.drawImage(image,0,0);
datauri = canvas.toDataURL(ext);
context.drawImage(image, 0, 0);
datauri = canvas.toDataURL(ext);
callback(datauri, step);
}
}
image.src = src;
}
else {
@@ -52,7 +52,7 @@ function LoadImage(ref, name, src, main_callback) {
inBrowser: ref.options.inBrowser,
ui: ref.options.ui,
UI: ref.events,
output : ''
output: ''
};
@@ -69,7 +69,7 @@ function LoadImage(ref, name, src, main_callback) {
});
}
return loadImage(name,src);
return loadImage(name, src);
}
module.exports = LoadImage;

View File

@@ -18,6 +18,8 @@ test('benchmark all modules', function(t) {
var mods = Object.keys(sequencer.modules);
sequencer.loadImages(image);
while ((mods[0] === 'import-image' || (!!sequencer.modulesInfo(mods[0]).requires && sequencer.modulesInfo(mods[0]).requires.includes("webgl"))))
mods.splice(0, 1);
sequencer.addSteps(mods[0]);
global.start = Date.now()
global.idx = 0
@@ -30,6 +32,11 @@ test('benchmark all modules', function(t) {
if (mods.length > 1) { //Last one is test module, we need not benchmark it
sequencer.steps[global.idx].output.src = image;
global.idx++;
if (mods[0] === 'import-image' || (!!sequencer.modulesInfo(mods[0]).requires && sequencer.modulesInfo(mods[0]).requires.includes("webgl"))) {
/* Not currently working */
console.log("Bypassing import-image");
mods.splice(0, 1);
}
sequencer.addSteps(mods[0]);
global.start = Date.now();
sequencer.run({ index: global.idx }, cb);

View File

@@ -6,26 +6,26 @@ require('../../../src/ImageSequencer')
var sequencer = ImageSequencer({ui: false})
var red = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEX+AAD///+KQee0AAAAAWJLR0QB/wIt3gAAAAd0SU1FB+EGHRIVAvrm6EMAAAAMSURBVAjXY2AgDQAAADAAAceqhY4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDYtMjlUMTg6MjE6MDIrMDI6MDDGD83DAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA2LTI5VDE4OjIxOjAyKzAyOjAwt1J1fwAAAABJRU5ErkJggg=="
var benchmark = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAklEQVR4AewaftIAAACSSURBVKXBMUoDURAA0Dc/w4ZgJdh5AE/urawsBMuIpDBkx4VNESzWH/57gTKgGZSuXvGAPQJh2wkfyHd8onDAhIaw7Yxn5CP2mJFIBMK2whPygAkXq7AK/5uQgR0aCqFfQ1oEAuU+gXQj3KfQDEp/lH6FdFUolD4XfCEtfnDGjNLnhDekxRHfmFH6vFjlzphm0C96GR7JNsLICQAAAABJRU5ErkJggg=="
var benchmark = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAklEQVR4AewaftIAAAA0SURBVKXBwRGAIBDAwBiu/44ZeWgFZPcBXgKJht/mzmwaiSSSSCKJJJJIIomGS4vPLBqJDh2XAyeCsOZ9AAAAAElFTkSuQmCC"
var target = 'test_outputs'
var options = {blur: 3.25}
test('Blur module loads correctly', function(t) {
sequencer.loadImages('test', red)
sequencer.loadImages(red)
sequencer.addSteps('blur', options)
t.equal(sequencer.images.test.steps[1].options.name, 'blur', 'Blur module is getting loaded')
t.equal(sequencer.steps[1].options.name, 'blur', 'Blur module is getting loaded')
t.end()
})
test('Blur module loads with correct options', function(t) {
t.equal(sequencer.images.test.steps[1].options.blur, 3.25, 'Options are correct');
t.equal(sequencer.steps[1].options.blur, 3.25, 'Options are correct');
t.end();
})
test('Blur module works correctly', function(t) {
sequencer.run({mode:'test'}, function(out) {
var result = sequencer.images.test.steps[1].output.src
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(benchmark, target, 'benchmark')
result = './test_outputs/result.png'

View File

@@ -0,0 +1,34 @@
var test = require('tape');
require('../../../src/ImageSequencer.js');
var sequencer = ImageSequencer({ ui: false });
var options = { width: 500, height: 500 };
var red = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEX+AAD///+KQee0AAAAAWJLR0QB/wIt3gAAAAd0SU1FB+EGHRIVAvrm6EMAAAAMSURBVAjXY2AgDQAAADAAAceqhY4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDYtMjlUMTg6MjE6MDIrMDI6MDDGD83DAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA2LTI5VDE4OjIxOjAyKzAyOjAwt1J1fwAAAABJRU5ErkJggg==";
// Test 1 to check brightness module is getting loaded
test('Load canvas-resize module', function(t) {
sequencer.loadImages(red);
sequencer.addSteps('canvas-resize', options);
t.equal(sequencer.steps[1].options.name, 'canvas-resize', 'Canvas resize module is getting loaded');
t.end();
});
// Test 2 to check options are correct
test('Check Options', function(t) {
t.equal(sequencer.steps[1].options.width, 500, 'Options are correct');
t.equal(sequencer.steps[1].options.height, 500, 'Options are correct');
t.end();
});
// Test 3 to check brightness module works as expected
test('canvas-resize module works correctly', function(t) {
sequencer.run({ mode: 'test' }, function(out) {
var result = sequencer.steps[1].output.src;
require('get-pixels')(result, (err, pix) => {
t.equal(pix.shape[0], 500);
t.equal(pix.shape[1], 500);
t.end();
});
});
});

View File

@@ -13,20 +13,20 @@ var target = 'test_outputs'
var options = {channel: 'red'}
test('Channel module loads correctly', function(t) {
sequencer.loadImages('test', red)
sequencer.loadImages( red)
sequencer.addSteps('channel', options)
t.equal(sequencer.images.test.steps[1].options.name, 'channel', 'Channel module is getting loaded')
t.equal(sequencer.steps[1].options.name, 'channel', 'Channel module is getting loaded')
t.end()
})
test('Channel module loads with correct options', function(t) {
t.equal(sequencer.images.test.steps[1].options.channel, 'red', 'Options are correct');
t.equal(sequencer.steps[1].options.channel, 'red', 'Options are correct');
t.end();
})
test('Channel module works correctly', function(t) {
sequencer.run({mode:'test'}, function(out) {
var result = sequencer.images.test.steps[1].output.src
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(benchmark, target, 'benchmark')
result = './test_outputs/result.png'

View File

@@ -13,20 +13,20 @@ var target = 'test_outputs'
var options = {colormap: 'blutoredjet'}
test('Colormap module loads correctly', function(t) {
sequencer.loadImages('test', red)
sequencer.loadImages( red)
sequencer.addSteps('colormap', options)
t.equal(sequencer.images.test.steps[1].options.name, 'colormap', 'Colormap module is getting loaded')
t.equal(sequencer.steps[1].options.name, 'colormap', 'Colormap module is getting loaded')
t.end()
})
test('Colormap module loads with correct options', function(t) {
t.equal(sequencer.images.test.steps[1].options.colormap, 'blutoredjet', 'Options are correct');
t.equal(sequencer.steps[1].options.colormap, 'blutoredjet', 'Options are correct');
t.end();
})
test('Colormap module works correctly', function(t) {
sequencer.run({mode:'test'}, function(out) {
var result = sequencer.images.test.steps[1].output.src
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(benchmark, target, 'benchmark')
result = './test_outputs/result.png'

File diff suppressed because one or more lines are too long

View File

@@ -13,20 +13,20 @@ var target = 'test_outputs'
var options = {dither: 'bayer'}
test('Dither module loads correctly', function(t) {
sequencer.loadImages('test', red)
sequencer.loadImages(red)
sequencer.addSteps('dither', options)
t.equal(sequencer.images.test.steps[1].options.name, 'dither', 'Dither module is getting loaded')
t.equal(sequencer.steps[1].options.name, 'dither', 'Dither module is getting loaded')
t.end()
})
test('Dither module loads with correct options', function(t) {
t.equal(sequencer.images.test.steps[1].options.dither, 'bayer', 'Options are correct');
t.equal(sequencer.steps[1].options.dither, 'bayer', 'Options are correct');
t.end();
})
test('Dither module works correctly', function(t) {
sequencer.run({mode:'test'}, function(out) {
var result = sequencer.images.test.steps[1].output.src
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(benchmark, target, 'benchmark')
result = './test_outputs/result.png'

View File

@@ -13,20 +13,20 @@ var target = 'test_outputs'
var options = {resize: '129%'}
test('Resize module loads correctly', function(t) {
sequencer.loadImages('test', red)
sequencer.loadImages(red)
sequencer.addSteps('resize', options)
t.equal(sequencer.images.test.steps[1].options.name, 'resize', 'Resize module is getting loaded')
t.equal(sequencer.steps[1].options.name, 'resize', 'Resize module is getting loaded')
t.end()
})
test('Resize module loads with correct options', function(t) {
t.equal(sequencer.images.test.steps[1].options.resize, '129%', 'Options are correct');
t.equal(sequencer.steps[1].options.resize, '129%', 'Options are correct');
t.end();
})
test('Resize module works correctly', function(t) {
sequencer.run({mode:'test'}, function(out) {
var result = sequencer.images.test.steps[1].output.src
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(benchmark, target, 'benchmark')
result = './test_outputs/result.png'

View File

@@ -12,20 +12,20 @@ var target = 'test_outputs'
var options = {rotate: 45}
test('Rotate module loads correctly', function(t) {
sequencer.loadImages('test', red)
sequencer.loadImages(red)
sequencer.addSteps('rotate', options)
t.equal(sequencer.images.test.steps[1].options.name, 'rotate', 'Rotate module is getting loaded')
t.equal(sequencer.steps[1].options.name, 'rotate', 'Rotate module is getting loaded')
t.end()
})
test('Rotate module loads with correct options', function(t) {
t.equal(sequencer.images.test.steps[1].options.rotate, 45, 'Options are correct');
t.equal(sequencer.steps[1].options.rotate, 45, 'Options are correct');
t.end();
})
test('Rotate module works correctly', function(t) {
sequencer.run({mode:'test'}, function(out) {
var result = sequencer.images.test.steps[1].output.src
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(benchmark, target, 'benchmark')
result = './test_outputs/result.png'

View File

@@ -0,0 +1,42 @@
var test = require('tape');
var base64Img = require('base64-img');
var looksSame = require('looks-same');
require('../../../src/ImageSequencer.js');
var sequencer = ImageSequencer({ ui: false });
var options = {text : "Hello World"};
var target = 'test_outputs';
var red = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEX+AAD///+KQee0AAAAAWJLR0QB/wIt3gAAAAd0SU1FB+EGHRIVAvrm6EMAAAAMSURBVAjXY2AgDQAAADAAAceqhY4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDYtMjlUMTg6MjE6MDIrMDI6MDDGD83DAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA2LTI5VDE4OjIxOjAyKzAyOjAwt1J1fwAAAABJRU5ErkJggg==";
// Test 1 to check text overlay module is getting loaded.
test('Load Text Overlay module', function(t) {
sequencer.loadImages(red);
sequencer.addSteps('text-overlay', options);
t.equal(sequencer.steps[1].options.name, 'text-overlay', 'Text Overlay module is getting loaded');
t.end();
});
// Test 2 to check options are correct.
test('Check Options', function(t) {
t.equal(sequencer.steps[1].options.text, "Hello World", 'Options are correct');
t.end();
});
// Test 3 to check Text Overlay module works as expected.
test('Text Overlay module works correctly', function(t) {
sequencer.run({ mode: 'test' }, function(out) {
// The test runs in node , and the text overlay is a browser only module,
// thus it there is no image processing and output is same as input.
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(red, target, 'red')
result = './test_outputs/result.png'
red = './test_outputs/red.png'
looksSame(result, red, function(err, res) {
if (err) console.log(err)
t.equal(res.equal, true)
t.end()
})
})
})

View File

@@ -0,0 +1,43 @@
const test = require('tape')
const base64Img = require('base64-img')
const looksSame = require('looks-same')
require('../../../src/ImageSequencer.js');
var sequencer = ImageSequencer({ui: false})
var options = {red: 240, green: 240, blue: 240}
var target = 'test_outputs'
var image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEX+AAD///+KQee0AAAAAWJLR0QB/wIt3gAAAAd0SU1FB+EGHRIVAvrm6EMAAAAMSURBVAjXY2AgDQAAADAAAceqhY4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDYtMjlUMTg6MjE6MDIrMDI6MDDGD83DAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA2LTI5VDE4OjIxOjAyKzAyOjAwt1J1fwAAAABJRU5ErkJggg=='
var benchmark = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAklEQVR4AewaftIAAAApSURBVKXBAQEAAAiDMKR/5xuC7QYjkEgiiSSSSCKJJJJIIokkkkgiiR5YbQIegx78CAAAAABJRU5ErkJggg=='
// Test for loading module
test('Load white balance module', function(t){
sequencer.loadImages(image)
sequencer.addSteps('white-balance', options)
t.equal(sequencer.steps[1].options.name, 'white-balance', 'White Balance module loads correctly')
t.end()
})
// Test for checking options
test('Options are correct', function(t){
t.equal(sequencer.steps[1].options.red, 240, 'Red component is correct')
t.equal(sequencer.steps[1].options.green, 240, 'Green component is correct')
t.equal(sequencer.steps[1].options.blue, 240, 'Blue component is correct')
t.end()
})
// Test for correct output
test('White Balance module works correctly', function(t){
sequencer.run({ mode: 'test' }, function(out) {
var result = sequencer.steps[1].output.src
base64Img.imgSync(result, target, 'result')
base64Img.imgSync(benchmark, target, 'benchmark')
result = './test_outputs/result.png'
benchmark = './test_outputs/benchmark.png'
looksSame(result, benchmark, function(err, res) {
if (err) console.log(err)
t.equal(res.equal, true)
t.end()
})
})
})

243
yarn.lock
View File

@@ -87,6 +87,13 @@ after@0.8.2:
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
agent-base@^4.1.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9"
integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==
dependencies:
es6-promisify "^5.0.0"
ajax-request@^1.2.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/ajax-request/-/ajax-request-1.2.3.tgz#99fcbec1d6d2792f85fa949535332bd14f5f3790"
@@ -129,10 +136,10 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
ansi-regex@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9"
integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==
ansi-regex@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
ansi-styles@^2.2.1:
version "2.2.1"
@@ -146,6 +153,11 @@ ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
ansicolors@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef"
integrity sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8=
anymatch@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@@ -175,7 +187,7 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.2:
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
@@ -854,6 +866,14 @@ can-promise@0.0.1:
dependencies:
window-or-global "^1.0.1"
cardinal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-1.0.0.tgz#50e21c1b0aa37729f9377def196b5a9cec932ee9"
integrity sha1-UOIcGwqjdyn5N33vGWtanOyTLuk=
dependencies:
ansicolors "~0.2.1"
redeyed "~1.0.0"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
@@ -1070,9 +1090,9 @@ combined-stream@~1.0.6:
delayed-stream "~1.0.0"
commander@^2.11.0, commander@^2.2.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
version "2.20.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
commander@~2.13.0:
version "2.13.0"
@@ -1268,6 +1288,11 @@ cssstyle@^1.1.1:
dependencies:
cssom "0.3.x"
csv-parse@^2.0.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-2.5.0.tgz#65748997ecc3719c594622db1b9ea0e2eb7d56bb"
integrity sha512-4OcjOJQByI0YDU5COYw9HAqjo8/MOLLmT9EKyMCXUzgvh30vS1SlMK+Ho84IH5exN44cSnrYecw/7Zpu2m4lkA==
currently-unhandled@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
@@ -1369,6 +1394,13 @@ debug@^3.1.0:
dependencies:
ms "^2.1.1"
debug@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@@ -1785,11 +1817,23 @@ es6-map@^0.1.5:
es6-symbol "~3.1.1"
event-emitter "~0.3.5"
es6-promise@^4.0.3:
version "4.2.6"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f"
integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==
es6-promise@^4.0.5:
version "4.2.5"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054"
integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==
es6-promisify@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
dependencies:
es6-promise "^4.0.3"
es6-set@^0.1.5, es6-set@~0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
@@ -1869,16 +1913,16 @@ esprima@^1.0.3:
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.5.tgz#0993502feaf668138325756f30f9a51feeec11e9"
integrity sha1-CZNQL+r2aBODJXVvMPmlH+7sEek=
esprima@^2.6.0:
version "2.7.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=
esprima@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
esprima@~1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad"
@@ -1889,6 +1933,11 @@ esprima@~1.1.1:
resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549"
integrity sha1-W28VR/TRAuZw4UDFCb5ncdautUk=
esprima@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.0.0.tgz#53cf247acda77313e551c3aa2e73342d3fb4f7d9"
integrity sha1-U88kes2ncxPlUcOqLnM0LT+099k=
estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
@@ -2048,7 +2097,7 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
extract-zip@^1.0.3:
extract-zip@^1.0.3, extract-zip@^1.6.6:
version "1.6.7"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9"
integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=
@@ -2349,6 +2398,14 @@ gaze@^1.1.0:
dependencies:
globule "^1.0.0"
geotiff@^1.0.0-beta.6:
version "1.0.0-beta.6"
resolved "https://registry.yarnpkg.com/geotiff/-/geotiff-1.0.0-beta.6.tgz#500f256196a2c23517b73ccb36a45dc82a1f7a70"
integrity sha512-xdZ/MLcnrv1+6wQlQZQIs11zNJywylnV1pXqDw7Ao7bmLRpM421a39dXP5e6SG+vio0mnDUZkL2XknKbqppFzw==
dependencies:
pako "^1.0.3"
xmldom "0.1.*"
get-assigned-identifiers@^1.1.0, get-assigned-identifiers@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1"
@@ -2604,9 +2661,9 @@ grunt-legacy-util@~1.1.1:
which "~1.3.0"
grunt@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.3.tgz#b3c99260c51d1b42835766e796527b60f7bba374"
integrity sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==
version "1.0.4"
resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.4.tgz#c799883945a53a3d07622e0737c8f70bfe19eb38"
integrity sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==
dependencies:
coffeescript "~1.10.0"
dateformat "~1.0.12"
@@ -2619,7 +2676,7 @@ grunt@^1.0.3:
grunt-legacy-log "~2.0.0"
grunt-legacy-util "~1.1.1"
iconv-lite "~0.4.13"
js-yaml "~3.5.2"
js-yaml "~3.13.0"
minimatch "~3.0.2"
mkdirp "~0.5.1"
nopt "~3.0.6"
@@ -2856,6 +2913,19 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
https-proxy-agent@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0"
integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==
dependencies:
agent-base "^4.1.0"
debug "^3.1.0"
humanize@^0.0.9:
version "0.0.9"
resolved "https://registry.yarnpkg.com/humanize/-/humanize-0.0.9.tgz#1994ffaecdfe9c441ed2bdac7452b7bb4c9e41a4"
integrity sha1-GZT/rs3+nEQe0r2sdFK3u0yeQaQ=
iconv-lite@0.4.23:
version "0.4.23"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
@@ -3277,9 +3347,9 @@ isstream@~0.1.2:
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
jasmine-core@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.3.0.tgz#dea1cdc634bc93c7e0d4ad27185df30fa971b10e"
integrity sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA==
version "3.4.0"
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.4.0.tgz#2a74618e966026530c3518f03e9f845d26473ce3"
integrity sha512-HU/YxV4i6GcmiH4duATwAbJQMlE0MsDIR5XmSVxURxKHn3aGAdbY1/ZJFmVRbKtnLwIxxMJD7gYaPsypcbYimg==
jasmine-jquery@^2.1.1:
version "2.1.1"
@@ -3309,32 +3379,32 @@ jpeg-js@^0.3.2:
integrity sha512-6IzjQxvnlT8UlklNmDXIJMWxijULjqGrzgqc0OG7YadZdvm7KPQ1j0ehmQQHckgEWOfgpptzcnWgESovxudpTA==
jquery@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca"
integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==
version "3.4.0"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.0.tgz#8de513fa0fa4b2c7d2e48a530e26f0596936efdf"
integrity sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ==
js-graph-algorithms@1.0.18:
version "1.0.18"
resolved "https://registry.yarnpkg.com/js-graph-algorithms/-/js-graph-algorithms-1.0.18.tgz#f96ec87bf194f5c0a31365fa0e1d07b7b962d891"
integrity sha1-+W7Ie/GU9cCjE2X6Dh0Ht7li2JE=
js-yaml@~3.5.2:
version "3.5.5"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.5.5.tgz#0377c38017cabc7322b0d1fbcd25a491641f2fbe"
integrity sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=
js-yaml@~3.13.0:
version "3.13.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.0.tgz#38ee7178ac0eea2c97ff6d96fff4b18c7d8cf98e"
integrity sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==
dependencies:
argparse "^1.0.2"
esprima "^2.6.0"
argparse "^1.0.7"
esprima "^4.0.0"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jsdom@^13.1.0:
version "13.2.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-13.2.0.tgz#b1a0dbdadc255435262be8ea3723d2dba0d7eb3a"
integrity sha512-cG1NtMWO9hWpqRNRR3dSvEQa8bFI6iLlqU2x4kwX51FQjp0qus8T9aBaAO6iGp3DeBrhdwuKxckknohkmfvsFw==
jsdom@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-14.0.0.tgz#c7f1441ebcc57902d08d5fb2f6ba2baf746da7c6"
integrity sha512-/VkyPmdtbwqpJSkwDx3YyJ3U1oawYNB/h5z8vTUZGAzjtu2OHTeFRfnJqyMHsJ5Cyes23trOmvUpM1GfHH1leA==
dependencies:
abab "^2.0.0"
acorn "^6.0.4"
@@ -3555,7 +3625,7 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10, lodash@~4.17.5:
lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.3, lodash@^4.17.4, lodash@~4.17.10, lodash@~4.17.5:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
@@ -3573,9 +3643,9 @@ longest@^1.0.1:
integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=
looks-same@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/looks-same/-/looks-same-7.1.0.tgz#8ecab8d015c428a3efd13003b9c649f8852f57e4"
integrity sha512-nroqc3WnrTLYRGWVx6geMS3kO4ww50AQM0QdGP3Zy8Q5ohma6k7xEq3gUEd8Mf7CiXiJAbrUJpokcN0xLBDCUQ==
version "7.2.0"
resolved "https://registry.yarnpkg.com/looks-same/-/looks-same-7.2.0.tgz#54772d2ed088f77691e271c4531d7ba97a5818eb"
integrity sha512-LCE5Md8ZQ9Wn5lJbaGW4r6Fs00P8p8+JOjvXKkq9LdI/datYG8JOSRycMes+bp2h/UJ/RYYzJjvP0CXLPeVq1A==
dependencies:
color-diff "^1.1.0"
concat-stream "^1.6.2"
@@ -3727,6 +3797,11 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"
microplugin@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/microplugin/-/microplugin-0.0.3.tgz#1fc2e1bb7c9e19e82bd84bba9137bbe71250d8cd"
integrity sha1-H8Lhu3yeGegr2Eu6kTe75xJQ2M0=
miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
@@ -3757,6 +3832,11 @@ mime@^1.2.11, mime@^1.3.4, mime@^1.6.0:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
mime@^2.0.3:
version "2.4.2"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.2.tgz#ce5229a5e99ffc313abac806b482c10e7ba6ac78"
integrity sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
@@ -4219,15 +4299,15 @@ optionator@^0.8.1:
wordwrap "~1.0.0"
ora@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-3.2.0.tgz#67e98a7e11f7f0ac95deaaaf11bb04de3d09e481"
integrity sha512-XHMZA5WieCbtg+tu0uPF8CjvwQdNzKCX6BVh3N6GFsEXH40mTk5dsw/ya1lBTUGJslcEFJFQ8cBhOgkkZXQtMA==
version "3.4.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318"
integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==
dependencies:
chalk "^2.4.2"
cli-cursor "^2.1.0"
cli-spinners "^2.0.0"
log-symbols "^2.2.0"
strip-ansi "^5.0.0"
strip-ansi "^5.2.0"
wcwidth "^1.0.1"
ordered-emitter@~0.1.0:
@@ -4322,6 +4402,11 @@ pace@0.0.4:
dependencies:
charm "~0.1.0"
pako@^1.0.3:
version "1.0.10"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732"
integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==
pako@~0.2.0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
@@ -4606,6 +4691,16 @@ progress-stream@^1.1.0:
speedometer "~0.1.2"
through2 "~0.2.3"
progress@^2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
proxy-from-env@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee"
integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=
psl@^1.1.24:
version "1.1.29"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
@@ -4651,7 +4746,21 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qrcode@1.3.3:
puppeteer@^1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.14.0.tgz#828c1926b307200d5fc8289b99df4e13e962d339"
integrity sha512-SayS2wUX/8LF8Yo2Rkpc5nkAu4Jg3qu+OLTDSOZtisVQMB2Z5vjlY2TdPi/5CgZKiZroYIiyUN3sRX63El9iaw==
dependencies:
debug "^4.1.0"
extract-zip "^1.6.6"
https-proxy-agent "^2.2.1"
mime "^2.0.3"
progress "^2.0.1"
proxy-from-env "^1.0.0"
rimraf "^2.6.1"
ws "^6.1.0"
qrcode@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.3.3.tgz#5ef50c0c890cffa1897f452070f0f094936993de"
integrity sha512-SH7V13AcJusH3GT8bMNOGz4w0L+LjcpNOU/NiOgtBhT/5DoWeZE6D5ntMJnJ84AMkoaM4kjJJoHoh9g++8lWFg==
@@ -4860,6 +4969,13 @@ redent@^1.0.0:
indent-string "^2.1.0"
strip-indent "^1.0.1"
redeyed@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-1.0.1.tgz#e96c193b40c0816b00aec842698e61185e55498a"
integrity sha1-6WwZO0DAgWsArshCaY5hGF5VSYo=
dependencies:
esprima "~3.0.0"
regex-cache@^0.4.2:
version "0.4.4"
resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
@@ -5105,6 +5221,14 @@ scope-analyzer@^2.0.1:
estree-is-function "^1.0.0"
get-assigned-identifiers "^1.1.0"
selectize@^0.12.6:
version "0.12.6"
resolved "https://registry.yarnpkg.com/selectize/-/selectize-0.12.6.tgz#c2cf08cbaa4cb06c5e99bb452919d71b080690d6"
integrity sha512-bWO5A7G+I8+QXyjLfQUgh31VI4WKYagUZQxAXlDyUmDDNrFxrASV0W9hxCOl0XJ/XQ1dZEu3G9HjXV4Wj0yb6w==
dependencies:
microplugin "0.0.3"
sifter "^0.5.1"
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
@@ -5230,6 +5354,17 @@ shell-quote@^1.4.2, shell-quote@^1.6.1:
array-reduce "~0.0.0"
jsonify "~0.0.0"
sifter@^0.5.1:
version "0.5.3"
resolved "https://registry.yarnpkg.com/sifter/-/sifter-0.5.3.tgz#5e6507fe8c114b2b28d90b6bf4e5b636e611e48b"
integrity sha1-XmUH/owRSyso2Qtr9OW2NuYR5Is=
dependencies:
async "^2.6.0"
cardinal "^1.0.0"
csv-parse "^2.0.0"
humanize "^0.0.9"
optimist "^0.6.1"
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@@ -5662,12 +5797,12 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
strip-ansi@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f"
integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==
strip-ansi@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.0.0"
ansi-regex "^4.1.0"
strip-bom@^2.0.0:
version "2.0.0"
@@ -6382,6 +6517,13 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
ws@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb"
integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==
dependencies:
async-limiter "~1.0.0"
ws@^6.1.2:
version "6.1.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8"
@@ -6416,6 +6558,11 @@ xmlchars@^1.3.1:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-1.3.1.tgz#1dda035f833dbb4f86a0c28eaa6ca769214793cf"
integrity sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==
xmldom@0.1.*:
version "0.1.27"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk=
xmlhttprequest-ssl@~1.5.4:
version "1.5.5"
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"