[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\n    [\n      \"@babel/preset-env\",\n      {\n        \"targets\": {\n          \"node\": \"12.22.1\"\n        }\n      }\n    ]\n  ]\n}\n"
  },
  {
    "path": ".eslintignore",
    "content": "# don't ever lint node_modules\nnode_modules\n# don't lint build output\nlib\n# don't lint test\ntest\n\nsharp.js\njimp.js\nsrc/cjs.js\n.eslintrc.js\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  parser: \"@typescript-eslint/parser\",\n  plugins: [\"@typescript-eslint\"],\n  extends: [\"eslint:recommended\", \"plugin:@typescript-eslint/recommended\"],\n  ignorePatterns: [\"examples/*\"],\n  rules: {\n    \"@typescript-eslint/ban-ts-comment\": \"off\",\n  },\n}\n"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL\"\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    # The branches below must be a subset of the branches above\n    branches: [ master ]\n  schedule:\n    - cron: '20 4 * * 3'\n\njobs:\n  analyze:\n    name: Analyze\n    runs-on: ubuntu-latest\n    permissions:\n      actions: read\n      contents: read\n      security-events: write\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'javascript' ]\n        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]\n        # Learn more about CodeQL language support at https://git.io/codeql-language-support\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v2\n\n    # Initializes the CodeQL tools for scanning.\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v1\n      with:\n        languages: ${{ matrix.language }}\n        # If you wish to specify custom queries, you can do so here or in a config file.\n        # By default, queries listed here will override any specified in a config file.\n        # Prefix the list here with \"+\" to use these queries and those in the config file.\n        # queries: ./path/to/local/query, your-org/your-repo/queries@main\n\n    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).\n    # If this step fails, then you should remove it and run the build manually (see below)\n    - name: Autobuild\n      uses: github/codeql-action/autobuild@v1\n\n    # ℹ️ Command-line programs to run using the OS shell.\n    # 📚 https://git.io/JvXDl\n\n    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines\n    #    and modify them (or add more) to build your code if your project\n    #    uses a compiled language\n\n    #- run: |\n    #   make bootstrap\n    #   make release\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v1\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n*.log\ntest/build\ntest/**/build/*.js\ntest/**/build/**/*.png\ntest/**/build/**/*.jpg\ntest/**/build/**/*.avif\ntest/**/build/**/*.jpeg\ntest/**/build/**/*.webp\n.node-version\nlib\n.vscode\n.envrc\n.tool-versions"
  },
  {
    "path": ".travis.yml",
    "content": "os: osx\nlanguage: node_js\nnode_js:\n  - '12'\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Change Log\n\n## v1.1.0\n\n - Added `min` and `max` options to automatically generate a number of images, and `steps` option to say how many images ([#31](https://github.com/herrstucki/responsive-loader/pull/31)).\n\n## v1.0.0\n\n### New\n\n- 🚀 Added support for [sharp](https://github.com/lovell/sharp) ([#19](https://github.com/herrstucki/responsive-loader/pull/29))\n\n### Breaking\n\n#### Webpack 2 support\n\nRemoved support for webpack 1! Please upgrade to webpack >= 2.\n\nThe syntax to import images has changed. The query part now comes _after_ the resource (the image) instead of the loader.\n\n```diff\n- require('responsive-loader?size=100!some-image.jpg')\n+ require('responsive-loader!some-image.jpg?size=100')\n```\n\nThat means if `responsive-loader` is configured in your webpack-config, it's possible to specify image-specific options without having to add the loader part to the import path. For example:\n\n```js\n// webpack.config.js\nmodule.exports = {\n  // ...\n  module: {\n    rules: [\n      {\n        test: /\\.jpg$/,\n        loader: 'responsive-loader',\n        options: {\n          size: 1000\n          //...\n        }\n      }\n    ]\n  },\n}\n\n// some-file.js\nconst image1000 = require('some-image.jpg') // will have size 1000 from the config\nconst image500 = require('some-image.jpg?size=500')\n```\n\n#### Other breaking changes\n\n- The `ext` option was removed, in favor of `format=jpg|png`. `[ext]` is now part of the `name` option like in other loaders (fixes [#13](https://github.com/herrstucki/responsive-loader/issues/13))\n- Changed default JPEG `quality` to `85`\n- The `pass` option is now called `disable`\n\n## v0.7.0\n\n- Add `placeholder` option ([#16](https://github.com/herrstucki/responsive-loader/pull/16))\n- Add `width` and `height` attributes to output ([#19](https://github.com/herrstucki/responsive-loader/pull/19))\n\n## v0.6.1\n\n- Declare default `name`, `context`, `quality`, and `background` through webpack options when they're not specified in the loader query ([#12](https://github.com/herrstucki/responsive-loader/pull/12)).\n\n## v0.6.0\n\n- Add linting ([#7](https://github.com/herrstucki/responsive-loader/pull/7))\n- Breaking (maybe): Require node >= v4\n\n## v0.5.3\n\n- Fix wrong callback being called on file load error ([#6](https://github.com/herrstucki/responsive-loader/pull/6))\n\n## v0.5.2\n\n- Added tests!\n- Update `queue-async` to `d3-queue`\n\n## v0.5.1\n\n- Optimization: skip resizing images of the same size ([#5](https://github.com/herrstucki/responsive-loader/pull/5))\n\n## v0.5.0\n\nUsing the `size` option for getting only one resized image no longer just returns a string but the same object structure as when using `sizes`. The difference is, that when `toString()` is called on that object, it will return the path of the first resized image.\n\nAlso, for pure convenience, the returned object also contains a `src` property, so it can be spread onto a React component (e.g. `<img {...resized} />`).\n\n### Before\n\nThis worked:\n\n```js\nimport resized from 'responsive?sizes[]=100,sizes[]=200';\n\n<img srcSet={resized.srcSet} src={resized.images[0].path} />\n```\n\n```css\n.foo { background-image: url('responsive?size=100'); }\n```\n\nBut this didn't :sob::\n\n```js\nimport resized from 'responsive?size=100';\n\n// Whoops, error because `resized` ist just a string\n<img srcSet={resized.srcSet} src={resized.images[0].path} />\n```\n\n```css\n/* Whoops, `url('[object Object]')` */\n.foo { background-image: url('responsive?sizes[]=100'); }\n```\n\n### After\n\nAll these work :v:\n\n```js\nimport resized from 'responsive?sizes[]=100,sizes[]=200';\n\n<img srcSet={resized.srcSet} src={resized.src} />\n<img srcSet={resized.srcSet} src={resized} />\n<img {...resized} />\n```\n\n```css\n.foo { background-image: url('responsive?sizes[]=100,sizes[]=200'); }\n.foo { background-image: url('responsive?sizes[]=100'); }\n.foo { background-image: url('responsive?size=100'); }\n```\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2016, Jeremy Stucki\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of responsive-loader nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# responsive-loader\n\n[![build][travis]][travis-url]\n[![node][node]][node-url]\n\nA webpack loader for responsive images. Creates multiple images from one source image, and returns a `srcset`. For more information on how to use `srcset`, read [Responsive Images](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images). Browser support is [pretty good](http://caniuse.com/#search=srcset).\n\n## Install\n\n### With sharp\n\n```\nnpm install responsive-loader sharp --save-dev\n```\n\nFor [super-charged performance](http://sharp.dimens.io/en/stable/performance/) and webp and avif formats support, responsive-loader works with [sharp](https://github.com/lovell/sharp). It's recommended to use sharp if you have lots of images to transform.\n\n```js\nmodule.exports = {\n  // ...\n  module: {\n    rules: [\n      {\n        test: /\\.(png|jpe?g)$/,\n        use: [\n          {\n            loader: 'responsive-loader',\n            options: {\n              // Set options for all transforms\n            },\n          },\n        ],\n        type: 'javascript/auto',\n      },\n    ],\n  },\n}\n```\n\n### With jimp\n\n```\nnpm install responsive-loader jimp --save-dev\n```\n\nResponsive-loader can be use with [jimp](https://github.com/oliver-moran/jimp) to transform images. which needs to be installed alongside responsive-loader. Because jimp is written entirely in JavaScript and doesn't have any native dependencies it will work anywhere. The main drawback is that it's pretty slow.\n\nIf you want to use jimp, you need to configure responsive-loader to use its adapter:\n\n```diff\nmodule.exports = {\n  // ...\n  module: {\n    rules: [\n      {\n        test: /\\.(png|jpe?g)$/,\n        use: [\n          {\n            loader: 'responsive-loader',\n            options: {\n+               adapter: require('responsive-loader/jimp')\n            },\n          },\n        ],\n        type: 'javascript/auto',\n      }\n    ]\n  },\n}\n```\n\n### Typescript\n\n```typescript\n//declare a module to your type definitions files *.d.ts \ninterface ResponsiveImageOutput {\n  src: string\n  srcSet: string\n  placeholder: string | undefined\n  images: { path: string; width: number; height: number }[]\n  width: number\n  height: number\n  toString: () => string\n}\n\ndeclare module '*!rl' {\n  const src: ResponsiveImageOutput\n  export default src\n}\n```\n\n```\nimport responsiveImage from 'img/myImage.jpg?sizes[]=300,sizes[]=600,sizes[]=1024,sizes[]=2048!rl';\nimport responsiveImageWebp from 'img/myImage.jpg?sizes[]=300,sizes[]=600,sizes[]=1024,sizes[]=2048&format=webp!rl';\n...\n```\n\n---\n\nThen import images in your JavaScript files:\n\n```js\nimport responsiveImage from 'img/myImage.jpg?sizes[]=300,sizes[]=600,sizes[]=1024,sizes[]=2048';\nimport responsiveImageWebp from 'img/myImage.jpg?sizes[]=300,sizes[]=600,sizes[]=1024,sizes[]=2048&format=webp';\n\n// Outputs\n// responsiveImage.srcSet => '2fefae46cb857bc750fa5e5eed4a0cde-300.jpg 300w,2fefae46cb857bc750fa5e5eed4a0cde-600.jpg 600w,2fefae46cb857bc750fa5e5eed4a0cde-600.jpg 600w ...'\n// responsiveImage.images => [{height: 150, path: '2fefae46cb857bc750fa5e5eed4a0cde-300.jpg', width: 300}, {height: 300, path: '2fefae46cb857bc750fa5e5eed4a0cde-600.jpg', width: 600} ...]\n// responsiveImage.src => '2fefae46cb857bc750fa5e5eed4a0cde-2048.jpg'\n// responsiveImage.toString() => '2fefae46cb857bc750fa5e5eed4a0cde-2048.jpg'\n...\n  <picture>\n    <source srcSet={responsiveImageWebp.srcSet} type='image/webp' sizes='(min-width: 1024px) 1024px, 100vw'/>\n    <img\n      src={responsiveImage.src}\n      srcSet={responsiveImage.srcSet}\n      width={responsiveImage.width}\n      height={responsiveImage.height}\n      sizes='(min-width: 1024px) 1024px, 100vw'\n      loading=\"lazy\"\n    />\n  </picture>\n...\n```\n\nNotes:\n\n- `width` and `height` are intrinsic and are used to avoid layout shift, other techniques involve the use of aspect ratio and padding.\n- `sizes`, without sizes, the browser assumes the image is always 100vw for any viewport.\n  - A helpful tool to determine proper sizes https://ausi.github.io/respimagelint/\n- `loading` do not add loading lazy if the image is part of the initial rendering of the page or close to it.\n- `srcset` Modern browsers will choose the closest best image depending on the pixel density of your screen.\n  - in the example above is your pixel density is `>1x` for a screen `>1024px` it will display the 2048 image.\n\nOr use it in CSS (only the first resized image will be used, if you use multiple `sizes`):\n\n```css\n.myImage {\n  background: url('myImage.jpg?size=1140');\n}\n\n@media (max-width: 480px) {\n  .myImage {\n    background: url('myImage.jpg?size=480');\n  }\n}\n```\n\n```js\n// Outputs placeholder image as a data URI, and three images with 100, 200, and 300px widths\nconst responsiveImage = require('myImage.jpg?placeholder=true&sizes[]=100,sizes[]=200,sizes[]=300')\n\n// responsiveImage.placeholder => 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAIBAQE…'\nReactDOM.render(\n  <div\n    style={{\n      height: responsiveImage.height,\n      width: responsiveImage.width,\n      backgroundSize: 'cover',\n      backgroundImage: 'url(\"' + responsiveImage.placeholder + '\")',\n    }}>\n    <img src={responsiveImage.src} srcSet={responsiveImage.srcSet} />\n  </div>,\n  el\n)\n```\n\nYou can also use [JSON5](https://json5.org/) notation:\n\n```\n<source srcSet={require('./image.jpg?{sizes:[50,100,200,300,400,500,600,700,800], format: \"webp\"}').srcSet} type='image/webp'/>\n```\n\n### Options\n\n| Option                                  | Type                  | Default                | Description                                                                                                                                                                                                                                                                                 |\n| --------------------------------------- | --------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `name`                                  | `string`              | `[hash]-[width].[ext]` | Filename template for output files.                                                                                                                                                                                                                                                         |\n| `outputPath`                            | `string \\| Function`  | `undefined`            | Configure a custom output path for your file                                                                                                                                                                                                                                                |\n| `publicPath`                            | `string \\| Function`  | `undefined`            | Configure a custom public path for your file.                                                                                                                                                                                                                                               |\n| `context`                               | `string`              | `this.options.context` | Custom file context, defaults to webpack.config.js [context](https://webpack.js.org/configuration/entry-context/#context)                                                                                                                                                                   |\n| `sizes`                                 | `array`               | _original size_        | Specify all widths you want to use; if a specified size exceeds the original image's width, the latter will be used (i.e. images won't be scaled up). You may also declare a default `sizes` array in the loader options in your `webpack.config.js`.                                       |\n| `size`                                  | `integer`             | _original size_        | Specify one width you want to use; if the specified size exceeds the original image's width, the latter will be used (i.e. images won't be scaled up)                                                                                                                                       |\n| `min`                                   | `integer`             |                        | As an alternative to manually specifying `sizes`, you can specify `min`, `max` and `steps`, and the sizes will be generated for you.                                                                                                                                                        |\n| `max`                                   | `integer`             |                        | See `min` above                                                                                                                                                                                                                                                                             |\n| `steps`                                 | `integer`             | `4`                    | Configure the number of images generated between `min` and `max` (inclusive)                                                                                                                                                                                                                |\n| `quality`                               | `integer`             | `85`                   | JPEG and WEBP compression quality                                                                                                                                                                                                                                                           |\n| `format`                                | `string`              | _original format_      | Either `png` or `jpg`; use to convert to another format. `webp` and `avif` is also supported, but only by the sharp adapter                                                                                                                                                                 |\n| `placeholder`                           | `boolean`             | `false`                | A true or false value to specify wether to output a placeholder image as a data URI                                                                                                                                                                                                         |\n| `placeholderSize`                       | `integer`             | `40`                   | A number value specifying the width of the placeholder image, if enabled with the option above                                                                                                                                                                                              |\n| `adapter`                               | `Adapter`             | JIMP                   | Specify which adapter to use. Can only be specified in the loader options.                                                                                                                                                                                                                  |\n| `disable`                               | `boolean`             | `false`                | Disable processing of images by this loader (useful in development). `srcSet` and other attributes will still be generated but only for the original size. Note that the `width` and `height` attributes will both be set to `100` but the image will retain its original dimensions.       |\n| **[`esModule`](#esmodule)**             | `boolean`             | `false`                | Use ES modules syntax.                                                                                                                                                                                                                                                                      |\n| `emitFile`                              | `boolean`             | `true`                 | If `true`, emits a file (writes a file to the filesystem). If `false`, the loader will still return a object with the public URI but will not emit the file. It is often useful to disable this option for server-side packages.                                                            |\n| **[`cacheDirectory`](#cachedirectory)** | `string` or `boolean` | `false`                | Experimental: If `true`, this will cache the result object but not the image files. The images are only produced once, when they are not found in the results object cache, or when the options change (cache key). For Development you can set query parameter to `?cacheDirectory=false`. |\n\n#### Adapter-specific options\n\n##### jimp\n\n- `background: number` — Background fill when converting transparent to opaque images. Make sure this is a valid hex number, e.g. `0xFFFFFFFF`)\n\n##### sharp\n\n- `background: string` — Background fill when converting transparent to opaque images. E.g. `#FFFFFF` or `%23FFFFFF` for webpack > 5\n- `format: webp` — Conversion to the `image/webp` format. Recognizes the `quality` option.\n- `format: avif` — Conversion to the `image/avif` format. Recognizes the `quality` option.\n- `progressive: boolean` - Use progressive (interlace) scan for `image/jpeg` format.\n- `rotate: number` - Rotates image [more here](https://sharp.pixelplumbing.com/api-operation#rotate)\n\n### Examples\n\nSet a default `sizes` array, so you don't have to declare them with each `require`.\n\n```js\nmodule.exports = {\n  entry: {...},\n  output: {...},\n  module: {\n    rules: [\n      {\n        test: /\\.(jpe?g|png|webp)$/i,\n         use: [\n          {\n            loader: \"responsive-loader\",\n            options: {\n              adapter: require('responsive-loader/sharp'),\n              sizes: [320, 640, 960, 1200, 1800, 2400],\n              placeholder: true,\n              placeholderSize: 20\n            },\n          },\n        ],\n      }\n    ]\n  },\n}\n```\n\n### `cacheDirectory`\n\nType: `Boolean` or `string`\nDefault: `false`\n\nExperimental: If `true`, this will cache the result object but not the image files. The images are only produced once, when they are not found in the results object cache, or when the options change (cache key). For Development you can set query parameter to individual images by using `?cacheDirectory=false`.\n\nDefault cache directory might be `.node_modules/.cache/responsive-loader`\n\n```js\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        test: /\\.(jpe?g|png)$/i,\n        use: [\n          {\n            loader: 'responsive-loader',\n            options: {\n              esModule: true,\n              cacheDirectory: true,\n              publicPath: '/_next',\n              name: 'static/media/[name]-[hash:7]-[width].[ext]',\n            },\n          },\n        ],\n      },\n    ],\n  },\n}\n```\n\n### `esModule`\n\nType: `Boolean`\nDefault: `false`\n\nBy default, `responsive-loader` generates JS modules that use the CommonJS syntax.\nThere are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/).\n\nYou can enable a ES module syntax using:\n\n**webpack.config.js**\n\n```js\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        test: /\\.(jpe?g|png)$/i,\n        use: [\n          {\n            loader: 'responsive-loader',\n            options: {\n              esModule: true,\n            },\n          },\n        ],\n      },\n    ],\n  },\n}\n```\n\n### Writing Your Own Adapter\n\nMaybe you want to use another image processing library or you want to change an existing one's behavior. You can write your own adapter with the following signature:\n\n```js\ntype Adapter = (imagePath: string) => {\n  metadata: () => Promise<{width: number, height: number}>\n  resize: (config: {width: number, mime: string, options: Object}) => Promise<{data: Buffer, width: number, height: number}>\n}\n```\n\nThe `resize` method takes a single argument which has a `width`, `mime` and `options` property (which receives all loader options)\n\nIn your webpack config, require your adapter\n\n```js\n{\n  test: /\\.(jpe?g|png)$/i,\n  loader: 'responsive-loader',\n  options: {\n    adapter: require('./my-adapter')\n    foo: 'bar' // will get passed to adapter.resize({width, mime, options: {foo: 'bar}})\n  }\n}\n```\n\n## Notes\n\n- Doesn't support `1x`, `2x` sizes, but you probably don't need it.\n\n## Usage Examples\n\n### Next.js\n\n- https://github.com/dazuaz/responsive-loader-example\n\n### Pug\n\n- [How to use responsive-loader with Pug](https://webdiscus.github.io/pug-plugin/responsive-image/). Thanks to the awesome [pug-loader](https://webdiscus.github.io/pug-plugin/hello-world/).\n\nPlease submit your own example to add here\n\n[node]: https://img.shields.io/node/v/responsive-loader.svg\n[node-url]: https://nodejs.org\n[travis]: https://travis-ci.com/dazuaz/responsive-loader.svg?branch=master\n[travis-url]: https://travis-ci.com/dazuaz/responsive-loader\n"
  },
  {
    "path": "jimp.js",
    "content": "module.exports = require('./lib/adapters/jimp');\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"responsive-loader\",\n  \"version\": \"3.1.2\",\n  \"description\": \"A webpack loader for responsive images\",\n  \"main\": \"lib/cjs.js\",\n  \"engines\": {\n    \"node\": \">= 12.22.1\"\n  },\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"lint\": \"eslint\",\n    \"test:clean\": \"find test/**/build/ -name '*.jpg' -o -name '*.png' -o -name '*.avif' -o -name '*.webp' -o -name '*.jpeg' -o -name '*.js' | xargs rm -f\",\n    \"test\": \"npm run build && npm run test:clean && webpack --config=./test/jimp/webpack.config.js && webpack --config=./test/sharp/webpack.config.js && jest\"\n  },\n  \"np\": {\n    \"yarn\": false,\n    \"contents\": \"lib\"\n  },\n  \"files\": [\n    \"lib\",\n    \"jimp.js\",\n    \"sharp.js\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/dazuaz/responsive-loader.git\"\n  },\n  \"keywords\": [\n    \"webpack\",\n    \"responsive\",\n    \"loader\",\n    \"srcset\"\n  ],\n  \"author\": \"Jeremy Stucki <jeremy@interactivethings.com>\",\n  \"contributors\": [\n    \"Daniel Zuloaga <daniel@staticprops.com> (https://staticprops.com/)\"\n  ],\n  \"license\": \"BSD-3-Clause\",\n  \"bugs\": {\n    \"url\": \"https://github.com/dazuaz/responsive-loader/issues\"\n  },\n  \"homepage\": \"https://github.com/dazuaz/responsive-loader\",\n  \"peerDependencies\": {\n    \"webpack\": \"^5.73.0\"\n  },\n  \"peerDependenciesMeta\": {\n    \"jimp\": {\n      \"optional\": true\n    },\n    \"sharp\": {\n      \"optional\": true\n    }\n  },\n  \"dependencies\": {\n    \"@types/node\": \"^18.11.9\",\n    \"find-cache-dir\": \"^3.3.2\",\n    \"json5\": \"^2.2.1\",\n    \"loader-utils\": \"^3.2.1\",\n    \"make-dir\": \"^3.1.0\",\n    \"schema-utils\": \"^4.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.20.2\",\n    \"@babel/preset-env\": \"^7.20.2\",\n    \"@types/find-cache-dir\": \"^3.2.1\",\n    \"@types/jest\": \"^29.2.3\",\n    \"@types/json-schema\": \"^7.0.11\",\n    \"@types/sharp\": \"^0.31.0\",\n    \"@types/webpack\": \"^5.28.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^5.43.0\",\n    \"@typescript-eslint/parser\": \"^5.43.0\",\n    \"babel-jest\": \"^29.3.1\",\n    \"eslint\": \"^8.27.0\",\n    \"jest\": \"^29.3.1\",\n    \"jimp\": \"^0.16.2\",\n    \"prettier\": \"^2.7.1\",\n    \"prettier-eslint\": \"^15.0.1\",\n    \"sharp\": \"^0.31.2\",\n    \"typescript\": \"^4.9.3\",\n    \"webpack\": \"^5.75.0\",\n    \"webpack-cli\": \"^5.0.0\"\n  },\n  \"jest\": {\n    \"testEnvironment\": \"node\"\n  }\n}\n"
  },
  {
    "path": "sharp.js",
    "content": "module.exports = require('./lib/adapters/sharp');\n"
  },
  {
    "path": "src/adapters/jimp.ts",
    "content": "import * as jimp from \"jimp\"\n\ntype ResizeProps = {\n  width: number\n  mime: \"image/jpeg\" | \"image/png\" | \"image/webp\" | \"image/avif\"\n  options: {\n    background?: string\n    rotate: number\n    quality: number\n    progressive?: boolean\n  }\n}\n\nclass JimpAdapter {\n  readImage: Promise<jimp>\n  constructor(imagePath: string) {\n    this.readImage = jimp.read(imagePath)\n  }\n  metadata(): Promise<{ height: number; width: number }> {\n    return this.readImage.then((image) => ({\n      width: image.bitmap.width,\n      height: image.bitmap.height,\n    }))\n  }\n  resize({\n    width,\n    mime,\n    options,\n  }: ResizeProps): Promise<{\n    width: number\n    height: number\n    data: Buffer\n  }> {\n    return new Promise((resolve, reject) => {\n      this.readImage.then((image) => {\n        image\n          .clone()\n          .resize(width, jimp.AUTO)\n          .quality(options.quality)\n          .background(parseInt(options.background + \"\", 16) || 0xffffffff)\n          .getBuffer(mime, function (err, data) {\n            // eslint-disable-line func-names\n            if (err) {\n              reject(err)\n            } else {\n              resolve({\n                data,\n                width,\n                height: this.bitmap.height,\n              })\n            }\n          })\n      })\n    })\n  }\n}\nmodule.exports = (imagePath: string): JimpAdapter => {\n  return new JimpAdapter(imagePath)\n}\n"
  },
  {
    "path": "src/adapters/sharp.ts",
    "content": "import * as sharp from 'sharp'\n\ntype ResizeProps = {\n  width: number\n  mime: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/avif'\n  options: {\n    background?: string\n    rotate: number\n    quality: number\n    progressive?: boolean\n  }\n}\n\nclass SharpAdapter {\n  image: sharp.Sharp\n  constructor(imagePath: string) {\n    this.image = sharp(imagePath)\n  }\n  metadata(): Promise<sharp.Metadata> {\n    return this.image.metadata()\n  }\n  resize({ width, mime, options }: ResizeProps): Promise<{ data: Buffer; width: number; height: number }> {\n    return new Promise((resolve, reject) => {\n      let resized = this.image.clone().resize(width, null)\n      if (!options.rotate) {\n        // .toBuffer() strips EXIF metadata like orientation, so portrait\n        // images will become landscape. This updates the image to reflect\n        // the EXIF metadata (if an EXIF orientation is set; otherwise unchanged).\n        resized.rotate()\n      }\n      if (options.background) {\n        resized = resized.flatten({\n          background: options.background,\n        })\n      }\n\n      if (mime === 'image/jpeg') {\n        resized = resized.jpeg({\n          quality: options.quality,\n          progressive: options.progressive,\n        })\n      }\n      if (mime === 'image/png') {\n        resized = resized.png({\n          quality: options.quality,\n          progressive: options.progressive,\n        })\n      }\n      if (mime === 'image/webp') {\n        resized = resized.webp({\n          quality: options.quality,\n        })\n      }\n      if (mime === 'image/avif') {\n        // @ts-ignore\n        resized = resized.avif({\n          quality: options.quality,\n        })\n      }\n      // rotate\n      if (options.rotate && options.rotate !== 0) {\n        resized = resized.rotate(options.rotate)\n      }\n      resized.toBuffer((err, data, { height }) => {\n        if (err) {\n          reject(err)\n        } else {\n          resolve({\n            data,\n            width,\n            height,\n          })\n        }\n      })\n    })\n  }\n}\n// export default SharpAdapter\nmodule.exports = (imagePath: string): SharpAdapter => {\n  return new SharpAdapter(imagePath)\n}\n"
  },
  {
    "path": "src/cache.ts",
    "content": "/**\n * Filesystem Cache\n *\n * Given a file and a transform function, cache the result into files\n * or retrieve the previously cached files if the given file is already known.\n *\n * @see https://github.com/babel/babel-loader/\n */\nimport * as fs from 'fs'\nimport * as os from 'os'\nimport * as path from 'path'\nimport * as zlib from 'zlib'\nimport * as crypto from 'crypto'\nimport * as findCacheDir from 'find-cache-dir'\nimport * as makeDir from 'make-dir'\nimport { promisify } from 'util'\nimport { CacheOptions, TransformParams } from './types'\nimport { transform } from '.'\n\n// Lazily instantiated when needed\nlet defaultCacheDirectory: string | null = null\n\nconst readFile = promisify(fs.readFile)\nconst writeFile = promisify(fs.writeFile)\nconst gunzip = promisify(zlib.gunzip)\nconst gzip = promisify(zlib.gzip)\n\n/**\n * Read the contents from the compressed file.\n *\n * @async\n * @params {String} filename\n * @params {Boolean} compress\n */\nconst read = async function (filename: string, compress: boolean) {\n  const data = await readFile(filename + (compress ? '.gz' : ''))\n  const content = compress ? await gunzip(data) : data\n\n  return JSON.parse(content.toString())\n}\n\n/**\n * Write contents into a compressed file.\n *\n * @async\n * @params {String} filename\n * @params {Boolean} compress\n * @params {String} result\n */\nconst write = async function (filename: string, compress: boolean, result: string) {\n  const content = JSON.stringify(result)\n\n  const data = compress ? await gzip(content) : content\n  return await writeFile(filename + (compress ? '.gz' : ''), data)\n}\n\n/**\n * Build the filename for the cached file\n *\n * @params {String} source  File source code\n * @params {Object} options Options used\n *\n * @return {String}\n */\nconst filename = function (source: string, identifier: string) {\n  const hash = crypto.createHash('md4')\n\n  const contents = JSON.stringify({ source, identifier })\n\n  hash.update(contents)\n\n  return hash.digest('hex') + '.json'\n}\n\n/**\n * Handle the cache\n *\n * @params {String} directory\n * @params {Object} params\n */\nconst handleCache = async function (\n  directory: string,\n  cacheOptions: CacheOptions,\n  params: TransformParams\n): Promise<string> {\n  const { cacheIdentifier, cacheDirectory, cacheCompression } = cacheOptions\n\n  const file = path.join(directory, filename(params.resourcePath, cacheIdentifier))\n\n  try {\n    // No errors mean that the file was previously cached\n    // we just need to return it\n    return await read(file, cacheCompression)\n  } catch (err) {\n    // continue regardless of error\n  }\n\n  const fallback = typeof cacheDirectory !== 'string' && directory !== os.tmpdir()\n\n  // Make sure the directory exists.\n  try {\n    await makeDir(directory)\n  } catch (err) {\n    if (fallback) {\n      return handleCache(os.tmpdir(), cacheOptions, params)\n    }\n\n    throw err\n  }\n\n  // Otherwise just transform the file\n  // return it to the user asap and write it in cache\n  const result = await transform(params)\n\n  try {\n    await write(file, cacheCompression, result)\n  } catch (err) {\n    if (fallback) {\n      // Fallback to tmpdir if node_modules folder not writable\n      return handleCache(os.tmpdir(), cacheOptions, params)\n    }\n\n    throw err\n  }\n\n  return result\n}\n\n/**\n * Retrieve file from cache, or create a new one for future reads\n *\n * @async\n * @param  {CacheOptions}   cacheOptions\n * @param  {TransformParams}   transformParams  Options to be given to the transform fn\n *\n */\n\nexport async function cache(cacheOptions: CacheOptions, transformParams: TransformParams): Promise<string> {\n  let directory\n\n  if (typeof cacheOptions.cacheDirectory === 'string') {\n    directory = cacheOptions.cacheDirectory\n  } else {\n    if (defaultCacheDirectory === null) {\n      defaultCacheDirectory = findCacheDir({ name: 'responsive-loader' }) || os.tmpdir()\n    }\n\n    directory = defaultCacheDirectory\n  }\n\n  return await handleCache(directory, cacheOptions, transformParams)\n}\n"
  },
  {
    "path": "src/cjs.js",
    "content": "const loader = require('./index')\n\nmodule.exports = loader.default\nmodule.exports.raw = loader.raw\n"
  },
  {
    "path": "src/index.ts",
    "content": "import * as schema from './schema.json'\nimport { validate } from 'schema-utils'\nimport { JSONSchema7 } from 'schema-utils/declarations/ValidationError'\n\nimport { parseOptions, getOutputAndPublicPath, createPlaceholder } from './utils'\nimport { cache } from './cache'\nimport type { LoaderContext } from 'webpack'\n\nimport { interpolateName } from 'loader-utils'\nimport { parseQuery } from './parseQuery'\n\nimport type {\n  Adapter,\n  Options,\n  CacheOptions,\n  AdapterImplementation,\n  MimeType,\n  AdapterResizeResponse,\n  TransformParams,\n} from './types'\n\nconst DEFAULTS = {\n  quality: 85,\n  placeholder: false,\n  placeholderSize: 40,\n  name: '[hash]-[width].[ext]',\n  steps: 4,\n  esModule: false,\n  emitFile: true,\n  rotate: 0,\n  cacheDirectory: false,\n  cacheCompression: true,\n  cacheIdentifier: '',\n}\n\n/**\n * **Responsive Loader**\n *\n * Creates multiple images from one source image, and returns a srcset\n * [Responsive Loader](https://github.com/dazuaz/responsive-loader)\n *\n * @param {Buffer} content Source\n *\n * @return {loaderCallback} loaderCallback Result\n */\nexport default function loader(this: LoaderContext<Options>, content: string): void {\n  const loaderCallback = this.async()\n  if (typeof loaderCallback == 'undefined') {\n    new Error('Responsive loader callback error')\n    return\n  }\n\n  // Parsers the query string and options\n  const parsedResourceQuery = this.resourceQuery ? parseQuery(this.resourceQuery) : {}\n\n  // Combines defaults, webpack options and query options,\n  const options = { ...DEFAULTS, ...this.getOptions(), ...parsedResourceQuery }\n\n  validate(schema as JSONSchema7, options, { name: 'Responsive Loader' })\n\n  const outputContext = options.context || this.rootContext\n  const { mime, ext, name, sizes, outputPlaceholder, placeholderSize, imageOptions, cacheOptions } = parseOptions(\n    this.resourcePath,\n    options\n  )\n\n  if (!mime) {\n    loaderCallback(new Error('No mime type for file with extension ' + ext + ' supported'))\n    return\n  }\n\n  const createFile = ({ data, width, height }: AdapterResizeResponse) => {\n    const fileName = interpolateName(this, name, {\n      context: outputContext,\n      content: data.toString(),\n    })\n      .replace(/\\[width\\]/gi, width + '')\n      .replace(/\\[height\\]/gi, height + '')\n\n    const { outputPath, publicPath } = getOutputAndPublicPath(fileName, {\n      outputPath: options.outputPath,\n      publicPath: options.publicPath,\n    })\n\n    if (options.emitFile) {\n      this.emitFile(outputPath, data)\n    }\n\n    return {\n      src: publicPath + `+${JSON.stringify(` ${width}w`)}`,\n      path: publicPath,\n      width: width,\n      height: height,\n    }\n  }\n\n  /**\n   * Disable processing of images by this loader (useful in development)\n   */\n  if (options.disable) {\n    const { path } = createFile({ data: content, width: 100, height: 100 })\n    loaderCallback(\n      null,\n      `${options.esModule ? 'export default' : 'module.exports ='} {\n        srcSet: ${path},\n        images: [{path:${path},width:100,height:100}],\n        src: ${path},\n        toString: function(){return ${path}}\n      }`\n    )\n    return\n  }\n  // The full config is passed to the adapter, later sources' properties overwrite earlier ones.\n  const adapterOptions = Object.assign({}, options, imageOptions)\n\n  const transformParams = {\n    adapterModule: options.adapter,\n    resourcePath: this.resourcePath,\n    adapterOptions,\n    createFile,\n    outputPlaceholder,\n    placeholderSize,\n    mime,\n    sizes,\n  }\n  orchestrate({ cacheOptions, transformParams })\n    .then((result) => loaderCallback(null, result))\n    .catch((err) => loaderCallback(err))\n}\ninterface OrchestrateParams {\n  cacheOptions: CacheOptions\n  transformParams: TransformParams\n}\nasync function orchestrate(params: OrchestrateParams) {\n  // use cached, or create new image.\n  let result\n  const { transformParams, cacheOptions } = params\n\n  if (cacheOptions.cacheDirectory) {\n    result = await cache(cacheOptions, transformParams)\n  } else {\n    result = await transform(transformParams)\n  }\n\n  return result\n}\n\n// Transform based on the parameters\nexport async function transform({\n  adapterModule,\n  resourcePath,\n  createFile,\n  sizes,\n  mime,\n  outputPlaceholder,\n  placeholderSize,\n  adapterOptions,\n}: TransformParams): Promise<string> {\n  const adapter: Adapter = adapterModule || require('./adapters/sharp')\n  const img = adapter(resourcePath)\n  const results = await transformations({ img, sizes, mime, outputPlaceholder, placeholderSize, adapterOptions })\n\n  let placeholder\n  let files\n\n  if (outputPlaceholder) {\n    files = results.slice(0, -1).map(createFile)\n    placeholder = createPlaceholder(results[results.length - 1], mime)\n  } else {\n    files = results.map(createFile)\n  }\n\n  const srcset = files.map((f) => f.src).join('+\",\"+')\n  const images = files.map((f) => `{path: ${f.path},width: ${f.width},height: ${f.height}}`).join(',')\n  // default to the biggest image\n  const defaultImage = files[files.length - 1]\n\n  return `${adapterOptions.esModule ? 'export default' : 'module.exports ='} {\n        srcSet: ${srcset},\n        images: [${images}],\n        src: ${defaultImage.path},\n        toString: function(){return ${defaultImage.path}},\n        ${placeholder ? 'placeholder: ' + placeholder + ',' : ''}\n        width: ${defaultImage.width},\n        height: ${defaultImage.height}\n      }`\n}\n\ninterface TransformationParams {\n  img: AdapterImplementation\n  sizes: number[]\n  mime: MimeType\n  outputPlaceholder: boolean\n  placeholderSize: number\n  adapterOptions: Options\n}\n/**\n * **Run Transformations**\n *\n * For each size defined in the parameters, resize an image via the adapter\n *\n */\nasync function transformations({\n  img,\n  sizes,\n  mime,\n  outputPlaceholder,\n  placeholderSize,\n  adapterOptions,\n}: TransformationParams): Promise<AdapterResizeResponse[]> {\n  const metadata = await img.metadata()\n  const promises = []\n  const widthsToGenerate = new Set()\n\n  sizes.forEach((size) => {\n    const width = Math.min(metadata.width, size)\n    // Only resize images if they aren't an exact copy of one already being resized...\n    if (!widthsToGenerate.has(width)) {\n      widthsToGenerate.add(width)\n      promises.push(\n        img.resize({\n          width,\n          mime,\n          options: adapterOptions,\n        })\n      )\n    }\n  })\n\n  if (outputPlaceholder) {\n    promises.push(\n      img.resize({\n        width: placeholderSize,\n        options: adapterOptions,\n        mime,\n      })\n    )\n  }\n  return Promise.all(promises)\n}\nexport const raw = true\n"
  },
  {
    "path": "src/loader-utils.d.ts",
    "content": "declare module 'loader-utils' {\n  export function interpolateName(LoaderContext: any, name: string, options: any): any\n}\n"
  },
  {
    "path": "src/parseQuery.ts",
    "content": "import * as JSON5 from 'json5'\n\ninterface LooseObject {\n  [key: string]: any\n}\n\nconst specialValues: LooseObject = {\n  null: null,\n  true: true,\n  false: false,\n}\n\nfunction parseQuery(query: string): LooseObject {\n  if (query.slice(0, 1) !== '?') {\n    throw new Error(\"A valid query string passed to parseQuery should begin with '?'\")\n  }\n\n  query = query.slice(1)\n\n  if (!query) {\n    return {}\n  }\n\n  if (query.slice(0, 1) === '{' && query.slice(-1) === '}') {\n    query = decodeURIComponent(query)\n    return JSON5.parse(query)\n  }\n\n  const queryArgs = query.split(/[,&]/g)\n  const result: LooseObject = {}\n\n  queryArgs.forEach((arg) => {\n    const idx = arg.indexOf('=')\n\n    if (idx >= 0) {\n      let name = arg.slice(0, idx)\n      let value = decodeURIComponent(arg.slice(idx + 1))\n      // const specialValues: LooseObject = {}\n\n      // eslint-disable-next-line no-prototype-builtins\n      if (specialValues.hasOwnProperty(value)) {\n        value = specialValues[value]\n      }\n      if (name.slice(-2) === '[]') {\n        name = decodeURIComponent(name.slice(0, name.length - 2))\n\n        if (!Array.isArray(result[name])) {\n          result[name] = []\n        }\n\n        result[name].push(value)\n      } else {\n        name = decodeURIComponent(name)\n        result[name] = value\n      }\n    } else {\n      if (arg.slice(0, 1) === '-') {\n        result[decodeURIComponent(arg.slice(1))] = false\n      } else if (arg.slice(0, 1) === '+') {\n        result[decodeURIComponent(arg.slice(1))] = true\n      } else {\n        result[decodeURIComponent(arg)] = true\n      }\n    }\n  })\n\n  return result\n}\nexport { parseQuery }\n"
  },
  {
    "path": "src/schema.json",
    "content": "{\n  \"title\": \"Responsive Loader options\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"size\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }]\n    },\n    \"sizes\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"description\": \"Array of strings or numbers\",\n        \"anyOf\": [\n          {\n            \"type\": \"string\"\n          },\n          {\n            \"type\": \"number\"\n          }\n        ]\n      }\n    },\n    \"min\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }]\n    },\n    \"max\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }]\n    },\n    \"steps\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }]\n    },\n    \"name\": {\n      \"type\": \"string\"\n    },\n\n    \"outputPath\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"instanceof\": \"Function\" }]\n    },\n    \"publicPath\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"instanceof\": \"Function\" }]\n    },\n    \"context\": { \"type\": \"string\" },\n    \"placeholderSize\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }]\n    },\n    \"quality\": { \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }] },\n    \"background\": { \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }] },\n    \"rotate\": {\n      \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"number\" }]\n    },\n    \"progressive\": { \"type\": \"boolean\" },\n    \"placeholder\": { \"type\": [\"string\", \"boolean\"] },\n    \"adapter\": {\n      \"instanceof\": \"Function\"\n    },\n    \"format\": { \"type\": \"string\", \"enum\": [\"png\", \"jpg\", \"jpeg\", \"webp\", \"avif\"] },\n    \"disable\": { \"type\": \"boolean\" },\n    \"esModule\": {\n      \"description\": \"By default, responsive-loader generates JS modules that don't use the ES modules syntax.\",\n      \"type\": \"boolean\"\n    },\n    \"emitFile\": {\n      \"description\": \"Enables/Disables emit files.\",\n      \"type\": \"boolean\"\n    },\n    \"cacheDirectory\": { \"anyOf\": [{ \"type\": \"string\" }, { \"type\": \"boolean\" }] },\n    \"cacheIdentifier\": { \"type\": \"string\" },\n    \"cacheCompression\": { \"type\": \"boolean\" }\n  },\n  \"additionalProperties\": true\n}\n"
  },
  {
    "path": "src/types.d.ts",
    "content": "export type Options = {\n  size?: string | number\n  sizes?: [string | number]\n  min?: string | number\n  max?: string | number\n  steps: string | number\n  name: string\n  outputPath?: ((...args: Array<unknown>) => string) | string\n  publicPath?: ((...args: Array<unknown>) => string) | string\n  context?: string\n  placeholder: string | boolean\n  placeholderSize: string | number\n  quality: string | number\n  background?: string | number\n  progressive?: boolean\n  rotate: string | number\n  adapter?: Adapter\n  format?: Format\n  disable?: boolean | null\n  esModule: boolean\n  emitFile: boolean\n  cacheDirectory: string | boolean\n  cacheIdentifier: string\n  cacheCompression: boolean\n}\nexport type Format = 'png' | 'jpg' | 'jpeg' | 'webp' | 'avif'\nexport type FileExt = 'jpg' | 'png' | 'webp' | 'avif'\nexport type MimeType = 'image/jpeg' | 'image/png' | 'image/webp' | 'image/avif'\n\nexport interface CacheOptions {\n  cacheDirectory: string | boolean\n  cacheIdentifier: string\n  cacheCompression: boolean\n}\n\nexport type Adapter = (imagePath: string) => AdapterImplementation\nexport interface ImageOptions {\n  quality: number\n  background?: string | number\n  progressive: boolean\n  rotate?: number\n}\nexport interface AdapterImplementation {\n  metadata: () => Promise<{ width: number; height: number }>\n  resize: (config: { width: number; mime: string; options: Options }) => Promise<AdapterResizeResponse>\n}\nexport type AdapterResizeResponse = { data: string | Buffer; width: number; height: number }\n\nexport interface TransformParams {\n  adapterModule: Adapter | undefined\n  resourcePath: string\n  createFile: ({ data, width, height }: AdapterResizeResponse) => {\n    src: string\n    path: string\n    width: number\n    height: number\n  }\n  outputPlaceholder: boolean\n  placeholderSize: number\n  mime: MimeType\n  sizes: number[]\n  adapterOptions: Options & ImageOptions\n}\n"
  },
  {
    "path": "src/utils.ts",
    "content": "import * as path from 'path'\nimport type { Options, MimeType, ImageOptions, CacheOptions } from './types'\n\nconst version = '3'\n\nenum MIMES {\n  jpg = 'image/jpeg',\n  jpeg = 'image/jpeg',\n  png = 'image/png',\n  webp = 'image/webp',\n  avif = 'image/avif',\n}\n\nenum EXTS {\n  'image/jpeg' = 'jpg',\n  'image/png' = 'png',\n  'image/webp' = 'webp',\n  'image/avif' = 'avif',\n}\n\ntype ParsedOptions = {\n  outputPlaceholder: boolean\n  placeholderSize: number\n  name: string\n  mime: MimeType | undefined\n  ext: string\n  sizes: number[]\n  imageOptions: ImageOptions\n  cacheOptions: CacheOptions\n}\n\nfunction parseOptions(resourcePath: string, options: Options): ParsedOptions {\n  const outputPlaceholder = Boolean(options.placeholder)\n  const placeholderSize: number = parseInt(options.placeholderSize + '', 10)\n\n  // Adapter compression options\n  const imageOptions: ImageOptions = {\n    quality: parseInt(options.quality + '', 10),\n    rotate: parseInt(options.rotate + '', 10),\n    background: options.background,\n    progressive: Boolean(options.progressive),\n  }\n\n  // let mime: MimeType | undefined\n  // let ext: FileExt | string\n  let mime\n  let ext\n  if (options.format) {\n    mime = MIMES[options.format]\n    ext = EXTS[mime]\n  } else {\n    ext = path.extname(resourcePath).replace(/\\./, '')\n    switch (ext) {\n      case 'jpg':\n      case 'jpeg':\n      case 'png':\n      case 'webp':\n      case 'avif':\n        mime = MIMES[ext]\n        break\n      default:\n        mime = undefined\n        break\n    }\n  }\n\n  const name = options.name.replace(/\\[ext\\]/gi, ext)\n  const min: number | void = options.min !== undefined ? parseInt(options.min + '', 10) : undefined\n  const max: number | void = options.max !== undefined ? parseInt(options.max + '', 10) : undefined\n  const steps: number = parseInt(options.steps + '', 10)\n\n  let generatedSizes\n  if (typeof min === 'number' && max) {\n    generatedSizes = []\n\n    for (let step = 0; step < steps; step++) {\n      const size = min + ((max - min) / (steps - 1)) * step\n      generatedSizes.push(Math.ceil(size))\n    }\n  }\n  const size = parseInt(options.size + '', 10)\n  const sizes = size\n    ? [size]\n    : options.sizes?.map((size) => parseInt(size + '', 10)) || generatedSizes || [Number.MAX_SAFE_INTEGER]\n\n  // Cache options\n  const cacheOptions: CacheOptions = {\n    cacheDirectory: options.cacheDirectory,\n    cacheIdentifier: JSON.stringify({\n      options,\n      'responsive-loader': version,\n    }),\n    cacheCompression: Boolean(options.cacheCompression),\n  }\n  return {\n    ext,\n    mime,\n    name,\n    sizes,\n    outputPlaceholder,\n    placeholderSize,\n    cacheOptions,\n    imageOptions,\n  }\n}\n\nconst createPlaceholder = ({ data }: { data: any }, mime: string): string => {\n  return `\"data:${mime};base64,${data.toString('base64')}\"`\n}\n// return `\"data:${mime};base64,${data.toString(\"base64\")}\"`\n\ninterface GetOutputAndPublicPath {\n  (\n    fileName: string,\n    {\n      outputPath,\n      publicPath,\n    }: {\n      outputPath?: ((...args: Array<unknown>) => string) | string\n      publicPath?: ((...args: Array<unknown>) => string) | string\n    }\n  ): {\n    outputPath: string\n    publicPath: string\n  }\n}\n/**\n * **Responsive Loader Paths**\n *\n * Returns the output and public path\n *\n * @method getOutputAndPublicPath\n *\n * @param {string} fileName\n * @param {Config} outputPath\n * @param {Config} publicPath\n *\n * @return {Config} Paths Result\n */\nconst getOutputAndPublicPath: GetOutputAndPublicPath = (\n  fileName: string,\n  { outputPath: configOutputPath, publicPath: configPublicPath }\n) => {\n  let outputPath = fileName\n  if (configOutputPath) {\n    if (typeof configOutputPath === 'function') {\n      outputPath = configOutputPath(fileName)\n    } else {\n      outputPath = path.posix.join(configOutputPath, fileName)\n    }\n  }\n  let publicPath = `__webpack_public_path__ + ${JSON.stringify(outputPath)}`\n\n  if (configPublicPath) {\n    if (typeof configPublicPath === 'function') {\n      publicPath = configPublicPath(fileName)\n    } else {\n      // publicPath can be a url or local path\n      // check if it's a valid url\n      if (isValidUrl(configPublicPath)) {\n        const url = new URL(configPublicPath)\n        url.pathname = path.posix.join(url.pathname, fileName)\n        publicPath = url.toString()\n      } else {\n        publicPath = path.posix.join(configPublicPath, fileName)\n      }\n    }\n    publicPath = JSON.stringify(publicPath)\n  }\n\n  return {\n    outputPath,\n    publicPath,\n  }\n}\nconst isValidUrl = (urlString: string) => {\n  try {\n    return Boolean(new URL(urlString))\n  } catch (e) {\n    return false\n  }\n}\n\nexport { parseOptions, getOutputAndPublicPath, createPlaceholder }\n"
  },
  {
    "path": "test/cjs.test.js",
    "content": "import src from '../lib'\nimport cjs from '../lib/cjs'\n\ndescribe('CJS', () => {\n  it('should export loader', () => {\n    expect(cjs).toEqual(src)\n  })\n\n  it('should export \"raw\" flag', () => {\n    expect(cjs.raw).toEqual(true)\n  })\n})\n"
  },
  {
    "path": "test/jimp/build/__snapshots__/test.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`disable 1`] = `\n{\n  \"default\": {\n    \"images\": [\n      {\n        \"height\": 100,\n        \"path\": \"foobar/82e6d197b5ce433a-100.jpg\",\n        \"width\": 100,\n      },\n    ],\n    \"src\": \"foobar/82e6d197b5ce433a-100.jpg\",\n    \"srcSet\": \"foobar/82e6d197b5ce433a-100.jpg\",\n    \"toString\": [Function],\n  },\n}\n`;\n\nexports[`doesn't emit file 1`] = `\n{\n  \"default\": {\n    \"height\": 225,\n    \"images\": [\n      {\n        \"height\": 225,\n        \"path\": \"foobar/445db0be601e84d6-250.jpg\",\n        \"width\": 250,\n      },\n    ],\n    \"src\": \"foobar/445db0be601e84d6-250.jpg\",\n    \"srcSet\": \"foobar/445db0be601e84d6-250.jpg 250w\",\n    \"toString\": [Function],\n    \"width\": 250,\n  },\n}\n`;\n\nexports[`multiple sizes 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"foobar/c869fe04ebafd01d-500.jpg 500w,foobar/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`output first resized image height & width 1`] = `\n{\n  \"default\": {\n    \"height\": 450,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n    ],\n    \"src\": \"foobar/c869fe04ebafd01d-500.jpg\",\n    \"srcSet\": \"foobar/c869fe04ebafd01d-500.jpg 500w\",\n    \"toString\": [Function],\n    \"width\": 500,\n  },\n}\n`;\n\nexports[`output should be in outputPath dir 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/img/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"foobar/img/76a7b8dd076af418-750.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"foobar/img/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"foobar/img/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"foobar/img/c869fe04ebafd01d-500.jpg 500w,foobar/img/76a7b8dd076af418-750.jpg 750w,foobar/img/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`output should be relative to context 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/test/c869fe04ebafd01d-500x450.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"foobar/test/76a7b8dd076af418-750x675.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"foobar/test/076d6ca8665b1d94-1000x900.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"foobar/test/076d6ca8665b1d94-1000x900.jpg\",\n    \"srcSet\": \"foobar/test/c869fe04ebafd01d-500x450.jpg 500w,foobar/test/76a7b8dd076af418-750x675.jpg 750w,foobar/test/076d6ca8665b1d94-1000x900.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`override min and max with size 1`] = `\n{\n  \"default\": {\n    \"height\": 90,\n    \"images\": [\n      {\n        \"height\": 90,\n        \"path\": \"foobar/f7443232972a8934-100.jpg\",\n        \"width\": 100,\n      },\n    ],\n    \"src\": \"foobar/f7443232972a8934-100.jpg\",\n    \"srcSet\": \"foobar/f7443232972a8934-100.jpg 100w\",\n    \"toString\": [Function],\n    \"width\": 100,\n  },\n}\n`;\n\nexports[`override min and max with sizes 1`] = `\n{\n  \"default\": {\n    \"height\": 180,\n    \"images\": [\n      {\n        \"height\": 90,\n        \"path\": \"foobar/f7443232972a8934-100.jpg\",\n        \"width\": 100,\n      },\n      {\n        \"height\": 180,\n        \"path\": \"foobar/974831fb3cc31ef7-200.jpg\",\n        \"width\": 200,\n      },\n    ],\n    \"src\": \"foobar/974831fb3cc31ef7-200.jpg\",\n    \"srcSet\": \"foobar/f7443232972a8934-100.jpg 100w,foobar/974831fb3cc31ef7-200.jpg 200w\",\n    \"toString\": [Function],\n    \"width\": 200,\n  },\n}\n`;\n\nexports[`parses json notation 1`] = `\n{\n  \"default\": {\n    \"height\": 180,\n    \"images\": [\n      {\n        \"height\": 45,\n        \"path\": \"foobar/843b57924a32e9ff-50.jpg\",\n        \"width\": 50,\n      },\n      {\n        \"height\": 90,\n        \"path\": \"foobar/f7443232972a8934-100.jpg\",\n        \"width\": 100,\n      },\n      {\n        \"height\": 180,\n        \"path\": \"foobar/974831fb3cc31ef7-200.jpg\",\n        \"width\": 200,\n      },\n    ],\n    \"src\": \"foobar/974831fb3cc31ef7-200.jpg\",\n    \"srcSet\": \"foobar/843b57924a32e9ff-50.jpg 50w,foobar/f7443232972a8934-100.jpg 100w,foobar/974831fb3cc31ef7-200.jpg 200w\",\n    \"toString\": [Function],\n    \"width\": 200,\n  },\n}\n`;\n\nexports[`png 1`] = `\n{\n  \"default\": {\n    \"height\": 595,\n    \"images\": [\n      {\n        \"height\": 580,\n        \"path\": \"foobar/f64253666cd2fe13-500.png\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 595,\n        \"path\": \"foobar/a44dff6b028c41f7-513.png\",\n        \"width\": 513,\n      },\n    ],\n    \"src\": \"foobar/a44dff6b028c41f7-513.png\",\n    \"srcSet\": \"foobar/f64253666cd2fe13-500.png 500w,foobar/a44dff6b028c41f7-513.png 513w\",\n    \"toString\": [Function],\n    \"width\": 513,\n  },\n}\n`;\n\nexports[`png to jpeg with background color 1`] = `\n{\n  \"default\": {\n    \"height\": 595,\n    \"images\": [\n      {\n        \"height\": 580,\n        \"path\": \"foobar/940321b5b2ba9532-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 595,\n        \"path\": \"foobar/07deb4eb4e131586-513.jpg\",\n        \"width\": 513,\n      },\n    ],\n    \"src\": \"foobar/07deb4eb4e131586-513.jpg\",\n    \"srcSet\": \"foobar/940321b5b2ba9532-500.jpg 500w,foobar/07deb4eb4e131586-513.jpg 513w\",\n    \"toString\": [Function],\n    \"width\": 513,\n  },\n}\n`;\n\nexports[`png to jpeg with background color 2`] = `\n{\n  \"default\": {\n    \"height\": 595,\n    \"images\": [\n      {\n        \"height\": 580,\n        \"path\": \"foobar/940321b5b2ba9532-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 595,\n        \"path\": \"foobar/07deb4eb4e131586-513.jpg\",\n        \"width\": 513,\n      },\n    ],\n    \"src\": \"foobar/07deb4eb4e131586-513.jpg\",\n    \"srcSet\": \"foobar/940321b5b2ba9532-500.jpg 500w,foobar/07deb4eb4e131586-513.jpg 513w\",\n    \"toString\": [Function],\n    \"width\": 513,\n  },\n}\n`;\n\nexports[`public path should replace global publicPath 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"public/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"public/76a7b8dd076af418-750.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"public/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"public/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"public/c869fe04ebafd01d-500.jpg 500w,public/76a7b8dd076af418-750.jpg 750w,public/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`public path should replace global publicPath absolute 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"/public/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"/public/76a7b8dd076af418-750.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"/public/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"/public/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"/public/c869fe04ebafd01d-500.jpg 500w,/public/76a7b8dd076af418-750.jpg 750w,/public/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`single size 1`] = `\n{\n  \"default\": {\n    \"height\": 450,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n    ],\n    \"src\": \"foobar/c869fe04ebafd01d-500.jpg\",\n    \"srcSet\": \"foobar/c869fe04ebafd01d-500.jpg 500w\",\n    \"toString\": [Function],\n    \"width\": 500,\n  },\n}\n`;\n\nexports[`with min and max sizes 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"foobar/76a7b8dd076af418-750.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"foobar/c869fe04ebafd01d-500.jpg 500w,foobar/76a7b8dd076af418-750.jpg 750w,foobar/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`with min and max sizes options 1`] = `\n{\n  \"default\": {\n    \"height\": 270,\n    \"images\": [\n      {\n        \"height\": 90,\n        \"path\": \"foobar/f7443232972a8934-100.jpg\",\n        \"width\": 100,\n      },\n      {\n        \"height\": 150,\n        \"path\": \"foobar/fb90951ca5da54c2-167.jpg\",\n        \"width\": 167,\n      },\n      {\n        \"height\": 211,\n        \"path\": \"foobar/fe6debad717249e9-234.jpg\",\n        \"width\": 234,\n      },\n      {\n        \"height\": 270,\n        \"path\": \"foobar/a990e2f8f763852a-300.jpg\",\n        \"width\": 300,\n      },\n    ],\n    \"src\": \"foobar/a990e2f8f763852a-300.jpg\",\n    \"srcSet\": \"foobar/f7443232972a8934-100.jpg 100w,foobar/fb90951ca5da54c2-167.jpg 167w,foobar/fe6debad717249e9-234.jpg 234w,foobar/a990e2f8f763852a-300.jpg 300w\",\n    \"toString\": [Function],\n    \"width\": 300,\n  },\n}\n`;\n\nexports[`with min and max sizes, and default steps 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"foobar/76a7b8dd076af418-750.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"foobar/c869fe04ebafd01d-500.jpg 500w,foobar/76a7b8dd076af418-750.jpg 750w,foobar/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`with placeholder image 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"foobar/76a7b8dd076af418-750.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"placeholder\": \"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx4BBQUFBwYHDggIDh4UERQeHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHv/AABEIACQAKAMBEQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AMnW/wBnaO4v4hpWo2tjZFv3reWxkRfRVzhvqSMe9bukuhnzO1mUm/ZomXVIZF8Uxy2YbMiyWZD47AYYg/pU+yGpF3XP2aNIuYi+na7cWlwe5hDRn/gORj86p0kHMzl7j9nPxZo9za32karY6lJGcyxMDCf+A5JB49cVlUoOUWjajW9nNS7HfeDPg9ObqK+8VyQsiHcLKE5DEf327j2HX1rCjgrO8zvxGZuS5aa+Z7dPNBa20tzcyRwwRKXkkfhVUDJJ9K9A8g8i8TftB+D9MuXg0u1utXZODKn7mIn2LfMf++cVm6iQ1FkvgT48eG/EWsRaXe2E+kTXB2xSPKJIi3oTgEZ9cYoVVdQcWeqQ3thcY+z3dtNuO0bJFbJ9OD1rS6ESFAeOfoaAPFPFvw98dalod43iv4hNNYW8DyPHH+7jbaCfnwACOOpzWMozfUtOK6HzWbIu/wC7IlQAH5PmyOnPpWG6L2Z33w1+Geta217cBlsJ9PmEWy5Uq27GfTjginKN0JSsz1v4S/DS78N+NINakuIfJSNmuQX3GSYhh8vA4AYHPrmqpwfMmwlJWPbAVfkZA7iuoyM+70+0u7SW2u4FninUpJDJ8yOD1BB4NTuB5/rHwltZ/F9j4h0pbKxNsQJIBbDy3VfukKMYYcfp6VDp63Q0+5sa5pOssrxxqmbniS4jjw+4Dgkg5HAxntUzTYIs/C7Tdfg8O+X4ilea4S5kEczABpI88EgdO/4VVNO2o5W6HXeQVyQcitCSVVGc5NMBr5DcE1LASJiwYtzzTQErcKBng0wAdM9z1oA//9k=\",\n    \"src\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"foobar/c869fe04ebafd01d-500.jpg 500w,foobar/76a7b8dd076af418-750.jpg 750w,foobar/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n\nexports[`with size defined in webpack.config.js 1`] = `\n{\n  \"default\": {\n    \"height\": 900,\n    \"images\": [\n      {\n        \"height\": 450,\n        \"path\": \"foobar/c869fe04ebafd01d-500.jpg\",\n        \"width\": 500,\n      },\n      {\n        \"height\": 675,\n        \"path\": \"foobar/76a7b8dd076af418-750.jpg\",\n        \"width\": 750,\n      },\n      {\n        \"height\": 900,\n        \"path\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n        \"width\": 1000,\n      },\n    ],\n    \"src\": \"foobar/076d6ca8665b1d94-1000.jpg\",\n    \"srcSet\": \"foobar/c869fe04ebafd01d-500.jpg 500w,foobar/76a7b8dd076af418-750.jpg 750w,foobar/076d6ca8665b1d94-1000.jpg 1000w\",\n    \"toString\": [Function],\n    \"width\": 1000,\n  },\n}\n`;\n"
  },
  {
    "path": "test/jimp/index.js",
    "content": "test('multiple sizes', () => {\n  const multi = require('../cat-1000.jpg?sizes[]=500&sizes[]=2000')\n  expect(multi).toMatchSnapshot()\n  expect(multi.default.toString()).toBe(multi.default.src)\n})\n\ntest('parses json notation', () => {\n  const multi = require('../cat-1000.jpg?{sizes:[50,100,200]}')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('single size', () => {\n  const single = require('../cat-1000.jpg?size=500')\n  expect(single).toMatchSnapshot()\n})\n\ntest('with size defined in webpack.config.js', () => {\n  const multi = require('../cat-1000.jpg')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('disable', () => {\n  const multi = require('../cat-1000.jpg?disable')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('output should be relative to context', () => {\n  const multi = require('../cat-1000.jpg?name=[path][hash]-[width]x[height].[ext]&context=./')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('output should be in outputPath dir', () => {\n  const multi = require('../cat-1000.jpg?outputPath=img/')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('public path should replace global publicPath', () => {\n  const multi = require('../cat-1000.jpg?outputPath=img/&publicPath=public/')\n  expect(multi).toMatchSnapshot()\n})\ntest('public path should replace global publicPath absolute', () => {\n  const multi = require('../cat-1000.jpg?outputPath=/img2/&publicPath=/public/')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('with placeholder image', () => {\n  const output = require('../cat-1000.jpg?placeholder=true')\n  expect(output).toMatchSnapshot()\n})\n\ntest('output first resized image height & width', () => {\n  const output = require('../cat-1000.jpg?size=500')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png', () => {\n  const output = require('../cat-transparent.png')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png to jpeg with background color', () => {\n  const output = require('../cat-transparent.png?background=0xFF0000FF&format=jpg')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png to jpeg with background color', () => {\n  const output = require('../cat-transparent.png?background=0xFF0000FF&format=jpg')\n  expect(output).toMatchSnapshot()\n})\n\ntest('with min and max sizes', () => {\n  const output = require('../cat-1000.jpg?min=600&max=800&steps=3')\n  expect(output).toMatchSnapshot()\n})\n\ntest('with min and max sizes, and default steps', () => {\n  const output = require('../cat-1000.jpg?min=500&max=1000')\n  expect(output).toMatchSnapshot()\n})\n\ntest('with min and max sizes options', () => {\n  const output = require('../cat-1000.jpg?minmax')\n  expect(output).toMatchSnapshot()\n})\n\ntest('override min and max with sizes', () => {\n  const output = require('../cat-1000.jpg?minmax&sizes[]=100&sizes[]=200')\n  expect(output).toMatchSnapshot()\n})\n\ntest('override min and max with size', () => {\n  const output = require('../cat-1000.jpg?minmax&size=100')\n  expect(output).toMatchSnapshot()\n})\n\ntest(\"doesn't emit file\", () => {\n  const multi = require('../cat-1000.jpg?emitFile=false&sizes[]=250')\n  expect(multi).toMatchSnapshot()\n})\n"
  },
  {
    "path": "test/jimp/webpack.config.js",
    "content": "const path = require('path')\n\nmodule.exports = {\n  mode: 'development',\n  entry: path.resolve(__dirname, 'index'),\n  module: {\n    rules: [\n      // This rule will be matched when the resourceQuery contains `minmax`, e.g. `cat-1000.jpg?minmax`\n      {\n        test: /\\.(png|jpg)$/,\n        resourceQuery: /minmax/,\n        loader: require.resolve('../../lib/index'),\n        options: {\n          min: 100,\n          max: 300,\n          esModule: true,\n          adapter: require('../../jimp'),\n        },\n        type: 'javascript/auto',\n      },\n      {\n        test: /\\.(png|jpg)$/,\n        loader: require.resolve('../../lib/index'),\n        options: {\n          sizes: [500, 750, 1000],\n          esModule: true,\n          adapter: require('../../jimp'),\n        },\n        type: 'javascript/auto',\n      },\n    ],\n  },\n  output: {\n    path: path.resolve(__dirname, 'build'),\n    publicPath: 'foobar/',\n    filename: 'test.js',\n  },\n  target: 'node',\n}\n"
  },
  {
    "path": "test/sharp/build/__snapshots__/test.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Works with the cache 1`] = `\n{\n  \"height\": 451,\n  \"images\": [\n    {\n      \"height\": 451,\n      \"path\": \"foobar/ab790bc248982116-501.jpg\",\n      \"width\": 501,\n    },\n  ],\n  \"src\": \"foobar/ab790bc248982116-501.jpg\",\n  \"srcSet\": \"foobar/ab790bc248982116-501.jpg 501w\",\n  \"toString\": [Function],\n  \"width\": 501,\n}\n`;\n\nexports[`creates jpeg extension 1`] = `\n{\n  \"height\": 395,\n  \"images\": [\n    {\n      \"height\": 395,\n      \"path\": \"foobar/f93d9af4a72634bc-439.jpeg\",\n      \"width\": 439,\n    },\n  ],\n  \"src\": \"foobar/f93d9af4a72634bc-439.jpeg\",\n  \"srcSet\": \"foobar/f93d9af4a72634bc-439.jpeg 439w\",\n  \"toString\": [Function],\n  \"width\": 439,\n}\n`;\n\nexports[`disable 1`] = `\n{\n  \"images\": [\n    {\n      \"height\": 100,\n      \"path\": \"foobar/82e6d197b5ce433a-100.jpg\",\n      \"width\": 100,\n    },\n  ],\n  \"src\": \"foobar/82e6d197b5ce433a-100.jpg\",\n  \"srcSet\": \"foobar/82e6d197b5ce433a-100.jpg\",\n  \"toString\": [Function],\n}\n`;\n\nexports[`doesn't emit file 1`] = `\n{\n  \"height\": 225,\n  \"images\": [\n    {\n      \"height\": 225,\n      \"path\": \"foobar/0a229ed85b2f5618-250.jpg\",\n      \"width\": 250,\n    },\n  ],\n  \"src\": \"foobar/0a229ed85b2f5618-250.jpg\",\n  \"srcSet\": \"foobar/0a229ed85b2f5618-250.jpg 250w\",\n  \"toString\": [Function],\n  \"width\": 250,\n}\n`;\n\nexports[`hash lenght output should be relative to context 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/test/282d046d-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/test/b8e60128-750.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/test/3cf3c375-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/test/3cf3c375-1000.jpg\",\n  \"srcSet\": \"foobar/test/282d046d-500.jpg 500w,foobar/test/b8e60128-750.jpg 750w,foobar/test/3cf3c375-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`jpg to webp 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/8593c1f9da542c50-500.webp\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/72befca36bd004a7-750.webp\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/c66204d304cfe4fd-1000.webp\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/c66204d304cfe4fd-1000.webp\",\n  \"srcSet\": \"foobar/8593c1f9da542c50-500.webp 500w,foobar/72befca36bd004a7-750.webp 750w,foobar/c66204d304cfe4fd-1000.webp 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`multiple sizes 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/3cf3c37514578847-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/3cf3c37514578847-1000.jpg\",\n  \"srcSet\": \"foobar/282d046d550fa19c-500.jpg 500w,foobar/3cf3c37514578847-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`output first resized image height & width 1`] = `\n{\n  \"height\": 450,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n  ],\n  \"src\": \"foobar/282d046d550fa19c-500.jpg\",\n  \"srcSet\": \"foobar/282d046d550fa19c-500.jpg 500w\",\n  \"toString\": [Function],\n  \"width\": 500,\n}\n`;\n\nexports[`output should be in outputPath dir 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/img/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/img/b8e6012830c98919-750.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/img/3cf3c37514578847-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/img/3cf3c37514578847-1000.jpg\",\n  \"srcSet\": \"foobar/img/282d046d550fa19c-500.jpg 500w,foobar/img/b8e6012830c98919-750.jpg 750w,foobar/img/3cf3c37514578847-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`output should be relative to context 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/test/282d046d550fa19c-500x450.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/test/b8e6012830c98919-750x675.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/test/3cf3c37514578847-1000x900.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/test/3cf3c37514578847-1000x900.jpg\",\n  \"srcSet\": \"foobar/test/282d046d550fa19c-500x450.jpg 500w,foobar/test/b8e6012830c98919-750x675.jpg 750w,foobar/test/3cf3c37514578847-1000x900.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`override min and max with size 1`] = `\n{\n  \"height\": 90,\n  \"images\": [\n    {\n      \"height\": 90,\n      \"path\": \"foobar/661fbbbdbe7372a2-100.jpg\",\n      \"width\": 100,\n    },\n  ],\n  \"src\": \"foobar/661fbbbdbe7372a2-100.jpg\",\n  \"srcSet\": \"foobar/661fbbbdbe7372a2-100.jpg 100w\",\n  \"toString\": [Function],\n  \"width\": 100,\n}\n`;\n\nexports[`override min and max with sizes 1`] = `\n{\n  \"height\": 180,\n  \"images\": [\n    {\n      \"height\": 90,\n      \"path\": \"foobar/661fbbbdbe7372a2-100.jpg\",\n      \"width\": 100,\n    },\n    {\n      \"height\": 180,\n      \"path\": \"foobar/daae2e5f7f65b269-200.jpg\",\n      \"width\": 200,\n    },\n  ],\n  \"src\": \"foobar/daae2e5f7f65b269-200.jpg\",\n  \"srcSet\": \"foobar/661fbbbdbe7372a2-100.jpg 100w,foobar/daae2e5f7f65b269-200.jpg 200w\",\n  \"toString\": [Function],\n  \"width\": 200,\n}\n`;\n\nexports[`parses json notation 1`] = `\n{\n  \"height\": 180,\n  \"images\": [\n    {\n      \"height\": 45,\n      \"path\": \"foobar/b58d8935f3e689e3-50.webp\",\n      \"width\": 50,\n    },\n    {\n      \"height\": 90,\n      \"path\": \"foobar/fffbb70a2c269cf1-100.webp\",\n      \"width\": 100,\n    },\n    {\n      \"height\": 180,\n      \"path\": \"foobar/701bf549670b5294-200.webp\",\n      \"width\": 200,\n    },\n  ],\n  \"src\": \"foobar/701bf549670b5294-200.webp\",\n  \"srcSet\": \"foobar/b58d8935f3e689e3-50.webp 50w,foobar/fffbb70a2c269cf1-100.webp 100w,foobar/701bf549670b5294-200.webp 200w\",\n  \"toString\": [Function],\n  \"width\": 200,\n}\n`;\n\nexports[`png 1`] = `\n{\n  \"height\": 595,\n  \"images\": [\n    {\n      \"height\": 580,\n      \"path\": \"foobar/ed6170e9b0b0edf0-500.png\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 595,\n      \"path\": \"foobar/418c98c2d061efc6-513.png\",\n      \"width\": 513,\n    },\n  ],\n  \"src\": \"foobar/418c98c2d061efc6-513.png\",\n  \"srcSet\": \"foobar/ed6170e9b0b0edf0-500.png 500w,foobar/418c98c2d061efc6-513.png 513w\",\n  \"toString\": [Function],\n  \"width\": 513,\n}\n`;\n\nexports[`png to avif 1`] = `\n{\n  \"height\": 595,\n  \"images\": [\n    {\n      \"height\": 595,\n      \"path\": \"foobar/54f4e72270566ed5-513.avif\",\n      \"width\": 513,\n    },\n  ],\n  \"src\": \"foobar/54f4e72270566ed5-513.avif\",\n  \"srcSet\": \"foobar/54f4e72270566ed5-513.avif 513w\",\n  \"toString\": [Function],\n  \"width\": 513,\n}\n`;\n\nexports[`png to avif 2`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/99b6b84c23e8a9b4-500.avif\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/d0b22cf68e1f393a-750.avif\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/6f9cba284621e494-1000.avif\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/6f9cba284621e494-1000.avif\",\n  \"srcSet\": \"foobar/99b6b84c23e8a9b4-500.avif 500w,foobar/d0b22cf68e1f393a-750.avif 750w,foobar/6f9cba284621e494-1000.avif 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`png to jpeg with background color 1`] = `\n{\n  \"height\": 595,\n  \"images\": [\n    {\n      \"height\": 580,\n      \"path\": \"foobar/0be420cbedde023f-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 595,\n      \"path\": \"foobar/9e08ba9531804694-513.jpg\",\n      \"width\": 513,\n    },\n  ],\n  \"src\": \"foobar/9e08ba9531804694-513.jpg\",\n  \"srcSet\": \"foobar/0be420cbedde023f-500.jpg 500w,foobar/9e08ba9531804694-513.jpg 513w\",\n  \"toString\": [Function],\n  \"width\": 513,\n}\n`;\n\nexports[`png to webp with transparent background 1`] = `\n{\n  \"height\": 595,\n  \"images\": [\n    {\n      \"height\": 580,\n      \"path\": \"foobar/548d85cfef6a6c88-500.webp\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 595,\n      \"path\": \"foobar/924e13d10c98fb28-513.webp\",\n      \"width\": 513,\n    },\n  ],\n  \"src\": \"foobar/924e13d10c98fb28-513.webp\",\n  \"srcSet\": \"foobar/548d85cfef6a6c88-500.webp 500w,foobar/924e13d10c98fb28-513.webp 513w\",\n  \"toString\": [Function],\n  \"width\": 513,\n}\n`;\n\nexports[`preserves rotation 1`] = `\n{\n  \"height\": 554,\n  \"images\": [\n    {\n      \"height\": 554,\n      \"path\": \"foobar/eb9b881857272a9d-499.jpg\",\n      \"width\": 499,\n    },\n  ],\n  \"src\": \"foobar/eb9b881857272a9d-499.jpg\",\n  \"srcSet\": \"foobar/eb9b881857272a9d-499.jpg 499w\",\n  \"toString\": [Function],\n  \"width\": 499,\n}\n`;\n\nexports[`progressive image 1`] = `\n{\n  \"height\": 864,\n  \"images\": [\n    {\n      \"height\": 684,\n      \"path\": \"foobar/e971e26ec2eea1f1-760.jpg\",\n      \"width\": 760,\n    },\n    {\n      \"height\": 864,\n      \"path\": \"foobar/e5e8c73f5f931a48-960.jpg\",\n      \"width\": 960,\n    },\n  ],\n  \"src\": \"foobar/e5e8c73f5f931a48-960.jpg\",\n  \"srcSet\": \"foobar/e971e26ec2eea1f1-760.jpg 760w,foobar/e5e8c73f5f931a48-960.jpg 960w\",\n  \"toString\": [Function],\n  \"width\": 960,\n}\n`;\n\nexports[`public path should replace global publicPath 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"public/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"public/b8e6012830c98919-750.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"public/3cf3c37514578847-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"public/3cf3c37514578847-1000.jpg\",\n  \"srcSet\": \"public/282d046d550fa19c-500.jpg 500w,public/b8e6012830c98919-750.jpg 750w,public/3cf3c37514578847-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`rotates 90 1`] = `\n{\n  \"height\": 666,\n  \"images\": [\n    {\n      \"height\": 666,\n      \"path\": \"foobar/aa309fc022524f4b-599.jpg\",\n      \"width\": 599,\n    },\n  ],\n  \"src\": \"foobar/aa309fc022524f4b-599.jpg\",\n  \"srcSet\": \"foobar/aa309fc022524f4b-599.jpg 599w\",\n  \"toString\": [Function],\n  \"width\": 599,\n}\n`;\n\nexports[`single size 1`] = `\n{\n  \"height\": 450,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n  ],\n  \"src\": \"foobar/282d046d550fa19c-500.jpg\",\n  \"srcSet\": \"foobar/282d046d550fa19c-500.jpg 500w\",\n  \"toString\": [Function],\n  \"width\": 500,\n}\n`;\n\nexports[`with min and max sizes 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/b8e6012830c98919-750.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/3cf3c37514578847-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/3cf3c37514578847-1000.jpg\",\n  \"srcSet\": \"foobar/282d046d550fa19c-500.jpg 500w,foobar/b8e6012830c98919-750.jpg 750w,foobar/3cf3c37514578847-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`with min and max sizes options 1`] = `\n{\n  \"height\": 270,\n  \"images\": [\n    {\n      \"height\": 90,\n      \"path\": \"foobar/661fbbbdbe7372a2-100.jpg\",\n      \"width\": 100,\n    },\n    {\n      \"height\": 150,\n      \"path\": \"foobar/87ddc3296017abd7-167.jpg\",\n      \"width\": 167,\n    },\n    {\n      \"height\": 211,\n      \"path\": \"foobar/c792e1e8f501c416-234.jpg\",\n      \"width\": 234,\n    },\n    {\n      \"height\": 270,\n      \"path\": \"foobar/5de63dd31e93ce82-300.jpg\",\n      \"width\": 300,\n    },\n  ],\n  \"src\": \"foobar/5de63dd31e93ce82-300.jpg\",\n  \"srcSet\": \"foobar/661fbbbdbe7372a2-100.jpg 100w,foobar/87ddc3296017abd7-167.jpg 167w,foobar/c792e1e8f501c416-234.jpg 234w,foobar/5de63dd31e93ce82-300.jpg 300w\",\n  \"toString\": [Function],\n  \"width\": 300,\n}\n`;\n\nexports[`with min and max sizes, and default steps 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/b8e6012830c98919-750.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/3cf3c37514578847-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/3cf3c37514578847-1000.jpg\",\n  \"srcSet\": \"foobar/282d046d550fa19c-500.jpg 500w,foobar/b8e6012830c98919-750.jpg 750w,foobar/3cf3c37514578847-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`with placeholder image 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/b8e6012830c98919-750.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/3cf3c37514578847-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"placeholder\": \"data:image/jpeg;base64,/9j/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAkACgDASIAAhEBAxEB/8QAHAAAAgEFAQAAAAAAAAAAAAAAAAcGAQIDBAgF/8QALBAAAQMDAwIGAgIDAAAAAAAAAQIDBAAFEQYSIQcxCBMiQVFhFDJxgSNSgv/EABgBAAMBAQAAAAAAAAAAAAAAAAABAwIE/8QAHBEAAwEBAAMBAAAAAAAAAAAAAAECEQMEEjEi/9oADAMBAAIRAxEAPwDx734dA/cGU2i4Q4EIq/yqKFlxCfhKckKP2SMVpK8M8tN1YWjVMd6EFEuhyGpLmPYABRB++RXSrzrEaO7JkONtMMpK3HFcJQkDJJPsBSk1N4g9FWuQti2MTL0pPHms4aaJ+lK5P8gVdzK+k02RK+eGW1yGiu2agfiyOf2jhTZ/oHI/o1F3/DprKzSok+0XK3XVxs5eaJLB/wCSrIPHzim1oTrvpfUl4ZtUuDKs8iSdrLjriXGlK9klQA25+SMU02pMN7HkyY7u47RscSrJ+OD3ocRSNTdS00JHRnR2S5KZm6tWx5SCFfgsK3biP919sfQ7/NFPEoBGO/0aKUcOcLEivXyevWtpiT1b0/6h3WxyxqzqGXbfHjrcW00A02vakn14CQRx3Oa5qMMuHc2pLiAAco9QI7c/Fd6zLdDmQnYsxhMhmQkodZc9SFg9wR2NL689JIz+sIOorSiBAMdSQ6x+MPKcSn9SEpwAocd+OB8Vmo34SVYIjpn01vd8XMlNlMF+3Ppa8uQClW7bnGPbgim30i6aTdNa1YvLjzCY6W1LlDzN298hQASMD0jcDn+am19tV6UFoQhvdL4clNN4XuA9JJByOBjJ7Vs9LLfqBnTezUbi3ZKZLnlvqSlKnW8+klI7e4rKj9D9nhLwUr5HA9xiiqeQU5IORRXRpMyoGVE5NWuZSeCaKKGBayoqCyrBrMrhIGe9FFCAByM+570UUUwP/9k=\",\n  \"src\": \"foobar/3cf3c37514578847-1000.jpg\",\n  \"srcSet\": \"foobar/282d046d550fa19c-500.jpg 500w,foobar/b8e6012830c98919-750.jpg 750w,foobar/3cf3c37514578847-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n\nexports[`with placeholder image on image with size 1`] = `\n{\n  \"height\": 360,\n  \"images\": [\n    {\n      \"height\": 360,\n      \"path\": \"foobar/c985fe28cb56f01d-400.jpg\",\n      \"width\": 400,\n    },\n  ],\n  \"placeholder\": \"data:image/jpeg;base64,/9j/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAkACgDASIAAhEBAxEB/8QAHAAAAgEFAQAAAAAAAAAAAAAAAAcGAQIDBAgF/8QALBAAAQMDAwIGAgIDAAAAAAAAAQIDBAAFEQYSIQcxCBMiQVFhFDJxgSNSgv/EABgBAAMBAQAAAAAAAAAAAAAAAAABAwIE/8QAHBEAAwEBAAMBAAAAAAAAAAAAAAECEQMEEjEi/9oADAMBAAIRAxEAPwDx734dA/cGU2i4Q4EIq/yqKFlxCfhKckKP2SMVpK8M8tN1YWjVMd6EFEuhyGpLmPYABRB++RXSrzrEaO7JkONtMMpK3HFcJQkDJJPsBSk1N4g9FWuQti2MTL0pPHms4aaJ+lK5P8gVdzK+k02RK+eGW1yGiu2agfiyOf2jhTZ/oHI/o1F3/DprKzSok+0XK3XVxs5eaJLB/wCSrIPHzim1oTrvpfUl4ZtUuDKs8iSdrLjriXGlK9klQA25+SMU02pMN7HkyY7u47RscSrJ+OD3ocRSNTdS00JHRnR2S5KZm6tWx5SCFfgsK3biP919sfQ7/NFPEoBGO/0aKUcOcLEivXyevWtpiT1b0/6h3WxyxqzqGXbfHjrcW00A02vakn14CQRx3Oa5qMMuHc2pLiAAco9QI7c/Fd6zLdDmQnYsxhMhmQkodZc9SFg9wR2NL689JIz+sIOorSiBAMdSQ6x+MPKcSn9SEpwAocd+OB8Vmo34SVYIjpn01vd8XMlNlMF+3Ppa8uQClW7bnGPbgim30i6aTdNa1YvLjzCY6W1LlDzN298hQASMD0jcDn+am19tV6UFoQhvdL4clNN4XuA9JJByOBjJ7Vs9LLfqBnTezUbi3ZKZLnlvqSlKnW8+klI7e4rKj9D9nhLwUr5HA9xiiqeQU5IORRXRpMyoGVE5NWuZSeCaKKGBayoqCyrBrMrhIGe9FFCAByM+570UUUwP/9k=\",\n  \"src\": \"foobar/c985fe28cb56f01d-400.jpg\",\n  \"srcSet\": \"foobar/c985fe28cb56f01d-400.jpg 400w\",\n  \"toString\": [Function],\n  \"width\": 400,\n}\n`;\n\nexports[`with size defined in webpack.config.js 1`] = `\n{\n  \"height\": 900,\n  \"images\": [\n    {\n      \"height\": 450,\n      \"path\": \"foobar/282d046d550fa19c-500.jpg\",\n      \"width\": 500,\n    },\n    {\n      \"height\": 675,\n      \"path\": \"foobar/b8e6012830c98919-750.jpg\",\n      \"width\": 750,\n    },\n    {\n      \"height\": 900,\n      \"path\": \"foobar/3cf3c37514578847-1000.jpg\",\n      \"width\": 1000,\n    },\n  ],\n  \"src\": \"foobar/3cf3c37514578847-1000.jpg\",\n  \"srcSet\": \"foobar/282d046d550fa19c-500.jpg 500w,foobar/b8e6012830c98919-750.jpg 750w,foobar/3cf3c37514578847-1000.jpg 1000w\",\n  \"toString\": [Function],\n  \"width\": 1000,\n}\n`;\n"
  },
  {
    "path": "test/sharp/index.js",
    "content": "test('Works with the cache', () => {\n  const output = require('../cat-1000.jpg?size=501,cacheDirectory')\n  expect(output).toMatchSnapshot()\n})\n\ntest('creates jpeg extension', () => {\n  const output = require('../cat-1000copy.jpeg?size=439')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png to avif', () => {\n  const output = require('../cat-transparent.png?format=avif&size=777')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png to avif', () => {\n  const output = require('../cat-1000.jpg?format=avif')\n  expect(output).toMatchSnapshot()\n})\n\ntest('preserves rotation', () => {\n  const single = require('../cat-rotated-1000.jpg?size=499')\n  expect(single).toMatchSnapshot()\n})\n\ntest('rotates 90', () => {\n  const single = require('../cat-1000.jpg?size=599&rotate=90')\n  expect(single).toMatchSnapshot()\n})\n\ntest('progressive image', () => {\n  const multi = require('../cat-1000.jpg?sizes[]=760&sizes[]=960&progressive=true')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('multiple sizes', () => {\n  const multi = require('../cat-1000.jpg?sizes[]=500&sizes[]=2000')\n  expect(multi).toMatchSnapshot()\n  expect(multi.toString()).toBe(multi.src)\n})\n\ntest('parses json notation', () => {\n  const multi = require('../cat-1000.jpg?{sizes:[50,100,200], format: \"webp\"}')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('single size', () => {\n  const single = require('../cat-1000.jpg?size=500')\n  expect(single).toMatchSnapshot()\n})\n\ntest('with size defined in webpack.config.js', () => {\n  const multi = require('../cat-1000.jpg')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('disable', () => {\n  const multi = require('../cat-1000.jpg?disable')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('output should be relative to context', () => {\n  const multi = require('../cat-1000.jpg?name=[path][hash]-[width]x[height].[ext]&context=./')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('hash lenght output should be relative to context', () => {\n  const multi = require('../cat-1000.jpg?name=[path][contenthash:8]-[width].[ext]&context=./')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('output should be in outputPath dir', () => {\n  const multi = require('../cat-1000.jpg?outputPath=img/')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('public path should replace global publicPath', () => {\n  const multi = require('../cat-1000.jpg?outputPath=img/&publicPath=public/')\n  expect(multi).toMatchSnapshot()\n})\n\ntest('with placeholder image', () => {\n  const output = require('../cat-1000.jpg?placeholder=true')\n  expect(output).toMatchSnapshot()\n})\ntest('with placeholder image on image with size', () => {\n  const output = require('../cat-1000.jpg?size=400&placeholder=true')\n  expect(output).toMatchSnapshot()\n})\n\ntest('output first resized image height & width', () => {\n  const output = require('../cat-1000.jpg?size=500')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png', () => {\n  const output = require('../cat-transparent.png')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png to jpeg with background color', () => {\n  const output = require('../cat-transparent.png?background=%23FF0000&format=jpg')\n  expect(output).toMatchSnapshot()\n})\n\ntest('with min and max sizes', () => {\n  const output = require('../cat-1000.jpg?min=600&max=800&steps=3')\n  expect(output).toMatchSnapshot()\n})\n\ntest('with min and max sizes, and default steps', () => {\n  const output = require('../cat-1000.jpg?min=500&max=1000')\n  expect(output).toMatchSnapshot()\n})\n\ntest('with min and max sizes options', () => {\n  const output = require('../cat-1000.jpg?minmax')\n  expect(output).toMatchSnapshot()\n})\n\ntest('override min and max with sizes', () => {\n  const output = require('../cat-1000.jpg?minmax&sizes[]=100&sizes[]=200')\n  expect(output).toMatchSnapshot()\n})\n\ntest('override min and max with size', () => {\n  const output = require('../cat-1000.jpg?minmax&size=100')\n  expect(output).toMatchSnapshot()\n})\n\ntest('jpg to webp', () => {\n  const output = require('../cat-1000.jpg?format=webp')\n  expect(output).toMatchSnapshot()\n})\n\ntest('png to webp with transparent background', () => {\n  const output = require('../cat-transparent.png?format=webp')\n  expect(output).toMatchSnapshot()\n})\n\ntest(\"doesn't emit file\", () => {\n  const multi = require('../cat-1000.jpg?emitFile=false&sizes[]=250')\n  expect(multi).toMatchSnapshot()\n})\n"
  },
  {
    "path": "test/sharp/webpack.config.js",
    "content": "const path = require('path')\n\nmodule.exports = {\n  mode: 'development',\n  entry: path.resolve(__dirname, 'index'),\n  module: {\n    rules: [\n      // This rule will be matched when the resourceQuery contains `minmax`, e.g. `cat-1000.jpg?minmax`\n      {\n        test: /\\.(png|jpe?g)$/,\n        resourceQuery: /minmax/,\n        use: [\n          {\n            loader: require.resolve('../../lib/index'),\n            options: {\n              min: 100,\n              max: 300,\n            },\n          },\n        ],\n        type: 'javascript/auto',\n      },\n      {\n        test: /\\.(png|jpe?g)$/,\n        use: [\n          {\n            loader: require.resolve('../../lib/index'),\n            options: {\n              sizes: [500, 750, 1000],\n            },\n          },\n        ],\n        type: 'javascript/auto',\n      },\n    ],\n  },\n  output: {\n    path: path.resolve(__dirname, 'build'),\n    publicPath: 'foobar/',\n    filename: 'test.js',\n  },\n  target: 'node',\n}\n"
  },
  {
    "path": "test/utils.test.js",
    "content": "import { getOutputAndPublicPath } from '../lib/utils'\n\ndescribe('Utils package', () => {\n  it('should create both paths respecting absolutes', () => {\n    const { outputPath, publicPath } = getOutputAndPublicPath('file.png', {\n      outputPath: '/dist/img/',\n      publicPath: '/public',\n    })\n    expect(outputPath).toBe('/dist/img/file.png')\n    expect(publicPath).toBe('\"/public/file.png\"')\n  })\n\n  it('should create both paths ', () => {\n    const { outputPath, publicPath } = getOutputAndPublicPath('file.png', {\n      outputPath: 'dist/img/',\n      publicPath: 'public/',\n    })\n    expect(outputPath).toBe('dist/img/file.png')\n    expect(publicPath).toBe('\"public/file.png\"')\n  })\n\n  it('https:// slashes are kept on public path', () => {\n    const { outputPath, publicPath } = getOutputAndPublicPath('file.png', {\n      outputPath: 'dist/img/',\n      publicPath: 'https://example.com/public/',\n    })\n    expect(publicPath).toBe('\"https://example.com/public/file.png\"')\n  })\n})\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig.json to read more about this file */\n    // node 10 https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping\n    \"target\": \"es2018\" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,\n    \"lib\": [\"es2018\"],\n    \"module\": \"commonjs\" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,\n    \"outDir\": \"lib\",\n    \"allowJs\": true,\n    /* Strict Type-Checking Options */\n    \"strict\": true /* Enable all strict type-checking options. */,\n    \"moduleResolution\": \"node\",\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    /* Additional Checks */\n    \"resolveJsonModule\": true\n  },\n  \"include\": [\"src/**/*\"],\n}\n"
  }
]