File obs-service-node_modules.obscpio of Package obs-service-node_modules

07070100000000000041ED00000000000000000000000265B7C7A000000000000000000000000000000000000000000000002100000000obs-service-node_modules/.github07070100000001000041ED00000000000000000000000265B7C7A000000000000000000000000000000000000000000000002B00000000obs-service-node_modules/.github/workflows07070100000002000081A400000000000000000000000165B7C7A0000001D0000000000000000000000000000000000000004100000000obs-service-node_modules/.github/workflows/integration_tests.yml---
name: Integration tests

on:
  push:
    branches:
      - "main"
  pull_request:

jobs:
  integration_tests:
    name: Run the integration tests
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
      - uses: Gr1N/setup-poetry@v7
      - uses: actions/cache@v2
        with:
          path: ~/.tox
          key: poetry-${{ hashFiles('poetry.lock') }}

      - run: 'poetry run pytest -vv -n auto'
07070100000003000081A400000000000000000000000165B7C7A00000042F000000000000000000000000000000000000002100000000obs-service-node_modules/COPYINGMIT License

Copyright (c) 2020-2021, SUSE LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
07070100000004000081A400000000000000000000000165B7C7A000000A49000000000000000000000000000000000000002300000000obs-service-node_modules/README.mdBuild RPM packages using node modules offline
=============================================

By default, npm download dependencies from `registry.npmjs.org` and
hides the details in the `node_modules` subdirectory. Its job is to
resolve version dependencies and provide it to Node application in such
a way that it satisfied the dependencies and does not conflict with
other dependencies. To be able to build and rebuild a package from
sources, we will need to be able to install and possibly update these
dependencies in a networkless environment like OBS.

When `npm` installs dependencies, it will create a `package-lock.json`
that will contain the entire list of packages that can possible exist in
the `node_modules` directory structure.

The purpose of this tool is to parse `package-lock.json` and prepare all
externally download sources for use by `npm` during `rpmbuild`.

## runtime requirements
`npm 7+` is required to produce `package-lock.json` with
`lockfileVersion:2`

## As OBS service

- Get `package-lock.json` with `localfileVersion: 2`. For example,
  - `npm install --package-lock-only --legacy-peer-deps --ignore-scripts`
    with npm 7+
  - `--legacy-peer-deps` is required to fetch peer dependencies from remote
    locally so they are available during peer resolution in the VM. Without
    this you may get additional warnings during install.
- Make sure to put the `package-lock.json` next to the spec file and
  remove it from the sources. Sources should only have `package.json`,
  even if they ship a compatible `package-lock.json`
- Add the following line to the spec file:
   ```
   %include  %{_sourcedir}/node_modules.spec.inc
   ```
- Create file `_service` with the following content:
  ```
  <services>
    <service name="node_modules" mode="manual">
      <param name="cpio">node_modules.obscpio</param>
      <param name="output">node_modules.spec.inc</param>
      <param name="source-offset">10000</param>
    </service>
  </services>
  ```
- `osc service manualrun`
  - this generates the NPM dependency archive along with its source URLs
- `osc add node_modules.obscpio`
- `osc add node_modules.spec.inc`
- `osc commit`

### Example

  ```
  Source10:       package-lock.json
  Source11:       node_modules.spec.inc
  %include        %{_sourcedir}/node_modules.spec.inc
  BuildRequires:  local-npm-registry

  [...]

  %prep
  %setup
  local-npm-registry %{_sourcedir} install --also=dev

  [...]

  %build
  npm run build
  ```

### In Practice
https://build.opensuse.org/package/show/openSUSE:Factory/cockpit-podman

### External Resources
https://github.com/openSUSE/npm-localhost-proxy
07070100000005000081A400000000000000000000000165B7C7A000000088000000000000000000000000000000000000002500000000obs-service-node_modules/conftest.pyfrom pytest_container import auto_container_parametrize


def pytest_generate_tests(metafunc):
    auto_container_parametrize(metafunc)
07070100000006000041ED00000000000000000000000265B7C7A000000000000000000000000000000000000000000000001E00000000obs-service-node_modules/data07070100000007000081A400000000000000000000000165B7C7A00000E70E000000000000000000000000000000000000003000000000obs-service-node_modules/data/package-lock.json{
  "name": "debug",
  "version": "4.3.2",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "debug",
      "version": "4.3.2",
      "license": "MIT",
      "dependencies": {
        "ms": "2.1.2"
      },
      "devDependencies": {
        "brfs": "^2.0.1",
        "mocha": "^5.2.0"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/acorn": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
      "dev": true,
      "bin": {
        "acorn": "bin/acorn"
      },
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/acorn-node": {
      "version": "1.8.2",
      "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
      "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
      "dev": true,
      "dependencies": {
        "acorn": "^7.0.0",
        "acorn-walk": "^7.0.0",
        "xtend": "^4.0.2"
      }
    },
    "node_modules/acorn-walk": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
      "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
      "dev": true,
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/array-from": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz",
      "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=",
      "dev": true
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
      "dev": true
    },
    "node_modules/brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "dev": true,
      "dependencies": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "node_modules/brfs": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/brfs/-/brfs-2.0.2.tgz",
      "integrity": "sha512-IrFjVtwu4eTJZyu8w/V2gxU7iLTtcHih67sgEdzrhjLBMHp2uYefUBfdM4k2UvcuWMgV7PQDZHSLeNWnLFKWVQ==",
      "dev": true,
      "dependencies": {
        "quote-stream": "^1.0.1",
        "resolve": "^1.1.5",
        "static-module": "^3.0.2",
        "through2": "^2.0.0"
      },
      "bin": {
        "brfs": "bin/cmd.js"
      }
    },
    "node_modules/browser-stdout": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
      "dev": true
    },
    "node_modules/buffer-equal": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
      "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=",
      "dev": true,
      "engines": {
        "node": ">=0.4.0"
      }
    },
    "node_modules/buffer-from": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
      "dev": true
    },
    "node_modules/commander": {
      "version": "2.15.1",
      "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
      "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
      "dev": true
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
      "dev": true
    },
    "node_modules/concat-stream": {
      "version": "1.6.2",
      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
      "dev": true,
      "engines": [
        "node >= 0.8"
      ],
      "dependencies": {
        "buffer-from": "^1.0.0",
        "inherits": "^2.0.3",
        "readable-stream": "^2.2.2",
        "typedarray": "^0.0.6"
      }
    },
    "node_modules/convert-source-map": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.1"
      }
    },
    "node_modules/convert-source-map/node_modules/safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
      "dev": true
    },
    "node_modules/core-util-is": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
      "dev": true
    },
    "node_modules/d": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
      "dev": true,
      "dependencies": {
        "es5-ext": "^0.10.50",
        "type": "^1.0.1"
      }
    },
    "node_modules/dash-ast": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
      "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
      "dev": true
    },
    "node_modules/deep-is": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
      "dev": true
    },
    "node_modules/diff": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
      "dev": true,
      "engines": {
        "node": ">=0.3.1"
      }
    },
    "node_modules/duplexer2": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
      "dev": true,
      "dependencies": {
        "readable-stream": "^2.0.2"
      }
    },
    "node_modules/es5-ext": {
      "version": "0.10.53",
      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
      "dev": true,
      "dependencies": {
        "es6-iterator": "~2.0.3",
        "es6-symbol": "~3.1.3",
        "next-tick": "~1.0.0"
      }
    },
    "node_modules/es6-iterator": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
      "dev": true,
      "dependencies": {
        "d": "1",
        "es5-ext": "^0.10.35",
        "es6-symbol": "^3.1.1"
      }
    },
    "node_modules/es6-map": {
      "version": "0.1.5",
      "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
      "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
      "dev": true,
      "dependencies": {
        "d": "1",
        "es5-ext": "~0.10.14",
        "es6-iterator": "~2.0.1",
        "es6-set": "~0.1.5",
        "es6-symbol": "~3.1.1",
        "event-emitter": "~0.3.5"
      }
    },
    "node_modules/es6-set": {
      "version": "0.1.5",
      "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
      "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
      "dev": true,
      "dependencies": {
        "d": "1",
        "es5-ext": "~0.10.14",
        "es6-iterator": "~2.0.1",
        "es6-symbol": "3.1.1",
        "event-emitter": "~0.3.5"
      }
    },
    "node_modules/es6-set/node_modules/es6-symbol": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
      "dev": true,
      "dependencies": {
        "d": "1",
        "es5-ext": "~0.10.14"
      }
    },
    "node_modules/es6-symbol": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
      "dev": true,
      "dependencies": {
        "d": "^1.0.1",
        "ext": "^1.1.2"
      }
    },
    "node_modules/escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
      "dev": true,
      "engines": {
        "node": ">=0.8.0"
      }
    },
    "node_modules/escodegen": {
      "version": "1.14.3",
      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
      "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
      "dev": true,
      "dependencies": {
        "esprima": "^4.0.1",
        "estraverse": "^4.2.0",
        "esutils": "^2.0.2",
        "optionator": "^0.8.1"
      },
      "bin": {
        "escodegen": "bin/escodegen.js",
        "esgenerate": "bin/esgenerate.js"
      },
      "engines": {
        "node": ">=4.0"
      },
      "optionalDependencies": {
        "source-map": "~0.6.1"
      }
    },
    "node_modules/esprima": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
      "dev": true,
      "bin": {
        "esparse": "bin/esparse.js",
        "esvalidate": "bin/esvalidate.js"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/estraverse": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
      "dev": true,
      "engines": {
        "node": ">=4.0"
      }
    },
    "node_modules/estree-is-function": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/estree-is-function/-/estree-is-function-1.0.0.tgz",
      "integrity": "sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA==",
      "dev": true
    },
    "node_modules/esutils": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/event-emitter": {
      "version": "0.3.5",
      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
      "dev": true,
      "dependencies": {
        "d": "1",
        "es5-ext": "~0.10.14"
      }
    },
    "node_modules/ext": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
      "dev": true,
      "dependencies": {
        "type": "^2.0.0"
      }
    },
    "node_modules/ext/node_modules/type": {
      "version": "2.5.0",
      "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
      "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==",
      "dev": true
    },
    "node_modules/fast-levenshtein": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
      "dev": true
    },
    "node_modules/fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
      "dev": true
    },
    "node_modules/function-bind": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
      "dev": true
    },
    "node_modules/get-assigned-identifiers": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
      "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
      "dev": true
    },
    "node_modules/growl": {
      "version": "1.10.5",
      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
      "dev": true,
      "engines": {
        "node": ">=4.x"
      }
    },
    "node_modules/has": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
      "dev": true,
      "dependencies": {
        "function-bind": "^1.1.1"
      },
      "engines": {
        "node": ">= 0.4.0"
      }
    },
    "node_modules/has-flag": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
      "dev": true,
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/he": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
      "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
      "dev": true,
      "bin": {
        "he": "bin/he"
      }
    },
    "node_modules/inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
      "dev": true,
      "dependencies": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "node_modules/inherits": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
      "dev": true
    },
    "node_modules/is-core-module": {
      "version": "2.6.0",
      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz",
      "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==",
      "dev": true,
      "dependencies": {
        "has": "^1.0.3"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/isarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
      "dev": true
    },
    "node_modules/levn": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
      "dev": true,
      "dependencies": {
        "prelude-ls": "~1.1.2",
        "type-check": "~0.3.2"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/magic-string": {
      "version": "0.25.1",
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz",
      "integrity": "sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==",
      "dev": true,
      "dependencies": {
        "sourcemap-codec": "^1.4.1"
      }
    },
    "node_modules/merge-source-map": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
      "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=",
      "dev": true,
      "dependencies": {
        "source-map": "^0.5.6"
      }
    },
    "node_modules/merge-source-map/node_modules/source-map": {
      "version": "0.5.7",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/minimatch": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
      "dev": true,
      "dependencies": {
        "brace-expansion": "^1.1.7"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/minimist": {
      "version": "0.0.8",
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
      "dev": true
    },
    "node_modules/mkdirp": {
      "version": "0.5.1",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
      "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
      "dev": true,
      "dependencies": {
        "minimist": "0.0.8"
      },
      "bin": {
        "mkdirp": "bin/cmd.js"
      }
    },
    "node_modules/mocha": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
      "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
      "dev": true,
      "dependencies": {
        "browser-stdout": "1.3.1",
        "commander": "2.15.1",
        "debug": "3.1.0",
        "diff": "3.5.0",
        "escape-string-regexp": "1.0.5",
        "glob": "7.1.2",
        "growl": "1.10.5",
        "he": "1.1.1",
        "minimatch": "3.0.4",
        "mkdirp": "0.5.1",
        "supports-color": "5.4.0"
      },
      "bin": {
        "_mocha": "bin/_mocha",
        "mocha": "bin/mocha"
      },
      "engines": {
        "node": ">= 4.0.0"
      }
    },
    "node_modules/mocha/node_modules/debug": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
      "dev": true,
      "dependencies": {
        "ms": "2.0.0"
      }
    },
    "node_modules/mocha/node_modules/glob": {
      "version": "7.1.2",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
      "dev": true,
      "dependencies": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.0.4",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/mocha/node_modules/ms": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
      "dev": true
    },
    "node_modules/ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
    },
    "node_modules/next-tick": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
      "dev": true
    },
    "node_modules/object-inspect": {
      "version": "1.11.0",
      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
      "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
      "dev": true,
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
      "dev": true,
      "dependencies": {
        "wrappy": "1"
      }
    },
    "node_modules/optionator": {
      "version": "0.8.3",
      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
      "dev": true,
      "dependencies": {
        "deep-is": "~0.1.3",
        "fast-levenshtein": "~2.0.6",
        "levn": "~0.3.0",
        "prelude-ls": "~1.1.2",
        "type-check": "~0.3.2",
        "word-wrap": "~1.2.3"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
      "dev": true
    },
    "node_modules/prelude-ls": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
      "dev": true,
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/process-nextick-args": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
      "dev": true
    },
    "node_modules/quote-stream": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz",
      "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=",
      "dev": true,
      "dependencies": {
        "buffer-equal": "0.0.1",
        "minimist": "^1.1.3",
        "through2": "^2.0.0"
      },
      "bin": {
        "quote-stream": "bin/cmd.js"
      }
    },
    "node_modules/quote-stream/node_modules/minimist": {
      "version": "1.2.5",
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
      "dev": true
    },
    "node_modules/readable-stream": {
      "version": "2.3.7",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
      "dev": true,
      "dependencies": {
        "core-util-is": "~1.0.0",
        "inherits": "~2.0.3",
        "isarray": "~1.0.0",
        "process-nextick-args": "~2.0.0",
        "safe-buffer": "~5.1.1",
        "string_decoder": "~1.1.1",
        "util-deprecate": "~1.0.1"
      }
    },
    "node_modules/readable-stream/node_modules/safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
      "dev": true
    },
    "node_modules/resolve": {
      "version": "1.20.0",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
      "dev": true,
      "dependencies": {
        "is-core-module": "^2.2.0",
        "path-parse": "^1.0.6"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/scope-analyzer": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/scope-analyzer/-/scope-analyzer-2.1.1.tgz",
      "integrity": "sha512-azEAihtQ9mEyZGhfgTJy3IbOWEzeOrYbg7NcYEshPKnKd+LZmC3TNd5dmDxbLBsTG/JVWmCp+vDJ03vJjeXMHg==",
      "dev": true,
      "dependencies": {
        "array-from": "^2.1.1",
        "dash-ast": "^1.0.0",
        "es6-map": "^0.1.5",
        "es6-set": "^0.1.5",
        "es6-symbol": "^3.1.1",
        "estree-is-function": "^1.0.0",
        "get-assigned-identifiers": "^1.1.0"
      }
    },
    "node_modules/shallow-copy": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz",
      "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=",
      "dev": true
    },
    "node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "optional": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/sourcemap-codec": {
      "version": "1.4.8",
      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
      "dev": true
    },
    "node_modules/static-eval": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz",
      "integrity": "sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==",
      "dev": true,
      "dependencies": {
        "escodegen": "^1.11.1"
      }
    },
    "node_modules/static-module": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/static-module/-/static-module-3.0.4.tgz",
      "integrity": "sha512-gb0v0rrgpBkifXCa3yZXxqVmXDVE+ETXj6YlC/jt5VzOnGXR2C15+++eXuMDUYsePnbhf+lwW0pE1UXyOLtGCw==",
      "dev": true,
      "dependencies": {
        "acorn-node": "^1.3.0",
        "concat-stream": "~1.6.0",
        "convert-source-map": "^1.5.1",
        "duplexer2": "~0.1.4",
        "escodegen": "^1.11.1",
        "has": "^1.0.1",
        "magic-string": "0.25.1",
        "merge-source-map": "1.0.4",
        "object-inspect": "^1.6.0",
        "readable-stream": "~2.3.3",
        "scope-analyzer": "^2.0.1",
        "shallow-copy": "~0.0.1",
        "static-eval": "^2.0.5",
        "through2": "~2.0.3"
      }
    },
    "node_modules/string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dev": true,
      "dependencies": {
        "safe-buffer": "~5.1.0"
      }
    },
    "node_modules/string_decoder/node_modules/safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
      "dev": true
    },
    "node_modules/supports-color": {
      "version": "5.4.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
      "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
      "dev": true,
      "dependencies": {
        "has-flag": "^3.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/through2": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
      "dev": true,
      "dependencies": {
        "readable-stream": "~2.3.6",
        "xtend": "~4.0.1"
      }
    },
    "node_modules/type": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
      "dev": true
    },
    "node_modules/type-check": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
      "dev": true,
      "dependencies": {
        "prelude-ls": "~1.1.2"
      },
      "engines": {
        "node": ">= 0.8.0"
      }
    },
    "node_modules/typedarray": {
      "version": "0.0.6",
      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
      "dev": true
    },
    "node_modules/util-deprecate": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
      "dev": true
    },
    "node_modules/word-wrap": {
      "version": "1.2.3",
      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
      "dev": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
      "dev": true
    },
    "node_modules/xtend": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
      "dev": true,
      "engines": {
        "node": ">=0.4"
      }
    }
  },
  "dependencies": {
    "acorn": {
      "version": "7.4.1",
      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
      "dev": true
    },
    "acorn-node": {
      "version": "1.8.2",
      "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
      "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==",
      "dev": true,
      "requires": {
        "acorn": "^7.0.0",
        "acorn-walk": "^7.0.0",
        "xtend": "^4.0.2"
      }
    },
    "acorn-walk": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
      "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
      "dev": true
    },
    "array-from": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz",
      "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=",
      "dev": true
    },
    "balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
      "dev": true
    },
    "brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "dev": true,
      "requires": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "brfs": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/brfs/-/brfs-2.0.2.tgz",
      "integrity": "sha512-IrFjVtwu4eTJZyu8w/V2gxU7iLTtcHih67sgEdzrhjLBMHp2uYefUBfdM4k2UvcuWMgV7PQDZHSLeNWnLFKWVQ==",
      "dev": true,
      "requires": {
        "quote-stream": "^1.0.1",
        "resolve": "^1.1.5",
        "static-module": "^3.0.2",
        "through2": "^2.0.0"
      }
    },
    "browser-stdout": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
      "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
      "dev": true
    },
    "buffer-equal": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
      "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=",
      "dev": true
    },
    "buffer-from": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
      "dev": true
    },
    "commander": {
      "version": "2.15.1",
      "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
      "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
      "dev": true
    },
    "concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
      "dev": true
    },
    "concat-stream": {
      "version": "1.6.2",
      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
      "dev": true,
      "requires": {
        "buffer-from": "^1.0.0",
        "inherits": "^2.0.3",
        "readable-stream": "^2.2.2",
        "typedarray": "^0.0.6"
      }
    },
    "convert-source-map": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
      "dev": true,
      "requires": {
        "safe-buffer": "~5.1.1"
      },
      "dependencies": {
        "safe-buffer": {
          "version": "5.1.2",
          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
          "dev": true
        }
      }
    },
    "core-util-is": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
      "dev": true
    },
    "d": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
      "dev": true,
      "requires": {
        "es5-ext": "^0.10.50",
        "type": "^1.0.1"
      }
    },
    "dash-ast": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz",
      "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==",
      "dev": true
    },
    "deep-is": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
      "dev": true
    },
    "diff": {
      "version": "3.5.0",
      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
      "dev": true
    },
    "duplexer2": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
      "dev": true,
      "requires": {
        "readable-stream": "^2.0.2"
      }
    },
    "es5-ext": {
      "version": "0.10.53",
      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
      "dev": true,
      "requires": {
        "es6-iterator": "~2.0.3",
        "es6-symbol": "~3.1.3",
        "next-tick": "~1.0.0"
      }
    },
    "es6-iterator": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
      "dev": true,
      "requires": {
        "d": "1",
        "es5-ext": "^0.10.35",
        "es6-symbol": "^3.1.1"
      }
    },
    "es6-map": {
      "version": "0.1.5",
      "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
      "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
      "dev": true,
      "requires": {
        "d": "1",
        "es5-ext": "~0.10.14",
        "es6-iterator": "~2.0.1",
        "es6-set": "~0.1.5",
        "es6-symbol": "~3.1.1",
        "event-emitter": "~0.3.5"
      }
    },
    "es6-set": {
      "version": "0.1.5",
      "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
      "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
      "dev": true,
      "requires": {
        "d": "1",
        "es5-ext": "~0.10.14",
        "es6-iterator": "~2.0.1",
        "es6-symbol": "3.1.1",
        "event-emitter": "~0.3.5"
      },
      "dependencies": {
        "es6-symbol": {
          "version": "3.1.1",
          "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
          "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
          "dev": true,
          "requires": {
            "d": "1",
            "es5-ext": "~0.10.14"
          }
        }
      }
    },
    "es6-symbol": {
      "version": "3.1.3",
      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
      "dev": true,
      "requires": {
        "d": "^1.0.1",
        "ext": "^1.1.2"
      }
    },
    "escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
      "dev": true
    },
    "escodegen": {
      "version": "1.14.3",
      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
      "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
      "dev": true,
      "requires": {
        "esprima": "^4.0.1",
        "estraverse": "^4.2.0",
        "esutils": "^2.0.2",
        "optionator": "^0.8.1",
        "source-map": "~0.6.1"
      }
    },
    "esprima": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
      "dev": true
    },
    "estraverse": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
      "dev": true
    },
    "estree-is-function": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/estree-is-function/-/estree-is-function-1.0.0.tgz",
      "integrity": "sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA==",
      "dev": true
    },
    "esutils": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
      "dev": true
    },
    "event-emitter": {
      "version": "0.3.5",
      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
      "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
      "dev": true,
      "requires": {
        "d": "1",
        "es5-ext": "~0.10.14"
      }
    },
    "ext": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
      "dev": true,
      "requires": {
        "type": "^2.0.0"
      },
      "dependencies": {
        "type": {
          "version": "2.5.0",
          "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
          "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==",
          "dev": true
        }
      }
    },
    "fast-levenshtein": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
      "dev": true
    },
    "fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
      "dev": true
    },
    "function-bind": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
      "dev": true
    },
    "get-assigned-identifiers": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
      "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==",
      "dev": true
    },
    "growl": {
      "version": "1.10.5",
      "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
      "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
      "dev": true
    },
    "has": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
      "dev": true,
      "requires": {
        "function-bind": "^1.1.1"
      }
    },
    "has-flag": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
      "dev": true
    },
    "he": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
      "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
      "dev": true
    },
    "inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
      "dev": true,
      "requires": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "inherits": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
      "dev": true
    },
    "is-core-module": {
      "version": "2.6.0",
      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz",
      "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==",
      "dev": true,
      "requires": {
        "has": "^1.0.3"
      }
    },
    "isarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
      "dev": true
    },
    "levn": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
      "dev": true,
      "requires": {
        "prelude-ls": "~1.1.2",
        "type-check": "~0.3.2"
      }
    },
    "magic-string": {
      "version": "0.25.1",
      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz",
      "integrity": "sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==",
      "dev": true,
      "requires": {
        "sourcemap-codec": "^1.4.1"
      }
    },
    "merge-source-map": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
      "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=",
      "dev": true,
      "requires": {
        "source-map": "^0.5.6"
      },
      "dependencies": {
        "source-map": {
          "version": "0.5.7",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
          "dev": true
        }
      }
    },
    "minimatch": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
      "dev": true,
      "requires": {
        "brace-expansion": "^1.1.7"
      }
    },
    "minimist": {
      "version": "0.0.8",
      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
      "dev": true
    },
    "mkdirp": {
      "version": "0.5.1",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
      "dev": true,
      "requires": {
        "minimist": "0.0.8"
      }
    },
    "mocha": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
      "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
      "dev": true,
      "requires": {
        "browser-stdout": "1.3.1",
        "commander": "2.15.1",
        "debug": "3.1.0",
        "diff": "3.5.0",
        "escape-string-regexp": "1.0.5",
        "glob": "7.1.2",
        "growl": "1.10.5",
        "he": "1.1.1",
        "minimatch": "3.0.4",
        "mkdirp": "0.5.1",
        "supports-color": "5.4.0"
      },
      "dependencies": {
        "debug": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "glob": {
          "version": "7.1.2",
          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
          "dev": true,
          "requires": {
            "fs.realpath": "^1.0.0",
            "inflight": "^1.0.4",
            "inherits": "2",
            "minimatch": "^3.0.4",
            "once": "^1.3.0",
            "path-is-absolute": "^1.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
    },
    "next-tick": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
      "dev": true
    },
    "object-inspect": {
      "version": "1.11.0",
      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
      "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
      "dev": true
    },
    "once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
      "dev": true,
      "requires": {
        "wrappy": "1"
      }
    },
    "optionator": {
      "version": "0.8.3",
      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
      "dev": true,
      "requires": {
        "deep-is": "~0.1.3",
        "fast-levenshtein": "~2.0.6",
        "levn": "~0.3.0",
        "prelude-ls": "~1.1.2",
        "type-check": "~0.3.2",
        "word-wrap": "~1.2.3"
      }
    },
    "path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
      "dev": true
    },
    "path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
      "dev": true
    },
    "prelude-ls": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
      "dev": true
    },
    "process-nextick-args": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
      "dev": true
    },
    "quote-stream": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz",
      "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=",
      "dev": true,
      "requires": {
        "buffer-equal": "0.0.1",
        "minimist": "^1.1.3",
        "through2": "^2.0.0"
      },
      "dependencies": {
        "minimist": {
          "version": "1.2.5",
          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
          "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
          "dev": true
        }
      }
    },
    "readable-stream": {
      "version": "2.3.7",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
      "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
      "dev": true,
      "requires": {
        "core-util-is": "~1.0.0",
        "inherits": "~2.0.3",
        "isarray": "~1.0.0",
        "process-nextick-args": "~2.0.0",
        "safe-buffer": "~5.1.1",
        "string_decoder": "~1.1.1",
        "util-deprecate": "~1.0.1"
      },
      "dependencies": {
        "safe-buffer": {
          "version": "5.1.2",
          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
          "dev": true
        }
      }
    },
    "resolve": {
      "version": "1.20.0",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
      "dev": true,
      "requires": {
        "is-core-module": "^2.2.0",
        "path-parse": "^1.0.6"
      }
    },
    "scope-analyzer": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/scope-analyzer/-/scope-analyzer-2.1.1.tgz",
      "integrity": "sha512-azEAihtQ9mEyZGhfgTJy3IbOWEzeOrYbg7NcYEshPKnKd+LZmC3TNd5dmDxbLBsTG/JVWmCp+vDJ03vJjeXMHg==",
      "dev": true,
      "requires": {
        "array-from": "^2.1.1",
        "dash-ast": "^1.0.0",
        "es6-map": "^0.1.5",
        "es6-set": "^0.1.5",
        "es6-symbol": "^3.1.1",
        "estree-is-function": "^1.0.0",
        "get-assigned-identifiers": "^1.1.0"
      }
    },
    "shallow-copy": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz",
      "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=",
      "dev": true
    },
    "source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "optional": true
    },
    "sourcemap-codec": {
      "version": "1.4.8",
      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
      "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
      "dev": true
    },
    "static-eval": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.0.tgz",
      "integrity": "sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==",
      "dev": true,
      "requires": {
        "escodegen": "^1.11.1"
      }
    },
    "static-module": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/static-module/-/static-module-3.0.4.tgz",
      "integrity": "sha512-gb0v0rrgpBkifXCa3yZXxqVmXDVE+ETXj6YlC/jt5VzOnGXR2C15+++eXuMDUYsePnbhf+lwW0pE1UXyOLtGCw==",
      "dev": true,
      "requires": {
        "acorn-node": "^1.3.0",
        "concat-stream": "~1.6.0",
        "convert-source-map": "^1.5.1",
        "duplexer2": "~0.1.4",
        "escodegen": "^1.11.1",
        "has": "^1.0.1",
        "magic-string": "0.25.1",
        "merge-source-map": "1.0.4",
        "object-inspect": "^1.6.0",
        "readable-stream": "~2.3.3",
        "scope-analyzer": "^2.0.1",
        "shallow-copy": "~0.0.1",
        "static-eval": "^2.0.5",
        "through2": "~2.0.3"
      }
    },
    "string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dev": true,
      "requires": {
        "safe-buffer": "~5.1.0"
      },
      "dependencies": {
        "safe-buffer": {
          "version": "5.1.2",
          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
          "dev": true
        }
      }
    },
    "supports-color": {
      "version": "5.4.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
      "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
      "dev": true,
      "requires": {
        "has-flag": "^3.0.0"
      }
    },
    "through2": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
      "dev": true,
      "requires": {
        "readable-stream": "~2.3.6",
        "xtend": "~4.0.1"
      }
    },
    "type": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
      "dev": true
    },
    "type-check": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
      "dev": true,
      "requires": {
        "prelude-ls": "~1.1.2"
      }
    },
    "typedarray": {
      "version": "0.0.6",
      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
      "dev": true
    },
    "util-deprecate": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
      "dev": true
    },
    "word-wrap": {
      "version": "1.2.3",
      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
      "dev": true
    },
    "wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
      "dev": true
    },
    "xtend": {
      "version": "4.0.2",
      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
      "dev": true
    }
  }
}
07070100000008000081ED00000000000000000000000165B7C7A000005580000000000000000000000000000000000000002900000000obs-service-node_modules/node_modules.py#!/usr/bin/python3
# Copyright (c) 2020 SUSE LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import argparse
import hashlib
import json
import logging
import os
import glob
import subprocess
import sys
import stat
import time
import struct
import urllib.error
import urllib.parse
import urllib.request
from base64 import b64decode
from binascii import hexlify
from lxml import etree as ET

from pathlib import Path

# filename -> { url: <string>, sum: <string>, path = set([<string>, ..]) }
MODULE_MAP = dict()

# this is a hack for obs_scm integration
OBS_SCM_COMPRESSION = None

class CpioReader:
    def __init__(self, fn):
        self.fh = open(fn, 'rb')

    def extract(self, outdir):

        class CpioFile:
            def __init__(self, fh):
                self.fh = fh
                self.name = None

            def __enter__(self):
                if (self.fh.tell() & 3):
                    raise Exception("invalid offset %d" % self.fh.tell())

                fmt = "6s8s8s8s8s8s8s8s8s8s8s8s8s8s"

                fields = struct.unpack(fmt, self.fh.read(struct.calcsize(fmt)))

                if fields[0] != b"070701":
                    raise Exception("invalid cpio header %s" % fields[0])

                names = ("c_ino", "c_mode", "c_uid", "c_gid",
                         "c_nlink", "c_mtime", "c_filesize",
                         "c_devmajor", "c_devminor", "c_rdevmajor",
                         "c_rdevminor", "c_namesize", "c_check")
                for (n, v) in zip(names, fields[1:]):
                    setattr(self, n, int(v, 16))

                self.name = struct.unpack('%ds' % (self.c_namesize - 1), self.fh.read(self.c_namesize - 1))[0]
                self.fh.read(1)  # \0
                if (self.c_namesize+2) % 4:
                    self.fh.read(4 - (self.c_namesize+2) % 4)

                return self

            def __exit__(self, exc_type, exc_value, traceback):
                if exc_type:
                    return None
                if self.c_filesize % 4:
                    self.fh.read(4 - self.c_filesize % 4)

            def last(self):
                return self.name == b'TRAILER!!!'

            def __str__(self):
                return "[%s %d]" % (self.name, self.c_filesize)

            def read(self):
                return self.fh.read(self.c_filesize)

        while True:
            with CpioFile(self.fh) as f:
                if f.last():
                    break
                with open(os.path.join(outdir if outdir else '.', os.path.basename(f.name.decode())), 'wb') as ofh:
                    ofh.write(f.read())


class CpioWriter:
    def __init__(self, fn):
        self.cpio = open(fn, 'wb')

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        if exc_type:
            return None
        self.add('TRAILER!!!', b'')
        return self

    def add(self, name, content, perm=0o644):
        if isinstance(name, str):
            name = name.encode()
        if isinstance(content, str):
            content = content.encode()

        name += b'\0'
        mode = perm | 0x8000  # regular file

        size = len(content)

        header = b'070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%s' % (
            0, mode, 0, 0, 1, 0, size, 0, 0, 0, 0, len(name), 0, name)

        self.cpio.write(header)
        if len(header):
            self.cpio.write(b'\0' * (4 - len(header) % 4))
        self.cpio.write(content)
        if size % 4:
            self.cpio.write(b'\0' * (4 - size % 4))

    def addstream(self, name, fh):
        if isinstance(name, str):
            name = name.encode()
        name += b'\0'

        info = os.stat(fh.fileno())
        size = info[stat.ST_SIZE]

        header = b'070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%s' % (
            0,  # inode
            0o644 | 0x8000, # MODE and regular file
            0,  # UID,
            0,  # GID,
            1,  # nlink
            1577836800, # 2020-01-01 00:00:00
            size,
            0,  # major
            0,  # minor
            0,  # rmajor
            0,  # rminor
            len(name),
            0,  # checksum
            name
            )

        self.cpio.write(header)
        if len(header) % 4:
            self.cpio.write(b'\0' * (4 - len(header) % 4))
        self.cpio.write(fh.read())
        if size % 4:
            self.cpio.write(b'\0' * (4 - size % 4))

    def addfile(self, name):
        with open(name, 'rb') as fh:
            self.addstream(name, fh)

def parse_supported_fetch_url(from_entry):
    if from_entry[0] == '@':
        from_entry = from_entry[1:]
    end_name_pos = from_entry.find('@')
    schema_pos = from_entry.find('//')
    if schema_pos > end_name_pos:
        from_entry = from_entry[end_name_pos+1:]

    o = urllib.parse.urlparse(from_entry)
    if o.scheme in ("git+http", "git+https", "https"):
        return o
    return False

def add_git_dependency(o, module, install_path):
    _, scheme = o.scheme.split("+")
    branch = "master"
    # XXX: not sure that is correct
    if o.fragment:
        branch = o.fragment
    p = os.path.basename(o.path)
    if p.endswith(".git"):
        p = p[:-4]
    if OBS_SCM_COMPRESSION:
        fn = "{}-{}.tar.{}".format(p, branch, OBS_SCM_COMPRESSION)
    else:
        fn = "{}-{}.tgz".format(p, branch)
    MODULE_MAP[fn] = {
        "scm": "git",
        "branch": branch,
        "basename": p,
        "url": urllib.parse.urlunparse(
            (scheme, o.netloc, o.path, o.params, o.query, None)
        ),
    }

    MODULE_MAP[fn].setdefault("path", set()).add(install_path)
    return True

def make_unique_fn_from_path(o):
    path = o.path.split('/')
    original_fn = path[-1]
    prepended = []

    for pos in range(1,len(path)-1):
        s = path[pos]
        if original_fn[:len(s)] == s or s == '-':
            continue
        prepended = prepended + [s]

    return '-'.join(prepended + [original_fn])

def add_standard_dependency(o, integrities, module, install_path):
    url = urllib.parse.urlunparse(o)
    # pick the longest integrity assuming it will be better (eg sha1 vs sha256)
    integrity = max(integrities.split(" "), key=len)
    algo, chksum = integrity.split("-", 2)
    chksum = hexlify(b64decode(chksum)).decode("ascii")
    fn = make_unique_fn_from_path(o)

    if fn in MODULE_MAP:
        if (
            MODULE_MAP[fn]["url"] != url
            or MODULE_MAP[fn]["algo"] != algo
            or MODULE_MAP[fn]["chksum"] != chksum
        ):
            logging.error(
                "%s: mismatch %s <> %s, %s:%s <> %s:%s",
                module,
                MODULE_MAP[fn]["url"],
                url,
                MODULE_MAP[fn]["algo"],
                MODULE_MAP[fn]["chksum"],
                algo,
                chksum,
            )
    else:
        MODULE_MAP[fn] = {"url": url, "algo": algo, "chksum": chksum}

    MODULE_MAP[fn].setdefault("path", set()).add(install_path)

def fetch_non_resolved_dependency_location(entry, module, install_path):
    # format of the "from" field is in `npm-package-arg` NPM package
    labels = ["from", "version"]
    o = False

    for label in labels:
        if (label not in entry):
            continue
        o = parse_supported_fetch_url(entry[label])
        if (o != False):
            break

    if (o == False):
        # unsupported localtion or nothing to download?
        if "from" in entry:
            logging.warning(
                "entry %s is from unsupported location %s",
                module,
                entry["from"],
            )
            return False

        logging.warning("entry %s has no download", module)
        return False

    if o.scheme == "https":
        integrity = entry["integrity"]
        return add_standard_dependency(o, integrity, module, install_path)
    elif o.scheme.startswith("git+"):
        return add_git_dependency(o, module, install_path)

    return False


def collect_v2_deps_recursive(d, deps):
    for module in sorted(deps):
        path = "/".join(("node_modules", module))
        if d:
            path = "/".join((d, path))
        entry = deps[module]
        if "resolved" not in entry:
            fetch_non_resolved_dependency_location(entry, module, path)
        else:
            url = entry["resolved"]
            if "integrity" not in entry:
                logging.warning("No integrity field for %s. Try to regenerate package-lock.json.", url)
                integrity = 'NONE-'
            else:
                integrity = entry["integrity"]
            add_standard_dependency(parse_supported_fetch_url(url), integrity, module, path)

        if "dependencies" in entry:
            collect_v2_deps_recursive(path, entry["dependencies"])

def collect_v3_deps(packages):
    deps = packages.keys()
    for module in sorted(deps):
        if module == "":
            continue

        if module[:13] != "node_modules/":
            raise Exception("unexpected module key: " + module)

        path = "/" + module
        entry = packages[module]
        module = module[13:]
        if "resolved" not in entry:
            fetch_non_resolved_dependency_location(entry, module, path)
        else:
            url = entry["resolved"]
            integrity = entry["integrity"]
            o = urllib.parse.urlparse(url)
            if o.scheme.startswith("git+"):
                add_git_dependency(o, module, "/" + module)
            else:
                add_standard_dependency(parse_supported_fetch_url(url), integrity, module, path)

def write_rpm_sources(fh, args):
    i = args.source_offset if args.source_offset is not None else ''
    for fn in sorted(MODULE_MAP):
        fh.write("Source{}:         {}#/{}\n".format(i, MODULE_MAP[fn]["url"], fn))
        if args.source_offset is not None:
            i += 1

def process_packagelock_file(js):
    if not "lockfileVersion" in js:
        raise Exception("Only package-lock.json with lockfileVersion=2+ are supported")
    elif js["lockfileVersion"] == 2:
        collect_v2_deps_recursive("", js["dependencies"])
    elif js["lockfileVersion"] == 3:
        collect_v3_deps(js["packages"])
    else:
        raise Exception("Unsupported lockfileVersion found")

def main(args):
    # special settings when run as obs service
    if args.outdir:
        if not args.spec and not args.output:
            specfiles = glob.glob('*.spec')
            if specfiles:
                if len(specfiles) > 1:
                    raise Exception("more than one spec file found. Choose one")
                args.spec = specfiles[0]
            else:
                raise Exception("This service needs a spec file to operate with")

        if not args.checksums:
            args.checksums = 'node_modules.sums'

        args.download = True

    def _out(fn):
        return os.path.join(args.outdir, fn) if args.outdir else fn

    def update_checksum(fn):
        with open(_out(fn), 'rb') as fh:
            h = hashlib.new(MODULE_MAP[fn].setdefault("algo", 'sha256'), fh.read())
            MODULE_MAP[fn]["chksum"] = h.hexdigest()
    pattern = f"*{args.input}"
    input_file = next(reversed(sorted(Path(Path.cwd()).glob(pattern))), None)

    with open(input_file) as fh:
        js = json.load(fh)

    if "name" in js:
        process_packagelock_file(js)
    else:
        for i in js.keys():
            process_packagelock_file(js[i])

    if args.output:
        with open(_out(args.output), "w") as fh:
            write_rpm_sources(fh, args)

    if args.spec:
        ok = False
        newfn = _out(args.spec)
        if not args.outdir:
            newfn += '.new'
        with open(newfn, "w") as ofh:
            with open(args.spec, "r") as ifh:
                for line in ifh:
                    if line.startswith('# NODE_MODULES BEGIN'):
                        ofh.write(line)
                        for line in ifh:
                            if line.startswith('# NODE_MODULES END'):
                                write_rpm_sources(ofh, args)
                                ok = True
                                break

                    ofh.write(line)
        if not ok:
            raise Exception("# NODE_MODULES [BEGIN|END] not found")
        if not args.outdir:
            os.rename(args.spec+".new", args.spec)

    if args.download:
        if args.cpio and os.path.exists(args.cpio) and not args.download_always:
            CpioReader(args.cpio).extract(args.outdir)

        for fn in sorted(MODULE_MAP):
            if args.file and fn not in args.file:
                continue
            url = MODULE_MAP[fn]["url"]
            if "scm" in MODULE_MAP[fn]:
                if os.path.exists(_out(fn)) and MODULE_MAP[fn]["branch"] != "master" and not args.download_always:
                    logging.info("skipping update of existing %s", _out(fn))
                    continue

                d = MODULE_MAP[fn]["basename"]
                # TODO: use same cache as tar_scm
                if os.path.exists(d):
                    r = subprocess.run(["git", "remote", "update"], cwd=d)
                    if r.returncode:
                        logging.error("failed to clone %s", url)
                        continue
                else:
                    r = subprocess.run(["git", "clone", "--bare", url, d])
                    if r.returncode:
                        logging.error("failed to clone %s", url)
                        continue
                r = subprocess.run(
                    [
                        "git",
                        "archive",
                        "--format=tar." + (OBS_SCM_COMPRESSION if OBS_SCM_COMPRESSION else 'gz'),
                        "-o",
                        _out(fn),
                        "--prefix",
                        "package/",
                        MODULE_MAP[fn]["branch"],
                    ],
                    cwd=d,
                )
                if not args.outdir:
                    os.rename(os.path.join(d, fn), fn)
                if r.returncode:
                    logging.error("failed to create tar %s", url)
                    continue
            else:
                req = urllib.request.Request(url)
                if os.path.exists(_out(fn)):
                    if not args.download_always:
                        logging.info("skipping download of existing %s", fn)
                        continue
                    stamp = time.strftime(
                        "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(os.path.getmtime(_out(fn)))
                    )
                    logging.debug("adding If-Modified-Since %s: %s", fn, stamp)
                    req.add_header("If-Modified-Since", stamp)

                logging.info("fetching %s as %s", url, fn)
                algo = MODULE_MAP[fn]["algo"]
                chksum = MODULE_MAP[fn]["chksum"]
                h = hashlib.new(algo)
                response = urllib.request.urlopen(req)
                try:
                    data = response.read()
                    h.update(data)
                    if h.hexdigest() != chksum:
                        logging.error(
                            "checksum failure for %s %s %s %s",
                            fn,
                            algo,
                            h.hexdigest,
                            chksum,
                        )
                    else:
                        try:
                            with open(_out(fn) + ".new", "wb") as fh:
                                fh.write(data)
                        except OSError as e:
                            logging.error(e)
                        finally:
                            os.rename(_out(fn) + ".new", _out(fn))
                except urllib.error.HTTPError as e:
                    logging.error(e)

    if args.checksums:
        with open(_out(args.checksums), "w") as fh:
            for fn in sorted(MODULE_MAP):
                if 'algo' not in MODULE_MAP[fn]:
                    update_checksum(fn)
                fh.write(
                    "{} ({}) = {}\n".format(
                        MODULE_MAP[fn]["algo"].upper(), fn, MODULE_MAP[fn]["chksum"]
                    )
                )

    if args.cpio:
        with CpioWriter(_out(args.cpio) + ".new") as c:
            for fn in sorted(MODULE_MAP):
                with open(_out(fn), 'rb') as fh:
                    c.addstream(os.path.basename(fn), fh)
                os.unlink(_out(fn))
        os.rename(_out(args.cpio) + ".new", _out(args.cpio))

    if args.obs_service:
        parser = ET.XMLParser(remove_blank_text=True)
        tree = ET.parse(args.obs_service, parser)
        root = tree.getroot()
        # to make sure pretty printing works
        for element in root.iter():
            element.tail = None

        if not args.obs_service_scm_only:
            # FIXME: remove only entries we added?
            for node in root.findall("service[@name='download_url']"):
                root.remove(node)

        tar_scm_toremove = set()
        for fn in sorted(MODULE_MAP):
            if "scm" in MODULE_MAP[fn]:
                tar_scm_toremove.add(MODULE_MAP[fn]['url'])

        for u in tar_scm_toremove:
            for node in root.findall("service[@name='obs_scm']"):
                if node.find("param[@name='url']").text == u:
                    root.remove(node)

        for fn in sorted(MODULE_MAP):
            if args.file and fn not in args.file:
                continue
            url = MODULE_MAP[fn]["url"]
            if "scm" in MODULE_MAP[fn]:
                s = ET.SubElement(root, 'service', {'name': 'obs_scm'})
                ET.SubElement(s, 'param', {'name': 'scm'}).text = "git"
                ET.SubElement(s, 'param', {'name': 'url'}).text = MODULE_MAP[fn]["url"]
                ET.SubElement(s, 'param', {'name': 'revision'}).text = MODULE_MAP[fn]["branch"]
                ET.SubElement(s, 'param', {'name': 'version'}).text = MODULE_MAP[fn]["branch"]
            elif not args.obs_service_scm_only:
                s = ET.SubElement(root, 'service', {'name': 'download_url'})
                ET.SubElement(s, 'param', {'name': 'url'}).text = MODULE_MAP[fn]["url"]
                ET.SubElement(s, 'param', {'name': 'prefer-old'}).text = 'enable'

        tree.write(args.obs_service, pretty_print=True)

    return 0


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Maintain spec file for node modules"
    )
    parser.add_argument("--dry", action="store_true", help="dry run")
    parser.add_argument("--debug", action="store_true", help="debug output")
    parser.add_argument("--verbose", action="store_true", help="verbose")
    parser.add_argument(
        "-i",
        "--input",
        metavar="FILE",
        default="package-lock.json",
        help="input package lock file",
    )
    parser.add_argument(
        "-f", "--file", nargs="+", metavar="FILE", help="limit to file"
    )
    parser.add_argument(
        "-o", "--output", metavar="FILE", help="spec files source lines into that file"
    )
    parser.add_argument(
        "--spec", metavar="FILE", help="spec file to process"
    )
    parser.add_argument(
        "--source-offset", metavar="N", type=int, help="Spec file source offset"
    )
    parser.add_argument(
        "--checksums", metavar="FILE", help="Write BSD style checksum file"
    )
    parser.add_argument(
        "--obs-service", metavar="FILE", help="OBS service file for download_url"
    )
    parser.add_argument(
        "--outdir", metavar="DIR", help="where to put files"
    )
    parser.add_argument(
        "--cpio", metavar="ARCHIVE", help="cpio archive to use instead of individual files"
    )
    parser.add_argument(
        "--compression", metavar="EXT", help="use EXT compression"
    )
    parser.add_argument(
        "--obs-service-scm-only",
        action="store_true",
        help="only generate tar_scm entries in service file",
    )

    parser.add_argument("--download", action="store_true", help="download files")
    parser.add_argument(
        "--download-always",
        action="store_true",
        help="download existing files again",
    )

    args = parser.parse_args()

    if args.debug:
        level = logging.DEBUG
    elif args.verbose:
        level = logging.INFO
    else:
        level = logging.WARNING

    logging.basicConfig(format='%(levelname)s:%(message)s', level=level)

    if args.outdir and not args.outdir[0] == '/':
        raise Exception("outdir must be absolute")

    if args.compression:
        OBS_SCM_COMPRESSION = args.compression
    elif args.obs_service:
        OBS_SCM_COMPRESSION = 'xz'

    sys.exit(main(args))

# vim: sw=4 et
07070100000009000081A400000000000000000000000165B7C7A0000001D6000000000000000000000000000000000000002E00000000obs-service-node_modules/node_modules.service<service name="node_modules">
  <summary>download node modules</summary>
  <description>download node modules</description>
  <parameter name="cpio">
    <description>cpio file name to store all tarballs in</description>
  </parameter>
  <parameter name="output">
    <description>write rpm source lines to that file</description>
  </parameter>
  <parameter name="source-offset">
    <description>rpm source number to start with</description>
  </parameter>
</service>
0707010000000A000081A400000000000000000000000165B7C7A0000079CF000000000000000000000000000000000000002500000000obs-service-node_modules/poetry.lock[[package]]
name = "atomicwrites"
version = "1.4.0"
description = "Atomic file writes."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"

[[package]]
name = "attrs"
version = "21.2.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"

[package.extras]
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]

[[package]]
name = "colorama"
version = "0.4.4"
description = "Cross-platform colored terminal text."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"

[[package]]
name = "dataclasses"
version = "0.8"
description = "A backport of the dataclasses module for Python 3.6"
category = "dev"
optional = false
python-versions = ">=3.6, <3.7"

[[package]]
name = "execnet"
version = "1.9.0"
description = "execnet: rapid multi-Python deployment"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"

[package.extras]
testing = ["pre-commit"]

[[package]]
name = "importlib-metadata"
version = "4.8.2"
description = "Read metadata from Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.dependencies]
typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""}
zipp = ">=0.5"

[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
perf = ["ipython"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"]

[[package]]
name = "iniconfig"
version = "1.1.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = "*"

[[package]]
name = "lxml"
version = "4.6.4"
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"

[package.extras]
cssselect = ["cssselect (>=0.7)"]
html5 = ["html5lib"]
htmlsoup = ["beautifulsoup4"]
source = ["Cython (>=0.29.7)"]

[[package]]
name = "lxml-stubs"
version = "0.2.0"
description = "Type annotations for the lxml package"
category = "dev"
optional = false
python-versions = "*"

[package.extras]
test = ["pytest (>=6.0.0)", "pytest-mypy-plugins (==1.4.0)", "coverage[toml] (==5.2)"]

[[package]]
name = "mypy"
version = "0.910"
description = "Optional static typing for Python"
category = "dev"
optional = false
python-versions = ">=3.5"

[package.dependencies]
mypy-extensions = ">=0.4.3,<0.5.0"
toml = "*"
typed-ast = {version = ">=1.4.0,<1.5.0", markers = "python_version < \"3.8\""}
typing-extensions = ">=3.7.4"

[package.extras]
dmypy = ["psutil (>=4.0)"]
python2 = ["typed-ast (>=1.4.0,<1.5.0)"]

[[package]]
name = "mypy-extensions"
version = "0.4.3"
description = "Experimental type system extensions for programs checked with the mypy typechecker."
category = "dev"
optional = false
python-versions = "*"

[[package]]
name = "packaging"
version = "21.3"
description = "Core utilities for Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.dependencies]
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"

[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.dependencies]
importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}

[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]

[[package]]
name = "py"
version = "1.11.0"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"

[[package]]
name = "pyparsing"
version = "3.0.6"
description = "Python parsing module"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]

[[package]]
name = "pytest"
version = "6.2.5"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.dependencies]
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
py = ">=1.8.2"
toml = "*"

[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]

[[package]]
name = "pytest-container"
version = "0.0.1"
description = "Pytest fixtures for writing container based tests"
category = "dev"
optional = false
python-versions = ">=3.6.2,<4.0"
develop = false

[package.dependencies]
dataclasses = {version = ">=0.8", markers = "python_version < \"3.7\""}
pytest = ">= 3.10"
pytest-testinfra = ">=6.4.0"

[package.source]
type = "git"
url = "https://github.com/dcermak/pytest_container.git"
reference = "main"
resolved_reference = "4c1920dd5bbbaba42d9a643fecb2f6077330fd6a"

[[package]]
name = "pytest-forked"
version = "1.3.0"
description = "run tests in isolated forked subprocesses"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"

[package.dependencies]
py = "*"
pytest = ">=3.10"

[[package]]
name = "pytest-testinfra"
version = "6.4.0"
description = "Test infrastructures"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.dependencies]
pytest = "!=3.0.2"

[package.extras]
ansible = ["ansible"]
paramiko = ["paramiko"]
salt = ["salt"]
winrm = ["pywinrm"]

[[package]]
name = "pytest-xdist"
version = "2.4.0"
description = "pytest xdist plugin for distributed testing and loop-on-failing modes"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.dependencies]
execnet = ">=1.1"
pytest = ">=6.0.0"
pytest-forked = "*"

[package.extras]
psutil = ["psutil (>=3.0)"]
setproctitle = ["setproctitle"]
testing = ["filelock"]

[[package]]
name = "toml"
version = "0.10.2"
description = "Python Library for Tom's Obvious, Minimal Language"
category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"

[[package]]
name = "typed-ast"
version = "1.4.3"
description = "a fork of Python 2 and 3 ast modules with type comment support"
category = "dev"
optional = false
python-versions = "*"

[[package]]
name = "typing-extensions"
version = "4.0.1"
description = "Backported and Experimental Type Hints for Python 3.6+"
category = "dev"
optional = false
python-versions = ">=3.6"

[[package]]
name = "urllib3"
version = "1.26.7"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"

[package.extras]
brotli = ["brotlipy (>=0.6.0)"]
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]

[[package]]
name = "zipp"
version = "3.6.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "dev"
optional = false
python-versions = ">=3.6"

[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]

[metadata]
lock-version = "1.1"
python-versions = ">=3.6.2,<4.0"
content-hash = "2170ed578b480eb51ef67f432bd92380b32eee231b4cffcc78cc288999008bb2"

[metadata.files]
atomicwrites = [
    {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
    {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
]
attrs = [
    {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
    {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
]
colorama = [
    {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
    {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
]
dataclasses = [
    {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"},
    {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"},
]
execnet = [
    {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"},
    {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"},
]
importlib-metadata = [
    {file = "importlib_metadata-4.8.2-py3-none-any.whl", hash = "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100"},
    {file = "importlib_metadata-4.8.2.tar.gz", hash = "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb"},
]
iniconfig = [
    {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
    {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
]
lxml = [
    {file = "lxml-4.6.4-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bbf2dc330bd44bfc0254ab37677ec60f7c7ecea55ad8ba1b8b2ea7bf20c265f5"},
    {file = "lxml-4.6.4-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b667c51682fe9b9788c69465956baa8b6999531876ccedcafc895c74ad716cd8"},
    {file = "lxml-4.6.4-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:72e730d33fe2e302fd07285f14624fca5e5e2fb2bb4fb2c3941e318c41c443d1"},
    {file = "lxml-4.6.4-cp27-cp27m-win32.whl", hash = "sha256:433df8c7dde0f9e41cbf4f36b0829d50a378116ef5e962ba3881f2f5f025c7be"},
    {file = "lxml-4.6.4-cp27-cp27m-win_amd64.whl", hash = "sha256:35752ee40f7bbf6adc9ff4e1f4b84794a3593736dcce80db32e3c2aa85e294ac"},
    {file = "lxml-4.6.4-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ff5bb2a198ea67403bb6818705e9a4f90e0313f2215428ec51001ce56d939fb"},
    {file = "lxml-4.6.4-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9b87727561c1150c0cc91c5d9d389448b37a7d15f0ba939ed3d1acb2f11bf6c5"},
    {file = "lxml-4.6.4-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:45fdb2899c755138722797161547a40b3e2a06feda620cc41195ee7e97806d81"},
    {file = "lxml-4.6.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:38b9de0de3aa689fe9fb9877ae1be1e83b8cf9621f7e62049d0436b9ecf4ad64"},
    {file = "lxml-4.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:662523cd2a0246740225c7e32531f2e766544122e58bee70e700a024cfc0cf81"},
    {file = "lxml-4.6.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:4aa349c5567651f34d4eaae7de6ed5b523f6d70a288f9c6fbac22d13a0784e04"},
    {file = "lxml-4.6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:08eb9200d88b376a8ed5e50f1dc1d1a45b49305169674002a3b5929943390591"},
    {file = "lxml-4.6.4-cp310-cp310-win32.whl", hash = "sha256:bdc224f216ead849e902151112efef6e96c41ee1322e15d4e5f7c8a826929aee"},
    {file = "lxml-4.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:ab6db93a2b6b66cbf62b4e4a7135f476e708e8c5c990d186584142c77d7f975a"},
    {file = "lxml-4.6.4-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:50790313df028aa05cf22be9a8da033b86c42fa32523e4fd944827b482b17bf0"},
    {file = "lxml-4.6.4-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6764998345552b1dfc9326a932d2bad6367c6b37a176bb73ada6b9486bf602f7"},
    {file = "lxml-4.6.4-cp35-cp35m-win32.whl", hash = "sha256:543b239b191bb3b6d9bef5f09f1fb2be5b7eb09ab4d386aa655e4d53fbe9ff47"},
    {file = "lxml-4.6.4-cp35-cp35m-win_amd64.whl", hash = "sha256:a75c1ad05eedb1a3ff2a34a52a4f0836cfaa892e12796ba39a7732c82701eff4"},
    {file = "lxml-4.6.4-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:47e955112ce64241fdb357acf0216081f9f3255b3ac9c502ca4b3323ec1ca558"},
    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:20d7c8d90d449c6a353b15ee0459abae8395dbe59ad01e406ccbf30cd81c6f98"},
    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:240db6f3228d26e3c6f4fad914b9ddaaf8707254e8b3efd564dc680c8ec3c264"},
    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:351482da8dd028834028537f08724b1de22d40dcf3bb723b469446564f409074"},
    {file = "lxml-4.6.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e678a643177c0e5ec947b645fa7bc84260dfb9b6bf8fb1fdd83008dfc2ca5928"},
    {file = "lxml-4.6.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:15d0381feb56f08f78c5cc4fc385ddfe0bde1456e37f54a9322833371aec4060"},
    {file = "lxml-4.6.4-cp36-cp36m-win32.whl", hash = "sha256:4ba74afe5ee5cb5e28d83b513a6e8f0875fda1dc1a9aea42cc0065f029160d2a"},
    {file = "lxml-4.6.4-cp36-cp36m-win_amd64.whl", hash = "sha256:9c91a73971a922c13070fd8fa5a114c858251791ba2122a941e6aa781c713e44"},
    {file = "lxml-4.6.4-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:6020c70ff695106bf80651953a23e37718ef1fee9abd060dcad8e32ab2dc13f3"},
    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f5dd358536b8a964bf6bd48de038754c1609e72e5f17f5d21efe2dda17594dbf"},
    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:7ae7089d81fc502df4b217ad77f03c54039fe90dac0acbe70448d7e53bfbc57e"},
    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:80d10d53d3184837445ff8562021bdd37f57c4cadacbf9d8726cc16220a00d54"},
    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e95da348d57eb448d226a44b868ff2ca5786fbcbe417ac99ff62d0a7d724b9c7"},
    {file = "lxml-4.6.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ffd65cfa33fed01735c82aca640fde4cc63f0414775cba11e06f84fae2085a6e"},
    {file = "lxml-4.6.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:877666418598f6cb289546c77ff87590cfd212f903b522b0afa0b9fb73b3ccfb"},
    {file = "lxml-4.6.4-cp37-cp37m-win32.whl", hash = "sha256:e91d24623e747eeb2d8121f4a94c6a7ad27dc48e747e2dc95bfe88632bd028a2"},
    {file = "lxml-4.6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:4ec9a80dd5704ecfde54319b6964368daf02848c8954d3bacb9b64d1c7659159"},
    {file = "lxml-4.6.4-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:2901625f4a878a055d275beedc20ba9cb359cefc4386a967222fee29eb236038"},
    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b567178a74a2261345890eac66fbf394692a6e002709d329f28a673ca6042473"},
    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4717123f7c11c81e0da69989e5a64079c3f402b0efeb4c6241db6c369d657bd8"},
    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:cf201bf5594d1aab139fe53e3fca457e4f8204a5bbd65d48ab3b82a16f517868"},
    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a77a3470ba37e11872c75ca95baf9b3312133a3d5a5dc720803b23098c653976"},
    {file = "lxml-4.6.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:619c6d2b552bba00491e96c0518aad94002651c108a0f7364ff2d7798812c00e"},
    {file = "lxml-4.6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:601f0ab75538b280aaf1e720eb9d68d4fa104ac274e1e9e6971df488f4dcdb0f"},
    {file = "lxml-4.6.4-cp38-cp38-win32.whl", hash = "sha256:75d3c5bbc0ddbad03bb68b9be638599f67e4b98ed3dcd0fec9f6f39e41ee96cb"},
    {file = "lxml-4.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:4341d135f5660db10184963d9c3418c3e28d7f868aaf8b11a323ebf85813f7f4"},
    {file = "lxml-4.6.4-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:9db24803fa71e3305fe4a7812782b708da21a0b774b130dd1860cf40a6d7a3ee"},
    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:afd60230ad9d8bcba005945ec3a343722f09e0b7f8ae804246e5d2cfc6bd71a6"},
    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:0c15e1cd55055956e77b0732270f1c6005850696bc3ef3e03d01e78af84eaa42"},
    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6d422b3c729737d8a39279a25fa156c983a56458f8b2f97661ee6fb22b80b1d6"},
    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2eb90f6ec3c236ef2f1bb38aee7c0d23e77d423d395af6326e7cca637519a4cb"},
    {file = "lxml-4.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:51a0e5d243687596f46e24e464121d4b232ad772e2d1785b2a2c0eb413c285d4"},
    {file = "lxml-4.6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d43bd68714049c84e297c005456a15ecdec818f7b5aa5868c8b0a865cfb78a44"},
    {file = "lxml-4.6.4-cp39-cp39-win32.whl", hash = "sha256:ee9e4b07b0eba4b6a521509e9e1877476729c1243246b6959de697ebea739643"},
    {file = "lxml-4.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:48eaac2991b3036175b42ee8d3c23f4cca13f2be8426bf29401a690ab58c88f4"},
    {file = "lxml-4.6.4-pp37-pypy37_pp73-macosx_10_14_x86_64.whl", hash = "sha256:2b06a91cf7b8acea7793006e4ae50646cef0fe35ce5acd4f5cb1c77eb228e4a1"},
    {file = "lxml-4.6.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:523f195948a1ba4f9f5b7294d83c6cd876547dc741820750a7e5e893a24bbe38"},
    {file = "lxml-4.6.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b0ca0ada9d3bc18bd6f611bd001a28abdd49ab9698bd6d717f7f5394c8e94628"},
    {file = "lxml-4.6.4-pp38-pypy38_pp73-macosx_10_14_x86_64.whl", hash = "sha256:197b7cb7a753cf553a45115739afd8458464a28913da00f5c525063f94cd3f48"},
    {file = "lxml-4.6.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:6298f5b42a26581206ef63fffa97c754245d329414108707c525512a5197f2ba"},
    {file = "lxml-4.6.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0b12c95542f04d10cba46b3ff28ea52ea56995b78cf918f0b11b05e75812bb79"},
    {file = "lxml-4.6.4.tar.gz", hash = "sha256:daf9bd1fee31f1c7a5928b3e1059e09a8d683ea58fb3ffc773b6c88cb8d1399c"},
]
lxml-stubs = [
    {file = "lxml-stubs-0.2.0.tar.gz", hash = "sha256:78f1bfb31b1f2af9a5c9e9a602ab1b589a64a5a3cc444931a39cdfd02d6864b0"},
    {file = "lxml_stubs-0.2.0-py3-none-any.whl", hash = "sha256:f0b3621ec2a23bea4145f484490c8b27383ecb407b3f8b079199ad4a0af4180b"},
]
mypy = [
    {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"},
    {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"},
    {file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"},
    {file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"},
    {file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"},
    {file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"},
    {file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"},
    {file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"},
    {file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"},
    {file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"},
    {file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"},
    {file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"},
    {file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"},
    {file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"},
    {file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"},
    {file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"},
    {file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"},
    {file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"},
    {file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"},
    {file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"},
    {file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"},
    {file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"},
    {file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"},
]
mypy-extensions = [
    {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
    {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
]
packaging = [
    {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
    {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
]
pluggy = [
    {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
    {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
py = [
    {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
    {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
]
pyparsing = [
    {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
    {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
]
pytest = [
    {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
    {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
]
pytest-container = []
pytest-forked = [
    {file = "pytest-forked-1.3.0.tar.gz", hash = "sha256:6aa9ac7e00ad1a539c41bec6d21011332de671e938c7637378ec9710204e37ca"},
    {file = "pytest_forked-1.3.0-py2.py3-none-any.whl", hash = "sha256:dc4147784048e70ef5d437951728825a131b81714b398d5d52f17c7c144d8815"},
]
pytest-testinfra = [
    {file = "pytest-testinfra-6.4.0.tar.gz", hash = "sha256:5c3d1f61852a4e2c08bf40dbdf9ff004b10ee8308985883986e53d1610c0b2c3"},
    {file = "pytest_testinfra-6.4.0-py3-none-any.whl", hash = "sha256:b3f147cf18608298381b976ba5e161bc625e9f58ca6d8d61eb769fbd99716de6"},
]
pytest-xdist = [
    {file = "pytest-xdist-2.4.0.tar.gz", hash = "sha256:89b330316f7fc475f999c81b577c2b926c9569f3d397ae432c0c2e2496d61ff9"},
    {file = "pytest_xdist-2.4.0-py3-none-any.whl", hash = "sha256:7b61ebb46997a0820a263553179d6d1e25a8c50d8a8620cd1aa1e20e3be99168"},
]
toml = [
    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
typed-ast = [
    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"},
    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"},
    {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"},
    {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"},
    {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"},
    {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"},
    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"},
    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"},
    {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"},
    {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"},
    {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"},
    {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"},
    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"},
    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"},
    {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"},
    {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"},
    {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"},
    {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"},
    {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"},
    {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"},
    {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"},
    {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"},
    {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"},
    {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"},
    {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"},
    {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"},
    {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"},
    {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"},
    {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"},
    {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"},
]
typing-extensions = [
    {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"},
    {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"},
]
urllib3 = [
    {file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
    {file = "urllib3-1.26.7.tar.gz", hash = "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece"},
]
zipp = [
    {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"},
    {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"},
]
0707010000000B000081A400000000000000000000000165B7C7A000000288000000000000000000000000000000000000002800000000obs-service-node_modules/pyproject.toml[tool.poetry]
name = "obs-service-node_modules"
version = "1.0"
description = "Downloads npm packages for offline installation"
authors = ["Ludwig Nussel <ludwig.nussel@suse.de>", "Adam Majer <amajer@suse.de>"]
license = "MIT"

[tool.poetry.dependencies]
python = ">=3.6.2,<4.0"
urllib3 = ">= 1.25.10"
lxml = ">= 4.0.0"

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
pytest-testinfra = "^6.4.0"
lxml-stubs = "^0.2.0"
mypy = "^0.910"
pytest-xdist = "^2.3.0"
pytest_container = { git = "https://github.com/dcermak/pytest_container.git", branch = "main" }

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
0707010000000C000081A400000000000000000000000165B7C7A0000014B7000000000000000000000000000000000000003700000000obs-service-node_modules/test_node_modules_download.pyfrom typing import List

from pytest_container import DerivedContainer


SLE_CONTAINERFILE = """WORKDIR /opt/playground

RUN zypper --non-interactive in python3 python3-pip && \
    pip install urllib3 aiohttp lxml && \
    if python3 -c "import sys; from platform import python_version_tuple; sys.exit(0 if int(python_version_tuple()[1]) < 8 else 1)"; then pip install typing; fi

COPY node_modules.py /bin/node_modules.py
COPY data/package-lock.json /opt/playground/package-lock.json"""

OPENSUSE_CONTAINERFILE = """WORKDIR /opt/playground

RUN zypper -n in python3 python3-urllib3 python3-aiohttp python3-lxml && \
    if python3 -c "import sys; from platform import python_version_tuple; sys.exit(0 if int(python_version_tuple()[1]) < 8 else 1)"; then zypper -n in python3-typing_extensions; fi
COPY node_modules.py /bin/node_modules.py
COPY data/package-lock.json /opt/playground/package-lock.json"""


TUMBLEWEED_CONTAINER = DerivedContainer(
    base="registry.opensuse.org/opensuse/tumbleweed:latest",
    containerfile=OPENSUSE_CONTAINERFILE,
)
LEAP_CONTAINERS = [
    DerivedContainer(
        base="registry.opensuse.org/opensuse/leap:15.3",
        containerfile=OPENSUSE_CONTAINERFILE,
    ),
    DerivedContainer(
        base="registry.opensuse.org/opensuse/leap:15.2",
        containerfile=OPENSUSE_CONTAINERFILE,
    ),
]
SLE_BCI_CONTAINERS = [
    DerivedContainer(
        base="registry.suse.com/suse/sle15:15.3",
        containerfile=SLE_CONTAINERFILE,
    ),
]

CONTAINER_IMAGES: List[DerivedContainer] = (
    [TUMBLEWEED_CONTAINER] + LEAP_CONTAINERS + SLE_BCI_CONTAINERS
)


def test_fetch_debug_js_deps(auto_container):
    """
    This test tries to fetch the dependencies of a stripped down
    package-log.json from debug (https://github.com/visionmedia/debug)
    """
    auto_container.connection.run_expect(
        [0], "cd /opt/playground && /bin/node_modules.py --download"
    )

    tarballs = set(
        auto_container.connection.file("/opt/playground/").listdir()
    )
    tarballs.remove("package-lock.json")
    expected_tarballs = set(
        [
            "acorn-7.4.1.tgz",
            "acorn-node-1.8.2.tgz",
            "acorn-walk-7.2.0.tgz",
            "array-from-2.1.1.tgz",
            "balanced-match-1.0.2.tgz",
            "brace-expansion-1.1.11.tgz",
            "brfs-2.0.2.tgz",
            "browser-stdout-1.3.1.tgz",
            "buffer-equal-0.0.1.tgz",
            "buffer-from-1.1.2.tgz",
            "commander-2.15.1.tgz",
            "concat-map-0.0.1.tgz",
            "concat-stream-1.6.2.tgz",
            "convert-source-map-1.8.0.tgz",
            "core-util-is-1.0.2.tgz",
            "d-1.0.1.tgz",
            "dash-ast-1.0.0.tgz",
            "debug-3.1.0.tgz",
            "deep-is-0.1.3.tgz",
            "diff-3.5.0.tgz",
            "duplexer2-0.1.4.tgz",
            "es5-ext-0.10.53.tgz",
            "es6-iterator-2.0.3.tgz",
            "es6-map-0.1.5.tgz",
            "es6-set-0.1.5.tgz",
            "es6-symbol-3.1.1.tgz",
            "es6-symbol-3.1.3.tgz",
            "escape-string-regexp-1.0.5.tgz",
            "escodegen-1.14.3.tgz",
            "esprima-4.0.1.tgz",
            "estraverse-4.3.0.tgz",
            "estree-is-function-1.0.0.tgz",
            "esutils-2.0.3.tgz",
            "event-emitter-0.3.5.tgz",
            "ext-1.4.0.tgz",
            "fast-levenshtein-2.0.6.tgz",
            "fs.realpath-1.0.0.tgz",
            "function-bind-1.1.1.tgz",
            "get-assigned-identifiers-1.2.0.tgz",
            "glob-7.1.2.tgz",
            "growl-1.10.5.tgz",
            "has-1.0.3.tgz",
            "has-flag-3.0.0.tgz",
            "he-1.1.1.tgz",
            "inflight-1.0.6.tgz",
            "inherits-2.0.4.tgz",
            "isarray-1.0.0.tgz",
            "is-core-module-2.6.0.tgz",
            "levn-0.3.0.tgz",
            "magic-string-0.25.1.tgz",
            "merge-source-map-1.0.4.tgz",
            "minimatch-3.0.4.tgz",
            "minimist-0.0.8.tgz",
            "minimist-1.2.5.tgz",
            "mkdirp-0.5.1.tgz",
            "mocha-5.2.0.tgz",
            "ms-2.0.0.tgz",
            "ms-2.1.2.tgz",
            "next-tick-1.0.0.tgz",
            "object-inspect-1.11.0.tgz",
            "once-1.4.0.tgz",
            "optionator-0.8.3.tgz",
            "path-is-absolute-1.0.1.tgz",
            "path-parse-1.0.7.tgz",
            "prelude-ls-1.1.2.tgz",
            "process-nextick-args-2.0.1.tgz",
            "quote-stream-1.0.2.tgz",
            "readable-stream-2.3.7.tgz",
            "resolve-1.20.0.tgz",
            "safe-buffer-5.1.2.tgz",
            "scope-analyzer-2.1.1.tgz",
            "shallow-copy-0.0.1.tgz",
            "source-map-0.5.7.tgz",
            "source-map-0.6.1.tgz",
            "sourcemap-codec-1.4.8.tgz",
            "static-eval-2.1.0.tgz",
            "static-module-3.0.4.tgz",
            "string_decoder-1.1.1.tgz",
            "supports-color-5.4.0.tgz",
            "through2-2.0.5.tgz",
            "type-1.2.0.tgz",
            "type-2.5.0.tgz",
            "type-check-0.3.2.tgz",
            "typedarray-0.0.6.tgz",
            "util-deprecate-1.0.2.tgz",
            "word-wrap-1.2.3.tgz",
            "wrappy-1.0.2.tgz",
            "xtend-4.0.2.tgz",
        ]
    )
    assert tarballs == expected_tarballs
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!245 blocks
openSUSE Build Service is sponsored by