[
  {
    "path": ".github/workflows/node.js.yml",
    "content": "# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions\n\nname: Node.js CI\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n\n    env:\n      DEBUG: \"gm*\"\n\n    strategy:\n      matrix:\n        os: [windows-latest, ubuntu-latest]\n        node-version: [14.x, 16.x, 18.x]\n        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/\n\n    steps:\n    - name: Install GraphicsMagic and Imagemagick on Ubuntu\n      if: contains(matrix.os, 'ubuntu')\n      run: sudo apt-get install -y imagemagick graphicsmagick\n    - name: Install GraphicsMagic and Imagemagick on Windows\n      if: contains(matrix.os, 'windows')\n      run: choco install -y imagemagick graphicsmagick\n    - uses: actions/checkout@v3\n    - name: Use Node.js ${{ matrix.node-version }}\n      uses: actions/setup-node@v3\n      with:\n        node-version: ${{ matrix.node-version }}\n    - run: npm i\n    - name: Run tests on Windows\n      if: contains(matrix.os, 'windows')\n      shell: cmd\n      run: |\n        call refreshenv\n        npm test\n    - name: Run tests on Ubuntu\n      if: contains(matrix.os, 'ubuntu')\n      run: npm test"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\npackage-lock.json\nexamples/imgs/*\n!examples/imgs/original.jpg\n!examples/imgs/original.png\n!examples/imgs/original.gif\n!examples/imgs/originalSideways.jpg\n!examples/imgs/morpher.jpg\n!examples/imgs/photo.JPG\n!examples/imgs/orientation/*\\d.jpg\n!examples/imgs/orientation/*.correct.jpg\n*.sw*\n.idea\n"
  },
  {
    "path": ".npmignore",
    "content": "test/\nexamples/\n"
  },
  {
    "path": "History.md",
    "content": "1.25.1 / 2025-02-24\n\n* deps: bump cross-spawn [talyuk](https://github.com/talyuk)\n\n1.25.0 / 2022-09-21\n\n* fixed: windows support #846, #774, #594, #524, #528, #559, #652, #682 [piotr-cz](https://github.com/piotr-cz)\n* docs; improvements from #821 [agokhale](https://github.com/agokhale)\n* docs; improvements #801 [aarongarciah](https://github.com/aarongarciah)\n\n1.24.0 / 2022-09-18\n\n* fixed: infering format of buffered or streamed ico files #429 freund17\n* fixed; preserve color info duing autoOrient() #714, #844 reco\n* tests; switch to Github Actions\n* docs; fix links #834 delesseps\n* docs; clarify install directions #689 PatrykMiszczak\n* refactor; clean up compare.js #788 LongTengDao\n\n1.23.1 / 2017-12-27\n\n * fixed: use debug > 2.6.9 because of security issue #685 danez\n * tests; add nsp check\n * tests; get tests passing on OSX\n\n1.23.0 / 2016-08-03\n\n * fixed; webpack support #547 sean-shirazi\n * fixed; windows support - use cross-spawn to spawn processes #537 bdukes\n * added; allow thumbnail to accept the same options as resize #527 Sebmaster\n * added; dispose support #487 dlwr\n * docs; add example of loading image from URL #544 wahengchang\n * docs; Fix a link in README.md #532 clbn\n * travis; update travis versions #551 amilajack\n\n1.22.0 / 2016-04-07\n\n * fixed; identity parser: support multi-value keys by creating an array #508 #509 [emaniacs](https://github.com/emaniacs)\n * fixed; error handling if gm is not installed #499 [aeo3](https://github.com/aeo3)\n * fixed; highlightColor typo in compare #504 [DanielHudson](https://github.com/DanielHudson)\n * docs; Fix typo #475 [rodrigoalviani](https://github.com/rodrigoalviani)\n\n1.21.1 / 2015-10-26\n\n* fixed: Fixed #465 hard coded gm binary, also fixed issues with compare and fixed tests so they will fail on subsequent runs when they should do [rwky](https://github.com/rwky)\n\n1.21.0 / 2015-10-26 **contains security fix**\n\n* fixed: gm.compare fails to escape arguments properly (Reported by Brendan Scarvell) [rwky](https://github.com/rwky)\n\n1.20.0 / 2015-09-23\n\n* changed: Reverted \"Add format inference from filename for buffers/streams\" due to errors #448\n\n1.19.0 / 2015-09-16\n\n* changed: Added error to notify about image magick not supporting minify [encima](https://github.com/encima)\n* changed: Refactored orientation getter to use faster identify call [lbeschastny](https://github.com/lbeschastny)\n* added: resizeExact function [DanMMX](https://github.com/DanMMX)\n* added: thumbExact function [DanMMX](https://github.com/DanMMX)\n* added: Add format inference from filename for buffers/streams [adurrive](https://github.com/adurrive)\n* fixed: Hex values when passed to compare aren't quoted automatically [DanMMX](https://github.com/DanMMX)\n* fixed: identify returning last frame size instead of the larges on animated gifs [preynal](https://github.com/preynal)\n* docs: Updated docs [laurilehmijoki](https://github.com/laurilehmijoki)\n\n1.18.1 / 2015-05-18\n\n* changed: Added io.js support [rwky](https://github.com/rwky)\n\n1.18.0 / 2015-05-18\n\n* changed: Removed support for node 0.8 and added support for 0.12 [rwky](https://github.com/rwky)\n* changed: Listen to stdin error event for spawn errors [kapouer](https://github.com/kapouer)\n* changed: Improved error handling when gm isn't installed [FreshXOpenSource](https://github.com/FreshXOpenSource)\n* changed: Allow append method to use an array of arguments [emohacker](https://github.com/emohacker)\n* changed: appPath option now specifies full path to gm binary John Borkowski\n* changed: Ignore warning messages for identify [asrail](https://github.com/asrail)\n* added: Montage method [donaldpcook](https://github.com/donaldpcook)\n* added: Progressive option to thumb [mohebifar](https://github.com/mohebifar)\n* added: Native gm auto-orient for use with gm >= 1.3.18 [bog](https://github.com/bog)\n* added: Timeout support by passing the timeout option in milliseconds [marcbachmann](https://github.com/marcbachmann)\n* fixed: density when using ImageMagick [syzer](https://github.com/syzer)\n* fixed: resize behaviour for falsy values [adius](https://github.com/adius)\n\n\n1.17.0 / 2014-10-28\n==================\n\n * changed: extended compare callback also returns the file names #297 [mastix](https://github.com/mastix)\n * changed: pass spawn crash to callback #306 [medikoo](https://github.com/medikoo)\n * changed: geometry supports arbitary string as first argument #330 [jdiez17](https://github.com/jdiez17)\n * added: support for repage+ option #275 [desigens](https://github.com/desigens)\n * added: added the dissolve command #300 [microadm](https://github.com/microadam)\n * added: composite method #332 [jdiez17](https://github.com/jdiez17)\n * fixed: cannot set tolerance to 0 #302 [rwky](https://github.com/rwky)\n * fixed: handle empty buffers #330 [alcidesv](https://github.com/alcidesv)\n\n1.16.0 / 2014-05-09\n==================\n\n * fixed; dropped \"+\" when 0 passed as vertical roll amt #267 [dwtkns](https://github.com/dwtkns)\n * added; highlight-style support #272 [fdecampredon](https://github.com/fdecampredon)\n\n1.15.0 / 2014-05-03\n===================\n\n * changed; gm.compare logic to always run the mse comparison as expected #258 [Vokkim](https://github.com/Vokkim)\n * added; `tolerance` to gm.compare options object #258 [Vokkim](https://github.com/Vokkim)\n * added; option to set ImageMagick application path explicitly #250 (akreitals)\n * fixed; gm.compare: support values like 9.51582e-05 #260 [normanrz](https://github.com/normanrz)\n * README: add call for maintainers\n\n1.14.2 / 2013-12-24\n===================\n\n* fixed; background is now a setting #246 (PEM--)\n\n1.14.1 / 2013-12-09\n===================\n\n* fixed; identify -verbose colon behavior #240 ludow\n\n1.14.0 / 2013-12-04\n===================\n\n* added; compare method for imagemagick (longlho)\n\n1.13.3 / 2013-10-22\n===================\n\n* fixed; escape diffOptions.file in compare (dwabyick)\n\n1.13.2 / 2013-10-18\n===================\n\n* fixed; density is a setting not an operator\n\n1.13.1 / 2013-09-15\n===================\n\n* added; boolean for % crop\n\n1.13.0 / 2013-09-07\n===================\n\n* added; morph more than two images (overra)\n\n1.12.2 / 2013-08-29\n===================\n\n* fixed; fallback to through in node 0.8\n\n1.12.1 / 2013-08-29 (unpublished)\n===================\n\n* refactor; replace through with stream.PassThrough\n\n1.12.0 / 2013-08-27\n===================\n\n* added; diff image output file (chenglou)\n\n1.11.1 / 2013-08-17\n===================\n\n* added; proto.selectFrame(#)\n* fixed; getters should not ignore frame selection\n\n1.11.0 / 2013-07-23\n===================\n\n* added; optional formatting string for gm().identify(format, callback) (tornillo)\n* removed; error messages when gm/im binary is not installed\n\n1.10.0 / 2013-06-27\n===================\n\n* refactor; use native `-auto-orient` for imagemagick\n\n1.9.2 / 2013-06-12\n==================\n\n  * refactor; move `streamToBuffer` to a separate module\n  * fixed; .stream(format) without a callback\n\n1.9.1 / 2013-05-07\n==================\n\n  * fixed; gm().resize(width) always only resizes width\n  * fixed; gm('img.gif').format() returns the format of the first frame\n\n1.9.0 / 2013-04-21\n==================\n\n  * added; node v0.10 support\n  * removed; node < v0.8 support - `Buffer.concat()`\n  * tests; all tests now run on Travis\n  * added; gm().stream() returns a stream when no callback is present\n  * added; gm().toBuffer(callback)\n  * fixed; gm().size() only returns the size of the first frame of a GIF\n\n1.8.2 / 2013-03-07\n==================\n\n  * include source path in identify data #126 [soupdiver](https://github.com/soupdiver)\n\n1.8.1 / 2012-12-21\n==================\n\n  * Avoid losing already set arguments on identify #105 #113 #109 [JNissi](https://github.com/JNissi)\n  * tests; add autoOrient + thumb() test\n  * tests; add test case for #113\n  * tests; added test for #109\n  * tests; add resize on buffer test\n\n1.8.0 / 2012-12-14\n==================\n\n  * added; geometry support to scale() #98\n  * removed; incorrect/broken dissolve() method (never worked)\n  * fixed; handle child_proc error when using Buffer input #109\n  * fixed; use of Buffers with identify() #109\n  * fixed; no longer include -size arg with resize() #98\n  * fixed; remove -size arg from extent() #103\n  * fixed; magnify support\n  * fixed; autoOrient to work with all types of exif orientations [dambalah](https://github.com/dambalah) #108\n  * tests; npm test runs unit only (now compatible with travis)\n  * tests; fix magnify test on imagemagick\n  * tests; added for cmd line args\n\n1.7.0 / 2012-12-06\n==================\n\n  * added; gm.compare support\n  * added; passing Buffers directly [danmilon](https://github.com/danmilon)\n\n1.6.1 / 2012-11-13\n==================\n\n  * fixed regression; only pass additional params on error #96\n\n1.6.0 / 2012-11-10\n==================\n\n  * changed; rename internal buffer to _buffer #88 [kof](https://github.com/kof)\n  * changed; optimized identify getters (format, depth, size, color, filesize). #83 please read this for details: https://github.com/aheckmann/gm/commit/8fcf3f8f84a02cc2001da874cbebb89bf7084409\n  * added; visionmedia/debug support\n  * added; `gm convert -thumbnail` support. _differs from thumb()._ [danmilon](https://github.com/danmilon)\n  * fixed; -rotate 0 support #90\n  * fixed; multi-execution of same gm instance arguments corruption\n  * fixed; gracefully handle parser errors #94 [eldilibra](https://github.com/eldilibra)\n\n1.5.1 / 2012-10-02\n==================\n\n  * fixed; passing multiple paths to append() #77\n\n1.5.0 / 2012-09-15\n==================\n\n  * fixed; callback scope\n  * fixed; append() usage #77\n\n1.4.2 / 2012-08-17\n==================\n\n  * fixed; identify parsing for ImageMagick exif data (#58)\n  * fixed; when in imageMagick mode, complain about missing imageMagick [bcherry](https://github.com/bcherry) (#73)\n  * added; tests\n\n1.4.1 / 2012-07-31\n==================\n\n  * fixed; scenes() args\n  * fixed; accept the left-to-right arg of append()\n  * added; _subCommand\n\n## v1.4 - 07/28/2012\n\n  * added; adjoin() [Math-]\n  * added; affine() [Math-]\n  * added; append() [Math-]\n  * added; authenticate() [Math-]\n  * added; average() [Math-]\n  * added; backdrop() [Math-]\n  * added; blackThreshold() [Math-]\n  * added; bluePrimary() [Math-]\n  * added; border() [Math-]\n  * added; borderColor() [Math-]\n  * added; box() [Math-]\n  * added; channel() [Math-]\n  * added; clip() [Math-]\n  * added; coalesce() [Math-]\n  * added; colorMap() [Math-]\n  * added; compose() [Math-]\n  * added; compress() [Math-]\n  * added; convolve() [Math-]\n  * added; createDirectories() [Math-]\n  * added; deconstruct() [Math-]\n  * added; delay() [Math-]\n  * added; define() [Math-]\n  * added; displace() [Math-]\n  * added; display() [Math-]\n  * added; dispose() [Math-]\n  * added; disolve() [Math-]\n  * added; encoding() [Math-]\n  * added; endian() [Math-]\n  * added; file() [Math-]\n  * added; flatten() [Math-]\n  * added; foreground() [Math-]\n  * added; frame() [Math-]\n  * added; fuzz() [Math-]\n  * added; gaussian() [Math-]\n  * added; geometry() [Math-]\n  * added; greenPrimary() [Math-]\n  * added; highlightColor() [Math-]\n  * added; highlightStyle() [Math-]\n  * added; iconGeometry() [Math-]\n  * added; intent() [Math-]\n  * added; lat() [Math-]\n  * added; level() [Math-]\n  * added; list() [Math-]\n  * added; log() [Math-]\n  * added; map() [Math-]\n  * added; matte() [Math-]\n  * added; matteColor() [Math-]\n  * added; mask() [Math-]\n  * added; maximumError() [Math-]\n  * added; mode() [Math-]\n  * added; monitor() [Math-]\n  * added; mosaic() [Math-]\n  * added; motionBlur() [Math-]\n  * added; name() [Math-]\n  * added; noop() [Math-]\n  * added; normalize() [Math-]\n  * added; opaque() [Math-]\n  * added; operator() [Math-]\n  * added; orderedDither() [Math-]\n  * added; outputDirectory() [Math-]\n  * added; page() [Math-]\n  * added; pause() [Math-]\n  * added; pen() [Math-]\n  * added; ping() [Math-]\n  * added; pointSize() [Math-]\n  * added; preview() [Math-]\n  * added; process() [Math-]\n  * added; profile() [Math-]\n  * added; progress() [Math-]\n  * added; rawSize() [Math-]\n  * added; randomThreshold() [Math-]\n  * added; recolor() [Math-]\n  * added; redPrimary() [Math-]\n  * added; remote() [Math-]\n  * added; render() [Math-]\n  * added; repage() [Math-]\n  * added; sample() [Math-]\n  * added; samplingFactor() [Math-]\n  * added; scene() [Math-]\n  * added; scenes() [Math-]\n  * added; screen() [Math-]\n  * added; segment() [Math-]\n  * added; set() [Math-]\n  * added; shade() [Math-]\n  * added; shadow() [Math-]\n  * added; sharedMemory() [Math-]\n  * added; shave() [Math-]\n  * added; shear() [Math-]\n  * added; silent() [Math-]\n  * added; snaps() [Math-]\n  * added; stagano() [Math-]\n  * added; stereo() [Math-]\n  * added; textFont() [Math-]\n  * added; texture() [Math-]\n  * added; threshold() [Math-]\n  * added; tile() [Math-]\n  * added; transform() [Math-]\n  * added; transparent() [Math-]\n  * added; treeDepth() [Math-]\n  * added; update() [Math-]\n  * added; units() [Math-]\n  * added; unsharp() [Math-]\n  * added; usePixmap() [Math-]\n  * added; view() [Math-]\n  * added; virtualPixel() [Math-]\n  * added; visual() [Math-]\n  * added; watermark() [Math-]\n  * added; wave() [Math-]\n  * added; whitePoint() [Math-]\n  * added; whiteThreshold() [Math-]\n  * added; window() [Math-]\n  * added; windowGroup() [Math-]\n\n## v1.3.2 - 06/22/2012\n\n  * added; node >= 0.7/0.8 compat\n\n## v1.3.1 - 06/06/2012\n\n  * fixed; thumb() alignment and cropping [thomaschaaf]\n  * added; hint when graphicsmagick is not installed (#62)\n  * fixed; minify() (#59)\n\n## v1.3.0 - 04/11/2012\n\n  * added; flatten support [jwarchol]\n  * added; background support [jwarchol]\n  * fixed; identify parser error [chriso]\n\n## v1.2.0 - 03/30/2012\n\n  * added; extent and gravity support [jwarchol]\n\n## v1.1.0 - 03/15/2012\n\n  * added; filter() support [travisbeck]\n  * added; density() [travisbeck]\n  * fixed; permit either width or height in resize [dambalah]\n  * updated; docs\n\n## v1.0.5 - 02/15/2012\n\n  * added; strip() support [Math-]\n  * added; interlace() support [Math-]\n  * added; setFormat() support [Math-]\n  * fixed; regexps for image types [Math-]\n\n## v1.0.4 - 02/09/2012\n\n  * expose utils\n\n## v1.0.3 - 01/27/2012\n\n  * removed; console.log\n\n## v1.0.2 - 01/24/2012\n\n  * added; debugging info on parser errors\n  * fixed; exports.version\n\n## v1.0.1 - 01/12/2012\n\n  * fixed; use of reserved keyword `super` for node v0.5+\n\n## v1.0.0 - 01/12/2012\n\n  * added; autoOrient support [kainosnoema] (#21)\n  * added; orientation support [kainosnoema] (#21)\n  * fixed; identify parser now properly JSON formats all data output by `gm identify` such as IPTC, GPS, Make, etc (#20)\n  * added; support for running as imagemagick (#23, #29)\n  * added; subclassing support; useful for setting default constructor options like one constructor for ImageMagick, the other for GM\n  * added; more tests\n  * changed; remove redundant `orientation`, `resolution`, and `filesize` from `this.data` in `indentify()`. Use their uppercase equivalents.\n\n## v0.6.0 - 12/14/2011\n\n  * added; stream support [kainosnoema] (#22)\n\n## v0.5.0 - 07/07/2011\n\n  * added; gm#trim() support [lepokle]\n  * added; gm#inputIs() support\n  * fixed; 'geometry does not contain image' error: gh-17\n\n## v0.4.3 - 05/17/2011\n\n  * added; bunch of tests\n  * fixed; polygon, polyline, bezier drawing bug\n\n## v0.4.2 - 05/10/2011\n\n  * added; resize options support\n\n## v0.4.1 - 04/28/2011\n\n  * shell args are now escaped (thanks @visionmedia)\n  * added; gm.in()\n  * added; gm.out()\n  * various refactoring\n\n## v0.4.0 - 9/21/2010\n\n  * removed deprecated `new` method\n  * added drawing docs\n\n## v0.3.2 - 9/06/2010\n\n  * new images are now created using same gm() constructor\n\n## v0.3.1 - 9/06/2010\n\n  * can now create images from scratch\n  * add type method\n\n## v0.3.0 - 8/26/2010\n\n  * add drawing api\n\n## v0.2.2 - 8/22/2010\n\n  * add quality option to thumb()\n  * add teropa to contributors\n  * added support for colorspace()\n\n## v0.2.1 - 7/31/2010\n\n  * fixed naming conflict. depth() manipulation method renamed bitdepth()\n  * added better docs\n\n## v0.2.0 - 7/29/2010\n\nnew methods\n\n  - swirl\n  - spread\n  - solarize\n  - sharpen\n  - roll\n  - sepia\n  - region\n  - raise\n  - lower\n  - paint\n  - noise\n  - negative\n  - morph\n  - median\n  - antialias\n  - limit\n  - label\n  - implode\n  - gamma\n  - enhance\n  - equalize\n  - emboss\n  - edge\n  - dither\n  - monochrome\n  - despeckle\n  - depth\n  - cycle\n  - contrast\n  - comment\n  - colors\n\nadded more default args to several methods\nadded more examples\n\n\n## v0.1.2 - 7/28/2010\n\n  * refactor project into separate modules\n\n\n## v0.1.1 - 7/27/2010\n\n  * add modulate method\n  * add colorize method\n  * add charcoal method\n  * add chop method\n  * bug fix in write without a callback\n\n\n## v0.1.0 - 6/27/2010\n\n  * no longer supporting mogrify\n  * add image data getter methods\n\n    * size\n    * format\n    * color\n    * res\n    * depth\n    * filesize\n    * identify\n\n  * add new convert methods\n\n    * scale\n    * resample\n    * rotate\n    * flip\n    * flop\n    * crop\n    * magnify\n    * minify\n    * quality\n    * blur\n    * thumb\n\n\n## v0.0.1 - 6/11/2010\nInitial release\n"
  },
  {
    "path": "README.md",
    "content": "# 2025-02-24 This project is not maintained\n\nInstead of using this project, execute the `gm` or `magick` binaries using\n[`cross-spawn`](https://www.npmjs.com/package/cross-spawn) directly.\n\nNearly [15 years ago](https://github.com/aheckmann/gm/commit/defc7360d70d87f7a13da4f6e2ef0104594776b9) I started this project as part of my start up which I sold later that year (2010). Having not used this project in over a decade and with no contributors for years, it's time to officially sunset `gm`.\n\nNo further Issues will be addressed. No Pull Requests will be merged. No new commits or npm releases will be made.\n\n---\n\n😍 _Massive **thank you** to [everyone](https://github.com/aheckmann/gm/graphs/contributors) who contributed to this project over the years._ 😍\n\n---\n\n## I want to continue using gm. What do I do?\n\nAll past `gm` releases published to the npm registry will continue to be available for install. However, you should **prioritize moving off of this project to an alternative** because the risk of unpatched vulnerabilities in this project will continue to _increase_ over time. No new commits will land and no new releases will be published.\n\nThe most obvious alternative to `gm` I see is installing [cross-spawn](https://www.npmjs.com/package/cross-spawn) and executing the GraphicsMagick or ImageMagick binaries directly, after all, that's pretty much all this project did. There may be other `gm` alternatives on npm but I don't what they are offhand so you'll need to search for something suitable yourself.\n\n---\n\n\n# gm [![Build Status](https://travis-ci.org/aheckmann/gm.png?branch=master)](https://travis-ci.org/aheckmann/gm)  [![NPM Version](https://img.shields.io/npm/v/gm.svg?style=flat)](https://www.npmjs.org/package/gm)\n\nGraphicsMagick and ImageMagick for node\n\n## Bug Reports\n\nWhen reporting bugs please include the version of graphicsmagick/imagemagick you're using (gm -version/convert -version) as well as the version of this module and copies of any images you're having problems with.\n\n## Getting started\nFirst download and install [GraphicsMagick](http://www.graphicsmagick.org/) or [ImageMagick](http://www.imagemagick.org/). In Mac OS X, you can simply use [Homebrew](http://mxcl.github.io/homebrew/) and do:\n\n    brew install imagemagick\n    brew install graphicsmagick\n\nthen either use npm:\n\n    npm install gm\n\nor clone the repo:\n\n    git clone git://github.com/aheckmann/gm.git\n\n\n## Use ImageMagick instead of gm\n\nSubclass `gm` to enable [ImageMagick 7+](https://imagemagick.org/script/porting.php)\n\n```js\nconst fs = require('fs')\nconst gm = require('gm').subClass({ imageMagick: '7+' });\n```\n\nOr, to enable ImageMagick legacy mode (for ImageMagick version < 7)\n\n```js\nconst fs = require('fs')\nconst gm = require('gm').subClass({ imageMagick: true });\n```\n\n## Specify the executable path\n\nOptionally specify the path to the executable.\n\n```js\nconst fs = require('fs')\nconst gm = require('gm').subClass({\n  appPath: String.raw`C:\\Program Files\\ImageMagick-7.1.0-Q16-HDRI\\magick.exe`\n});\n```\n\n## Basic Usage\n\n```js\nvar fs = require('fs')\n  , gm = require('gm');\n\n// resize and remove EXIF profile data\ngm('/path/to/my/img.jpg')\n.resize(240, 240)\n.noProfile()\n.write('/path/to/resize.png', function (err) {\n  if (!err) console.log('done');\n});\n\n// some files would not be resized appropriately\n// http://stackoverflow.com/questions/5870466/imagemagick-incorrect-dimensions\n// you have two options:\n// use the '!' flag to ignore aspect ratio\ngm('/path/to/my/img.jpg')\n.resize(240, 240, '!')\n.write('/path/to/resize.png', function (err) {\n  if (!err) console.log('done');\n});\n\n// use the .resizeExact with only width and/or height arguments\ngm('/path/to/my/img.jpg')\n.resizeExact(240, 240)\n.write('/path/to/resize.png', function (err) {\n  if (!err) console.log('done');\n});\n\n// obtain the size of an image\ngm('/path/to/my/img.jpg')\n.size(function (err, size) {\n  if (!err)\n    console.log(size.width > size.height ? 'wider' : 'taller than you');\n});\n\n// output all available image properties\ngm('/path/to/img.png')\n.identify(function (err, data) {\n  if (!err) console.log(data)\n});\n\n// pull out the first frame of an animated gif and save as png\ngm('/path/to/animated.gif[0]')\n.write('/path/to/firstframe.png', function (err) {\n  if (err) console.log('aaw, shucks');\n});\n\n// auto-orient an image\ngm('/path/to/img.jpg')\n.autoOrient()\n.write('/path/to/oriented.jpg', function (err) {\n  if (err) ...\n})\n\n// crazytown\ngm('/path/to/my/img.jpg')\n.flip()\n.magnify()\n.rotate('green', 45)\n.blur(7, 3)\n.crop(300, 300, 150, 130)\n.edge(3)\n.write('/path/to/crazy.jpg', function (err) {\n  if (!err) console.log('crazytown has arrived');\n})\n\n// annotate an image\ngm('/path/to/my/img.jpg')\n.stroke(\"#ffffff\")\n.drawCircle(10, 10, 20, 10)\n.font(\"Helvetica.ttf\", 12)\n.drawText(30, 20, \"GMagick!\")\n.write(\"/path/to/drawing.png\", function (err) {\n  if (!err) console.log('done');\n});\n\n// creating an image\ngm(200, 400, \"#ddff99f3\")\n.drawText(10, 50, \"from scratch\")\n.write(\"/path/to/brandNewImg.jpg\", function (err) {\n  // ...\n});\n```\n\n## Streams\n\n```js\n// passing a stream\nvar readStream = fs.createReadStream('/path/to/my/img.jpg');\ngm(readStream, 'img.jpg')\n.write('/path/to/reformat.png', function (err) {\n  if (!err) console.log('done');\n});\n\n\n// passing a downloadable image by url\n\nvar request = require('request');\nvar url = \"www.abc.com/pic.jpg\"\n\ngm(request(url))\n.write('/path/to/reformat.png', function (err) {\n  if (!err) console.log('done');\n});\n\n\n// can also stream output to a ReadableStream\n// (can be piped to a local file or remote server)\ngm('/path/to/my/img.jpg')\n.resize('200', '200')\n.stream(function (err, stdout, stderr) {\n  var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');\n  stdout.pipe(writeStream);\n});\n\n// without a callback, .stream() returns a stream\n// this is just a convenience wrapper for above.\nvar writeStream = fs.createWriteStream('/path/to/my/resized.jpg');\ngm('/path/to/my/img.jpg')\n.resize('200', '200')\n.stream()\n.pipe(writeStream);\n\n// pass a format or filename to stream() and\n// gm will provide image data in that format\ngm('/path/to/my/img.jpg')\n.stream('png', function (err, stdout, stderr) {\n  var writeStream = fs.createWriteStream('/path/to/my/reformatted.png');\n  stdout.pipe(writeStream);\n});\n\n// or without the callback\nvar writeStream = fs.createWriteStream('/path/to/my/reformatted.png');\ngm('/path/to/my/img.jpg')\n.stream('png')\n.pipe(writeStream);\n\n// combine the two for true streaming image processing\nvar readStream = fs.createReadStream('/path/to/my/img.jpg');\ngm(readStream)\n.resize('200', '200')\n.stream(function (err, stdout, stderr) {\n  var writeStream = fs.createWriteStream('/path/to/my/resized.jpg');\n  stdout.pipe(writeStream);\n});\n\n// GOTCHA:\n// when working with input streams and any 'identify'\n// operation (size, format, etc), you must pass \"{bufferStream: true}\" if\n// you also need to convert (write() or stream()) the image afterwards\n// NOTE: this buffers the readStream in memory!\nvar readStream = fs.createReadStream('/path/to/my/img.jpg');\ngm(readStream)\n.size({bufferStream: true}, function(err, size) {\n  this.resize(size.width / 2, size.height / 2)\n  this.write('/path/to/resized.jpg', function (err) {\n    if (!err) console.log('done');\n  });\n});\n\n```\n\n## Buffers\n\n```js\n// A buffer can be passed instead of a filepath as well\nvar buf = require('fs').readFileSync('/path/to/image.jpg');\n\ngm(buf, 'image.jpg')\n.noise('laplacian')\n.write('/path/to/out.jpg', function (err) {\n  if (err) return handle(err);\n  console.log('Created an image from a Buffer!');\n});\n\n/*\nA buffer can also be returned instead of a stream\nThe first argument to toBuffer is optional, it specifies the image format\n*/\ngm('img.jpg')\n.resize(100, 100)\n.toBuffer('PNG',function (err, buffer) {\n  if (err) return handle(err);\n  console.log('done!');\n})\n```\n\n## Custom Arguments\n\nIf `gm` does not supply you with a method you need or does not work as you'd like, you can simply use `gm().in()` or `gm().out()` to set your own arguments.\n\n- `gm().command()` - Custom command such as `identify` or `convert`\n- `gm().in()` - Custom input arguments\n- `gm().out()` - Custom output arguments\n\nThe command will be formatted in the following order:\n\n1. `command` - ie `convert`\n2. `in` - the input arguments\n3. `source` - stdin or an image file\n4. `out` - the output arguments\n5. `output` - stdout or the image file to write to\n\nFor example, suppose you want the following command:\n\n```bash\ngm \"convert\" \"label:Offline\" \"PNG:-\"\n```\n\nHowever, using `gm().label()` may not work as intended for you:\n\n```js\ngm()\n.label('Offline')\n.stream();\n```\n\nwould yield:\n\n```bash\ngm \"convert\" \"-label\" \"\\\"Offline\\\"\" \"PNG:-\"\n```\n\nInstead, you can use `gm().out()`:\n\n```js\ngm()\n.out('label:Offline')\n.stream();\n```\n\nwhich correctly yields:\n\n```bash\ngm \"convert\" \"label:Offline\" \"PNG:-\"\n```\n\n### Custom Identify Format String\n\nWhen identifying an image, you may want to use a custom formatting string instead of using `-verbose`, which is quite slow.\nYou can use your own [formatting string](http://www.imagemagick.org/script/escape.php) when using `gm().identify(format, callback)`.\nFor example,\n\n```js\ngm('img.png').format(function (err, format) {\n\n})\n\n// is equivalent to\n\ngm('img.png').identify('%m', function (err, format) {\n\n})\n```\n\nsince `%m` is the format option for getting the image file format.\n\n## Platform differences\n\nPlease document and refer to any [platform or ImageMagick/GraphicsMagick issues/differences here](https://github.com/aheckmann/gm/wiki/GraphicsMagick-and-ImageMagick-versions).\n\n## Examples:\n\n  Check out the [examples](http://github.com/aheckmann/gm/tree/master/examples/) directory to play around.\n  Also take a look at the [extending gm](http://wiki.github.com/aheckmann/gm/extending-gm)\n  page to see how to customize gm to your own needs.\n\n## Constructor:\n\n  There are a few ways you can use the `gm` image constructor.\n\n  - 1) `gm(path)` When you pass a string as the first argument it is interpreted as the path to an image you intend to manipulate.\n  - 2) `gm(stream || buffer, [filename])` You may also pass a ReadableStream or Buffer as the first argument, with an optional file name for format inference.\n  - 3) `gm(width, height, [color])` When you pass two integer arguments, gm will create a new image on the fly with the provided dimensions and an optional background color. And you can still chain just like you do with pre-existing images too. See [here](http://github.com/aheckmann/gm/blob/master/examples/new.js) for an example.\n\nThe links below refer to an older version of gm but everything should still work, if anyone feels like updating them please make a PR\n\n## Methods\n\n  - getters\n    - [size](http://aheckmann.github.io/gm/docs.html#getters) - returns the size (WxH) of the image\n    - [orientation](http://aheckmann.github.io/gm/docs.html#getters) - returns the EXIF orientation of the image\n    - [format](http://aheckmann.github.io/gm/docs.html#getters) - returns the image format (gif, jpeg, png, etc)\n    - [depth](http://aheckmann.github.io/gm/docs.html#getters) - returns the image color depth\n    - [color](http://aheckmann.github.io/gm/docs.html#getters) - returns the number of colors\n    - [res](http://aheckmann.github.io/gm/docs.html#getters)   - returns the image resolution\n    - [filesize](http://aheckmann.github.io/gm/docs.html#getters) - returns image filesize\n    - [identify](http://aheckmann.github.io/gm/docs.html#getters) - returns all image data available. Takes an optional format string.\n\n  - manipulation\n    - [adjoin](http://aheckmann.github.io/gm/docs.html#adjoin)\n    - [affine](http://aheckmann.github.io/gm/docs.html#affine)\n    - [antialias](http://aheckmann.github.io/gm/docs.html#antialias)\n    - [append](http://aheckmann.github.io/gm/docs.html#append)\n    - [authenticate](http://aheckmann.github.io/gm/docs.html#authenticate)\n    - [autoOrient](http://aheckmann.github.io/gm/docs.html#autoOrient)\n    - [average](http://aheckmann.github.io/gm/docs.html#average)\n    - [backdrop](http://aheckmann.github.io/gm/docs.html#backdrop)\n    - [bitdepth](http://aheckmann.github.io/gm/docs.html#bitdepth)\n    - [blackThreshold](http://aheckmann.github.io/gm/docs.html#blackThreshold)\n    - [bluePrimary](http://aheckmann.github.io/gm/docs.html#bluePrimary)\n    - [blur](http://aheckmann.github.io/gm/docs.html#blur)\n    - [border](http://aheckmann.github.io/gm/docs.html#border)\n    - [borderColor](http://aheckmann.github.io/gm/docs.html#borderColor)\n    - [box](http://aheckmann.github.io/gm/docs.html#box)\n    - [channel](http://aheckmann.github.io/gm/docs.html#channel)\n    - [charcoal](http://aheckmann.github.io/gm/docs.html#charcoal)\n    - [chop](http://aheckmann.github.io/gm/docs.html#chop)\n    - [clip](http://aheckmann.github.io/gm/docs.html#clip)\n    - [coalesce](http://aheckmann.github.io/gm/docs.html#coalesce)\n    - [colors](http://aheckmann.github.io/gm/docs.html#colors)\n    - [colorize](http://aheckmann.github.io/gm/docs.html#colorize)\n    - [colorMap](http://aheckmann.github.io/gm/docs.html#colorMap)\n    - [colorspace](http://aheckmann.github.io/gm/docs.html#colorspace)\n    - [comment](http://aheckmann.github.io/gm/docs.html#comment)\n    - [compose](http://aheckmann.github.io/gm/docs.html#compose)\n    - [compress](http://aheckmann.github.io/gm/docs.html#compress)\n    - [contrast](http://aheckmann.github.io/gm/docs.html#contrast)\n    - [convolve](http://aheckmann.github.io/gm/docs.html#convolve)\n    - [createDirectories](http://aheckmann.github.io/gm/docs.html#createDirectories)\n    - [crop](http://aheckmann.github.io/gm/docs.html#crop)\n    - [cycle](http://aheckmann.github.io/gm/docs.html#cycle)\n    - [deconstruct](http://aheckmann.github.io/gm/docs.html#deconstruct)\n    - [delay](http://aheckmann.github.io/gm/docs.html#delay)\n    - [define](http://aheckmann.github.io/gm/docs.html#define)\n    - [density](http://aheckmann.github.io/gm/docs.html#density)\n    - [despeckle](http://aheckmann.github.io/gm/docs.html#despeckle)\n    - [dither](http://aheckmann.github.io/gm/docs.html#dither)\n    - [displace](http://aheckmann.github.io/gm/docs.html#dither)\n    - [display](http://aheckmann.github.io/gm/docs.html#display)\n    - [dispose](http://aheckmann.github.io/gm/docs.html#dispose)\n    - [dissolve](http://aheckmann.github.io/gm/docs.html#dissolve)\n    - [edge](http://aheckmann.github.io/gm/docs.html#edge)\n    - [emboss](http://aheckmann.github.io/gm/docs.html#emboss)\n    - [encoding](http://aheckmann.github.io/gm/docs.html#encoding)\n    - [enhance](http://aheckmann.github.io/gm/docs.html#enhance)\n    - [endian](http://aheckmann.github.io/gm/docs.html#endian)\n    - [equalize](http://aheckmann.github.io/gm/docs.html#equalize)\n    - [extent](http://aheckmann.github.io/gm/docs.html#extent)\n    - [file](http://aheckmann.github.io/gm/docs.html#file)\n    - [filter](http://aheckmann.github.io/gm/docs.html#filter)\n    - [flatten](http://aheckmann.github.io/gm/docs.html#flatten)\n    - [flip](http://aheckmann.github.io/gm/docs.html#flip)\n    - [flop](http://aheckmann.github.io/gm/docs.html#flop)\n    - [foreground](http://aheckmann.github.io/gm/docs.html#foreground)\n    - [frame](http://aheckmann.github.io/gm/docs.html#frame)\n    - [fuzz](http://aheckmann.github.io/gm/docs.html#fuzz)\n    - [gamma](http://aheckmann.github.io/gm/docs.html#gamma)\n    - [gaussian](http://aheckmann.github.io/gm/docs.html#gaussian)\n    - [geometry](http://aheckmann.github.io/gm/docs.html#geometry)\n    - [gravity](http://aheckmann.github.io/gm/docs.html#gravity)\n    - [greenPrimary](http://aheckmann.github.io/gm/docs.html#greenPrimary)\n    - [highlightColor](http://aheckmann.github.io/gm/docs.html#highlightColor)\n    - [highlightStyle](http://aheckmann.github.io/gm/docs.html#highlightStyle)\n    - [iconGeometry](http://aheckmann.github.io/gm/docs.html#iconGeometry)\n    - [implode](http://aheckmann.github.io/gm/docs.html#implode)\n    - [intent](http://aheckmann.github.io/gm/docs.html#intent)\n    - [interlace](http://aheckmann.github.io/gm/docs.html#interlace)\n    - [label](http://aheckmann.github.io/gm/docs.html#label)\n    - [lat](http://aheckmann.github.io/gm/docs.html#lat)\n    - [level](http://aheckmann.github.io/gm/docs.html#level)\n    - [list](http://aheckmann.github.io/gm/docs.html#list)\n    - [limit](http://aheckmann.github.io/gm/docs.html#limit)\n    - [log](http://aheckmann.github.io/gm/docs.html#log)\n    - [loop](http://aheckmann.github.io/gm/docs.html#loop)\n    - [lower](http://aheckmann.github.io/gm/docs.html#lower)\n    - [magnify](http://aheckmann.github.io/gm/docs.html#magnify)\n    - [map](http://aheckmann.github.io/gm/docs.html#map)\n    - [matte](http://aheckmann.github.io/gm/docs.html#matte)\n    - [matteColor](http://aheckmann.github.io/gm/docs.html#matteColor)\n    - [mask](http://aheckmann.github.io/gm/docs.html#mask)\n    - [maximumError](http://aheckmann.github.io/gm/docs.html#maximumError)\n    - [median](http://aheckmann.github.io/gm/docs.html#median)\n    - [minify](http://aheckmann.github.io/gm/docs.html#minify)\n    - [mode](http://aheckmann.github.io/gm/docs.html#mode)\n    - [modulate](http://aheckmann.github.io/gm/docs.html#modulate)\n    - [monitor](http://aheckmann.github.io/gm/docs.html#monitor)\n    - [monochrome](http://aheckmann.github.io/gm/docs.html#monochrome)\n    - [morph](http://aheckmann.github.io/gm/docs.html#morph)\n    - [mosaic](http://aheckmann.github.io/gm/docs.html#mosaic)\n    - [motionBlur](http://aheckmann.github.io/gm/docs.html#motionBlur)\n    - [name](http://aheckmann.github.io/gm/docs.html#name)\n    - [negative](http://aheckmann.github.io/gm/docs.html#negative)\n    - [noise](http://aheckmann.github.io/gm/docs.html#noise)\n    - [noop](http://aheckmann.github.io/gm/docs.html#noop)\n    - [normalize](http://aheckmann.github.io/gm/docs.html#normalize)\n    - [noProfile](http://aheckmann.github.io/gm/docs.html#profile)\n    - [opaque](http://aheckmann.github.io/gm/docs.html#opaque)\n    - [operator](http://aheckmann.github.io/gm/docs.html#operator)\n    - [orderedDither](http://aheckmann.github.io/gm/docs.html#orderedDither)\n    - [outputDirectory](http://aheckmann.github.io/gm/docs.html#outputDirectory)\n    - [paint](http://aheckmann.github.io/gm/docs.html#paint)\n    - [page](http://aheckmann.github.io/gm/docs.html#page)\n    - [pause](http://aheckmann.github.io/gm/docs.html#pause)\n    - [pen](http://aheckmann.github.io/gm/docs.html#pen)\n    - [ping](http://aheckmann.github.io/gm/docs.html#ping)\n    - [pointSize](http://aheckmann.github.io/gm/docs.html#pointSize)\n    - [preview](http://aheckmann.github.io/gm/docs.html#preview)\n    - [process](http://aheckmann.github.io/gm/docs.html#process)\n    - [profile](http://aheckmann.github.io/gm/docs.html#profile)\n    - [progress](http://aheckmann.github.io/gm/docs.html#progress)\n    - [quality](http://aheckmann.github.io/gm/docs.html#quality)\n    - [raise](http://aheckmann.github.io/gm/docs.html#raise)\n    - [rawSize](http://aheckmann.github.io/gm/docs.html#rawSize)\n    - [randomThreshold](http://aheckmann.github.io/gm/docs.html#randomThreshold)\n    - [recolor](http://aheckmann.github.io/gm/docs.html#recolor)\n    - [redPrimary](http://aheckmann.github.io/gm/docs.html#redPrimary)\n    - [region](http://aheckmann.github.io/gm/docs.html#region)\n    - [remote](http://aheckmann.github.io/gm/docs.html#remote)\n    - [render](http://aheckmann.github.io/gm/docs.html#render)\n    - [repage](http://aheckmann.github.io/gm/docs.html#repage)\n    - [resample](http://aheckmann.github.io/gm/docs.html#resample)\n    - [resize](http://aheckmann.github.io/gm/docs.html#resize)\n    - [roll](http://aheckmann.github.io/gm/docs.html#roll)\n    - [rotate](http://aheckmann.github.io/gm/docs.html#rotate)\n    - [sample](http://aheckmann.github.io/gm/docs.html#sample)\n    - [samplingFactor](http://aheckmann.github.io/gm/docs.html#samplingFactor)\n    - [scale](http://aheckmann.github.io/gm/docs.html#scale)\n    - [scene](http://aheckmann.github.io/gm/docs.html#scene)\n    - [scenes](http://aheckmann.github.io/gm/docs.html#scenes)\n    - [screen](http://aheckmann.github.io/gm/docs.html#screen)\n    - [segment](http://aheckmann.github.io/gm/docs.html#segment)\n    - [sepia](http://aheckmann.github.io/gm/docs.html#sepia)\n    - [set](http://aheckmann.github.io/gm/docs.html#set)\n    - [setFormat](http://aheckmann.github.io/gm/docs.html#setformat)\n    - [shade](http://aheckmann.github.io/gm/docs.html#shade)\n    - [shadow](http://aheckmann.github.io/gm/docs.html#shadow)\n    - [sharedMemory](http://aheckmann.github.io/gm/docs.html#sharedMemory)\n    - [sharpen](http://aheckmann.github.io/gm/docs.html#sharpen)\n    - [shave](http://aheckmann.github.io/gm/docs.html#shave)\n    - [shear](http://aheckmann.github.io/gm/docs.html#shear)\n    - [silent](http://aheckmann.github.io/gm/docs.html#silent)\n    - [solarize](http://aheckmann.github.io/gm/docs.html#solarize)\n    - [snaps](http://aheckmann.github.io/gm/docs.html#snaps)\n    - [stegano](http://aheckmann.github.io/gm/docs.html#stegano)\n    - [stereo](http://aheckmann.github.io/gm/docs.html#stereo)\n    - [strip](http://aheckmann.github.io/gm/docs.html#strip) _imagemagick only_\n    - [spread](http://aheckmann.github.io/gm/docs.html#spread)\n    - [swirl](http://aheckmann.github.io/gm/docs.html#swirl)\n    - [textFont](http://aheckmann.github.io/gm/docs.html#textFont)\n    - [texture](http://aheckmann.github.io/gm/docs.html#texture)\n    - [threshold](http://aheckmann.github.io/gm/docs.html#threshold)\n    - [thumb](http://aheckmann.github.io/gm/docs.html#thumb)\n    - [tile](http://aheckmann.github.io/gm/docs.html#tile)\n    - [transform](http://aheckmann.github.io/gm/docs.html#transform)\n    - [transparent](http://aheckmann.github.io/gm/docs.html#transparent)\n    - [treeDepth](http://aheckmann.github.io/gm/docs.html#treeDepth)\n    - [trim](http://aheckmann.github.io/gm/docs.html#trim)\n    - [type](http://aheckmann.github.io/gm/docs.html#type)\n    - [update](http://aheckmann.github.io/gm/docs.html#update)\n    - [units](http://aheckmann.github.io/gm/docs.html#units)\n    - [unsharp](http://aheckmann.github.io/gm/docs.html#unsharp)\n    - [usePixmap](http://aheckmann.github.io/gm/docs.html#usePixmap)\n    - [view](http://aheckmann.github.io/gm/docs.html#view)\n    - [virtualPixel](http://aheckmann.github.io/gm/docs.html#virtualPixel)\n    - [visual](http://aheckmann.github.io/gm/docs.html#visual)\n    - [watermark](http://aheckmann.github.io/gm/docs.html#watermark)\n    - [wave](http://aheckmann.github.io/gm/docs.html#wave)\n    - [whitePoint](http://aheckmann.github.io/gm/docs.html#whitePoint)\n    - [whiteThreshold](http://aheckmann.github.io/gm/docs.html#whiteThreshold)\n    - [window](http://aheckmann.github.io/gm/docs.html#window)\n    - [windowGroup](http://aheckmann.github.io/gm/docs.html#windowGroup)\n\n  - drawing primitives\n    - [draw](http://aheckmann.github.io/gm/docs.html#draw)\n    - [drawArc](http://aheckmann.github.io/gm/docs.html#drawArc)\n    - [drawBezier](http://aheckmann.github.io/gm/docs.html#drawBezier)\n    - [drawCircle](http://aheckmann.github.io/gm/docs.html#drawCircle)\n    - [drawEllipse](http://aheckmann.github.io/gm/docs.html#drawEllipse)\n    - [drawLine](http://aheckmann.github.io/gm/docs.html#drawLine)\n    - [drawPoint](http://aheckmann.github.io/gm/docs.html#drawPoint)\n    - [drawPolygon](http://aheckmann.github.io/gm/docs.html#drawPolygon)\n    - [drawPolyline](http://aheckmann.github.io/gm/docs.html#drawPolyline)\n    - [drawRectangle](http://aheckmann.github.io/gm/docs.html#drawRectangle)\n    - [drawText](http://aheckmann.github.io/gm/docs.html#drawText)\n    - [fill](http://aheckmann.github.io/gm/docs.html#fill)\n    - [font](http://aheckmann.github.io/gm/docs.html#font)\n    - [fontSize](http://aheckmann.github.io/gm/docs.html#fontSize)\n    - [stroke](http://aheckmann.github.io/gm/docs.html#stroke)\n    - [strokeWidth](http://aheckmann.github.io/gm/docs.html#strokeWidth)\n    - [setDraw](http://aheckmann.github.io/gm/docs.html#setDraw)\n\n  - image output\n    - **write** - writes the processed image data to the specified filename\n    - **stream** - provides a `ReadableStream` with the processed image data\n    - **toBuffer** - returns the image as a `Buffer` instead of a stream\n\n## compare\n\nGraphicsmagicks `compare` command is exposed through `gm.compare()`. This allows us to determine if two images can be considered \"equal\".\n\nCurrently `gm.compare` only accepts file paths.\n\n    gm.compare(path1, path2 [, options], callback)\n\n```js\ngm.compare('/path/to/image1.jpg', '/path/to/another.png', function (err, isEqual, equality, raw, path1, path2) {\n  if (err) return handle(err);\n\n  // if the images were considered equal, `isEqual` will be true, otherwise, false.\n  console.log('The images were equal: %s', isEqual);\n\n  // to see the total equality returned by graphicsmagick we can inspect the `equality` argument.\n  console.log('Actual equality: %d', equality);\n\n  // inspect the raw output\n  console.log(raw);\n\n  // print file paths\n  console.log(path1, path2);\n})\n```\n\nYou may wish to pass a custom tolerance threshold to increase or decrease the default level of `0.4`.\n\n\n```js\ngm.compare('/path/to/image1.jpg', '/path/to/another.png', 1.2, function (err, isEqual) {\n  ...\n})\n```\n\nTo output a diff image, pass a configuration object to define the diff options and tolerance.\n\n\n```js\nvar options = {\n  file: '/path/to/diff.png',\n  highlightColor: 'yellow',\n  tolerance: 0.02\n}\ngm.compare('/path/to/image1.jpg', '/path/to/another.png', options, function (err, isEqual, equality, raw) {\n  ...\n})\n```\n\n## composite\n\nGraphicsMagick supports compositing one image on top of another. This is exposed through `gm.composite()`. Its first argument is an image path with the changes to the base image, and an optional mask image.\n\nCurrently, `gm.composite()` only accepts file paths.\n\n    gm.composite(other [, mask])\n\n```js\ngm('/path/to/image.jpg')\n.composite('/path/to/second_image.jpg')\n.geometry('+100+150')\n.write('/path/to/composite.png', function(err) {\n    if(!err) console.log(\"Written composite image.\");\n});\n```\n\n## montage\n\nGraphicsMagick supports montage for combining images side by side. This is exposed through `gm.montage()`. Its only argument is an image path with the changes to the base image.\n\nCurrently, `gm.montage()` only accepts file paths.\n\n    gm.montage(other)\n\n```js\ngm('/path/to/image.jpg')\n.montage('/path/to/second_image.jpg')\n.geometry('+100+150')\n.write('/path/to/montage.png', function(err) {\n    if(!err) console.log(\"Written montage image.\");\n});\n```\n\n## Contributors\n[https://github.com/aheckmann/gm/contributors](https://github.com/aheckmann/gm/contributors)\n\n## Inspiration\nhttp://github.com/quiiver/magickal-node\n\n## Plugins\n[https://github.com/aheckmann/gm/wiki](https://github.com/aheckmann/gm/wiki)\n\n## Tests\n`npm test`\n\nTo run a single test:\n\n```\nnpm test -- alpha.js\n```\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2010 [Aaron Heckmann](aaron.heckmann+github@gmail.com)\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/append.js",
    "content": "var gm = require('../')\n  , dir = __dirname + '/imgs'\n  , imgs = 'lost.png original.jpg'.split(' ').map(function (img) {\n      return dir + '/' + img\n    })\n  , out = dir + '/append.jpg'\n\ngm(imgs[0])\n.append(imgs[1])\n.append()\n.background('#222')\n.write(out, function (err) {\n  if (err) return console.dir(arguments)\n  console.log(this.outname + \" created  ::  \" + arguments[3])\n  require('child_process').exec('open ' + out)\n});\n\n"
  },
  {
    "path": "examples/background.js",
    "content": "var gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + \"/original.jpg\")\n  .crop(140,100)\n  .background(\"#FF0000\")\n  .extent(340,300)\n  .write(dir + '/background.jpg', function (err) {\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n});\n\n"
  },
  {
    "path": "examples/bitdepth.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .bitdepth(2)\n  .write(dir + '/bitdepth.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/blur.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .blur(19, 10)\n  .write(dir + '/blur.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/changeFormat.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.png')\n  .write(dir + '/original.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/charcoal.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .charcoal(1)\n  .write(dir + '/charcoal.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/chop.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.png')\n  .chop(54, 1, 307, 1)\n  .write(dir + \"/chop.jpg\", function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/colorize.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .colorize(80, 0, 30)\n  .write(dir + '/colorize.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/colors.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .colors(16)\n  .write(dir + '/colors.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/comment.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .comment(\"%m:%f %wx%h\")\n  .write(dir + '/comment.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/compare.js",
    "content": "var gm = require('../')\n  , dir = __dirname + '/imgs'\n  , imgs = 'bitdepth.png original.jpg'.split(' ').map(function (img) {\n      return dir + '/' + img\n    })\n  , out = dir + '/compare.jpg'\n\ngm.compare(imgs[0], imgs[1], { highlightColor: \"#fff\", file: out }, function (err) {\n  if (err) return console.dir(arguments)\n  console.log('The images are equal: %s', arguments[1]);\n  console.log('Actual equality: %d', arguments[2]);\n  console.log(this.outname + \" created  ::  \" + arguments[3]);\n  require('child_process').exec('open ' + out);\n});\n\n"
  },
  {
    "path": "examples/contrast.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .contrast(2)\n  .write(dir + '/contrast.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/crop.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.png')\n  .crop(200, 155, 300, 0)\n  .write(dir + \"/crop.jpg\", function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/cycle.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .cycle(4)\n  .write(dir + '/cycle.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/despeckle.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .despeckle()\n  .write(dir + '/despeckle.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/dither.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .monochrome()\n  .dither()\n  .write(dir + '/dither.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/drawing.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .blur(8, 4)\n  .stroke(\"red\", 7)\n  .fill(\"#ffffffbb\")\n  .drawLine(20, 10, 50, 40)\n  .fill(\"#2c2\")\n  .stroke(\"blue\", 1)\n  .drawRectangle(40, 10, 50, 20)\n  .drawRectangle(60, 10, 70, 20, 3)\n  .drawArc(80, 10, 90, 20, 0, 180)\n  .drawEllipse(105, 15, 3, 5)\n  .drawCircle(125, 15, 120, 15)\n  .drawPolyline([140, 10], [143, 13], [145, 13], [147, 15], [145, 17], [143, 19])\n  .drawPolygon([160, 10], [163, 13], [165, 13], [167, 15], [165, 17], [163, 19])\n  .drawBezier([180, 10], [183, 13], [185, 13], [187, 15], [185, 17], [183, 19])\n  .fontSize(68)\n  .stroke(\"#efe\", 2)\n  .fill(\"#888\")\n  .drawText(-20, 98, \"graphics magick\")\n  .write(dir + '/drawing.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/edge.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .edge(2)\n  .write(dir + '/edge.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/emboss.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .emboss(2)\n  .write(dir + '/emboss.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/enhance.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .enhance()\n  .write(dir + '/enhance.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/equalize.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .equalize()\n  .write(dir + '/equalize.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/extent.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.jpg')\n  .resize(200,100)\n  .extent(300, 300)\n  .write(dir + '/extent.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n)\n"
  },
  {
    "path": "examples/flatten.js",
    "content": "// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/layers.psd')\n  .flatten()\n  .write(dir + \"/unlayered.jpg\", function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n)\n"
  },
  {
    "path": "examples/flip.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .flip()\n  .write(dir + '/flip.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created :: \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/flop.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .flop()\n  .write(dir + '/flop.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created :: \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/gamma.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .gamma(1.7, 2.3, 1.3)\n  .write(dir + '/gamma.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/getters.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\nvar methods = \n[ \"size\"\n, \"identify\"\n, \"format\"\n, \"depth\"\n, \"color\"\n, \"res\"\n, \"filesize\"\n]\n\nvar image = gm(dir + '/original.png')\nmethods.forEach(function(method){\n  image[method](function(err, result){\n    console.log(method + \" result:\")\n    console.dir(result)\n  })\n})\n\n"
  },
  {
    "path": "examples/gravity.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.jpg')\n  .resize(200,100)\n  .gravity(\"South\") // Be sure to use gravity BEFORE extent\n  .extent(300, 300)\n  .write(dir + '/gravity.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n)\n"
  },
  {
    "path": "examples/implode.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .implode(0.8)\n  .write(dir + '/implode.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/label.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .label(\"%m:%f %wx%h\")\n  .write(dir + '/label.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/limit.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .limit(\"memory\", \"32MB\")\n  .limit(\"map\", \"64MB\")\n  .write(dir + '/limit.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/lower.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .lower(10, 14)\n  .write(dir + '/lower.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/magnify.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.png')\n  .magnify()\n  .write(dir + '/magnify.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/median.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .median(4)\n  .write(dir + '/median.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/minify.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs' \ngm(dir + '/original.png')\n  .minify()\n  .write(dir + '/minify.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) "
  },
  {
    "path": "examples/modulate.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .modulate(120, 100, 80)\n  .write(dir + '/modulate.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/monochrome.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .monochrome()\n  .write(dir + '/monochrome.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/morph.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .morph(dir + '/morpher.jpg', dir + '/morph.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/negative.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .negative()\n  .write(dir + '/negative.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/new.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(525, 110, \"#00ff55aa\")\n  .fontSize(68)\n  .stroke(\"#efe\", 2)\n  .fill(\"#555\")\n  .drawText(20, 72, \"graphics\")\n  .fill(\"#fa0\")\n  .drawText(274, 72, \" magick\")\n  .write(dir + '/new.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/noise1.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .noise(0.3)\n  .write(dir + '/noise1.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/noise2.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .noise(\"laplacian\")\n  .write(dir + '/noise2.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/paint.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .paint(2)\n  .write(dir + '/paint.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/quality.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.png')\n  .quality(5)\n  .write(dir + '/quality.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/raise.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .raise(10, 14)\n  .write(dir + '/raise.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/region.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  // region must come before other affected arguments\n  .region(130, 170, 307, 00).charcoal(1)\n  .write(dir + '/region.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/resample.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.jpg')\n  .resample(420, 120)\n  .write(dir + '/resample.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/resize.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.jpg')\n  .resize(58, 50, '%')\n  .write(dir + '/resize.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n)\n"
  },
  {
    "path": "examples/roll.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.jpg')\n  .roll(40,-100)\n  .quality(100)\n  .write(dir + '/roll.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/rotate.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.jpg')\n  .rotate('red', -30)\n  .write(dir + '/rotate.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/scale.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.jpg')\n  .resize(58, 20)\n  .write(dir + '/scale.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/sepia.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.jpg')\n  .sepia()\n  .write(dir + '/sepia.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/sharpen.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .sharpen(19, 10)\n  .write(dir + '/sharpen.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created  :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/size.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\nvar methods = \n[ \"size\"\n]\n\nvar image = gm(dir + '/original.png')\nmethods.forEach(function(method){\n  image[method](function(err, result){\n    console.log(method + \" result:\")\n    console.dir(result)\n  })\n})\n\n"
  },
  {
    "path": "examples/solarize.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .solarize(68.9)\n  .write(dir + '/solarize.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/source_buffer.js",
    "content": "var gm  = require('../')\n  , fs  = require('fs')\n  , dir = __dirname + '/../examples/imgs'\n\nvar buf = fs.readFileSync(dir + '/original.jpg');\n\ngm(buf)\n.noise('laplacian')\n.write(dir + '/fromBuffer.png', function (err) {\n  if (err) return console.dir(arguments);\n\n  console.log(this.outname + ' created :: ' + arguments[3]);\n});\n"
  },
  {
    "path": "examples/spread.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .spread(10)\n  .write(dir + '/spread.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/swirl.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.png')\n  .swirl(90) // degrees\n  .write(dir + '/swirl.png', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + ' created :: ' + arguments[3])\n  }\n) \n"
  },
  {
    "path": "examples/thumb.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.jpg')\n  .thumb(150, 50, dir + '/thumb.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  });\n"
  },
  {
    "path": "examples/thumbExact.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n\nvar gm = require('../')\n  , dir = __dirname + '/imgs'\n\ngm(dir + '/original.jpg')\n  .thumbExact(150, 50, dir + '/thumb.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  });\n"
  },
  {
    "path": "examples/thumbnail.js",
    "content": "var gm = require('../')\n  , dir = __dirname + '/imgs'\n  \ngm(dir + '/original.jpg')\n  .thumbnail(150, 150)\n  .write(dir + '/thumbnail.jpg', function(err){\n    if (err) return console.dir(arguments)\n    console.log(this.outname + \" created  ::  \" + arguments[3])\n  }\n) \n"
  },
  {
    "path": "index.js",
    "content": "\n/**\n * Module dependencies.\n */\n\nvar Stream = require('stream').Stream;\nvar EventEmitter = require('events').EventEmitter;\nvar util = require('util');\n\nutil.inherits(gm, EventEmitter);\n\n/**\n * Constructor.\n *\n * @param {String|Number} path - path to img source or ReadableStream or width of img to create\n * @param {Number} [height] - optional filename of ReadableStream or height of img to create\n * @param {String} [color] - optional hex background color of created img\n */\n\nfunction gm (source, height, color) {\n  var width;\n\n  if (!(this instanceof gm)) {\n    return new gm(source, height, color);\n  }\n\n  EventEmitter.call(this);\n\n  this._options = {};\n  this.options(this.__proto__._options);\n\n  this.data = {};\n  this._in = [];\n  this._out = [];\n  this._outputFormat = null;\n  this._subCommand = 'convert';\n\n  if (source instanceof Stream) {\n    this.sourceStream = source;\n    source = height || 'unknown.jpg';\n  } else if (Buffer.isBuffer(source)) {\n    this.sourceBuffer = source;\n    source = height || 'unknown.jpg';\n  } else if (height) {\n    // new images\n    width = source;\n    source = \"\";\n\n    this.in(\"-size\", width + \"x\" + height);\n\n    if (color) {\n      this.in(\"xc:\"+ color);\n    }\n  }\n\n  if (typeof source === \"string\") {\n    // then source is a path\n\n    // parse out gif frame brackets from filename\n    // since stream doesn't use source path\n    // eg. \"filename.gif[0]\"\n    var frames = source.match(/(\\[.+\\])$/);\n    if (frames) {\n      this.sourceFrames = source.substr(frames.index, frames[0].length);\n      source = source.substr(0, frames.index);\n    }\n  }\n\n  this.source = source;\n\n  this.addSrcFormatter(function (src) {\n    // must be first source formatter\n\n    var inputFromStdin = this.sourceStream || this.sourceBuffer;\n    var ret = inputFromStdin ? '-' : this.source;\n\n    const fileNameProvied = typeof height === 'string';\n    if (inputFromStdin && fileNameProvied && /\\.ico$/i.test(this.source)) {\n      ret = `ico:-`;\n    }\n\n    if (ret && this.sourceFrames) ret += this.sourceFrames;\n\n    src.length = 0;\n    src[0] = ret;\n  });\n}\n\n/**\n * Subclasses the gm constructor with custom options.\n *\n * @param {options} options\n * @return {gm} the subclasses gm constructor\n */\n\nvar parent = gm;\ngm.subClass = function subClass (options) {\n  function gm (source, height, color) {\n    if (!(this instanceof parent)) {\n      return new gm(source, height, color);\n    }\n\n    parent.call(this, source, height, color);\n  }\n\n  gm.prototype.__proto__ = parent.prototype;\n  gm.prototype._options = {};\n  gm.prototype.options(options);\n\n  return gm;\n}\n\n/**\n * Augment the prototype.\n */\n\nrequire(\"./lib/options\")(gm.prototype);\nrequire(\"./lib/getters\")(gm);\nrequire(\"./lib/args\")(gm.prototype);\nrequire(\"./lib/drawing\")(gm.prototype);\nrequire(\"./lib/convenience\")(gm.prototype);\nrequire(\"./lib/command\")(gm.prototype);\nrequire(\"./lib/compare\")(gm.prototype);\nrequire(\"./lib/composite\")(gm.prototype);\nrequire(\"./lib/montage\")(gm.prototype);\n\n/**\n * Expose.\n */\n\nmodule.exports = exports = gm;\nmodule.exports.utils = require('./lib/utils');\nmodule.exports.compare = require('./lib/compare')();\nmodule.exports.version = require('./package.json').version;\n"
  },
  {
    "path": "lib/args.js",
    "content": "/**\n * Dependencies\n */\n\nvar argsToArray = require('./utils').argsToArray;\nvar isUtil = require('./utils').isUtil;\n/**\n * Extend proto\n */\n\nmodule.exports = function (proto) {\n  // change the specified frame.\n  // See #202.\n  proto.selectFrame = function (frame) {\n    if (typeof frame === 'number')\n      this.sourceFrames = '[' + frame + ']';\n    return this;\n  }\n\n  // define the sub-command to use, http://www.graphicsmagick.org/utilities.html\n  proto.command = proto.subCommand = function subCommand (name){\n    this._subCommand = name;\n    return this;\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-adjoin\n  proto.adjoin = function adjoin () {\n    return this.out(\"-adjoin\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-affine\n  proto.affine = function affine (matrix) {\n    return this.out(\"-affine\", matrix);\n  }\n\n  proto.alpha = function alpha (type) {\n    if (!this._options.imageMagick) return new Error('Method -alpha is not supported by GraphicsMagick');\n    return this.out('-alpha', type);\n  }\n\n  /**\n   * Appends images to the list of \"source\" images.\n   *\n   * We may also specify either top-to-bottom or left-to-right\n   * behavior of the appending by passing a boolean argument.\n   *\n   * Examples:\n   *\n   *    img = gm(src);\n   *\n   *    // +append means left-to-right\n   *    img.append(img1, img2)       gm convert src img1 img2 -append\n   *    img.append(img, true)        gm convert src img +append\n   *    img.append(img, false)       gm convert src img -append\n   *    img.append(img)              gm convert src img -append\n   *    img.append(img).append()     gm convert src img -append\n   *    img.append(img).append(true) gm convert src img +append\n   *    img.append(img).append(true) gm convert src img +append\n   *    img.append(img).background('#222) gm convert src img -background #222 +append\n   *    img.append([img1,img2...],true)\n\n   * @param {String} or {Array} [img]\n   * @param {Boolean} [ltr]\n   * @see http://www.graphicsmagick.org/GraphicsMagick.html#details-append\n   */\n\n  proto.append = function append (img, ltr) {\n    if (!this._append) {\n      this._append = [];\n      this.addSrcFormatter(function (src) {\n        this.out(this._append.ltr ? '+append' : '-append');\n        src.push.apply(src, this._append);\n      });\n    }\n\n    if (0 === arguments.length) {\n      this._append.ltr = false;\n      return this;\n    }\n\n    for (var i = 0; i < arguments.length; ++i) {\n      var arg = arguments[i];\n      switch (isUtil(arg)) {\n        case 'Boolean':\n          this._append.ltr = arg;\n          break;\n        case 'String':\n          this._append.push(arg);\n          break;\n        case 'Array':\n          for(var j=0,len=arg.length;j<len;j++){\n            if(isUtil(arg[j]) == 'String'){\n              this._append.push(arg[j]);\n            }\n          }\n          break;\n      }\n    }\n\n    return this;\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-authenticate\n  proto.authenticate = function authenticate (string) {\n    return this.out(\"-authenticate\", string);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-average\n  proto.average = function average () {\n    return this.out(\"-average\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-backdrop\n  proto.backdrop = function backdrop () {\n    return this.out(\"-backdrop\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-black-threshold\n  proto.blackThreshold = function blackThreshold (red, green, blue, opacity) {\n    return this.out(\"-black-threshold\", argsToArray(red, green, blue, opacity).join(','));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-blue-primary\n  proto.bluePrimary = function bluePrimary (x, y) {\n    return this.out(\"-blue-primary\", argsToArray(x, y).join(','));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-border\n  proto.border = function border (width, height) {\n    return this.out(\"-border\", width+\"x\"+height);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-bordercolor\n  proto.borderColor = function borderColor (color) {\n    return this.out(\"-bordercolor\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-box\n  proto.box = function box (color) {\n    return this.out(\"-box\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-channel\n  proto.channel = function channel (type) {\n    return this.out(\"-channel\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-chop\n  proto.chop = function chop (w, h, x, y) {\n    return this.in(\"-chop\", w+\"x\"+h + \"+\"+(x||0)+\"+\"+(y||0));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-clip\n  proto.clip = function clip () {\n    return this.out(\"-clip\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-coalesce\n  proto.coalesce = function coalesce () {\n    return this.out(\"-coalesce\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-colorize\n  proto.colorize = function colorize (r, g, b) {\n    return this.out(\"-colorize\", [r,g,b].join(\",\"));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-colormap\n  proto.colorMap = function colorMap (type) {\n    return this.out(\"-colormap\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-compose\n  proto.compose = function compose (operator) {\n    return this.out(\"-compose\", operator);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-compress\n  proto.compress = function compress (type) {\n    return this.out(\"-compress\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-kernel\n  proto.convolve = function convolve (kernel) {\n    return this.out(\"-convolve\", kernel);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-create-directories\n  proto.createDirectories = function createDirectories () {\n    return this.out(\"-create-directories\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-deconstruct\n  proto.deconstruct = function deconstruct () {\n    return this.out(\"-deconstruct\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-define\n  proto.define = function define (value) {\n    return this.out(\"-define\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-delay\n  proto.delay = function delay (value) {\n    return this.out(\"-delay\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-displace\n  proto.displace = function displace (horizontalScale, verticalScale) {\n    return this.out(\"-displace\", horizontalScale+'x'+verticalScale);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-display\n  proto.display = function display (value) {\n    return this.out(\"-display\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-dispose\n  proto.dispose = function dispose (method) {\n    return this.out(\"-dispose\", method);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-dissolve\n  proto.dissolve = function dissolve (percent) {\n    return this.out(\"-dissolve\", percent+'%');\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-encoding\n  proto.encoding = function encoding (type) {\n    return this.out(\"-encoding\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-endian\n  proto.endian = function endian (type) {\n    return this.out(\"-endian\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-file\n  proto.file = function file (filename) {\n    return this.out(\"-file\", filename);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-flatten\n  proto.flatten = function flatten () {\n    return this.out(\"-flatten\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-foreground\n  proto.foreground = function foreground (color) {\n    return this.out(\"-foreground\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-frame\n  proto.frame = function frame (width, height, outerBevelWidth, innerBevelWidth) {\n    if(arguments.length==0) return this.out(\"-frame\");\n    return this.out(\"-frame\", width+'x'+height+'+'+outerBevelWidth+'+'+innerBevelWidth);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-fuzz\n  proto.fuzz = function fuzz (distance, percent) {\n    return this.out(\"-fuzz\", distance+(percent?'%':''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-gaussian\n  proto.gaussian = function gaussian (radius, sigma) {\n    return this.out(\"-gaussian\", argsToArray(radius, sigma).join('x'));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-geometry\n  proto.geometry = function geometry (width, height, arg) {\n    // If the first argument is a string, and there is only one argument, this is a custom geometry command.\n    if(arguments.length == 1 && typeof arguments[0] === \"string\")\n      return this.out(\"-geometry\", arguments[0]);\n\n    // Otherwise, return a resizing geometry command with an option alrgument.\n    return this.out(\"-geometry\", width+'x'+height+(arg||''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-green-primary\n  proto.greenPrimary = function greenPrimary (x, y) {\n    return this.out(\"-green-primary\", x+','+y);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-highlight-color\n  proto.highlightColor = function highlightColor (color) {\n    return this.out(\"-highlight-color\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-highlight-style\n  proto.highlightStyle = function highlightStyle (style) {\n    return this.out(\"-highlight-style\", style);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-iconGeometry\n  proto.iconGeometry = function iconGeometry (geometry) {\n    return this.out(\"-iconGeometry\", geometry);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-intent\n  proto.intent = function intent (type) {\n    return this.out(\"-intent\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-lat\n  proto.lat = function lat (width, height, offset, percent) {\n    return this.out(\"-lat\", width+'x'+height+offset+(percent?'%':''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-level\n  proto.level = function level (blackPoint, gamma, whitePoint, percent) {\n    return this.out(\"-level\", argsToArray(blackPoint, gamma, whitePoint).join(',')+(percent?'%':''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-list\n  proto.list = function list (type) {\n    return this.out(\"-list\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-log\n  proto.log = function log (string) {\n    return this.out(\"-log\", string);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-loop\n  proto.loop = function loop (iterations) {\n    return this.out(\"-loop\", iterations);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-map\n  proto.map = function map (filename) {\n    return this.out(\"-map\", filename);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-mask\n  proto.mask = function mask (filename) {\n    return this.out(\"-mask\", filename);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-matte\n  proto.matte = function matte () {\n    return this.out(\"-matte\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-mattecolor\n  proto.matteColor = function matteColor (color) {\n    return this.out(\"-mattecolor\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-maximum-error\n  proto.maximumError = function maximumError (limit) {\n    return this.out(\"-maximum-error\", limit);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-mode\n  proto.mode = function mode (value) {\n    return this.out(\"-mode\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-monitor\n  proto.monitor = function monitor () {\n    return this.out(\"-monitor\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-mosaic\n  proto.mosaic = function mosaic () {\n    return this.out(\"-mosaic\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-motion-blur\n  proto.motionBlur = function motionBlur (radius, sigma, angle) {\n    var arg=radius;\n    if (typeof sigma!='undefined') arg+='x'+sigma;\n    if (typeof angle!='undefined') arg+='+'+angle;\n    return this.out(\"-motion-blur\", arg);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-name\n  proto.name = function name () {\n    return this.out(\"-name\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-noop\n  proto.noop = function noop () {\n    return this.out(\"-noop\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-normalize\n  proto.normalize = function normalize () {\n    return this.out(\"-normalize\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-opaque\n  proto.opaque = function opaque (color) {\n    return this.out(\"-opaque\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-operator\n  proto.operator = function operator (channel, operator, rvalue, percent) {\n    return this.out(\"-operator\", channel, operator, rvalue+(percent?'%':''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-ordered-dither\n  proto.orderedDither = function orderedDither (channeltype, NxN) {\n    return this.out(\"-ordered-dither\", channeltype, NxN);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-output-directory\n  proto.outputDirectory = function outputDirectory (directory) {\n    return this.out(\"-output-directory\", directory);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-page\n  proto.page = function page (width, height, arg) {\n    return this.out(\"-page\", width+'x'+height+(arg||''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-pause\n  proto.pause = function pause (seconds) {\n    return this.out(\"-pause\", seconds);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-pen\n  proto.pen = function pen (color) {\n    return this.out(\"-pen\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-ping\n  proto.ping = function ping () {\n    return this.out(\"-ping\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-pointsize\n  proto.pointSize = function pointSize (value) {\n    return this.out(\"-pointsize\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-preview\n  proto.preview = function preview (type) {\n    return this.out(\"-preview\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-process\n  proto.process = function process (command) {\n    return this.out(\"-process\", command);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-profile\n  proto.profile = function profile (filename) {\n    return this.out(\"-profile\", filename);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-progress\n  proto.progress = function progress () {\n    return this.out(\"+progress\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-random-threshold\n  proto.randomThreshold = function randomThreshold (channeltype, LOWxHIGH) {\n    return this.out(\"-random-threshold\", channeltype, LOWxHIGH);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-recolor\n  proto.recolor = function recolor (matrix) {\n    return this.out(\"-recolor\", matrix);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-red-primary\n  proto.redPrimary = function redPrimary (x, y) {\n    return this.out(\"-red-primary\", x, y);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-remote\n  proto.remote = function remote () {\n    return this.out(\"-remote\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-render\n  proto.render = function render () {\n    return this.out(\"-render\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-repage\n  proto.repage = function repage (width, height, xoff, yoff, arg) {\n    if (arguments[0] === \"+\") return this.out(\"+repage\");\n    return this.out(\"-repage\", width+'x'+height+'+'+xoff+'+'+yoff+(arg||''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-sample\n  proto.sample = function sample (geometry) {\n    return this.out(\"-sample\", geometry);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-sampling-factor\n  proto.samplingFactor = function samplingFactor (horizontalFactor, verticalFactor) {\n    return this.out(\"-sampling-factor\", horizontalFactor+'x'+verticalFactor);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-scene\n  proto.scene = function scene (value) {\n    return this.out(\"-scene\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-scenes\n  proto.scenes = function scenes (start, end) {\n    return this.out(\"-scenes\", start+'-'+end);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-screen\n  proto.screen = function screen () {\n    return this.out(\"-screen\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-set\n  proto.set = function set (attribute, value) {\n    return this.out(\"-set\", attribute, value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-segment\n  proto.segment = function segment (clusterThreshold, smoothingThreshold) {\n    return this.out(\"-segment\", clusterThreshold+'x'+smoothingThreshold);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-shade\n  proto.shade = function shade (azimuth, elevation) {\n    return this.out(\"-shade\", azimuth+'x'+elevation);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-shadow\n  proto.shadow = function shadow (radius, sigma) {\n    return this.out(\"-shadow\", argsToArray(radius, sigma).join('x'));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-shared-memory\n  proto.sharedMemory = function sharedMemory () {\n    return this.out(\"-shared-memory\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-shave\n  proto.shave = function shave (width, height, percent) {\n    return this.out(\"-shave\", width+'x'+height+(percent?'%':''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-shear\n  proto.shear = function shear (xDegrees, yDegreees) {\n    return this.out(\"-shear\", xDegrees+'x'+yDegreees);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-silent\n  proto.silent = function silent (color) {\n    return this.out(\"-silent\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-size\n  proto.rawSize = function rawSize (width, height, offset) {\n    var off = 'undefined' != typeof offset\n      ? '+' + offset\n      : '';\n    return this.out(\"-size\", width +'x'+ height + off);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-snaps\n  proto.snaps = function snaps (value) {\n    return this.out(\"-snaps\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-stegano\n  proto.stegano = function stegano (offset) {\n    return this.out(\"-stegano\", offset);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-stereo\n  proto.stereo = function stereo () {\n    return this.out(\"-stereo\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-text-font\n  proto.textFont = function textFont (name) {\n    return this.out(\"-text-font\", name);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-texture\n  proto.texture = function texture (filename) {\n    return this.out(\"-texture\", filename);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-threshold\n  proto.threshold = function threshold (value, percent) {\n    return this.out(\"-threshold\", value+(percent?'%':''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-thumbnail\n  proto.thumbnail = function thumbnail (w, h, options) {\n    options = options || \"\";\n    var geometry,\n      wIsValid = Boolean(w || w === 0),\n      hIsValid = Boolean(h || h === 0);\n\n    if (wIsValid && hIsValid) {\n      geometry = w + \"x\" + h + options\n    } else if (wIsValid) {\n      // GraphicsMagick requires <width>x<options>, ImageMagick requires <width><options>\n      geometry = (this._options.imageMagick) ? w + options : w +\n        'x' + options;\n    } else if (hIsValid) {\n      geometry = 'x' + h + options\n    } else {\n      return this\n    }\n\n    return this.out(\"-thumbnail\", geometry);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-tile\n  proto.tile = function tile (filename) {\n    return this.out(\"-tile\", filename);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-title\n  proto.title = function title (string) {\n    return this.out(\"-title\", string);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-transform\n  proto.transform = function transform (color) {\n    return this.out(\"-transform\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-transparent\n  proto.transparent = function transparent (color) {\n    return this.out(\"-transparent\", color);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-treedepth\n  proto.treeDepth = function treeDepth (value) {\n    return this.out(\"-treedepth\", value);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-update\n  proto.update = function update (seconds) {\n    return this.out(\"-update\", seconds);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-units\n  proto.units = function units (type) {\n    return this.out(\"-units\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-unsharp\n  proto.unsharp = function unsharp (radius, sigma, amount, threshold) {\n    var arg=radius;\n    if (typeof sigma != 'undefined') arg+='x'+sigma;\n    if (typeof amount != 'undefined') arg+='+'+amount;\n    if (typeof threshold != 'undefined') arg+='+'+threshold;\n    return this.out(\"-unsharp\", arg);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-use-pixmap\n  proto.usePixmap = function usePixmap () {\n    return this.out(\"-use-pixmap\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-view\n  proto.view = function view (string) {\n    return this.out(\"-view\", string);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-virtual-pixel\n  proto.virtualPixel = function virtualPixel (method) {\n    return this.out(\"-virtual-pixel\", method);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-visual\n  proto.visual = function visual (type) {\n    return this.out(\"-visual\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-watermark\n  proto.watermark = function watermark (brightness, saturation) {\n    return this.out(\"-watermark\", brightness+'x'+saturation);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-wave\n  proto.wave = function wave (amplitude, wavelength) {\n    return this.out(\"-wave\", amplitude+'x'+wavelength);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-white-point\n  proto.whitePoint = function whitePoint (x, y) {\n    return this.out(\"-white-point\", x+'x'+y);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-white-threshold\n  proto.whiteThreshold = function whiteThreshold (red, green, blue, opacity) {\n    return this.out(\"-white-threshold\", argsToArray(red, green, blue, opacity).join(','));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-window\n  proto.window = function window (id) {\n    return this.out(\"-window\", id);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-window-group\n  proto.windowGroup = function windowGroup () {\n    return this.out(\"-window-group\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-strip (graphicsMagick >= 1.3.15)\n  proto.strip = function strip () {\n    if (this._options.imageMagick) return this.out(\"-strip\");\n    return this.noProfile().out(\"+comment\");//Equivalent to \"-strip\" for all versions of graphicsMagick\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-interlace\n  proto.interlace = function interlace (type) {\n    return this.out(\"-interlace\", type || \"None\");\n  }\n\n  // force output format\n  proto.setFormat = function setFormat (format) {\n    if (format) this._outputFormat = format;\n    return this;\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-resize\n  proto.resize = function resize (w, h, options) {\n    options = options || \"\";\n    var geometry,\n      wIsValid = Boolean(w || w === 0),\n      hIsValid = Boolean(h || h === 0);\n\n    if (wIsValid && hIsValid) {\n      geometry = w + \"x\" + h + options\n    } else if (wIsValid) {\n      // GraphicsMagick requires <width>x<options>, ImageMagick requires <width><options>\n      geometry = (this._options.imageMagick) ? w + options : w +\n        'x' + options;\n    } else if (hIsValid) {\n      geometry = 'x' + h + options\n    } else {\n      return this\n    }\n\n    return this.out(\"-resize\", geometry);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-resize with '!' option\n  proto.resizeExact = function resize (w, h) {\n    var options = \"!\";\n    return proto.resize.apply(this, [w, h, options]);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-scale\n  proto.scale = function scale (w, h, options) {\n    options = options || \"\";\n    var geometry;\n    if (w && h) {\n      geometry = w + \"x\" + h + options\n    } else if (w && !h) {\n      geometry = (this._options.imageMagick) ? w + options : w + 'x' + options;\n    } else if (!w && h) {\n      geometry = 'x' + h + options\n    }\n\n    return this.out(\"-scale\", geometry);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-filter\n  proto.filter = function filter (val) {\n    return this.out(\"-filter\", val);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-density\n  proto.density = function density (w, h) {\n    if (w && !h && this._options.imageMagick) {\n      // GraphicsMagick requires <width>x<height>y, ImageMagick may take dpi<resolution>\n      // recommended 300dpi for higher quality\n      return this.in(\"-density\", w);\n    }\n    return this.in(\"-density\", w +\"x\"+ h);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-profile\n  proto.noProfile = function noProfile () {\n    this.out('+profile', '\"*\"');\n    return this;\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-resample\n  proto.resample = function resample (w, h) {\n    return this.out(\"-resample\", w+\"x\"+h);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-rotate\n  proto.rotate = function rotate (color, deg) {\n    return this.out(\"-background\", color, \"-rotate\", String(deg || 0));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-flip\n  proto.flip = function flip () {\n    return this.out(\"-flip\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-flop\n  proto.flop = function flop () {\n    return this.out(\"-flop\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-crop\n  proto.crop = function crop (w, h, x, y, percent) {\n    if (this.inputIs('jpg')) {\n      // avoid error \"geometry does not contain image (unable to crop image)\" - gh-17\n      var index = this._in.indexOf('-size');\n      if (~index) {\n        this._in.splice(index, 2);\n      }\n    }\n\n    return this.out(\"-crop\", w + \"x\" + h + \"+\" + (x || 0) + \"+\" + (y || 0) + (percent ? '%' : ''));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-magnify\n  proto.magnify = function magnify (factor) {\n    return this.in(\"-magnify\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.minify = function minify () {\n    return this.in(\"-minify\")\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-quality\n  proto.quality = function quality (val) {\n    return this.in(\"-quality\", val || 75);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-blur\n  proto.blur = function blur (radius, sigma) {\n    return this.out(\"-blur\", radius + (sigma ? \"x\"+sigma : \"\"));\n  }\n\n  // http://www.graphicsmagick.org/convert.html\n  proto.charcoal = function charcoal (factor) {\n    return this.out(\"-charcoal\", factor || 2);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-modulate\n  proto.modulate = function modulate (b, s, h) {\n    return this.out(\"-modulate\", [b,s,h].join(\",\"));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-antialias\n  // note: antialiasing is enabled by default\n  proto.antialias = function antialias (disable) {\n    return false === disable\n      ? this.out(\"+antialias\")\n      : this;\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-depth\n  proto.bitdepth = function bitdepth (val) {\n    return this.out(\"-depth\", val);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-colors\n  proto.colors = function colors (val) {\n    return this.out(\"-colors\", val || 128);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-colorspace\n  proto.colorspace = function colorspace (val) {\n    return this.out(\"-colorspace\", val);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-comment\n  proto.comment = comment(\"-comment\");\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-contrast\n  proto.contrast = function contrast (mult) {\n    var arg = (parseInt(mult, 10) || 0) > 0\n      ? \"+contrast\"\n      : \"-contrast\";\n\n    mult = Math.abs(mult) || 1;\n\n    while (mult--) {\n      this.out(arg);\n    }\n\n    return this;\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-cycle\n  proto.cycle = function cycle (amount) {\n    return this.out(\"-cycle\", amount || 2);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.despeckle = function despeckle () {\n    return this.out(\"-despeckle\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-dither\n  // note: either colors() or monochrome() must be used for this\n  // to take effect.\n  proto.dither = function dither (on) {\n    var sign = false === on\n      ? \"+\"\n      : \"-\";\n\n    return this.out(sign + \"dither\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.monochrome = function monochrome () {\n    return this.out(\"-monochrome\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.edge = function edge (radius) {\n    return this.out(\"-edge\", radius || 1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.emboss = function emboss (radius) {\n    return this.out(\"-emboss\", radius || 1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.enhance = function enhance () {\n    return this.out(\"-enhance\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.equalize = function equalize () {\n    return this.out(\"-equalize\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-gamma\n  proto.gamma = function gamma (r, g, b) {\n    return this.out(\"-gamma\", [r,g,b].join());\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.implode = function implode (factor) {\n    return this.out(\"-implode\", factor || 1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-comment\n  proto.label = comment(\"-label\");\n\n  var limits = [ \"disk\", \"file\", \"map\", \"memory\", \"pixels\", \"threads\"];\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-limit\n  proto.limit = function limit (type, val) {\n    type = type.toLowerCase();\n\n    if (!~limits.indexOf(type)) {\n      return this;\n    }\n\n    return this.out(\"-limit\", type, val);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.median = function median (radius) {\n    return this.out(\"-median\", radius || 1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-negate\n  proto.negative = function negative (grayscale) {\n    var sign = grayscale ? \"+\" : \"-\";\n    return this.out(sign + \"negate\");\n  }\n\n  var noises = [\n      \"uniform\"\n    , \"gaussian\"\n    , \"multiplicative\"\n    , \"impulse\"\n    , \"laplacian\"\n    , \"poisson\"\n  ];\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-noise\n  proto.noise = function noise (radius) {\n    radius = (String(radius)).toLowerCase();\n\n    var sign = ~noises.indexOf(radius)\n      ? \"+\"\n      : \"-\";\n\n    return this.out(sign + \"noise\", radius);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-paint\n  proto.paint = function paint (radius) {\n    return this.out(\"-paint\", radius);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-raise\n  proto.raise = function raise (w, h) {\n    return this.out(\"-raise\", (w||0)+\"x\"+(h||0));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-raise\n  proto.lower = function lower (w, h) {\n    return this.out(\"+raise\", (w||0)+\"x\"+(h||0));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-region\n  proto.region = function region (w, h, x, y) {\n    w = w || 0;\n    h = h || 0;\n    x = x || 0;\n    y = y || 0;\n    return this.out(\"-region\", w + \"x\" + h + \"+\" + x + \"+\" + y);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-roll\n  proto.roll = function roll (x, y) {\n    x = ((x = parseInt(x, 10) || 0) >= 0 ? \"+\" : \"\") + x;\n    y = ((y = parseInt(y, 10) || 0) >= 0 ? \"+\" : \"\") + y;\n    return this.out(\"-roll\", x+y);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-sharpen\n  proto.sharpen = function sharpen (radius, sigma) {\n    sigma = sigma\n      ? \"x\" + sigma\n      : \"\";\n\n    return this.out(\"-sharpen\", radius + sigma);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-solarize\n  proto.solarize = function solarize (factor) {\n    return this.out(\"-solarize\", (factor || 1)+\"%\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-spread\n  proto.spread = function spread (amount) {\n    return this.out(\"-spread\", amount || 5);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-swirl\n  proto.swirl = function swirl (degrees) {\n    return this.out(\"-swirl\", degrees || 180);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-type\n  proto.type = function type (type) {\n    return this.in(\"-type\", type);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-trim\n  proto.trim = function trim () {\n    return this.out(\"-trim\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-extent\n  proto.extent = function extent (w, h, options) {\n    options = options || \"\";\n    var geometry;\n    if (w && h) {\n      geometry = w + \"x\" + h + options\n    } else if (w && !h) {\n      geometry = (this._options.imageMagick) ? w + options : w + 'x' + options;\n    } else if (!w && h) {\n      geometry = 'x' + h + options\n    }\n\n    return this.out(\"-extent\", geometry);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-gravity\n  // Be sure to use gravity BEFORE extent\n  proto.gravity = function gravity (type) {\n    if (!type || !~gravity.types.indexOf(type)) {\n      type = \"NorthWest\"; // Documented default.\n    }\n\n    return this.out(\"-gravity\", type);\n  }\n\n  proto.gravity.types = [\n      \"NorthWest\"\n    , \"North\"\n    , \"NorthEast\"\n    , \"West\"\n    , \"Center\"\n    , \"East\"\n    , \"SouthWest\"\n    , \"South\"\n    , \"SouthEast\"\n  ];\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-flatten\n  proto.flatten = function flatten () {\n    return this.out(\"-flatten\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-background\n  proto.background = function background (color) {\n    return this.in(\"-background\", color);\n  }\n};\n\n/**\n * Generates a handler for comments/labels.\n */\n\nfunction comment (arg) {\n  return function (format) {\n    format = String(format);\n\n    format = \"@\" == format.charAt(0)\n      ? format.substring(1)\n      : format;\n\n    return this.out(arg, '\"' + format + '\"');\n  }\n}\n"
  },
  {
    "path": "lib/command.js",
    "content": "\n/**\n * Module dependencies.\n */\n\nvar spawn = require('cross-spawn');\nvar utils = require('./utils');\nvar debug = require('debug')('gm');\nvar series = require('array-series');\nvar PassThrough = require('stream').PassThrough;\n\n/**\n * Error messaging.\n */\n\nvar noBufferConcat = 'gm v1.9.0+ required node v0.8+. Please update your version of node, downgrade gm < 1.9, or do not use `bufferStream`.';\n\n/**\n * Extend proto\n */\n\nmodule.exports = function (proto) {\n\n  function args (prop) {\n    return function args () {\n      var len = arguments.length;\n      var a = [];\n      var i = 0;\n\n      for (; i < len; ++i) {\n        a.push(arguments[i]);\n      }\n\n      this[prop] = this[prop].concat(a);\n      return this;\n    }\n  }\n\n  function streamToUnemptyBuffer(stream, callback) {\n    var done = false\n    var buffers = []\n\n    stream.on('data', function (data) {\n      buffers.push(data)\n    })\n\n    stream.on('end', function () {\n      if (done)\n        return\n\n      done = true\n      let result = Buffer.concat(buffers)\n      buffers = null\n\n      if (result.length === 0) {\n        const err = new Error(\"Stream yields empty buffer\");\n        callback(err, null);\n      } else {\n        callback(null, result);\n      }\n    })\n\n    stream.on('error', function (err) {\n      done = true\n      buffers = null\n      callback(err)\n    })\n  }\n\n  proto.in = args('_in');\n  proto.out = args('_out');\n\n  proto._preprocessor = [];\n  proto.preprocessor = args('_preprocessor');\n\n  /**\n   * Execute the command and write the image to the specified file name.\n   *\n   * @param {String} name\n   * @param {Function} callback\n   * @return {Object} gm\n   */\n\n  proto.write = function write (name, callback) {\n    if (!callback) callback = name, name = null;\n\n    if (\"function\" !== typeof callback) {\n      throw new TypeError(\"gm().write() expects a callback function\")\n    }\n\n    if (!name) {\n      return callback(TypeError(\"gm().write() expects a filename when writing new files\"));\n    }\n\n    this.outname = name;\n\n    var self = this;\n    this._preprocess(function (err) {\n      if (err) return callback(err);\n      self._spawn(self.args(), true, callback);\n    });\n  }\n\n  /**\n   * Execute the command and return stdin and stderr\n   * ReadableStreams providing the image data.\n   * If no callback is passed, a \"through\" stream will be returned,\n   * and stdout will be piped through, otherwise the error will be passed.\n   *\n   * @param {String} format (optional)\n   * @param {Function} callback (optional)\n   * @return {Stream}\n   */\n\n  proto.stream = function stream (format, callback) {\n    if (!callback && typeof format === 'function') {\n      callback = format;\n      format = null;\n    }\n\n    var throughStream;\n\n    if (\"function\" !== typeof callback) {\n      throughStream = new PassThrough();\n      callback = function (err, stdout, stderr) {\n        if (err) throughStream.emit('error', err);\n        else stdout.pipe(throughStream);\n      }\n    }\n\n    if (format) {\n      format = format.split('.').pop();\n      this.outname = format + \":-\";\n    }\n\n    var self = this;\n    this._preprocess(function (err) {\n      if (err) return callback(err);\n      return self._spawn(self.args(), false, callback);\n    });\n\n    return throughStream || this;\n  }\n\n  /**\n   * Convenience function for `proto.stream`.\n   * Simply returns the buffer instead of the stream.\n   *\n   * @param {String} format (optional)\n   * @param {Function} callback\n   * @return {null}\n   */\n\n  proto.toBuffer = function toBuffer (format, callback) {\n    if (!callback) callback = format, format = null;\n\n    if (\"function\" !== typeof callback) {\n      throw new Error('gm().toBuffer() expects a callback.');\n    }\n\n    return this.stream(format, function (err, stdout) {\n      if (err) return callback(err);\n\n      streamToUnemptyBuffer(stdout, callback);\n    })\n  }\n\n  /**\n    * Run any preProcessor functions in series. Used by autoOrient.\n    *\n    * @param {Function} callback\n    * @return {Object} gm\n    */\n\n  proto._preprocess = function _preprocess (callback) {\n    series(this._preprocessor, this, callback);\n  }\n\n  /**\n    * Execute the command, buffer input and output, return stdout and stderr buffers.\n    *\n    * @param {String} bin\n    * @param {Array} args\n    * @param {Function} callback\n    * @return {Object} gm\n    */\n\n  proto._exec = function _exec (args, callback) {\n    return this._spawn(args, true, callback);\n  }\n\n  /**\n    * Execute the command with stdin, returning stdout and stderr streams or buffers.\n    * @param {String} bin\n    * @param {Array} args\n    * @param {ReadableStream} stream\n    * @param {Boolean} shouldBuffer\n    * @param {Function} callback, signature (err, stdout, stderr) -> *\n    * @return {Object} gm\n    * @TODO refactor this mess\n    */\n\n  proto._spawn = function _spawn (args, bufferOutput, callback) {\n    var appPath = this._options.appPath || '';\n    var bin\n\n    // Resolve executable\n    switch (this._options.imageMagick) {\n      // legacy behavior\n      case true:\n        bin = args.shift();\n        break;\n\n      // ImgeMagick >= 7\n      case '7+':\n        bin = 'magick'\n        break;\n\n      // GraphicsMagick\n      default:\n        bin = 'gm';\n        break;\n    }\n\n    // Prepend app path\n    bin = appPath + bin\n\n    var cmd = bin + ' ' + args.map(utils.escape).join(' ')\n      , self = this\n      , proc, err\n      , timeout = parseInt(this._options.timeout)\n      , disposers = this._options.disposers\n      , timeoutId;\n\n    debug(cmd);\n    //imageMagick does not support minify (https://github.com/aheckmann/gm/issues/385)\n    if(args.indexOf(\"-minify\") > -1 && this._options.imageMagick){\n      return cb(new Error(\"imageMagick does not support minify, use -scale or -sample. Alternatively, use graphicsMagick\"));\n    }\n    try {\n      proc = spawn(bin, args);\n    } catch (e) {\n      return cb(e);\n    }\n    proc.stdin.once('error', cb);\n\n    proc.on('error', function(err){\n      if (err.code === 'ENOENT') {\n        cb(new Error('Could not execute GraphicsMagick/ImageMagick: '+cmd+\" this most likely means the gm/convert binaries can't be found\"));\n      } else {\n        cb(err);\n      }\n    });\n\n    if (timeout) {\n      timeoutId = setTimeout(function(){\n        dispose('gm() resulted in a timeout.');\n      }, timeout);\n    }\n\n    if (disposers) {\n      disposers.forEach(function(disposer) {\n        disposer.events.forEach(function(event) {\n          disposer.emitter.on(event, dispose);\n        });\n      });\n    }\n\n    if (self.sourceBuffer) {\n      proc.stdin.write(this.sourceBuffer);\n      proc.stdin.end();\n    } else if (self.sourceStream) {\n\n      if (!self.sourceStream.readable) {\n        return cb(new Error(\"gm().stream() or gm().write() with a non-readable stream.\"));\n      }\n\n      self.sourceStream.pipe(proc.stdin);\n\n      // bufferStream\n      // We convert the input source from a stream to a buffer.\n      if (self.bufferStream && !this._buffering) {\n        if (!Buffer.concat) {\n          throw new Error(noBufferConcat);\n        }\n\n        // Incase there are multiple processes in parallel,\n        // we only need one\n        self._buffering = true;\n\n        streamToUnemptyBuffer(self.sourceStream, function (err, buffer) {\n          self.sourceBuffer = buffer;\n          self.sourceStream = null; // The stream is now dead\n        })\n      }\n    }\n\n    // for _exec operations (identify() mostly), we also\n    // need to buffer the output stream before returning\n    if (bufferOutput) {\n      var stdout = ''\n        , stderr = ''\n        , onOut\n        , onErr\n        , onExit\n\n      proc.stdout.on('data', onOut = function (data) {\n        stdout += data;\n      });\n\n      proc.stderr.on('data', onErr = function (data) {\n        stderr += data;\n      });\n\n      proc.on('close', onExit = function (code, signal) {\n        let err;\n        if (code !== 0 || signal !== null) {\n          err = new Error('Command failed: ' + stderr);\n          err.code = code;\n          err.signal = signal;\n        };\n        cb(err, stdout, stderr, cmd);\n        stdout = stderr = onOut = onErr = onExit = null;\n      });\n    } else {\n      cb(null, proc.stdout, proc.stderr, cmd);\n    }\n\n    return self;\n\n    function cb (err, stdout, stderr, cmd) {\n      if (cb.called) return;\n      if (timeoutId) clearTimeout(timeoutId);\n      cb.called = 1;\n      if (args[0] !== 'identify' && bin !== 'identify') {\n        self._in = [];\n        self._out = [];\n      }\n      callback.call(self, err, stdout, stderr, cmd);\n    }\n\n    function dispose (msg) {\n      const message = msg ? msg : 'gm() was disposed';\n      const err = new Error(message);\n      cb(err);\n      if (proc.exitCode === null) {\n        proc.stdin.pause();\n        proc.kill();\n      }\n    }\n  }\n\n  /**\n   * Returns arguments to be used in the command.\n   *\n   * @return {Array}\n   */\n\n  proto.args = function args () {\n    var outname = this.outname || \"-\";\n  \tif (this._outputFormat) outname = this._outputFormat + ':' + outname;\n\n    return [].concat(\n        this._subCommand\n      , this._in\n      , this.src()\n      , this._out\n      , outname\n    ).filter(Boolean); // remove falsey\n  }\n\n  /**\n   * Adds an img source formatter.\n   *\n   * `formatters` are passed an array of images which will be\n   * used as 'input' images for the command. Useful for methods\n   * like `.append()` where multiple source images may be used.\n   *\n   * @param {Function} formatter\n   * @return {gm} this\n   */\n\n  proto.addSrcFormatter = function addSrcFormatter (formatter) {\n    if ('function' != typeof formatter)\n      throw new TypeError('sourceFormatter must be a function');\n    this._sourceFormatters || (this._sourceFormatters = []);\n    this._sourceFormatters.push(formatter);\n    return this;\n  }\n\n  /**\n   * Applies all _sourceFormatters\n   *\n   * @return {Array}\n   */\n\n  proto.src = function src () {\n    var arr = [];\n    for (var i = 0; i < this._sourceFormatters.length; ++i) {\n      this._sourceFormatters[i].call(this, arr);\n    }\n    return arr;\n  }\n\n  /**\n   * Image types.\n   */\n\n  var types = {\n      'jpg': /\\.jpe?g$/i\n    , 'png' : /\\.png$/i\n    , 'gif' : /\\.gif$/i\n    , 'tiff': /\\.tif?f$/i\n    , 'bmp' : /(?:\\.bmp|\\.dib)$/i\n    , 'webp': /\\.webp$/i\n  };\n\n  types.jpeg = types.jpg;\n  types.tif = types.tiff;\n  types.dib = types.bmp;\n\n  /**\n   * Determine the type of source image.\n   *\n   * @param {String} type\n   * @return {Boolean}\n   * @example\n   *   if (this.inputIs('png')) ...\n   */\n\n  proto.inputIs = function inputIs (type) {\n    if (!type) return false;\n\n    var rgx = types[type];\n    if (!rgx) {\n      if ('.' !== type[0]) type = '.' + type;\n      rgx = new RegExp('\\\\' + type + '$', 'i');\n    }\n\n    return rgx.test(this.source);\n  }\n\n  /**\n   * add disposer (like 'close' of http.IncomingMessage) in order to dispose gm() with any event\n   *\n   * @param {EventEmitter} emitter\n   * @param {Array} events\n   * @return {Object} gm\n   * @example\n   *   command.addDisposer(req, ['close', 'end', 'finish']);\n   */\n\n  proto.addDisposer = function addDisposer (emitter, events) {\n    if (!this._options.disposers) {\n      this._options.disposers = [];\n    }\n    this._options.disposers.push({\n      emitter: emitter,\n      events: events\n    });\n    return this;\n  };\n}\n"
  },
  {
    "path": "lib/compare.js",
    "content": "// compare\n\nvar spawn = require('cross-spawn');\nvar debug = require('debug')('gm');\nvar utils = require('./utils');\n\n/**\n * Compare two images uses graphicsmagicks `compare` command.\n *\n * gm.compare(img1, img2, 0.4, function (err, equal, equality) {\n *   if (err) return handle(err);\n *   console.log('The images are equal: %s', equal);\n *   console.log('There equality was %d', equality);\n * });\n *\n * @param {String} orig Path to an image.\n * @param {String} compareTo Path to another image to compare to `orig`.\n * @param {Number|Object} [options] Options object or the amount of difference to tolerate before failing - defaults to 0.4\n * @param {Function} cb(err, Boolean, equality, rawOutput)\n */\n\nmodule.exports = exports = function (proto) {\n  function compare(orig, compareTo, options, cb) {\n\n    var isImageMagick = this._options && this._options.imageMagick;\n    var appPath = this._options && this._options.appPath || '';\n    var args = ['-metric', 'mse', orig, compareTo];\n\n    // Resove executable\n    let bin;\n\n    switch (isImageMagick) {\n      case true:\n        bin = 'compare';\n        break;\n      case '7+':\n        bin = 'magick'\n        args.unshift('compare');\n        break;\n      default:\n        bin = 'gm'\n        args.unshift('compare');\n        break\n    }\n\n    // Prepend app path\n    bin = appPath + bin\n\n    var tolerance = 0.4;\n    // outputting the diff image\n    if (typeof options === 'object') {\n\n      if (options.highlightColor && options.highlightColor.indexOf('\"') < 0) {\n        options.highlightColor = '\"' + options.highlightColor + '\"';\n      }\n\n      if (options.file) {\n        if (typeof options.file !== 'string') {\n          throw new TypeError('The path for the diff output is invalid');\n        }\n         // graphicsmagick defaults to red\n        if (options.highlightColor) {\n            args.push('-highlight-color');\n            args.push(options.highlightColor);\n        }\n        if (options.highlightStyle) {\n            args.push('-highlight-style')\n            args.push(options.highlightStyle)\n        }\n        // For IM, filename is the last argument. For GM it's `-file <filename>`\n        if (!isImageMagick) {\n            args.push('-file');\n        }\n        args.push(options.file);\n      }\n\n      if (typeof options.tolerance != 'undefined') {\n        if (typeof options.tolerance !== 'number') {\n          throw new TypeError('The tolerance value should be a number');\n        }\n        tolerance = options.tolerance;\n      }\n    } else {\n      // For ImageMagick diff file is required but we don't care about it, so null it out\n      if (isImageMagick) {\n        args.push('null:');\n      }\n\n      if (typeof options == 'function') {\n        cb = options; // tolerance value not provided, flip the cb place\n      } else {\n        tolerance = options\n      }\n    }\n\n    var cmd = bin + ' ' + args.map(utils.escape).join(' ')\n    debug(cmd);\n\n    var proc = spawn(bin, args);\n    var stdout = '';\n    var stderr = '';\n    proc.stdout.on('data',function(data) { stdout+=data });\n    proc.stderr.on('data',function(data) { stderr+=data });\n    proc.on('close', function (code) {\n      // ImageMagick returns err code 2 if err, 0 if similar, 1 if dissimilar\n      if (isImageMagick) {\n        if (code === 0) {\n          return cb(null, 0 <= tolerance, 0, stdout);\n        }\n        else if (code === 1) {\n          stdout = stderr;\n        } else {\n        return cb(stderr);\n        }\n      } else {\n        if(code !== 0) {\n          return cb(stderr);\n        }\n      }\n      // Since ImageMagick similar gives err code 0 and no stdout, there's really no matching\n      // Otherwise, output format for IM is `12.00 (0.123)` and for GM it's `Total: 0.123`\n      var regex = isImageMagick ? /\\((\\d+\\.?[\\d\\-\\+e]*)\\)/m : /Total: (\\d+\\.?\\d*)/m;\n      var match = regex.exec(stdout);\n      if (!match) {\n        return cb(new Error('Unable to parse output.\\nGot ' + stdout));\n      }\n\n      var equality = parseFloat(match[1]);\n      cb(null, equality <= tolerance, equality, stdout, orig, compareTo);\n    });\n  }\n\n  if (proto) {\n    proto.compare = compare;\n  }\n  return compare;\n};\n\n"
  },
  {
    "path": "lib/composite.js",
    "content": "// composite\n\n/**\n * Composite images together using the `composite` command in graphicsmagick.\n *\n * gm('/path/to/image.jpg')\n * .composite('/path/to/second_image.jpg')\n * .geometry('+100+150')\n * .write('/path/to/composite.png', function(err) {\n *   if(!err) console.log(\"Written composite image.\");\n * });\n *\n * @param {String} other  Path to the image that contains the changes.\n * @param {String} [mask] Path to the image with opacity informtion. Grayscale.\n */\n\nmodule.exports = exports = function(proto) {\n    proto.composite = function(other, mask) {\n        this.in(other);\n\n        // If the mask is defined, add it to the output.\n        if(typeof mask !== \"undefined\")\n            this.out(mask);\n\n        this.subCommand(\"composite\");\n\n        return this;\n    }\n}\n"
  },
  {
    "path": "lib/convenience/autoOrient.js",
    "content": "\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n\n  var exifTransforms = {\n      topleft:     ''\n    , topright:    ['-flop']\n    , bottomright: ['-rotate', 180]\n    , bottomleft:  ['-flip']\n    , lefttop:     ['-flip', '-rotate', 90]\n    , righttop:    ['-rotate', 90]\n    , rightbottom: ['-flop', '-rotate', 90]\n    , leftbottom:  ['-rotate', 270]\n  }\n\n  proto.autoOrient = function autoOrient () {\n    // Always strip EXIF data since we can't\n    // change/edit it.\n\n    // imagemagick has a native -auto-orient option\n    // so does graphicsmagick, but in 1.3.18.\n    // nativeAutoOrient option enables this if you know you have >= 1.3.18\n    if (this._options.nativeAutoOrient || this._options.imageMagick) {\n      this.out('-auto-orient');\n      return this;\n    }\n\n    this.preprocessor(function (callback) {\n      this.orientation({bufferStream: true}, function (err, orientation) {\n        if (err) return callback(err);\n\n        var transforms = exifTransforms[orientation.toLowerCase()];\n        if (transforms) {\n\n          // remove any existing transforms that might conflict\n          var index = this._out.indexOf(transforms[0]);\n          if (~index) {\n            this._out.splice(index, transforms.length);\n          }\n\n          // repage to fix coordinates\n          this._out.unshift.apply(this._out, transforms.concat('-page', '+0+0'));\n        }\n\n        callback();\n      });\n    });\n\n    return this;\n  }\n}\n"
  },
  {
    "path": "lib/convenience/morph.js",
    "content": "\n/**\n * Module dependencies.\n */\n\nvar fs = require('fs');\nvar parallel = require('array-parallel');\n\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n\n  /**\n   * Do nothing.\n   */\n\n  function noop () {}\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-morph\n  proto.morph = function morph (other, outname, callback) {\n    if (!outname) {\n      throw new Error(\"an output filename is required\");\n    }\n\n    callback = (callback || noop).bind(this)\n\n    var self = this;\n\n    if (Array.isArray(other)) {\n      other.forEach(function (img) {\n        self.out(img);\n      });\n      self.out(\"-morph\", other.length);\n    } else {\n      self.out(other, \"-morph\", 1);\n    }\n\n    self.write(outname, function (err, stdout, stderr, cmd) {\n      if (err) return callback(err, stdout, stderr, cmd);\n\n      // Apparently some platforms create the following temporary files.\n      // Check if the output file exists, if it doesn't, then\n      // work with temporary files.\n      fs.exists(outname, function (exists) {\n        if (exists) return callback(null, stdout, stderr, cmd);\n\n        parallel([\n          fs.unlink.bind(fs, outname + '.0'),\n          fs.unlink.bind(fs, outname + '.2'),\n          fs.rename.bind(fs, outname + '.1', outname)\n        ], function (err) {\n          callback(err, stdout, stderr, cmd);\n        })\n      })\n    });\n\n    return self;\n  }\n}\n"
  },
  {
    "path": "lib/convenience/sepia.js",
    "content": "\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n  proto.sepia = function sepia () {\n    return this.modulate(115, 0, 100).colorize(7, 21, 50);\n  }\n}\n"
  },
  {
    "path": "lib/convenience/thumb.js",
    "content": "\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n\n  proto.thumb = function thumb (w, h, name, quality, align, progressive, callback, opts) {\n    var self = this,\n      args = Array.prototype.slice.call(arguments);\n\n    opts = args.pop();\n\n    if (typeof opts === 'function') {\n      callback = opts;\n      opts = '';\n    } else {\n      callback = args.pop();\n    }\n\n    w = args.shift();\n    h = args.shift();\n    name = args.shift();\n    quality = args.shift() || 63;\n    align = args.shift() || 'topleft';\n    var interlace = args.shift() ? 'Line' : 'None';\n\n    self.size(function (err, size) {\n      if (err) {\n        return callback.apply(self, arguments);\n      }\n\n      w = parseInt(w, 10);\n      h = parseInt(h, 10);\n\n      var w1, h1;\n      var xoffset = 0;\n      var yoffset = 0;\n\n      if (size.width < size.height) {\n        w1 = w;\n        h1 = Math.floor(size.height * (w/size.width));\n        if (h1 < h) {\n          w1 = Math.floor(w1 * (((h-h1)/h) + 1));\n          h1 = h;\n        }\n      } else if (size.width > size.height) {\n        h1 = h;\n        w1 = Math.floor(size.width * (h/size.height));\n        if (w1 < w) {\n          h1 = Math.floor(h1 * (((w-w1)/w) + 1));\n          w1 = w;\n        }\n      } else if (size.width == size.height) {\n        var bigger = (w>h?w:h);\n        w1 = bigger;\n        h1 = bigger;\n      }\n\n      if (align == 'center') {\n        if (w < w1) {\n          xoffset = (w1-w)/2;\n        }\n        if (h < h1) {\n          yoffset = (h1-h)/2;\n        }\n      }\n\n      self\n      .quality(quality)\n      .in(\"-size\", w1+\"x\"+h1)\n      .scale(w1, h1, opts)\n      .crop(w, h, xoffset, yoffset)\n      .interlace(interlace)\n      .noProfile()\n      .write(name, function () {\n        callback.apply(self, arguments);\n      });\n    });\n\n    return self;\n  };\n\n  proto.thumbExact = function () {\n    var self = this,\n      args = Array.prototype.slice.call(arguments);\n\n    args.push('!');\n\n    self.thumb.apply(self, args);\n  };\n};\n"
  },
  {
    "path": "lib/convenience.js",
    "content": "\n/**\n * Extend proto\n */\n\nmodule.exports = function (proto) {\n  require(\"./convenience/thumb\")(proto);\n  require(\"./convenience/morph\")(proto);\n  require(\"./convenience/sepia\")(proto);\n  require(\"./convenience/autoOrient\")(proto);\n}\n"
  },
  {
    "path": "lib/drawing.js",
    "content": "\n/**\n * Module dependencies.\n */\n\nvar escape = require('./utils').escape;\n\n/**\n * Extend proto.\n */\n\nmodule.exports = function (proto) {\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-fill\n  proto.fill = function fill (color) {\n    return this.out(\"-fill\", color || \"none\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-stroke\n  proto.stroke = function stroke (color, width) {\n    if (width) {\n      this.strokeWidth(width);\n    }\n\n    return this.out(\"-stroke\", color || \"none\");\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-strokewidth\n  proto.strokeWidth = function strokeWidth (width) {\n    return this.out(\"-strokewidth\", width);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-font\n  proto.font = function font (font, size) {\n    if (size) {\n      this.fontSize(size);\n    }\n\n    return this.out(\"-font\", font);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html\n  proto.fontSize = function fontSize (size) {\n    return this.out(\"-pointsize\", size);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.draw = function draw (args) {\n    return this.out(\"-draw\", [].slice.call(arguments).join(\" \"));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawPoint = function drawPoint (x, y) {\n    return this.draw(\"point\", x +\",\"+ y);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawLine = function drawLine (x0, y0, x1, y1) {\n    return this.draw(\"line\", x0+\",\"+y0, x1+\",\"+y1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawRectangle = function drawRectangle (x0, y0, x1, y1, wc, hc) {\n    var shape = \"rectangle\"\n      , lastarg;\n\n    if (\"undefined\" !== typeof wc) {\n      shape = \"roundRectangle\";\n\n      if (\"undefined\" === typeof hc) {\n        hc = wc;\n      }\n\n      lastarg = wc+\",\"+hc;\n    }\n\n    return this.draw(shape, x0+\",\"+y0, x1+\",\"+y1, lastarg);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawArc = function drawArc (x0, y0, x1, y1, a0, a1) {\n    return this.draw(\"arc\", x0+\",\"+y0, x1+\",\"+y1, a0+\",\"+a1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawEllipse = function drawEllipse (x0, y0, rx, ry, a0, a1) {\n    if (a0 == undefined) a0 = 0;\n    if (a1 == undefined) a1 = 360;\n    return this.draw(\"ellipse\", x0+\",\"+y0, rx+\",\"+ry, a0+\",\"+a1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawCircle = function drawCircle (x0, y0, x1, y1) {\n    return this.draw(\"circle\", x0+\",\"+y0, x1+\",\"+y1);\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawPolyline = function drawPolyline () {\n    return this.draw(\"polyline\", formatPoints(arguments));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawPolygon = function drawPolygon () {\n    return this.draw(\"polygon\", formatPoints(arguments));\n  }\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawBezier = function drawBezier () {\n    return this.draw(\"bezier\", formatPoints(arguments));\n  }\n\n  proto._gravities = [\n      \"northwest\"\n\t  , \"north\"\n    , \"northeast\"\n\t  , \"west\"\n    , \"center\"\n\t  , \"east\"\n    , \"southwest\"\n    , \"south\"\n    , \"southeast\"];\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.drawText = function drawText (x0, y0, text, gravity) {\n    var gravity = String(gravity || \"\").toLowerCase()\n      , arg = [\"text \" + x0 + \",\" + y0 + \" \" + escape(text)];\n\n    if (~this._gravities.indexOf(gravity)) {\n      arg.unshift(\"gravity\", gravity);\n    }\n\n    return this.draw.apply(this, arg);\n  }\n\n  proto._drawProps = [\"color\", \"matte\"];\n\n  // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw\n  proto.setDraw = function setDraw (prop, x, y, method) {\n    prop = String(prop || \"\").toLowerCase();\n\n    if (!~this._drawProps.indexOf(prop)) {\n      return this;\n    }\n\n    return this.draw(prop, x+\",\"+y, method);\n  }\n\n}\n\nfunction formatPoints (points) {\n  var len = points.length\n    , result = []\n    , i = 0;\n\n  for (; i < len; ++i) {\n    result.push(points[i].join(\",\"));\n  }\n\n  return result;\n}\n"
  },
  {
    "path": "lib/getters.js",
    "content": "/**\n * Extend proto.\n */\n\nmodule.exports = function (gm) {\n\n  var proto = gm.prototype;\n\n  /**\n   * `identify` states\n   */\n\n  const IDENTIFYING = 1;\n  const IDENTIFIED = 2;\n\n  /**\n   * Map getter functions to output names.\n   *\n   * - format: specifying the -format argument (see man gm)\n   * - verbose: use -verbose instead of -format (only if necessary b/c its slow)\n   * - helper: use the conversion helper\n   */\n\n  var map = {\n      'format': { key: 'format', format: '%m ', helper: 'Format' }\n    , 'depth':  { key: 'depth',  format: '%q' }\n    , 'filesize': { key: 'Filesize', format: '%b' }\n    , 'size':  { key: 'size', format: '%wx%h ', helper: 'Geometry' }\n    , 'color': { key: 'color', format: '%k',  helper: 'Colors' }\n    , 'orientation': { key: 'Orientation', format: '%[EXIF:Orientation]', helper: 'Orientation' }\n    , 'res':   { key: 'Resolution', verbose: true }\n  }\n\n  /**\n   * Getter functions\n   */\n\n  Object.keys(map).forEach(function (getter) {\n    proto[getter] = function (opts, callback) {\n      if (!callback) callback = opts, opts = {};\n      if (!callback) return this;\n\n      var val = map[getter]\n        , key = val.key\n        , self = this;\n\n      if (self.data[key]) {\n        callback.call(self, null, self.data[key]);\n        return self;\n      }\n\n      self.on(getter, callback);\n\n      self.bufferStream = !!opts.bufferStream;\n\n      if (val.verbose) {\n        self.identify(opts, function (err, stdout, stderr, cmd) {\n          if (err) {\n            self.emit(getter, err, self.data[key], stdout, stderr, cmd);\n          } else {\n            self.emit(getter, err, self.data[key]);\n          }\n        });\n        return self;\n      }\n\n      var args = makeArgs(self, val);\n      self._exec(args, function (err, stdout, stderr, cmd) {\n        if (err) {\n          self.emit(getter, err, self.data[key], stdout, stderr, cmd);\n          return;\n        }\n\n        var result = (stdout||'').trim();\n\n        if (val.helper in helper) {\n          helper[val.helper](self.data, result);\n        } else {\n          self.data[key] = result;\n        }\n\n        self.emit(getter, err, self.data[key]);\n      });\n\n      return self;\n    }\n  });\n\n  /**\n   * identify command\n   *\n   * Overwrites all internal data with the parsed output\n   * which is more accurate than the fast shortcut\n   * getters.\n   */\n\n  proto.identify = function identify (opts, callback) {\n    // identify with pattern\n    if (typeof(opts) === 'string') {\n      opts = {\n        format: opts\n      }\n    }\n    if (!callback) callback = opts, opts = {};\n    if (!callback) return this;\n    if (opts && opts.format) return identifyPattern.call(this, opts, callback);\n\n    var self = this;\n\n    if (IDENTIFIED === self._identifyState) {\n      callback.call(self, null, self.data);\n      return self;\n    }\n\n    self.on('identify', callback);\n\n    if (IDENTIFYING === self._identifyState) {\n      return self;\n    }\n\n    self._identifyState = IDENTIFYING;\n\n    self.bufferStream = !!opts.bufferStream;\n\n    var args = makeArgs(self, { verbose: true });\n\n    self._exec(args, function (err, stdout, stderr, cmd) {\n      if (err) {\n        self.emit('identify', err, self.data, stdout, stderr, cmd);\n        return;\n      }\n\n      err = parse(stdout, self);\n\n      if (err) {\n        self.emit('identify', err, self.data, stdout, stderr, cmd);\n        return;\n      }\n\n      self.data.path = self.source;\n\n      self.emit('identify', null, self.data);\n      self._identifyState = IDENTIFIED;\n    });\n\n    return self;\n  }\n\n\n  /**\n   * identify with pattern\n   *\n   * Execute `identify -format` with custom pattern\n   */\n\n  function identifyPattern (opts, callback) {\n    var self = this;\n\n    self.bufferStream = !!opts.bufferStream;\n\n    var args = makeArgs(self, opts);\n    self._exec(args, function (err, stdout, stderr, cmd) {\n      if (err) {\n        return callback.call(self, err, undefined, stdout, stderr, cmd);\n      }\n\n      callback.call(self, err, (stdout||'').trim());\n    });\n\n    return self;\n  }\n\n\n  /**\n   * Parses `identify` responses.\n   *\n   * @param {String} stdout\n   * @param {Gm} self\n   * @return {Error} [optionally]\n   */\n\n  function parse (stdout, self) {\n    // normalize\n    var parts = (stdout||\"\").trim().replace(/\\r\\n|\\r/g, \"\\n\").split(\"\\n\");\n\n    // skip the first line (its just the filename)\n    parts.shift();\n\n    try {\n      var len = parts.length\n        , rgx1 = /^( *)(.+?): (.*)$/ // key: val\n        , rgx2 = /^( *)(.+?):$/      // key: begin nested object\n        , out = { indent: {} }\n        , level = null\n        , lastkey\n        , i = 0\n        , res\n        , o\n\n      for (; i < len; ++i) {\n        res = rgx1.exec(parts[i]) || rgx2.exec(parts[i]);\n        if (!res) continue;\n\n        var indent = res[1].length\n          , key = res[2] ? res[2].trim() : '';\n\n        if ('Image' == key || 'Warning' == key) continue;\n\n        var val = res[3] ? res[3].trim() : null;\n\n        // first iteration?\n        if (null === level) {\n          level = indent;\n          o = out.root = out.indent[level] = self.data;\n        } else if (indent < level) {\n          // outdent\n          if (!(indent in out.indent)) {\n            continue;\n          }\n          o = out.indent[indent];\n        } else if (indent > level) {\n          // dropping into a nested object\n          out.indent[level] = o;\n          // weird format, key/val pair with nested children. discard the val\n          o = o[lastkey] = {};\n        }\n\n        level = indent;\n\n        if (val) {\n          // if previous key was exist and we got the same key\n          // cast it to an array.\n          if(o.hasOwnProperty(key)){\n            // cast it to an array and dont forget the previous value\n            if(!Array.isArray(o[key])){\n              var tmp = o[key];\n              o[key] = [tmp];\n            }\n\n            // set value\n            o[key].push(val);\n          } else {\n            o[key] = val;\n          }\n\n          if (key in helper) {\n            helper[key](o, val);\n          }\n        }\n\n        lastkey = key;\n      }\n\n    } catch (err) {\n      err.message = err.message + \"\\n\\n  Identify stdout:\\n  \" + stdout;\n      return err;\n    }\n  }\n\n  /**\n   * Create an argument array for the identify command.\n   *\n   * @param {gm} self\n   * @param {Object} val\n   * @return {Array}\n   */\n\n  function makeArgs (self, val) {\n    var args = [\n        'identify'\n      , '-ping'\n    ];\n\n    if (val.format) {\n      args.push('-format', val.format);\n    }\n\n    if (val.verbose) {\n      args.push('-verbose');\n    }\n\n    args = args.concat(self.src());\n    return args;\n  }\n\n  /**\n   * Map exif orientation codes to orientation names.\n   */\n\n  var orientations = {\n      '1': 'TopLeft'\n    , '2': 'TopRight'\n    , '3': 'BottomRight'\n    , '4': 'BottomLeft'\n    , '5': 'LeftTop'\n    , '6': 'RightTop'\n    , '7': 'RightBottom'\n    , '8': 'LeftBottom'\n  }\n\n  /**\n   * identify -verbose helpers\n   */\n\n  var helper = gm.identifyHelpers = {};\n\n  helper.Geometry = function Geometry (o, val) {\n    // We only want the size of the first frame.\n    // Each frame is separated by a space.\n    var split = val.split(\" \").shift().split(\"x\");\n    var width = parseInt(split[0], 10);\n    var height = parseInt(split[1], 10);\n    if (o.size && o.size.width && o.size.height) {\n      if (width > o.size.width) o.size.width = width;\n      if (height > o.size.height) o.size.height = height;\n    } else {\n      o.size = {\n        width:  width,\n        height: height\n      }\n    }\n  };\n\n  helper.Format = function Format (o, val) {\n    o.format = val.split(\" \")[0];\n  };\n\n  helper.Depth = function Depth (o, val) {\n    o.depth = parseInt(val, 10);\n  };\n\n  helper.Colors = function Colors (o, val) {\n    o.color = parseInt(val, 10);\n  };\n\n  helper.Orientation = function Orientation (o, val) {\n    if (val in orientations) {\n      o['Profile-EXIF'] || (o['Profile-EXIF'] = {});\n      o['Profile-EXIF'].Orientation = val;\n      o.Orientation = orientations[val];\n    } else {\n      o.Orientation = val || 'Unknown';\n    }\n  };\n}\n\n"
  },
  {
    "path": "lib/montage.js",
    "content": "// montage\n\n/**\n * Montage images next to each other using the `montage` command in graphicsmagick.\n *\n * gm('/path/to/image.jpg')\n * .montage('/path/to/second_image.jpg')\n * .geometry('+100+150')\n * .write('/path/to/montage.png', function(err) {\n *   if(!err) console.log(\"Written montage image.\");\n * });\n *\n * @param {String} other  Path to the image that contains the changes.\n */\n\nmodule.exports = exports = function(proto) {\n    proto.montage = function(other) {\n        this.in(other);\n\n        this.subCommand(\"montage\");\n\n        return this;\n    }\n}\n"
  },
  {
    "path": "lib/options.js",
    "content": "\nmodule.exports = exports = function (proto) {\n  proto._options = {};\n\n  proto.options = function setOptions (options) {\n    var keys = Object.keys(options)\n      , i = keys.length\n      , key\n\n    while (i--) {\n      key = keys[i];\n      this._options[key] = options[key];\n    }\n\n    return this;\n  }\n}\n"
  },
  {
    "path": "lib/utils.js",
    "content": "\n/**\n * Escape the given shell `arg`.\n *\n * @param {String} arg\n * @return {String}\n * @api public\n */\n\nexports.escape = function escape (arg) {\n  return '\"' + String(arg).trim().replace(/\"/g, '\\\\\"') + '\"';\n};\n\nexports.unescape = function escape (arg) {\n    return String(arg).trim().replace(/\"/g, \"\");\n};\n\nexports.argsToArray = function (args) {\n  var arr = [];\n\n  for (var i = 0; i <= arguments.length; i++) {\n    if ('undefined' != typeof arguments[i])\n      arr.push(arguments[i]);\n  }\n\n  return arr;\n};\n\nexports.isUtil = function (v) {\n\tvar ty = 'object';\n\tswitch (Object.prototype.toString.call(v)) {\n\tcase '[object String]':\n\t\tty = 'String';\n\t\tbreak;\n\tcase '[object Array]':\n\t\tty = 'Array';\n\t\tbreak;\n\tcase '[object Boolean]':\n\t\tty = 'Boolean';\n\t\tbreak;\n\t}\n\treturn ty;\n}"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"gm\",\n  \"description\": \"GraphicsMagick and ImageMagick for node.js\",\n  \"version\": \"1.25.1\",\n  \"author\": \"Aaron Heckmann <aaron.heckmann+github@gmail.com>\",\n  \"keywords\": [\n    \"graphics\",\n    \"magick\",\n    \"image\",\n    \"graphicsmagick\",\n    \"imagemagick\",\n    \"gm\",\n    \"convert\",\n    \"identify\",\n    \"compare\"\n  ],\n  \"engines\": {\n    \"node\": \">=14\"\n  },\n  \"bugs\": {\n    \"url\": \"http://github.com/aheckmann/gm/issues\"\n  },\n  \"licenses\": [\n    {\n      \"type\": \"MIT\",\n      \"url\": \"http://www.opensource.org/licenses/mit-license.php\"\n    }\n  ],\n  \"main\": \"./index\",\n  \"scripts\": {\n    \"security\": \"npm audit\",\n    \"test\": \"npm run security && npm run test-integration\",\n    \"test-integration\": \"node test/ --integration\",\n    \"test-unit\": \"node test/\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/aheckmann/gm.git\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"async\": \"~0.9.0\"\n  },\n  \"dependencies\": {\n    \"array-parallel\": \"~0.1.3\",\n    \"array-series\": \"~0.1.5\",\n    \"cross-spawn\": \"^7.0.5\",\n    \"debug\": \"^3.1.0\"\n  }\n}\n"
  },
  {
    "path": "test/109.js",
    "content": "const fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration) return finish();\n\n  const original = path.join(dir, 'original.jpg');\n  const buf = fs.readFileSync(original);\n  const m = gm(buf, 'original.jpg').options({ imageMagick });\n\n  m.identify(function (err, _) {\n    finish(err);\n  });\n\n}\n"
  },
  {
    "path": "test/118.js",
    "content": "/*\n * If only the width is specified for a resize operation,\n * GraphicsMagick requires the format\n * -resize 10x\n * while ImageMagick requires the format\n * -resize 10\n *\n */\nconst assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration) return finish();\n\n  var src = path.join(dir, 'originalSideways.jpg');\n  var dst = path.join(dir, 'originalSideways10x.jpg');\n\n  gm(src).options({ imageMagick }).resize(10).write(dst, function(err) {\n    gm(dst).options({ imageMagick }).size(function(err, size) {\n      if (err) return finish(err);\n      assert.equal(10, size.width);\n      finish();\n    });\n  });\n\n}\n"
  },
  {
    "path": "test/393.js",
    "content": "const assert = require('assert');\nconst fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)  return finish();\n\n  var imagePath = path.join(__dirname, 'fixtures', 'nyancat.gif');\n  var inputStream = fs.createReadStream(imagePath);\n  gm(inputStream).options({ imageMagick }).identify({ bufferStream: true }, function(err, value) {\n      if (err) return finish(err);\n      var size = value.size;\n      assert.equal(400, size.width);\n      assert.equal(400, size.height);\n      finish();\n    });\n}\n"
  },
  {
    "path": "test/417.js",
    "content": "\nconst assert = require('assert')\nconst fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const originalPathName = path.join(dir, 'original.jpg');\n  const thumbPathName = path.join(dir, 'thumb.png');\n\n  gm(originalPathName).options({ imageMagick }).thumb(150, 40, thumbPathName, function thumb (err) {\n    gm(thumbPathName).options({ imageMagick }).size(function (err, size) {\n      if (err) return finish(err);\n\n      assert.equal(142, size.width);\n      assert.equal(40, size.height);\n\n      gm(originalPathName).options({ imageMagick }).thumbExact(150, 40, thumbPathName, function thumb (err) {\n        gm(thumbPathName).options({ imageMagick }).size(function (err, size) {\n          assert.equal(150, size.width);\n          assert.equal(40, size.height);\n          finish(err);\n        });\n      });\n    });\n  });\n}\n"
  },
  {
    "path": "test/422.js",
    "content": "const fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n  // Same image\n  const originalPathName = path.join(dir, 'original.jpg');\n\n  gm.compare(originalPathName, originalPathName, function(err, same, diff) {\n    if (err) return finish(err);\n    if (!same) {\n      const msg = `Compare should be the same! \"${same}\" \"${diff}\"`;\n      return finish(new Error(msg));\n    }\n\n    // Compare almost similar images for which ImageMagick\n    // returns an exponent-style floating point number\n    const compare1PathName = path.join(__dirname, 'fixtures', 'compare_1.png');\n    const compare2PathName = path.join(__dirname, 'fixtures', 'compare_2.png');\n\n    gm.compare(compare1PathName, compare2PathName, function(err, same, diff) {\n      if (err) return finish(err);\n      if (!same) {\n        const msg = `Compare should be the same! \"${same}\" \"${diff}\"`;\n        return finish(new Error(msg));\n      }\n\n      const noisePathName = path.join(dir, 'noise3.png');\n\n      // Create a new noisy image\n      gm.noise(0.3).write(noisePathName, function (err) {\n        if (err) return finish(err);\n\n        var options = {\n          highlightColor: '#fff',\n          file: path.join(dir, 'diff.png'),\n          tolerance: 0.001\n        };\n\n        const originalPathName = path.join(dir, 'original.jpg');\n\n        // Compare these images and write to a file.\n        gm.compare(originalPathName, noisePathName, options, function(err) {\n          if (err) return finish(err);\n\n          fs.access(options.file, fs.constants.F_OK, function(err) {\n            if (err) {\n              finish(new Error('Diff file does not exist.'));\n            } else {\n              fs.unlink(options.file, finish);\n            }\n          });\n        });\n      });\n    });\n  });\n};\n"
  },
  {
    "path": "test/429.js",
    "content": "const fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n  if (!GM.integration)  return finish();\n\n  const ico = path.join(__dirname, 'fixtures', 'test.ico');\n  const buffer = fs.readFileSync(ico);\n  const stream = fs.createReadStream(ico);\n\n  GM(ico).options({ imageMagick }).size(function (err) {\n    if (err) {\n      err.message = 'Failed using ico filename. ' + err.message;\n      return finish(err);\n    }\n\n    GM(buffer, 'img.ico').options({ imageMagick }).size(function (err) {\n      if (err) {\n        err.message = 'Failed using ico buffer. ' + err.message;\n        return finish(err);\n      }\n\n      GM(stream, 'img.ico').options({ imageMagick }).size({bufferStream: true}, function (err) {\n        if (err) {\n          err.message = 'Failed using ico stream. ' + err.message;\n          return finish(err);\n        }\n        finish();\n      });\n    });\n  });\n}"
  },
  {
    "path": "test/68.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\nvar assert = require('assert')\nvar url = require('url')\nvar http = require('http')\n\nmodule.exports = function (_, dir, finish, gm) {\n  return finish();\n\n  // use this test when gm is not installed.\n  // it demonstrates that err is often passed as null (timing)\n  // to detect the stream error that the gm command is not installed,\n  //   you must test the stderr output manually for \"execvp(): No such file or directory\"\n\n  function done (err){\n    if (err) return finish(done.ran = err);\n    if (done.ran) return;\n    finish();\n  }\n\n  http.get(url.parse('http://www.google.com/images/srpr/logo3w.png'), function (resp) {\n    gm(resp, 'logo3w.png').stream(function (err, stdout, stderr) {\n      return finish();\n\n      if (err) {\n        console.error('Error processing image', err)\n      } else {\n        stdout.on('data', function (chunk) {\n          console.log('Chunk recieved', chunk.toString())\n        })\n        stdout.on('end', function () {\n          console.log('Stream ended')\n        })\n        stderr.on('data', function (chunk) {\n          console.log('err Chunk recieved', chunk.toString())\n        })\n        stderr.on('end', function () {\n          console.log('err Stream ended')\n        })\n      }\n    })\n  })\n  .on('error', function (err) {\n    console.error('Error fetching image', err)\n  })\n\n}\n"
  },
  {
    "path": "test/70.js",
    "content": "\nconst assert = require('assert')\nconst path = require('path');\n\nvar times = 16;\nvar loading = path.join(__dirname, 'fixtures', 'loading.gif');\nvar favicon = path.join(__dirname, 'fixtures', 'favicon.png');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration) return finish();\n\n  var pending = times/2;\n\n  var res = {};\n  res[loading] = {};\n  res[favicon] = {};\n\n  function done (err){\n    if (err) return finish(done.ran = err);\n    if (done.ran) return;\n    if (--pending) return;\n    finish();\n  }\n\n  new Array(times).join('x').split('x').forEach(function (_, i) {\n    ;[loading, favicon].forEach(function (img) {\n      gm(img).options({imageMagick}).size(function (err, size) {\n        if (err) return done(err);\n\n        'width height'.split(' ').forEach(function (prop) {\n          if (!(prop in res[img])) {\n            res[img][prop] = size[prop];\n          } else {\n            assert.equal(res[img][prop], size[prop]);\n          }\n        });\n\n        done(err);\n      });\n    });\n  });\n\n}\n"
  },
  {
    "path": "test/78.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration) return finish();\n\n  var name = imageMagick ? '78-IM' : '78';\n  var out = path.join(dir, name);\n\n  _.resize(600, 450, '!').write(out + '.png', function (err) {\n    if (err) return finish(err);\n\n    var img = gm(out + '.png').options({ imageMagick });\n\n    img\n    .crop(70, 70, 100, 100)\n    .resize(50, 50)\n    .write(out + '-2.jpg', function (err) {\n      if (err) return finish(err);\n      finish();\n    })\n  });\n\n}\n"
  },
  {
    "path": "test/alpha.js",
    "content": "const assert = require('assert');\nconst Async = require('async');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration) return finish();\n\n  var alphaTypes = [\n    \"Activate\",\n    \"On\",\n    \"Deactivate\",\n    \"Off\",\n    \"Set\",\n    \"Opaque\",\n    \"Transparent\",\n    \"Extract\",\n    \"Copy\",\n    \"Shape\",\n    \"Background\"\n  ];\n\n  const edgePath = path.join(dir, 'original.png');\n  const failPath = path.join(dir, 'alpha_fail.png');\n\n  // alpha not supported by GM so only test IM\n  if (!imageMagick) {\n    assert.throws(function() {\n      gm(edgePath)\n        .alpha(alphaTypes.pop())\n        .write(failPath);\n    });\n    finish();\n  } else {\n\n    Async.eachSeries(alphaTypes, function(alphaType, cb) {\n      var m = gm(edgePath).options({imageMagick}).alpha( alphaType );\n      var args = m.args();\n      assert.equal('convert', args[0]);\n      assert.equal('-alpha', args[2]);\n      assert.equal(alphaType, args[3]);\n\n      const writePath = path.join(dir, `alpha_${alphaType}.png`);\n      m.write(writePath, cb);\n    }, finish);\n  }\n}\n"
  },
  {
    "path": "test/append.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  const out = path.resolve(dir, 'append.jpg');\n  const lostPath = path.join(dir, 'lost.png');\n  const originalPath = path.join(dir, 'original.jpg');\n\n  try {\n    require('fs').unlinkSync(out);\n  } catch (_) {}\n\n  var m = gm(lostPath)\n  .options({imageMagick})\n  .append(originalPath, originalPath)\n  .append()\n  .background('#222')\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-background',args[1]);\n  assert.equal('#222',args[2]);\n  assert.ok(/lost\\.png$/.test(args[3]));\n  assert.ok(/original\\.jpg$/,args[4]);\n  assert.ok(/original\\.jpg$/,args[5]);\n  assert.equal('-append',args[6]);\n  assert.equal('-',args[7]);\n\n  if (!gm.integration) {\n    return horizontal({ dir, finish, gm, originalPath, lostPath, imageMagick });\n  }\n\n  m.write(out, function (err) {\n    if (err) return finish(err);\n    gm(out)\n    .options({imageMagick})\n    .size(function (err, size) {\n      if (err) return finish(err);\n      assert.equal(460, size.width);\n      assert.equal(435, size.height);\n\n      horizontal({ dir, finish, gm, originalPath, lostPath, imageMagick });\n    })\n  });\n}\n\nfunction horizontal ({ dir, finish, gm, originalPath, lostPath, imageMagick }) {\n  var out = path.resolve(dir, 'appendHorizontal.jpg');\n\n  var m = gm(originalPath).append(lostPath, true).options({imageMagick});\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.ok(/original\\.jpg$/.test(args[1]));\n  assert.ok(/lost\\.png$/.test(args[2]));\n  assert.equal('+append',args[3]);\n  assert.equal('-',args[4]);\n\n  if (!gm.integration) {\n    return finish();\n  }\n\n  m.write(out, function (err) {\n    if (err) return finish(err);\n    gm(out).options({imageMagick}).size(function (err, size) {\n      if (err) return finish(err);\n      assert.equal(697, size.width);\n      assert.equal(155, size.height);\n\n      finish();\n    })\n  });\n\n}\n"
  },
  {
    "path": "test/arc.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"red\", 3)\n  .fill(\"#ffffffbb\")\n  .drawArc(80, 10, 90, 20, 0, 180)\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-blur', args[2]);\n  assert.equal('8x4', args[3]);\n  assert.equal('-strokewidth', args[4]);\n  assert.equal(3, args[5]);\n  assert.equal('-stroke', args[6]);\n  assert.equal('red', args[7]);\n  assert.equal('-fill', args[8]);\n  assert.equal('#ffffffbb', args[9]);\n  assert.equal('-draw', args[10]);\n  assert.equal('arc 80,10 90,20 0,180', args[11]);\n\n  if (!GM.integration) return finish();\n\n  const arcPath = path.join(dir, 'arc.png');\n\n  m.write(arcPath, function arc (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/autoOrient.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const sidewaysPath = path.join(dir, 'originalSideways.jpg');\n\n  gm(sidewaysPath)\n  .options({imageMagick})\n  .identify(function (err, o) {\n    if (err) return finish(err);\n\n    const geo = imageMagick ? '155x460+0+0' : '155x460';\n    assert.equal(geo, o.Geometry);\n\n    // this image is sideways, but may be auto-oriented by modern OS's\n    // try opening it in a browser to see its true orientation\n    gm(sidewaysPath)\n    .options({imageMagick})\n    .autoOrient()\n    .stream(function (err, stream) {\n      if (err) return finish(err);\n\n      gm(stream)\n      .options({imageMagick})\n      .identify(function (err, data) {\n        if (err) return finish(err);\n\n        const geo2 = imageMagick ? '460x155+0+0' : '460x155';\n        assert.equal(geo2, data.Geometry);\n        finish(err);\n      })\n    })\n  });\n}\n"
  },
  {
    "path": "test/autoOrientAll.js",
    "content": "const assert = require('assert');\nconst fs = require('fs');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration) return finish();\n\n  var beforeValues = {\n    'Landscape_1.jpg': ['TopLeft', 1, '600x450'],\n    'Landscape_2.jpg': ['TopRight', 2, '600x450'],\n    'Landscape_3.jpg': ['BottomRight', 3, '600x450'],\n    'Landscape_4.jpg': ['BottomLeft', 4, '600x450'],\n    'Landscape_5.jpg': ['LeftTop', 5, '450x600'],\n    'Landscape_6.jpg': ['RightTop', 6, '450x600'],\n    'Landscape_7.jpg': ['RightBottom', 7, '450x600'],\n    'Landscape_8.jpg': ['LeftBottom', 8, '450x600'],\n    'Portrait_1.jpg': ['TopLeft', 1, '450x600'],\n    'Portrait_2.jpg': ['TopRight', 2, '450x600'],\n    'Portrait_3.jpg': ['BottomRight', 3, '450x600'],\n    'Portrait_4.jpg': ['BottomLeft', 4, '450x600'],\n    'Portrait_5.jpg': ['LeftTop', 5, '600x450'],\n    'Portrait_6.jpg': ['RightTop', 6, '600x450'],\n    'Portrait_7.jpg': ['RightBottom', 7, '600x450'],\n    'Portrait_8.jpg': ['LeftBottom', 8, '600x450']\n  };\n\n  var afterValues = {\n    'Landscape_1.jpg': '600x450',\n    'Landscape_2.jpg': '600x450',\n    'Landscape_3.jpg': '600x450',\n    'Landscape_4.jpg': '600x450',\n    'Landscape_5.jpg': '600x450',\n    'Landscape_6.jpg': '600x450',\n    'Landscape_7.jpg': '600x450',\n    'Landscape_8.jpg': '600x450',\n    'Portrait_1.jpg': '450x600',\n    'Portrait_2.jpg': '450x600',\n    'Portrait_3.jpg': '450x600',\n    'Portrait_4.jpg': '450x600',\n    'Portrait_5.jpg': '450x600',\n    'Portrait_6.jpg': '450x600',\n    'Portrait_7.jpg': '450x600',\n    'Portrait_8.jpg': '450x600'\n  };\n\n  const orientationDir = path.join(dir, 'orientation');\n\n  fs.readdir(orientationDir, function(err, files) {\n    if (err) return finish(err);\n\n    var originalFiles = files.filter(function(file) {\n      return beforeValues[file] && afterValues[file];\n    });\n\n    function next () {\n      test(originalFiles.pop());\n    }\n\n    return next();\n\n    function test (filename) {\n      if (!filename) return finish();\n\n      const fileToAutoOrient = path.join(orientationDir, filename);\n      const newFilename = fileToAutoOrient + '.oriented.jpg';\n      const constant = fileToAutoOrient + '.correct.jpg';\n\n      gm(fileToAutoOrient).options({imageMagick}).orientation(function (err, o) {\n        if (err) return finish(err);\n\n        assert.equal(beforeValues[filename][0], o);\n        assert.equal(beforeValues[filename][1], this.data['Profile-EXIF'].Orientation, 'No Profile-EXIF data found');\n\n        // this image is sideways, but may be auto-oriented by modern OS's\n        // try opening it in a browser to see its true orientation\n        gm(fileToAutoOrient)\n        .options({ imageMagick })\n        .autoOrient()\n        .write(newFilename, function autoOrient (err) {\n          if (err) return finish(err);\n\n          // fs race condition\n          setTimeout(function () {\n            gm(newFilename).options({ imageMagick }).identify(function (err) {\n              if (err) return finish(err);\n\n              const afterValue = imageMagick ? `${afterValues[filename]}+0+0` : afterValues[filename];\n              assert.equal(afterValue, this.data.Geometry, `Bad-Geometry for ${filename}. Got \"${this.data.Geometry}\"`);\n\n              gm().options({imageMagick}).compare(newFilename, constant, 0.1, function (err, equal) {\n                if (err) return finish(err);\n                assert.ok(equal);\n                next();\n              })\n            });\n          }, 200);\n        });\n      });\n    }\n  });\n\n};\n"
  },
  {
    "path": "test/autoOrientAndThumb.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  var original = path.join(dir, 'orientation', 'Portrait_7.jpg');\n  var result = path.join(dir, 'autoOrientAndThumb.png');\n\n  size(original, imageMagick, function (err, origSize) {\n    if (err) return finish(err);\n\n    assert.ok(origSize.width < 610);\n    assert.ok(origSize.height < 460);\n\n    gm(original)\n    .options({imageMagick})\n    .autoOrient()\n    .thumb(100, 100, result, function (err) {\n      if (err) return finish(err);\n\n      size(result, imageMagick, function (err, newSize) {\n        if (err) return finish(err);\n        assert.ok(newSize.width < 80);\n        assert.ok(newSize.height < 110);\n        finish();\n      });\n\n    });\n  });\n\n  function size (file, imageMagick, cb) {\n    gm(file).options({imageMagick}).identify(function (err, data) {\n      if (err) return cb(err);\n      cb(err, data.size);\n    });\n  }\n}\n"
  },
  {
    "path": "test/autoOrientStream.js",
    "content": "\n// gm - Copyright Aaron Heckmann <aaron.heckmann+github@gmail.com> (MIT Licensed)\n// This is a copy of `autoOrient.js` using streams\n\nconst assert = require('assert')\nconst fs = require('fs')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const filename = path.join(dir, 'autoOrientStream.jpg');\n  const sidewaysPathName = path.join(dir, 'originalSideways.jpg');\n\n  gm(fs.createReadStream(sidewaysPathName)).options({imageMagick}).identify(function (err) {\n    if (err) return finish(err);\n\n    const geo = imageMagick ? '155x460+0+0' : '155x460';\n    assert.equal(geo, this.data.Geometry);\n\n    // this image is sideways, but may be auto-oriented by modern OS's\n    // try opening it in a browser to see its true orientation\n    gm(fs.createReadStream(sidewaysPathName))\n    .options({imageMagick})\n    .autoOrient()\n    .write(filename, function autoOrient (err) {\n      if (err) return finish(err);\n\n      // fs race condition\n      setTimeout(function () {\n        gm(filename).options({imageMagick}).identify(function (err) {\n          if (err) return finish(err);\n\n          const geo2 = imageMagick ? '460x155+0+0' : '460x155';\n          assert.equal(geo2, this.data.Geometry);\n\n          finish(err);\n        });\n      }, 200);\n    });\n  });\n}\n"
  },
  {
    "path": "test/background.js",
    "content": "const assert =require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .crop(140,100)\n  .background(\"#FF0000\")\n  .extent(340,300)\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-background', args[1]);\n  assert.equal('#FF0000', args[2]);\n  assert.equal('-crop', args[4]);\n  assert.equal('140x100+0+0', args[5]);\n  assert.equal('-extent', args[6]);\n  assert.equal('340x300', args[7]);\n\n  if (!GM.integration)\n    return finish();\n\n  const backgroundPathName = path.join(dir, 'background.jpg');\n\n  m.write(backgroundPathName, function (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/bezier.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"red\", 3)\n  .fill(\"#ffffffbb\")\n  .drawBezier([0, 10], [183, 163], [183, 10], [0, 10])\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-blur', args[2]);\n  assert.equal('8x4', args[3]);\n  assert.equal('-strokewidth', args[4]);\n  assert.equal(3, args[5]);\n  assert.equal('-stroke', args[6]);\n  assert.equal('red', args[7]);\n  assert.equal('-fill', args[8]);\n  assert.equal('#ffffffbb', args[9]);\n  assert.equal('-draw', args[10]);\n  assert.equal('bezier 0,10,183,163,183,10,0,10', args[11]);\n\n  if (!GM.integration)\n    return finish();\n\n  m\n  .write(path.join(dir, 'bezier.png'), function bezier (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/bitdepth.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .bitdepth(2);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-depth', args[2]);\n  assert.equal(2, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'bitdepth.png');\n  m.write(outpath, function bitdepth (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/blur.js",
    "content": "\nconst assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(18, 10);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-blur', args[2]);\n  assert.equal('18x10', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'blur.png');\n  m.write(outpath, function blur (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/changeFormat.js",
    "content": "const path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'changedformat.png');\n  gm.write(outpath, function changeformat (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/charcoal.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .charcoal(1);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-charcoal', args[2]);\n  assert.equal(1, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'charcoal.png');\n  m.write(outpath, function charcoal (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/chop.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .chop(54, 1, 307, 1);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-chop', args[1]);\n  assert.equal('54x1+307+1', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'chop.png');\n  m.write(outpath, function chop (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/circle.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"red\", 1)\n  .fill(\"#ffffffbb\")\n  .drawCircle(125, 45, 120, 5);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-blur', args[2]);\n  assert.equal('8x4', args[3]);\n  assert.equal('-strokewidth', args[4]);\n  assert.equal(1, args[5]);\n  assert.equal('-stroke', args[6]);\n  assert.equal('red', args[7]);\n  assert.equal('-fill', args[8]);\n  assert.equal('#ffffffbb', args[9]);\n  assert.equal('-draw', args[10]);\n  assert.equal('circle 125,45 120,5', args[11]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'circle.png');\n  m.write(outpath, function circle (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/colorize.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .colorize(80, 0, 30)\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-colorize', args[2]);\n  assert.equal('80,0,30', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'colorize.png');\n  m.write(outpath, function colorize (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/colors.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .colors(16);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-colors', args[2]);\n  assert.equal(16, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'colors.png');\n  m.write(outpath, function colors (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/comment.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .comment(\"%m:%f %wx%h\");\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-comment', args[2]);\n  assert.equal('\"%m:%f %wx%h\"', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const outpath = path.join(dir, 'comment.png');\n  m.write(outpath, function comment (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/compare.js",
    "content": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (gm, dir, finish) {\n  // Same image\n  const originalJPGFilePath = path.join(dir, 'original.jpg');\n  const originalPNGFilePath = path.join(dir, 'original.png');\n\n  gm.compare(originalJPGFilePath, originalPNGFilePath, function(err, same) {\n    if (err) return finish(err);\n    if (!same) return finish(new Error('Compare should be the same!'));\n\n    // Compare almost similar images for which ImageMagick\n    // returns a exponent-style floating point number\n    const compare1Path = path.join(__dirname, 'fixtures', 'compare_1.png');\n    const compare2Path = path.join(__dirname, 'fixtures', 'compare_2.png');\n\n    gm.compare(compare1Path, compare2Path, function(err, same, diff) {\n      if (err) return finish(err);\n      if (!same) return finish(new Error('Compare should be the same!'));\n\n      // Create a new noisy image\n      const noisePath = path.join(dir, 'noise3.png');\n      gm.noise(0.3).write(noisePath, function (err) {\n        if (err) return finish(err);\n\n        const options = {\n          highlightColor: 'yellow',\n          file: path.join(dir, `compare-test-${Date.now()}.png`),\n          tolerance: 0.001\n        };\n\n        // Compare these images and write to a file.\n        gm.compare(originalJPGFilePath, noisePath, options, function(err) {\n          if (err) return finish(err);\n\n          fs.access(options.file, fs.constants.F_OK, function(err) {\n            if (err) {\n              finish(new Error('Diff file does not exist.'));\n            } else {\n              fs.unlink(options.file, () => finish());\n            }\n          });\n        });\n      });\n    });\n  });\n};"
  },
  {
    "path": "test/composite.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  const sourcePath = path.join(__dirname, 'fixtures', 'compare_1.png');\n  gm.source = sourcePath;\n\n  const faviconPath = path.join(__dirname, 'fixtures', 'favicon.png');\n  const a = gm.composite(faviconPath)\n\n  const args = a.args();\n  assert.equal('composite', args[0]);\n  assert.equal(faviconPath, args[1]);\n  assert.equal(sourcePath, args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'composite.png');\n  a.write(destPath, function(err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/contrast.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  const m = gm.contrast(2);\n\n  const args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('+contrast', args[2]);\n  assert.equal('+contrast', args[3]);\n\n  if (!GM.integration) return finish();\n\n  const destPath = path.join(dir, 'contrast.png');\n\n  m.write(destPath, function contrast (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/crop.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n  const m = gm.crop(200, 155, 300, 0);\n\n  const args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-crop', args[2]);\n  assert.equal('200x155+300+0', args[3]);\n\n  const imagePath = path.join(dir, 'image.png');\n  const m2 = GM(imagePath).options({ imageMagick }).crop(200, 155, 300, 0, true);\n\n  const args2 = m2.args();\n  assert.equal('200x155+300+0%', args2[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'crop.png');\n  m.write(destPath, function crop (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/cycle.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  const m = gm.cycle(4);\n\n  const args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-cycle', args[2]);\n  assert.equal(4, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'cycle.png');\n  m.write(destPath, function cycle (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/densityGm.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n  var NUMBER = 100;\n  var NUMBER2 = 200;\n  var g = gm.density(NUMBER, NUMBER2);\n  var gArgs = g.args();\n  assert.equal('convert', gArgs[0]);\n  assert.equal('-density', gArgs[1]);\n  assert.equal(NUMBER + 'x' + NUMBER2, gArgs[2]);\n\n  if (imageMagick) {\n    // graphicsmagick does not support density with two arguments\n    var imArgs = GM().options({imageMagick}).density(NUMBER).args();\n    assert.equal('convert', imArgs[0]);\n    assert.equal('-density', imArgs[1]);\n    assert.equal(NUMBER, imArgs[2]);\n  }\n\n  if (!GM.integration) return finish();\n\n  const destPath = path.join(dir, 'density.png');\n  g.write(destPath, function density (err) {\n    finish(err);\n  });\n};\n"
  },
  {
    "path": "test/despeckle.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  var m = gm.despeckle();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-despeckle', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'despeckle.png');\n  m.write(destPath, function despeckle (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/dispose.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (img, dir, finish, gm, imageMagick) {\n  var EventEmitter = require('events').EventEmitter;\n  EventEmitter.prototype._maxListeners = 100;\n\n  assert.equal(undefined, gm.prototype._options.disposers);\n  assert.equal(undefined, img._options.disposers);\n\n  var emitter = new EventEmitter();\n\n  var disposer = {\n    emitter: emitter,\n    events: ['pleaseDispose', 'readyToDispose']\n  };\n\n  var g = gm('test').options({ disposers: [ disposer ], imageMagick });\n  assert.deepEqual([disposer], g._options.disposers);\n\n  var sub = gm.subClass({ disposers: [ disposer ], imageMagick });\n  assert.deepEqual([disposer], sub.prototype._options.disposers);\n\n  if (!gm.integration) {\n    return finish();\n  }\n\n  const photoPath = path.join(dir, 'photo.JPG');\n  const disposePath = path.join(dir, 'dispose.png');\n\n  gm(photoPath).options({ disposers: [ disposer ], imageMagick })\n  .thumb(1000, 1000, disposePath, function (err) {\n    assert.ok(err, \"Expecting a disposed error\");\n  });\n\n  emitter.emit('pleaseDispose');\n\n  noDispose();\n\n  function noDispose() {\n    gm(photoPath).options({ disposers: [ disposer ], imageMagick })\n    .thumb(1000, 1000, disposePath, function (err) {\n      finish(err);\n    });\n    emitter.emit('disposeOK');\n  }\n}\n"
  },
  {
    "path": "test/dither.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  if (gm._options.imageMagick)\n    return finish();\n\n  var g = gm.monochrome().dither();\n\n  var args = g.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-monochrome', args[2]);\n  assert.equal('-dither', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'dither.png');\n  g.write(destPath, function dither (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/edge.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .edge(2);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-edge', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'edge.png');\n  m.write(destPath, function edge (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/ellipse.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"blue\", 1)\n  .drawEllipse(155, 80, 130, 50);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-blur', args[2]);\n  assert.equal('8x4', args[3]);\n  assert.equal('-strokewidth', args[4]);\n  assert.equal(1, args[5]);\n  assert.equal('-stroke', args[6]);\n  assert.equal('blue', args[7]);\n  assert.equal('-draw', args[8]);\n  assert.equal('ellipse 155,80 130,50 0,360', args[9]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'ellipse.png');\n  m.write(destPath, function ellipse (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/emboss.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .emboss(2);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-emboss', args[2]);\n  assert.equal(2, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'emboss.png');\n  m.write(destPath, function emboss (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/enhance.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .enhance();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-enhance', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'enhance.png');\n  m.write(destPath, function enhance (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/equalize.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .equalize();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-equalize', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'equalize.png');\n  m.write(destPath, function equalize (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/extent.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .scale(200, 100)\n  .extent(300,300)\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-scale', args[2]);\n  assert.equal('200x100', args[3]);\n  assert.equal('-extent', args[4]);\n  assert.equal('300x300', args[5]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'extent.png');\n  m.write(destPath, function resize (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/flatten.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  // graphicsmagick considers PSD broken\n  // http://www.graphicsmagick.org/NEWS.html#may-30-2016\n  if (!imageMagick) {\n    return finish();\n  }\n\n  const layersPath = path.join(dir, 'layers.psd');\n  var m = gm(layersPath)\n  .options({ imageMagick })\n  .flatten();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-flatten', args[2]);\n\n  if (!gm.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'unlayered.jpg');\n  m.write(destPath, function (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/flip.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .flip();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-flip', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'flip.png');\n  m.write(destPath, function flip (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/flop.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .flop();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-flop', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'flop.png');\n  m.write(destPath, function flop (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/fromBuffer.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n  const original = path.join(dir, 'original.jpg');\n  const result = path.join(dir, 'fromBuffer.png');\n\n  var buf = fs.readFileSync(original);\n\n  var m = gm(buf).options({imageMagick}).rotate('red', 30);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-', args[1]);\n  assert.equal('-background', args[2]);\n  assert.equal('red', args[3]);\n  assert.equal('-rotate', args[4]);\n  assert.equal(30, args[5]);\n\n  if (!gm.integration)\n    return finish();\n\n  m.write(result, function crop (err) {\n    if (err) return finish(err);\n\n    // tolerance defaults to 0.4\n    m.compare(original, result, function (err, equal) {\n      if (err) return finish(err);\n      assert.ok(equal);\n\n      // accepts tolerance argument\n      m.compare(original, result, 0.1, function (err, equal, equality, raw) {\n        if (err) return finish(err);\n        assert.ok(!equal);\n        assert.ok(equality > 0.1);\n        assert.ok(raw);\n        finish();\n      })\n    })\n  });\n}\n"
  },
  {
    "path": "test/gamma.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .gamma(1.7, 2.3, 1.3);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-gamma', args[2]);\n  assert.equal('1.7,2.3,1.3', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'gamma.png');\n  m.write(destPath, function gamma (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/geometry.js",
    "content": "\nvar assert = require('assert')\n\nmodule.exports = function (_, __, finish, GM, imageMagick) {\n  var a = GM(\"dummy\").options({imageMagick}).geometry(\"asdf\"); // Custom geometry command\n  var args = a.args();\n  assert.equal('-geometry', args[2]);\n  assert.equal('asdf', args[3]);\n\n  var b = GM(\"dummy\").options({imageMagick}).geometry(\"\", 100);\n  var args = b.args();\n  assert.equal('-geometry', args[2]);\n  assert.equal('x100', args[3]); // Keep-aspect-ratio command\n\n  return finish();\n}\n"
  },
  {
    "path": "test/getterColor.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'blue.gif');\n  gm(destPath).options({imageMagick}).color(function (err, color) {\n    if (err) return finish(err);\n\n    assert.equal(1, color)\n    assert.equal(this.data.color, color)\n\n    finish();\n\n  });\n}\n"
  },
  {
    "path": "test/getterDepth.js",
    "content": "\nvar assert = require('assert')\n\nmodule.exports = function (gm, dir, finish, GM) {\n  if (!GM.integration)\n    return finish();\n\n  gm\n  .depth(function getterdepth (err, depth) {\n    if (err) return finish(err);\n    if (this._options.imageMagick) {\n      assert.equal(16, depth);\n      assert.equal(16, this.data.depth);\n    } else {\n      assert.equal(8, depth);\n      assert.equal(8, this.data.depth);\n    }\n    finish();\n  });\n}\n"
  },
  {
    "path": "test/getterFilesize.js",
    "content": "\nvar assert = require('assert')\n\nmodule.exports = function (gm, dir, finish, GM) {\n  if (!GM.integration)\n    return finish();\n\n  gm\n  .filesize(function getterfilesize (err, size) {\n    if (err) return finish(err);\n\n    if (this._options.imageMagick) {\n      assert.equal('7792B', size, size);\n    } else {\n      assert.ok(/7.6K[i]{0,1}/.test(size));\n    }\n\n    assert.equal(size, this.data.Filesize)\n\n    // make sure we are reading from the data cache and not\n    // hitting the fs again.\n    this.identify = function () {\n      assert.ok(false, 'Did not read from cache');\n    }\n\n    this.filesize(function (err, size) {\n      if (err) return finish(err);\n\n      if (this._options.imageMagick) {\n        assert.equal('7792B', size, size);\n      } else {\n        assert.ok(/7.6K[i]{0,1}/.test(size));\n      }\n\n      assert.equal(size, this.data.Filesize)\n      finish();\n    });\n\n  });\n}\n"
  },
  {
    "path": "test/getterFormat.js",
    "content": "\nvar assert = require('assert');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  if (!GM.integration)\n    return finish();\n\n  gm\n  .format(function getterformat (err, format) {\n    if (err) return finish(err);\n\n    assert.equal(format, 'JPEG');\n    assert.equal(gm.data.format, 'JPEG');\n\n    finish();\n  });\n}\n"
  },
  {
    "path": "test/getterFormatGIF.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'original.gif');\n  gm(destPath).options({imageMagick})\n  .format(function (err, type) {\n    if (err) return finish(err);\n\n    assert.equal(type, 'GIF');\n    assert.equal(this.data.format, 'GIF');\n\n    finish();\n  })\n}\n"
  },
  {
    "path": "test/getterIdentify.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst os = require('os')\n\nvar isLinux = os.platform() === 'linux'\n// Be more lax with the errors if we're on linux\nvar errorFactor = isLinux ? 10 : 1.1\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const photoPath = path.join(dir, 'photo.JPG');\n  var test = gm(photoPath).options({ imageMagick });\n\n  test.identify(function (err) {\n    if (err) return finish(err);\n\n    var d = this.data;\n\n    if (imageMagick) {\n      assert.equal(d.Orientation, 'TopLeft');\n      assert.equal(d['Geometry'], '430x488+0+0');\n      assert.equal(d['Print size'], '5.97222x6.77778');\n      assert.ok(d['Channel depth'].Red || d['Channel depth'].red);\n      assert.ok(d['Channel depth'].Green || d['Channel depth'].green);\n      assert.ok(/0\\s+\\(0\\)/.test(d['Channel statistics'].Red.min));\n\n      var sd = d['Channel statistics'].Red['standard deviation'].split(' ')\n      var sd1 = parseFloat(sd[0])\n      var sd2 = parseFloat(sd[1].slice(1, -1))\n      assert.ok(sd1 && Math.abs(sd1 - 71.7079) < .01 * errorFactor)\n      assert.ok(sd2 && Math.abs(sd2 - 0.281208) < .001 * errorFactor)\n\n      var imageStat = parseFloat(d['Image statistics'].Overall.kurtosis)\n      assert.ok(imageStat);\n\n      if (!isLinux) {\n        // This is undefined in Linux\n        assert.equal(d['Rendering intent'], 'Perceptual');\n      }\n      assert.equal(d.Properties['exif:DateTimeDigitized'], '2011:07:01 11:23:16');\n      assert.equal(d.Format, 'JPEG (Joint Photographic Experts Group JFIF format)');\n\n    } else {\n      assert.equal(d.Orientation, 'TopLeft');\n      assert.equal(d['JPEG-Quality'], 96);\n      assert.ok(/(0.2812)/.test(d['Channel Statistics'].Red['Standard Deviation']));\n\n      var ex = d['Profile-EXIF'];\n      assert.equal(ex.Make, 'Apple');\n      assert.equal(ex.Model, 'iPad 2');\n      assert.equal(ex['GPS Info'], 558);\n      assert.equal(ex['GPS Longitude'], '80/1,4970/100,0/1');\n      assert.equal(ex['GPS Time Stamp'], '15/1,23/1,945/1');\n      assert.equal(d.Format, 'JPEG (Joint Photographic Experts Group JFIF format)');\n      assert.equal(d['Geometry'], '430x488');\n    }\n\n    gif(function () {\n      pattern();\n    });\n  });\n\n  function gif (callback) {\n    const bluePath = path.join(dir, 'blue.gif');\n    var test = gm(bluePath).options({ imageMagick });\n\n    test.identify(function (err) {\n      if (err) return finish(err);\n\n      if (imageMagick) {\n        if (!isLinux) {\n          assert.equal(1, this.data.color);\n        }\n\n        assert.ok(/blue/.test(this.data.Colormap['0']));\n        assert.ok(/black/.test(this.data.Colormap['1']));\n\n      } else {\n        if (!isLinux) {\n          assert.equal(2, this.data.color);\n        }\n\n        var blueWorks = this.data.Colors['0'] == '(  0,  0,255)\\t  blue';\n        var blackWorks = this.data.Colors['1'] == '(  0,  0,  0)\\t  black';\n\n        if (!blueWorks) {\n          blueWorks = this.data.Colors['1'] == '(  0,  0,255)\\t  blue';\n          blackWorks = this.data.Colors['0'] == '(  0,  0,  0)\\t  black';\n        }\n\n        assert.ok(blueWorks);\n        assert.ok(blackWorks);\n      }\n\n      callback();\n    });\n  }\n\n  function pattern () {\n    const bluePath = path.join(dir, 'blue.gif');\n    var test = gm(bluePath);\n    var format = '%f: %m, %wx%h';\n    var value = 'blue.gif: GIF, 100x200';\n\n    test.options({ imageMagick });\n\n    test.identify(format, function (err, result) {\n      if (err) return finish(err);\n\n      assert.equal(result, value);\n\n      test.identify({\n        format: format\n      }, function (err, result) {\n        if (err) return finish(err);\n\n        assert.equal(result, value);\n\n        finish();\n      })\n    });\n  }\n}\n"
  },
  {
    "path": "test/getterIptc.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const iptcPath = path.join(__dirname, 'fixtures', 'iptc.jpg');\n  var test = gm(iptcPath).options({imageMagick})\n\n  test.identify(function (err) {\n    if (err) return finish(err);\n\n    var d = this.data;\n\n    if (imageMagick) {\n      var iptc = d['Profiles'] && d['Profiles']['Profile-iptc'];\n      assert.equal(iptc['Caption[2,120]'], 'Some caption with colon space: for example');\n    }\n\n    finish();\n  });\n\n}\n"
  },
  {
    "path": "test/getterMultipleIptc.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const iptcPath = path.join(__dirname, 'fixtures', 'iptc-multiple.jpg');\n  var test = gm(iptcPath).options({imageMagick})\n\n  test.identify(function (err) {\n    if (err) return finish(err);\n\n    var d = this.data;\n\n    if (imageMagick) {\n      var iptc = d['Profiles'] && d['Profiles']['Profile-iptc'];\n      var keywords = iptc['Keyword[2,25]'];\n      assert(Array.isArray(keywords));\n      assert.equal(keywords.length, 5);\n\n      // just make sure another value\n      assert(! Array.isArray(iptc['Headline[2,105]']));\n    }\n\n    finish();\n  });\n\n}\n"
  },
  {
    "path": "test/getterRes.js",
    "content": "\nvar assert = require('assert')\n\nmodule.exports = function (gm, dir, finish, GM) {\n  if (!GM.integration)\n    return finish();\n\n  gm\n  .res(function getterres (err, res) {\n    if (err) return finish(err);\n    if (gm._options.imageMagick) {\n      assert.equal('72x72', res);\n    } else {\n      assert.equal('72x72 pixels/inch', res);\n    }\n    assert.equal(res, this.data.Resolution)\n    finish();\n  });\n}\n"
  },
  {
    "path": "test/getterSize.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  sizeJPEG(function (err) {\n    if (err) return finish(err);\n\n    sizeGIF(function (err) {\n      if (err) return finish(err);\n\n      sizePNG(finish);\n    })\n  })\n\n  function sizeJPEG(done) {\n    const originalPath = path.join(dir, 'original.jpg');\n    gm(originalPath).options({imageMagick}).size(function gettersize (err, size) {\n      if (err) return done(err);\n\n      assert.equal(size.width, 460);\n      assert.equal(size.height, 155);\n\n      const identifyParseErrPath = path.join(dir, 'identifyParseErr.jpg');\n      gm(identifyParseErrPath).options({imageMagick}).size(done);\n    });\n  }\n\n  function sizeGIF(done) {\n    const originalGifPath = path.join(dir, 'original.gif');\n    gm(originalGifPath).options({imageMagick}).size(function (err, size) {\n      if (err) return done(err);\n\n      assert.equal(size.width, 192)\n      assert.equal(size.height, 56)\n\n      done()\n    })\n  }\n\n  function sizePNG(done) {\n    const originalPngPath = path.join(dir, 'original.png');\n    gm(originalPngPath).options({imageMagick}).size(function (err, size) {\n      if (err) return done(err);\n\n      assert.equal(size.width, 460)\n      assert.equal(size.height, 155)\n\n      done()\n    })\n  }\n}\n"
  },
  {
    "path": "test/gh-17.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  var m = gm\n  .crop(200, 155, 300, 0)\n  .resize(58, 50, '%');\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-crop', args[2]);\n  assert.equal('200x155+300+0', args[3]);\n  assert.equal('-resize', args[4]);\n  assert.equal('58x50%', args[5]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'cropresize.png');\n  m.write(destPath, function crop (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/gifFrame.js",
    "content": "const path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const originalGifPath = path.join(dir, 'original.gif[0]');\n  const gifFramePath = path.join(dir, 'gifFrame.jpg');\n  gm(originalGifPath).options({imageMagick})\n  .write(gifFramePath, function gifFrame (err){\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/gifFrameIdentify.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  const originalGifPath = path.join(dir, 'original.gif[0]');\n  var m = gm(originalGifPath).options({imageMagick});\n\n  if (!gm.integration)\n    return finish();\n\n  m.identify('%n', function (err, stdout) {\n    if (err) return finish(err);\n\n    assert.equal(parseInt(stdout.toString(), 10), 1);\n    finish();\n  })\n}\n"
  },
  {
    "path": "test/gifFrameStream.js",
    "content": "const assert = require('assert')\nconst path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  const originalGifPath = path.join(dir, 'original.gif');\n  const readStream = fs.createReadStream(originalGifPath);\n  const m = gm(readStream, \"original.gif[0]\").options({imageMagick});\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-[0]', args[1]);\n\n  if (!gm.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'gifFrameStream.jpg');\n  m.write(destPath, function gifFrame (err){\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/gravity.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (img, dir, finish, gm) {\n  var changed = gm('whatever.png').gravity(\"Souths\")\n  assert.equal(changed._out[1], 'NorthWest');\n\n  var m = img\n  .scale(200, 100)\n  .gravity(\"South\")\n  .extent(300,300);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  args= args.slice(2);\n  assert.deepEqual(args, [\n    '-scale',\n    '200x100',\n    '-gravity',\n    'South',\n    '-extent',\n    '300x300',\n    '-' ])\n\n  if (!gm.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'gravity.png');\n  m.write(destPath, function resize (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/implode.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .implode(0.8);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-implode', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'implode.png');\n  m.write(destPath, function implode (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/index.js",
    "content": "const cp = require('child_process');\nconst path = require('path');\nconst Async = require('async');\nconst dir = path.join(__dirname, '..', 'examples', 'imgs');\nconst gm = require('..');\nconst fs = require('fs');\nconst os = require('os');\n\nconst only = process.argv.slice(2);\ngm.integration = !! ~process.argv.indexOf('--integration');\nif (gm.integration) only.shift();\n\nlet files = fs.readdirSync(__dirname).filter(filter);\nif (files.length === 0) {\n  console.log('No tests found matching', only);\n}\n\nfunction filter (file) {\n  if (!/\\.js$/.test(file)) return false;\n  if ('index.js' === file) return false;\n  if (only.length && !~only.indexOf(file)) return false;\n\n  var filename = path.join(__dirname, file);\n  if (!fs.statSync(filename).isFile()) return false;\n  return true;\n}\n\nconst originalPathName = path.join(dir, 'original.jpg');\n\nfunction test (imageMagick) {\n  return gm(originalPathName).options({ imageMagick });\n}\n\nfunction finish (filename) {\n  return function (err) {\n    if (err) {\n      console.error('\\n\\nError occured with file: ' + filename);\n      throw err;\n    }\n  }\n}\n\nfunction isGraphicsMagickInstalled() {\n  try {\n    cp.execSync('gm -version');\n    return true;\n  } catch (_) {\n    return false;\n  }\n}\n\nfunction isConvertInstalled() {\n  try {\n    cp.execSync('convert -version');\n    return true;\n  } catch (_) {\n    return false;\n  }\n}\n\nfunction isMagickInstalled() {\n  try {\n    cp.execSync('magick -version');\n    return true;\n  } catch (_) {\n    return false;\n  }\n}\n\nconst isWindows = () => os.platform() === 'win32';\n\nvar q = Async.queue(function (task, callback) {\n  var filename = task.filename;\n  var im = task.imagemagick;\n\n  console.log(`Testing ${filename} ..`);\n  require(filename)(test(im), dir, function (err) {\n    finish(filename)(err);\n    callback();\n  }, gm, im);\n}, 1);\n\nq.drain = function(){\n  console.log(\"\\n\\u001B[32mAll tests passed\\u001B[0m\");\n};\n\nfiles = files.map(function (file) {\n  return path.join(__dirname, file);\n});\n\nif (isGraphicsMagickInstalled()) {\n  console.log('gm is installed');\n  files.forEach(function (filename) {\n    q.push({\n      imagemagick: false,\n      filename\n    })\n  });\n}\n\nif (!isWindows() && isConvertInstalled()) {\n  // windows has a different convert binary\n\n  console.log('convert is installed');\n  files.forEach(function (filename) {\n    q.push({\n      imagemagick: true,\n      filename\n    })\n  });\n}\n\nif (isMagickInstalled()) {\n  console.log('magick is installed');\n\n  files.forEach(function (filename) {\n    q.push({\n      imagemagick: '7+',\n      filename\n    })\n  });\n}"
  },
  {
    "path": "test/inputIs.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm) {\n  var err;\n\n  try {\n    const blahPath = path.join('path', 'to', 'blah.gif') ;\n    var gif = gm(blahPath);\n    assert.equal(true, gif.inputIs('gif'));\n    assert.equal(false, gif.inputIs('jpg'));\n    assert.equal(false, gif.inputIs('crazy'));\n\n    var png = gm('png.png');\n    assert.equal(true, png.inputIs('png'));\n    assert.equal(false, png.inputIs('gif'));\n    assert.equal(false, png.inputIs('tif'));\n\n    const jpgPath = path.join('super', 'duper.jpeg')\n    var jpg = gm(jpgPath);\n    assert.equal(true, jpg.inputIs('jpg'));\n    assert.equal(true, jpg.inputIs('jpeg'));\n    assert.equal(false, jpg.inputIs('gif'));\n    assert.equal(false, jpg.inputIs('tif'));\n    assert.equal(false, jpg.inputIs('gif'));\n\n    var unknown = gm('super.unknown');\n    assert.equal(true, unknown.inputIs('unknown'));\n    assert.equal(true, unknown.inputIs('.unknown'));\n    assert.equal(false, unknown.inputIs());\n    assert.equal(false, unknown.inputIs(''));\n    assert.equal(false, unknown.inputIs('png'));\n    assert.equal(false, unknown.inputIs('pngasdf'));\n  } catch (e) {\n    err = e;\n    console.error(e.stack);\n  }\n\n  finish(err);\n}\n"
  },
  {
    "path": "test/interlace.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .interlace();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-interlace', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'interlace.png');\n  m.write(destPath, function interlace (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/label.js",
    "content": "const assert = require('assert')\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .label(\"%m:%f %wx%h\")\n\n  var args= m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-label', args[2]);\n  assert.equal('\"%m:%f %wx%h\"', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'label.png');\n  m.write(destPath, function label (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/limit.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .limit(\"memory\", \"32MB\")\n  .limit(\"map\", \"64MB\")\n\n  var args = m.args()\n  assert.equal('convert', args[0]);\n  assert.equal('-limit', args[2]);\n  assert.equal('memory', args[3]);\n  assert.equal('32MB', args[4]);\n  assert.equal('-limit', args[5]);\n  assert.equal('map', args[6]);\n  assert.equal('64MB', args[7]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'limit.png');\n  m.write(destPath, function limit (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/line.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"red\", 3)\n  .drawLine(20, 10, 50, 40);\n\n  var args = m.args();\n  assert.equal('-blur', args[2]);\n  assert.equal('8x4', args[3]);\n  assert.equal('-strokewidth', args[4]);\n  assert.equal(3, args[5]);\n  assert.equal('-stroke', args[6]);\n  assert.equal('red', args[7]);\n  assert.equal('-draw', args[8]);\n  assert.equal('line 20,10 50,40', args[9]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'line.png');\n  m.write(destPath, function line (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/lower.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .lower(10, 14);\n\n  var args= m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('+raise', args[2]);\n  assert.equal('10x14', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'lower.png');\n  m.write(destPath, function lower (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/magnify.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (gm._options.imageMagick)\n    return finish();\n\n  var m = gm\n  .magnify();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-magnify', args[1]);\n  assert.equal(4, args.length);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'magnify.png');\n  m.write(destPath, function magnify (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/median.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .median(4);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-median', args[2]);\n  assert.equal(4, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'median.png');\n  m.write(destPath, function media (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/minify.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  if (gm._options.imageMagick) return finish();\n\n  var m = gm\n  .minify();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-minify', args[1]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'minify.png');\n  m.write(destPath, function minify (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/minifyIM.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  var m = gm.minify();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-minify', args[1]);\n\n  if(gm._options.imageMagick) {\n    assert.throws(\n      function() {\n        const destPath = path.join(dir, 'minify.png');\n        m.write(destPath, function minify (err) { throw err;})\n      },\n      Error\n    );\n  }\n  return finish();\n\n}"
  },
  {
    "path": "test/modulate.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .modulate(120, 100, 80);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-modulate', args[2]);\n  assert.equal('120,100,80', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'modulate.png');\n  m.write(destPath, function modulate (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/monochrome.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .monochrome();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-monochrome', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'monochrome.png');\n  m.write(destPath, function monochrome (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/montage.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n  const fixturesPath = path.join(__dirname, 'fixtures');\n  const srcPath = path.join(fixturesPath, 'compare_1.png');\n\n  gm.source = srcPath;\n  const faviconPath = path.join(fixturesPath, 'favicon.png');\n  var a = gm.montage(faviconPath);\n\n  var args = a.args();\n  assert.equal('montage', args[0]);\n  assert.equal(faviconPath, args[1]);\n  assert.equal(srcPath, args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'montage.png');\n  a.write(destPath, function(err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/morph-more.js",
    "content": "const path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (gm._options.imageMagick) return finish();\n\n  if (!GM.integration)\n    return finish();\n\n  const morpherPath = path.join(dir, 'morpher.jpg');\n  const originalPath = path.join(dir, 'original.png');\n  const morphedPath = path.join(dir, 'morphed2.jpg');\n\n  gm\n    .morph([morpherPath, originalPath], morphedPath, function morph (err) {\n      finish(err);\n    });\n}\n"
  },
  {
    "path": "test/morph.js",
    "content": "const path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (gm._options.imageMagick) return finish();\n\n  if (!GM.integration)\n    return finish();\n\n  const morpherPath = path.join(dir, 'morpher.jpg');\n  const morphedPath = path.join(dir, 'morphed.jpg');\n\n  gm.morph(morpherPath, morphedPath, function morph (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/negative.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = GM('temp.jpg').negative(true);\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('+negate', args[2]);\n\n  m = gm.negative();\n  args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-negate', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'negative.png');\n  m.write(destPath, function negative (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/new.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n  var m = gm(525, 110, \"#00ff55aa\")\n  .options({imageMagick})\n  .fontSize(68)\n  .stroke(\"#efe\", 2)\n  .fill(\"#555\")\n  .drawText(20, 72, \"graphics\")\n  .fill(\"#fa0\")\n  .drawText(274, 72, \" magick\");\n\n  var args = m.args();\n  assert.deepEqual(args, [\n    'convert',\n    '-size',\n    '525x110',\n    'xc:#00ff55aa',\n    '-pointsize',\n    68,\n    '-strokewidth',\n    2,\n    '-stroke',\n    '#efe',\n    '-fill',\n    '#555',\n    '-draw',\n    'text 20,72 \"graphics\"',\n    '-fill',\n    '#fa0',\n    '-draw',\n    'text 274,72 \"magick\"',\n    '-'\n  ])\n\n  if (!gm.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'new.png');\n  m.write(destPath, function New (err){\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/newImage.js",
    "content": "// https://github.com/aheckmann/gm/issues/127\n\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const dest1Path = path.join(dir, 'ignore.me.png');\n  createImage().write(dest1Path, function (err) {\n    if (err) return finish(err);\n\n    createImage().stream(function (err, stdout) {\n      if (err) return finish(err);\n\n      const dest2Path = path.join(dir, 'ignore.me.2.png');\n      stdout.pipe(fs.createWriteStream(dest2Path))\n\n      stdout.on('error', finish)\n      stdout.on('end', finish)\n    })\n  })\n\n  function createImage() {\n    return gm(70, 30, '#000')\n      .options({imageMagick})\n      .font(\"arial\", 20)\n      .stroke(\"#fff\", 2)\n      .fill(\"#888\")\n      .drawText(10, 22, 'Some text')\n  }\n}\n"
  },
  {
    "path": "test/noise1.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .noise(0.3);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-noise', args[2]);\n  assert.equal(0.3, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'noise1.png');\n  m.write(destPath, function noise1 (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/noise2.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m  = gm\n  .noise('laplacian');\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('+noise', args[2]);\n  assert.equal('laplacian', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n\n  const destPath = path.join(dir, 'noise2.png');\n  m.write(destPath, function noise2 (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/options.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs');\n\nconst checkCmd = (cmd, imageMagick) => {\n  switch (imageMagick) {\n    case true:\n      assert.ok(/^convert /.test(cmd));\n      break;\n    case '7+':\n      assert.ok(/^magick \"convert\" /.test(cmd));\n      break;\n    default:\n      assert.ok(/^gm \"convert\" /.test(cmd));\n      break;\n  }\n}\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n  var sub = gm.subClass({ subclassed: true });\n  var s = sub('test').options({ setWithMethod: 2 });\n  var g = gm('test').options({ hellowwww: 'there' });\n\n  assert.equal(2, s._options.setWithMethod);\n  assert.equal(true, s._options.subclassed);\n  assert.equal('there', g._options.hellowwww);\n  assert.equal(undefined, g._options.setWithMethod);\n  assert.equal(undefined, s._options.hellowwww);\n  assert.equal(undefined, g._options.subclassed);\n\n  /// subclass options\n  var s2 = sub('another');\n  assert.equal(true, s2._options.subclassed);\n  assert.equal(undefined, s2._options.setWithMethod);\n\n  if (!gm.integration)\n    return finish();\n\n  // test commands\n  // test with subclass\n\n  const photoPath = path.join(dir, 'photo.JPG');\n  const writeFile = path.join(dir, `options${Math.random()}.png`);\n  const instance = gm.subClass({ imageMagick });\n\n  instance(photoPath)\n  .negative()\n  .write(writeFile, function (err, _1, _2, cmd) {\n    if (err) return finish(err);\n\n    checkCmd(cmd, imageMagick);\n\n    fs.stat(writeFile, function (err) {\n      if (err) return finish(new Error('did not write file'));\n\n      try {\n        fs.unlinkSync(writeFile);\n      } catch (e) {}\n\n      /// inline options\n      gm(photoPath)\n      .negative()\n      .options({ imageMagick })\n      .write(writeFile, function (err, _1, _2, cmd) {\n        if (err) return finish(err);\n\n        checkCmd(cmd, imageMagick);\n\n        fs.stat(writeFile, function (err) {\n          if (err) return finish(new Error('did not write 2nd file'));\n          try {\n            fs.unlinkSync(writeFile);\n          } catch (e) {}\n          finish();\n        });\n      });\n    });\n  });\n}\n"
  },
  {
    "path": "test/paint.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .paint(2);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-paint', args[2]);\n  assert.equal(2, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'paint.png');\n  m.write(destPath, function paint (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/polygon.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"red\", 3)\n  .fill(\"#ffffffbb\")\n  .drawPolygon([60, 10], [183, 73], [185, 13], [167, 35], [165, 17], [163, 19]);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  args = args.slice(2);\n  assert.deepEqual(args, [\n    '-blur',\n    '8x4',\n    '-strokewidth',\n    3,\n    '-stroke',\n    'red',\n    '-fill',\n    '#ffffffbb',\n    '-draw',\n    'polygon 60,10,183,73,185,13,167,35,165,17,163,19',\n    '-'\n  ])\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'polygon.png');\n  m.write(destPath, function polygon (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/polyline.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"red\", 3)\n  .fill(\"#ffffffbb\")\n  .drawPolyline([40, 10], [143, 153], [185, 53], [147, 15], [145, 17], [43, 19]);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  args = args.slice(2);\n  assert.deepEqual(args, [\n    '-blur',\n    '8x4',\n    '-strokewidth',\n    3,\n    '-stroke',\n    'red',\n    '-fill',\n    '#ffffffbb',\n    '-draw',\n    'polyline 40,10,143,153,185,53,147,15,145,17,43,19',\n    '-'\n  ])\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'polyline.png');\n  m.write(destPath, function polyline (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/quality.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .quality(5);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-quality', args[1]);\n  assert.equal(5, args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'quality.png');\n  m.write(destPath, function quality (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/raise.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .raise(10,14);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-raise', args[2]);\n  assert.equal('10x14', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'raise.png');\n  m.write(destPath, function raise (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/rectangle.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .stroke(\"red\", 3)\n  .fill(\"#ffffffbb\")\n  .drawRectangle(40, 10, 251, 120)\n  .drawRectangle(160, 10, 270, 220, 3);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  args = args.slice(2);\n  assert.deepEqual(args, [\n    '-blur',\n    '8x4',\n    '-strokewidth',\n    3,\n    '-stroke',\n    'red',\n    '-fill',\n    '#ffffffbb',\n    '-draw',\n    'rectangle 40,10 251,120 ',\n    '-draw',\n    'roundRectangle 160,10 270,220 3,3',\n    '-'\n   ])\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'rectangle.png');\n  m.write(destPath, function rectangle (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/region.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .region(130, 170, 307, 00);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-region', args[2]);\n  assert.equal('130x170+307+0', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'region.png');\n  m.write(destPath, function region (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/repagePlus.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .repage('+');\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('+repage', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'repage.png');\n  m.write(destPath, function blur (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/resample.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .resample(420, 120);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-resample', args[2]);\n  assert.equal('420x120', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'resample.png');\n  m.write(destPath, function resample (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/resize.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n\n  var a = GM('img.png').options({imageMagick}).resize(10);\n  var args = a.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-resize', args[2]);\n  if (imageMagick) {\n    assert.equal('10', args[3]);\n  } else {\n    assert.equal('10x', args[3]);\n  }\n\n  var a = GM('img.png').options({imageMagick}).resize(10, 20);\n  var args = a.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-resize', args[2]);\n  assert.equal('10x20', args[3]);\n\n  var a = GM('img.png').options({imageMagick}).resize(10, false, '%');\n  var args = a.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-resize', args[2]);\n  if (imageMagick) {\n    assert.equal('10%', args[3]);\n  } else {\n    assert.equal('10x%', args[3]);\n  }\n\n  var a = GM('img.png').options({imageMagick}).resize('10%');\n  var args = a.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-resize', args[2]);\n  if (imageMagick) {\n    assert.equal('10%', args[3]);\n  } else {\n    assert.equal('10%x', args[3]);\n  }\n\n  var m = gm.options({imageMagick}).resize(58, 50, '%');\n  var args=  m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-resize', args[2]);\n  assert.equal('58x50%', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'resize.png');\n  m.write(destPath, function resize (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/resizeAndAutoOrientFromBuffer.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n  const original = path.join(dir, 'orientation', 'Portrait_7.jpg');\n  const result = path.join(dir, 'resizeAutoOrientFromBuffer.png');\n\n  var buf = fs.readFileSync(original);\n\n  var m = gm(buf, 'resizefrombuffer.jpg')\n  .options({imageMagick})\n  .autoOrient()\n  .resize('20%')\n\n  const expectedArgs = imageMagick ?\n    ['convert', '-', '-auto-orient', '-resize', '20%', '-'] :\n    ['convert', '-', '-resize', '20%x', '-'];\n\n  assert.deepEqual(m.args(), expectedArgs);\n\n  if (!gm.integration)\n    return finish();\n\n  size(original, imageMagick, function (err, origSize) {\n    if (err) return finish(err);\n\n    m\n    .write(result, function resizeFromBuffer (err) {\n      if (err) return finish(err);\n\n      size(result, imageMagick, function (err, newSize) {\n        if (err) return finish(err);\n        assert.ok(origSize.width / 2 >= newSize.width);\n        assert.ok(origSize.height / 2 >= newSize.height);\n        finish();\n      });\n    });\n  });\n\n\n  function size (file, imageMagick, cb) {\n    gm(file).options({imageMagick}).identify(function (err, data) {\n      if (err) return cb(err);\n      cb(err, data.size);\n    });\n  }\n}\n"
  },
  {
    "path": "test/resizeBuffer.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n  var original = path.join(dir, 'original.jpg');\n  var result = path.join(dir, 'resizeFromBuffer.png');\n\n  var buf = fs.readFileSync(original);\n\n  var m = gm(buf, 'resizefrombuffer.jpg')\n  .options({imageMagick})\n  .resize('48%')\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-', args[1]);\n  assert.equal('-resize', args[2]);\n  if (m._options.imageMagick) {\n    assert.equal('48%', args[3]);\n  } else {\n    assert.equal('48%x', args[3]);\n  }\n\n  if (!gm.integration)\n    return finish();\n\n  size(original, imageMagick, function (err, origSize) {\n    if (err) return finish(err);\n\n    m\n    .write(result, function resizeFromBuffer (err) {\n      if (err) return finish(err);\n\n      size(result, imageMagick, function (err, newSize) {\n        if (err) return finish(err);\n        assert.ok(origSize.width / 2 >= newSize.width);\n        assert.ok(origSize.height / 2 >= newSize.height);\n        finish();\n      });\n    });\n  });\n\n\n  function size (file, imageMagick, cb) {\n    gm(file).options({imageMagick}).identify(function (err, data) {\n      if (err) return cb(err);\n      cb(err, data.size);\n    });\n  }\n}\n"
  },
  {
    "path": "test/resizeWrong.js",
    "content": "const path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const original = path.join(dir, 'original.png');\n  const resized = path.join(dir, 'resize');\n  var widths = [300, 700, 400, 800, 200], i, cb;\n  var resizeExact = function (width, index) {\n    var name = resized + index + '.png';\n\n    if (index == widths.length) {\n      return finish();\n    } else {\n      index++;\n    }\n    gm(original)\n      .options({imageMagick})\n      .resizeExact(width)\n      .write(name, function(err){\n        if (err) return finish(err);\n\n        gm(name).options({imageMagick})\n          .size(function (err, size) {\n            if (err) return finish(err);\n            if (size.width !== width) {\n              return finish(\"Wrong resizing on requested:\" + width + \", resized:\" + size.width);\n            }\n\n            if (cb) return cb();\n            resizeExact(widths[index], index);\n          });\n      });\n  };\n\n  resizeExact(widths[0], 0);\n}"
  },
  {
    "path": "test/roll.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .roll(40,-100);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-roll', args[2]);\n  assert.equal('+40-100', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'roll.png');\n  m.write(destPath, function roll (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/rotate.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .rotate('red', -40);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-background', args[2]);\n  assert.equal('red', args[3]);\n  assert.equal('-rotate', args[4]);\n  assert.equal(-40, args[5]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'rotate.png');\n  m.write(destPath, function rotate (err, _0, _1, cmd) {\n    assert.ok(/\"-rotate\" \"-40\"/.test(cmd));\n\n    m\n    .rotate('red', 0)\n    .write(destPath, function rotate (err, _0, _1, cmd) {\n      assert.ok(!/\"-rotate\" \"-40\"/.test(cmd));\n      assert.ok(/\"-rotate\" \"0\"/.test(cmd));\n      finish(err);\n    });\n\n  });\n}\n"
  },
  {
    "path": "test/scale.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n\n  var a = GM('img.png').options({imageMagick}).scale(100);\n  var args = a.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-scale', args[2]);\n  if (a._options.imageMagick) {\n    assert.equal('100', args[3]);\n  } else {\n    assert.equal('100x', args[3]);\n  }\n\n  var a = GM('img.png').options({imageMagick}).scale(100, 200, '%');\n  var args = a.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-scale', args[2]);\n  assert.equal('100x200%', args[3]);\n\n  var a = GM('img.png').options({imageMagick}).scale(100, '200%');\n  var args = a.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-scale', args[2]);\n  assert.equal('100x200%', args[3]);\n\n  var m = gm.options({imageMagick}).scale(100, 100);\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-scale', args[2]);\n  assert.equal('100x100', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'scale.png');\n  m.write(destPath, function scale (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/selectFrame.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  const gifPath = path.join(dir, 'original.gif[0]');\n  var m = gm(gifPath);\n\n  if (!gm.integration)\n    return finish();\n\n  m.options({imageMagick}).identify('%#', function (err, hash1) {\n    if (err) return finish(err);\n\n    m.selectFrame(2).identify('%#', function (err, hash2) {\n      if (err) return finish(err);\n\n      assert.ok(hash1.toString().trim() !== hash2.toString().trim())\n      finish();\n    })\n  })\n}"
  },
  {
    "path": "test/sepia.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .sepia();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-modulate', args[2]);\n  assert.equal('115,0,100', args[3]);\n  assert.equal('-colorize', args[4]);\n  assert.equal('7,21,50', args[5]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'sepia.png');\n  m.write(destPath, function sepia (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/setFormat.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .setFormat('png');\n\n  assert.equal('png', m._outputFormat);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'setFormat.png');\n  m.write(destPath, function setformat (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/sharpen.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .sharpen(19, 10);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-sharpen', args[2]);\n  assert.equal('19x10', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'sharpen.png');\n  m.write(destPath, function sharpen (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/solarize.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .solarize(68.5);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-solarize', args[2]);\n  assert.equal('68.5%', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'solarize.png');\n  m.write(destPath, function solarize (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/spread.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .spread(12);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-spread', args[2]);\n  assert.equal(12, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'spread.png');\n  m.write(destPath, function spread (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/streamIn.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n  const originalPath = path.join(dir, 'original.jpg');\n  const stream = fs.createReadStream(originalPath);\n  const m = gm(stream, \"original.jpg\").options({imageMagick});\n\n  assert.equal(stream, m.sourceStream);\n  assert.equal('original.jpg', m.source);\n\n  if (!gm.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'streamIn.png');\n  m.write(destPath, function streamIn (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/streamInGetter.js",
    "content": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration)\n    return finish();\n\n  const originalPath = path.join(dir, 'original.jpg');\n  gm(fs.createReadStream(originalPath))\n  .options({imageMagick})\n  .size({bufferStream: true}, function (err, size) {\n    const destPath = path.join(dir, 'streamInGetter.png');\n    this.write(destPath, function streamInGetter (err){\n      finish(err);\n    });\n  });\n}"
  },
  {
    "path": "test/streamInOut.js",
    "content": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n\n  if (!gm.integration)\n    return finish();\n\n  const originalPath = path.join(dir, 'original.jpg');\n  gm(fs.createReadStream(originalPath), \"original.jpg\")\n  .options({imageMagick})\n  .stream(function streamOut (err, stdout, stderr) {\n    if (err) return finish(err);\n    const destPath = path.join(dir, 'streamInOut.jpg');\n    stdout.pipe(fs.createWriteStream(destPath));\n    stdout.on('error', finish);\n    stdout.on('close', finish);\n  });\n}\n"
  },
  {
    "path": "test/streamOut.js",
    "content": "const path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (!GM.integration)\n    return finish();\n\n  withCallback(function (err) {\n    if (err) return finish(err);\n\n    withoutCallback(finish);\n  });\n\n  function withCallback(done) {\n    gm\n    .stream(function streamOut (err, stdout, stderr) {\n      if (err) return done(err);\n      const destPath = path.join(dir, 'streamOut.png');\n      stdout.pipe(fs.createWriteStream(destPath));\n      stdout.on('error', done);\n      stdout.on('close', done);\n    });\n  }\n\n  function withoutCallback(done) {\n    var stream = gm.stream()\n    stream.on('error', done)\n    const destPath = path.join(dir, 'streamOut2.png');\n    stream.pipe(fs.createWriteStream(destPath))\n    stream.on('end', done)\n  }\n}\n"
  },
  {
    "path": "test/streamOutFormat.js",
    "content": "const assert = require('assert')\nconst path = require('path');\nconst fs = require('fs');\n\nmodule.exports = function (gm, dir, finish, GM, imageMagick) {\n  if (!GM.integration)\n    return finish();\n\n  withCallback(function (err) {\n    if (err) return finish(err);\n\n    withoutCallback(function (err) {\n      if (err) return finish(err);\n\n      checkOutputFormat(finish);\n    });\n  });\n\n  function withCallback(done) {\n    gm\n    .stream('PNG', function streamOut (err, stdout, stderr) {\n      if (err) return done(err);\n      const destPath = path.join(dir, 'streamOutFormat.png');\n      stdout.pipe(fs.createWriteStream(destPath));\n      stdout.on('error', done);\n      stdout.on('close', done);\n    });\n  }\n\n  function withoutCallback(done) {\n    var stream = gm.stream('PNG')\n    stream.on('error', done)\n    const destPath = path.join(dir, 'streamOutFormat2.png');\n    stream.pipe(fs.createWriteStream(destPath))\n    stream.on('end', done)\n  }\n\n  function checkOutputFormat(done) {\n    var stream = gm.stream('PNG')\n    stream.on('error', done)\n    GM(stream).options({imageMagick}).format(function (err, value) {\n      if (err)\n        return done(err)\n\n      assert.equal(value.toLowerCase(), 'png')\n      done()\n    })\n  }\n}\n"
  },
  {
    "path": "test/strip.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (!gm._options.imageMagick) return finish();\n\n  var m = gm\n  .strip();\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-strip', args[2]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'strip.png');\n  m.write(destPath, function strip (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/subclass.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  assert.equal('gm', gm('test').constructor.name);\n  assert.equal(undefined, gm.prototype._options.imageMagick);\n\n  var sub = gm.subClass({ imageMagick: true });\n\n  assert.equal('gm', sub('test').constructor.name);\n  assert.equal(true, sub.prototype._options.imageMagick);\n  assert.equal(undefined, gm.prototype._options.imageMagick);\n\n  var s = sub('test');\n  assert.equal(true, s._options.imageMagick);\n\n  var g = gm('test');\n  assert.equal(undefined, g._options.imageMagick);\n\n  var imageMagick7 = gm.subClass({ imageMagick: '7+'});\n  assert.equal('7+', imageMagick7.prototype._options.imageMagick);\n\n  if (!gm.integration)\n    return finish();\n\n  const sourcePath = path.join(dir, 'photo.JPG');\n  const destPath = path.join(dir, 'subclass.png');\n  const m = gm.subClass({ imageMagick });\n  m(sourcePath)\n  .thumb(50, 80, destPath, function subthumb (err) {\n    if (err) return finish(err);\n    finish();\n  });\n}\n"
  },
  {
    "path": "test/swirl.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .swirl(129);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-swirl', args[2]);\n  assert.equal(129, args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'swirl.png');\n  m.write(destPath, function swirl (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/text.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .blur(8, 4)\n  .fontSize(68)\n  .stroke(\"#efe\", 2)\n  .fill(\"#888\")\n  .drawText(-20, 98, \"graphics magick\");\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  args = args.slice(2)\n  assert.deepEqual(args, [\n   '-blur',\n    '8x4',\n    '-pointsize',\n    68,\n    '-strokewidth',\n    2,\n    '-stroke',\n    '#efe',\n    '-fill',\n    '#888',\n    '-draw',\n    'text -20,98 \"graphics magick\"',\n    '-'\n  ]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'text.png');\n  m.write(destPath, function text (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/thumb.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'thumb.png');\n  gm.thumb(150, 40, destPath, function thumb (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/thumbnail.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  var m = gm\n  .thumbnail(200, 201);\n\n  var args = m.args();\n  assert.equal('convert', args[0]);\n  assert.equal('-thumbnail', args[2]);\n  assert.equal('200x201', args[3]);\n\n  if (!GM.integration)\n    return finish();\n\n  const destPath = path.join(dir, 'thumbnail.png');\n  m.write(destPath, function thumbnail (err) {\n    finish(err);\n  });\n}\n"
  },
  {
    "path": "test/timeout.js",
    "content": "const assert = require('assert');\nconst path = require('path');\n\nmodule.exports = function (img, dir, finish, gm, imageMagick) {\n\n  assert.equal(undefined, gm.prototype._options.timeout);\n  assert.equal(undefined, img._options.timeout);\n\n  var g = gm('test').options({ timeout: 100 });\n  assert.equal(100, g._options.timeout);\n\n  var sub = gm.subClass({ timeout: 2000 });\n  assert.equal(2000, sub.prototype._options.timeout);\n\n\n  if (!gm.integration)\n    return finish();\n\n  const sourcePath = path.join(dir, 'photo.JPG');\n  const timeoutPath = path.join(dir, 'timeout.png');\n  gm(sourcePath).options({ timeout: 1, imageMagick })\n  .thumb(50, 80, timeoutPath, function subthumb (err) {\n    assert.ok(err, \"Expecting a timeout error\");\n    noTimeout();\n  });\n\n\n  function noTimeout() {\n    gm(sourcePath).options({ timeout: 0, imageMagick })\n    .thumb(50, 80, timeoutPath, function subthumb (err) {\n      finish(err);\n    });\n  }\n\n}\n"
  },
  {
    "path": "test/toBuffer.js",
    "content": "var assert = require('assert');\nvar fs = require('fs');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (!GM.integration)\n    return finish();\n\n  gm\n  .toBuffer(function (err, buffer) {\n    if (err) return finish(err);\n\n    assert.ok(buffer instanceof Buffer);\n    assert.ok(buffer.length);\n\n    finish();\n  })\n}\n"
  },
  {
    "path": "test/toBufferFormat.js",
    "content": "var assert = require('assert');\nvar fs = require('fs');\n\nmodule.exports = function (gm, dir, finish, GM) {\n\n  if (!GM.integration)\n    return finish();\n\n  gm\n  .toBuffer('PNG', function (err, buffer) {\n    if (err) return finish(err);\n\n    assert.ok(buffer instanceof Buffer);\n    assert.ok(buffer.length);\n\n    finish();\n  })\n}\n"
  },
  {
    "path": "test/utils.js",
    "content": "\nvar assert = require('assert')\n\nmodule.exports = function (_, dir, finish, gm) {\n\n  assert.equal('function', typeof gm.utils.escape);\n  assert.equal('function', typeof gm.utils.unescape);\n  finish();\n\n}\n"
  },
  {
    "path": "test/webp.js",
    "content": "const assert = require('assert');\nconst path = require('path');\nconst fs = require('fs')\n\nmodule.exports = function (_, dir, finish, gm, imageMagick) {\n  if (!gm.integration) return finish()\n\n  // Don't know how to install IM with WEBP on ubuntu\n  // if (require('os').platform() === 'linux') return finish()\n\n  // GraphicsMagick currently does not support webp :(\n  // if (!im) return finish()\n\n  gm = gm.subClass({\n    imageMagick\n  })\n\n  const imagePath = path.join(dir, 'original.png');\n\n  write(function (err) {\n    if (err) return finish(err)\n\n    stream(finish)\n  })\n\n  function write(done) {\n    const webpPath = path.join(dir, 'original.x.webp');\n    gm(imagePath)\n    .write(webpPath, function (err) {\n      if (err) return done(err)\n\n      gm(webpPath).identify(function (err, value) {\n        if (err) return done(err)\n\n        assert.ok(value)\n        assert.equal(value.format, 'WEBP')\n        done()\n      })\n    })\n  }\n\n  function stream(done) {\n    gm(imagePath)\n    .stream('webp', function (err, stdout) {\n      if (err) return done(err)\n\n      gm(stdout).identify(function (err, value) {\n        if (err) return done(err)\n\n        assert.ok(value)\n        assert.equal(value.format, 'WEBP')\n\n        done()\n      })\n    })\n  }\n}"
  }
]