├── LICENSE
├── README.md
├── docs
└── architecture.png
├── infra
├── .gitignore
├── Pulumi.yaml
├── S3ServiceAccount.ts
├── TraefikRoute.ts
├── index.ts
├── package-lock.json
├── package.json
└── tsconfig.json
└── model-template
├── cookiecutter.json
└── {{cookiecutter.project_slug}}
├── .dockerignore
├── .github
└── workflows
│ └── deploy.yml
├── .gitignore
├── Dockerfile
├── Makefile
├── README.rst
├── data
├── .dvc
│ ├── .gitignore
│ ├── config
│ └── plots
│ │ ├── confusion.json
│ │ ├── confusion_normalized.json
│ │ ├── default.json
│ │ ├── linear.json
│ │ ├── scatter.json
│ │ └── smooth.json
├── .dvcignore
├── .gitignore
└── iris.csv.dvc
├── infra
├── .gitignore
├── Pulumi.yaml
├── TraefikRoute.ts
├── index.ts
├── package-lock.json
├── package.json
└── tsconfig.json
├── poetry.lock
├── pyproject.toml
├── src
└── {{cookiecutter.module_name}}
│ ├── __init__.py
│ ├── serving
│ ├── EXAMPLES.md
│ ├── __init__.py
│ └── __main__.py
│ └── training
│ ├── __init__.py
│ └── train.py
└── tests
├── __init__.py
└── test_{{cookiecutter.module_name}}.py
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2021 Aporia
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ML Platform Workshop
2 |
3 | This repo contains example code for a (very basic) ML platform.
4 |
5 | * The **model-template** directory contains an example for a Cookiecutter-based template that data scientists can clone to start a new project.
6 | * The **infra** directory contains Pulumi code that spins up the shared infrastructure of the ML platform, such as Kubernetes, MLFlow, etc.
7 |
8 |
Made with :heart: by Aporia
9 |
10 | ## The YouTube Video
11 |
12 | [](https://www.youtube.com/watch?v=s8Jj9gzQ3xA)
13 |
14 | ## Why?
15 |
16 | As data science teams become more mature with models reaching actual production, the need for a proper infrastructure becomes crucial. Leading companies in the field with massive engineering teams like Uber, Netflix and Airbnb had created multiple solutions for their infrastructure and named the combination of them as “ML Platform”.
17 |
18 | We hope this repo can help you get started with building your own ML platform ❤️
19 |
20 | ## Architecture
21 |
22 |
23 |
24 | ### Based on the following projects:
25 | * [FastAPI](https://fastapi.tiangolo.com/) - for model serving
26 | * [MLFlow](https://www.mlflow.org/) - for experiment tracking
27 | * [DVC](https://dvc.org/) - for data versioning
28 | * [Cookiecutter](https://cookiecutter.readthedocs.io/) - for the model template
29 | * [Pulumi](https://www.pulumi.com/) - Infrastructure as Code
30 | * [GitHub Actions](https://github.com/features/actions) - for CI/CD
31 | * [Traefik](https://traefik.io/) - API gateway
32 | * [Poetry](https://python-poetry.org/) - Python dependency management
33 |
34 | When building your own ML platform, do not take these tools for granted! [Check out alternatives](https://mlops.toys) and find the best tools that solve each one of your problems.
35 |
36 |
37 | ## What's missing from this?
38 |
39 | Well... a lot actually. Here's a partial list:
40 |
41 | * HTTPS & Authentication
42 | * Environments (staging, production)
43 | * Common library for preprocessing, postprocessing, etc
44 | * Model input & validation
45 | * Training orchestration
46 | * and probably much more!
47 |
48 | We would love your help!
49 |
--------------------------------------------------------------------------------
/docs/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aporia-ai/mlplatform-workshop/268141ed1d2d6c3b18c743680945bda92265cef1/docs/architecture.png
--------------------------------------------------------------------------------
/infra/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 | /node_modules/
3 |
--------------------------------------------------------------------------------
/infra/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: mlplatform-infra
2 | runtime: nodejs
3 | description: Infrastructure for open ML platform
4 |
--------------------------------------------------------------------------------
/infra/S3ServiceAccount.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from '@pulumi/pulumi';
2 | import * as aws from '@pulumi/aws';
3 | import * as k8s from '@pulumi/kubernetes';
4 |
5 | export interface S3ServiceAccountArgs {
6 | oidcProvider: aws.iam.OpenIdConnectProvider;
7 | namespace: pulumi.Input;
8 | readOnly: pulumi.Input;
9 | }
10 |
11 | export default class S3ServiceAccount extends pulumi.ComponentResource {
12 | public /*out*/ readonly name: pulumi.Output;
13 | public /*out*/ readonly serviceAccount: pulumi.Output;
14 | public /*out*/ readonly role: pulumi.Output;
15 |
16 | constructor(name: string, args: S3ServiceAccountArgs, opts?: pulumi.ResourceOptions) {
17 | super("pkg:index:S3ServiceAccount", name, {}, opts);
18 |
19 | // Create the new IAM policy for the Service Account using the AssumeRoleWebWebIdentity action.
20 | const serviceAccountAssumeRolePolicy = pulumi
21 | .all([args.oidcProvider.url, args.oidcProvider.arn, args.namespace])
22 | .apply(([url, arn, namespace]: string[]) =>
23 | aws.iam.getPolicyDocument({
24 | statements: [
25 | {
26 | actions: ['sts:AssumeRoleWithWebIdentity'],
27 | conditions: [{
28 | test: 'StringEquals',
29 | values: [`system:serviceaccount:${namespace}:${name}`],
30 | variable: `${url.replace('https://', '')}:sub`,
31 | },],
32 | effect: 'Allow',
33 | principals: [{identifiers: [arn], type: 'Federated'}],
34 | },
35 | ],
36 | })
37 | );
38 |
39 | // Create a new IAM role that assumes the AssumeRoleWebWebIdentity policy.
40 | const serviceAccountRole = new aws.iam.Role(name, {
41 | assumeRolePolicy: serviceAccountAssumeRolePolicy.json,
42 | });
43 |
44 | // Attach the IAM role to an AWS S3 access policy.
45 | new aws.iam.RolePolicyAttachment(name, {
46 | policyArn: args.readOnly ?
47 | 'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess' :
48 | 'arn:aws:iam::aws:policy/AmazonS3FullAccess',
49 | role: serviceAccountRole,
50 | });
51 |
52 | // Create a Service Account with the IAM role annotated to use with the Pod.
53 | this.serviceAccount = pulumi.output(new k8s.core.v1.ServiceAccount(name, {
54 | metadata: {
55 | namespace: args.namespace,
56 | name,
57 | annotations: {
58 | 'eks.amazonaws.com/role-arn': serviceAccountRole.arn,
59 | },
60 | },
61 | }, { provider: opts?.provider }));
62 |
63 | this.name = pulumi.output(this.serviceAccount.metadata.name);
64 | this.role = pulumi.output(serviceAccountRole);
65 |
66 | super.registerOutputs({
67 | name: this.serviceAccount.metadata.name,
68 | serviceAccount: this.serviceAccount,
69 | role: serviceAccountRole,
70 | });
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/infra/TraefikRoute.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from '@pulumi/pulumi';
2 | import * as k8s from '@pulumi/kubernetes';
3 |
4 | export interface TraefikRouteArgs {
5 | namespace: pulumi.Input;
6 | prefix: pulumi.Input;
7 | service: pulumi.Input|string;
8 | stripPrefix?: pulumi.Input|undefined;
9 | port?: pulumi.Input|undefined;
10 | }
11 |
12 | export default class TraefikRoute extends pulumi.ComponentResource {
13 | constructor(name: string, args: TraefikRouteArgs, opts?: pulumi.ResourceOptions) {
14 | super("pkg:index:TraefikRoute", name, {}, opts);
15 |
16 | const middlewares = []
17 |
18 | // Remove trailing /
19 | const trailingSlashMiddleware = new k8s.apiextensions.CustomResource(`${name}-trailing-slash`, {
20 | apiVersion: 'traefik.containo.us/v1alpha1',
21 | kind: 'Middleware',
22 | metadata: { namespace: args.namespace },
23 | spec: {
24 | redirectRegex: {
25 | regex: `^.*\\${args.prefix}$`,
26 | replacement: `${args.prefix}/`,
27 | permanent: false,
28 | },
29 | },
30 | }, { provider: opts?.provider });
31 |
32 | middlewares.push({ name: trailingSlashMiddleware.metadata.name });
33 |
34 | // Strip prefix
35 | if (args.stripPrefix || args.stripPrefix === undefined) {
36 | const stripPrefixMiddleware = new k8s.apiextensions.CustomResource(`${name}-strip-prefix`, {
37 | apiVersion: 'traefik.containo.us/v1alpha1',
38 | kind: 'Middleware',
39 | metadata: { namespace: args.namespace },
40 | spec: {
41 | stripPrefix: {
42 | prefixes: [args.prefix],
43 | },
44 | },
45 | }, { provider: opts?.provider });
46 |
47 | middlewares.push({ name: stripPrefixMiddleware.metadata.name });
48 | }
49 |
50 | new k8s.apiextensions.CustomResource(`${name}-ingress-route`, {
51 | apiVersion: 'traefik.containo.us/v1alpha1',
52 | kind: 'IngressRoute',
53 | metadata: { namespace: args.namespace },
54 | spec: {
55 | entryPoints: ['web'],
56 | routes: [{
57 | match: `PathPrefix(\`${args.prefix}\`)`,
58 | kind: 'Rule',
59 | middlewares,
60 | services: [{
61 | name: typeof args.service === "string" ? args.service : pulumi.output(args.service).metadata.name,
62 | port: args.port ? args.port :
63 | (typeof args.service !== "string" ? pulumi.output(args.service).spec.ports[0].port : 80),
64 | }],
65 | }]
66 | },
67 | }, { provider: opts?.provider });
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/infra/index.ts:
--------------------------------------------------------------------------------
1 | import * as aws from '@pulumi/aws';
2 | import * as eks from '@pulumi/eks';
3 | import * as k8s from '@pulumi/kubernetes';
4 | import * as random from '@pulumi/random';
5 | import S3ServiceAccount from './S3ServiceAccount';
6 | import TraefikRoute from './TraefikRoute';
7 |
8 |
9 | // Create a Kubernetes cluster.
10 | const cluster = new eks.Cluster('mlplatform-eks', {
11 | createOidcProvider: true,
12 | });
13 |
14 |
15 | // Install Traefik
16 | const traefik = new k8s.helm.v3.Chart('traefik', {
17 | chart: 'traefik',
18 | fetchOpts: { repo: 'https://containous.github.io/traefik-helm-chart' },
19 | }, { provider: cluster.provider })
20 |
21 |
22 |
23 | // Create PostgreSQL database for MLFlow - this will save model metadata
24 | const dbPassword = new random.RandomPassword('mlplatform-db-password', { length: 16, special: false });
25 | const db = new aws.rds.Instance('mlflow-db', {
26 | allocatedStorage: 10,
27 | engine: "postgres",
28 | engineVersion: "11.10",
29 | instanceClass: "db.t3.medium",
30 | name: "mlflow",
31 | password: dbPassword.result,
32 | skipFinalSnapshot: true,
33 | vpcSecurityGroupIds: [cluster.clusterSecurityGroup.id, cluster.nodeSecurityGroup.id],
34 | username: "postgres",
35 | });
36 |
37 |
38 | // Create S3 bucket for MLFlow
39 | const mlflowBucket = new aws.s3.Bucket("mlflow-bucket", {
40 | acl: "public-read-write",
41 | });
42 |
43 |
44 | // Create S3 bucket for DVC
45 | const dvcBucket = new aws.s3.Bucket("dvc-bucket", {
46 | acl: "public-read-write",
47 | });
48 |
49 |
50 | // Install MLFlow
51 | const mlflowNamespace = new k8s.core.v1.Namespace('mlflow-namespace', {
52 | metadata: { name: 'mlflow' },
53 | }, { provider: cluster.provider });
54 |
55 | const mlflowServiceAccount = new S3ServiceAccount('mlflow-service-account', {
56 | namespace: mlflowNamespace.metadata.name,
57 | oidcProvider: cluster.core.oidcProvider!,
58 | readOnly: false,
59 | }, { provider: cluster.provider });
60 |
61 | const mlflow = new k8s.helm.v3.Chart("mlflow", {
62 | chart: "mlflow",
63 | namespace: mlflowNamespace.metadata.name,
64 | values: {
65 | "backendStore": {
66 | "postgres": {
67 | "username": db.username,
68 | "password": db.password,
69 | "host": db.address,
70 | "port": db.port,
71 | "database": "mlflow"
72 | }
73 | },
74 | "defaultArtifactRoot": mlflowBucket.bucket.apply((bucketName: string) => `s3://${bucketName}`),
75 | "serviceAccount": {
76 | "create": false,
77 | "name": mlflowServiceAccount.name,
78 | }
79 | },
80 | fetchOpts: { repo: "https://larribas.me/helm-charts" },
81 | }, { provider: cluster.provider });
82 |
83 |
84 | // Expose MLFlow in Traefik as /mlflow
85 | new TraefikRoute('mlflow', {
86 | prefix: '/mlflow',
87 | service: mlflow.getResource('v1/Service', 'mlflow', 'mlflow'),
88 | namespace: mlflowNamespace.metadata.name,
89 | }, { provider: cluster.provider, dependsOn: [mlflow] });
90 |
91 |
92 | // Service account for models with read only access to models
93 | const modelsServiceAccount = new S3ServiceAccount('models-service-account', {
94 | namespace: 'default',
95 | oidcProvider: cluster.core.oidcProvider!,
96 | readOnly: true,
97 | }, { provider: cluster.provider });
98 |
99 |
100 | // Set ml.mycompany.com DNS record in Route53
101 | new aws.route53.Record("record", {
102 | zoneId: "",
103 | name: "ml.mycompany.com",
104 | type: "CNAME",
105 | ttl: 300,
106 | records: [traefik.getResource('v1/Service', 'traefik').status.loadBalancer.ingress[0].hostname],
107 | });
108 |
109 |
110 | export const kubeconfig = cluster.kubeconfig;
111 | export const mlflowTrackingURI = `http://ml.mycompany.com/mlflow`;
112 | export const dvcBucketURI = dvcBucket.bucket.apply((bucketName: string) => `s3://${bucketName}`);
113 | export const modelsServiceAccountName = modelsServiceAccount.name;
114 |
--------------------------------------------------------------------------------
/infra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mlplatform-infra",
3 | "devDependencies": {
4 | "@types/node": "^14.14.41"
5 | },
6 | "dependencies": {
7 | "@pulumi/aws": "^4.0.0",
8 | "@pulumi/awsx": "^0.30.0",
9 | "@pulumi/eks": "^0.30.0",
10 | "@pulumi/kubernetes": "^3.0.0",
11 | "@pulumi/pulumi": "^3.0.0",
12 | "@pulumi/random": "^4.0.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/infra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "outDir": "bin",
5 | "target": "es2016",
6 | "module": "commonjs",
7 | "moduleResolution": "node",
8 | "sourceMap": true,
9 | "experimentalDecorators": true,
10 | "pretty": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true
14 | },
15 | "files": [
16 | "index.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/model-template/cookiecutter.json:
--------------------------------------------------------------------------------
1 | {
2 | "full_name": "Alon Gubkin",
3 | "email": "alon@aporia.com",
4 | "project_name": "My Model",
5 | "project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '-') }}",
6 | "module_name": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}",
7 | "project_short_description": "My awesome model!",
8 | "version": "0.1.0"
9 | }
10 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .cache
3 | __pycache__
4 | node_modules
5 | data
6 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | deploy:
8 | runs-on: ubuntu-20.04
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@master
12 |
13 | - name: Install dependencies
14 | run: make install-deps
15 |
16 | - name: Deploy
17 | run: make deploy
18 | env:
19 | AWS_ACCESS_KEY_ID: {% raw %}${{ secrets.AWS_ACCESS_KEY_ID }}{% endraw %}
20 | AWS_SECRET_ACCESS_KEY: {% raw %}${{ secrets.AWS_SECRET_ACCESS_KEY }}{% endraw %}
21 | AWS_REGION: {% raw %}${{ secrets.AWS_REGION }}{% endraw %}
22 | AWS_ECR_ACCOUNT_URL: {% raw %}${{ secrets.AWS_ECR_ACCOUNT_URL }}{% endraw %}
23 | PULUMI_ACCESS_TOKEN: {% raw %}${{ secrets.PULUMI_ACCESS_TOKEN }}{% endraw %}
24 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 |
132 | mlruns
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-slim
2 | WORKDIR /{{cookiecutter.project_slug}}
3 | STOPSIGNAL SIGINT
4 |
5 | ENV LISTEN_PORT 80
6 |
7 | # System dependencies
8 | RUN apt update && apt install -y libgomp1
9 | RUN pip3 install poetry
10 |
11 | # Project dependencies
12 | COPY poetry.lock pyproject.toml ./
13 |
14 | RUN poetry config virtualenvs.create false
15 | RUN poetry install --no-interaction --no-ansi --no-dev
16 |
17 | COPY . .
18 |
19 | WORKDIR /{{cookiecutter.project_slug}}/src
20 | ENTRYPOINT uvicorn {{cookiecutter.module_name}}.serving.__main__:app --host 0.0.0.0 --port $LISTEN_PORT --workers 2
21 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/Makefile:
--------------------------------------------------------------------------------
1 | SHELL := /bin/bash
2 |
3 | STACK_NAME=dev5
4 | BASE_STACK_NAME=mlplatform-infra/dev
5 | PULUMI_CMD=pulumi --non-interactive --stack $(STACK_NAME) --cwd infra/
6 |
7 | install-deps:
8 | curl -fsSL https://get.pulumi.com | sh
9 | npm install -C infra/
10 |
11 | sudo pip3 install poetry --upgrade
12 | poetry install
13 |
14 | train:
15 | poetry run train
16 |
17 | dvc-pull:
18 | poetry run dvc --cd data/ pull
19 |
20 | deploy: dvc-pull
21 | $(PULUMI_CMD) stack init $(STACK_NAME) || true
22 | $(PULUMI_CMD) config set aws:region $(AWS_REGION)
23 | $(PULUMI_CMD) config set baseStackName $(BASE_STACK_NAME)
24 | $(PULUMI_CMD) config set runID $(shell poetry run train | awk '/Run ID/{print $$NF}')
25 | $(PULUMI_CMD) up --yes --skip-preview
26 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/README.rst:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aporia-ai/mlplatform-workshop/268141ed1d2d6c3b18c743680945bda92265cef1/model-template/{{cookiecutter.project_slug}}/README.rst
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/.gitignore:
--------------------------------------------------------------------------------
1 | /config.local
2 | /tmp
3 | /cache
4 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/config:
--------------------------------------------------------------------------------
1 | [core]
2 | remote = s3
3 | ['remote "s3"']
4 | url = s3://dvc-bucket-511118e
5 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/plots/confusion.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
3 | "data": {
4 | "values": ""
5 | },
6 | "title": "",
7 | "facet": {
8 | "field": "rev",
9 | "type": "nominal"
10 | },
11 | "spec": {
12 | "transform": [
13 | {
14 | "aggregate": [
15 | {
16 | "op": "count",
17 | "as": "xy_count"
18 | }
19 | ],
20 | "groupby": [
21 | "",
22 | ""
23 | ]
24 | },
25 | {
26 | "impute": "xy_count",
27 | "groupby": [
28 | "rev",
29 | ""
30 | ],
31 | "key": "",
32 | "value": 0
33 | },
34 | {
35 | "impute": "xy_count",
36 | "groupby": [
37 | "rev",
38 | ""
39 | ],
40 | "key": "",
41 | "value": 0
42 | },
43 | {
44 | "joinaggregate": [
45 | {
46 | "op": "max",
47 | "field": "xy_count",
48 | "as": "max_count"
49 | }
50 | ],
51 | "groupby": []
52 | },
53 | {
54 | "calculate": "datum.xy_count / datum.max_count",
55 | "as": "percent_of_max"
56 | }
57 | ],
58 | "encoding": {
59 | "x": {
60 | "field": "",
61 | "type": "nominal",
62 | "sort": "ascending",
63 | "title": ""
64 | },
65 | "y": {
66 | "field": "",
67 | "type": "nominal",
68 | "sort": "ascending",
69 | "title": ""
70 | }
71 | },
72 | "layer": [
73 | {
74 | "mark": "rect",
75 | "width": 300,
76 | "height": 300,
77 | "encoding": {
78 | "color": {
79 | "field": "xy_count",
80 | "type": "quantitative",
81 | "title": "",
82 | "scale": {
83 | "domainMin": 0,
84 | "nice": true
85 | }
86 | }
87 | }
88 | },
89 | {
90 | "mark": "text",
91 | "encoding": {
92 | "text": {
93 | "field": "xy_count",
94 | "type": "quantitative"
95 | },
96 | "color": {
97 | "condition": {
98 | "test": "datum.percent_of_max > 0.5",
99 | "value": "white"
100 | },
101 | "value": "black"
102 | }
103 | }
104 | }
105 | ]
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/plots/confusion_normalized.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
3 | "data": {
4 | "values": ""
5 | },
6 | "title": "",
7 | "facet": {
8 | "field": "rev",
9 | "type": "nominal"
10 | },
11 | "spec": {
12 | "transform": [
13 | {
14 | "aggregate": [
15 | {
16 | "op": "count",
17 | "as": "xy_count"
18 | }
19 | ],
20 | "groupby": [
21 | "",
22 | ""
23 | ]
24 | },
25 | {
26 | "impute": "xy_count",
27 | "groupby": [
28 | "rev",
29 | ""
30 | ],
31 | "key": "",
32 | "value": 0
33 | },
34 | {
35 | "impute": "xy_count",
36 | "groupby": [
37 | "rev",
38 | ""
39 | ],
40 | "key": "",
41 | "value": 0
42 | },
43 | {
44 | "joinaggregate": [
45 | {
46 | "op": "sum",
47 | "field": "xy_count",
48 | "as": "sum_y"
49 | }
50 | ],
51 | "groupby": [
52 | ""
53 | ]
54 | },
55 | {
56 | "calculate": "datum.xy_count / datum.sum_y",
57 | "as": "percent_of_y"
58 | }
59 | ],
60 | "encoding": {
61 | "x": {
62 | "field": "",
63 | "type": "nominal",
64 | "sort": "ascending",
65 | "title": ""
66 | },
67 | "y": {
68 | "field": "",
69 | "type": "nominal",
70 | "sort": "ascending",
71 | "title": ""
72 | }
73 | },
74 | "layer": [
75 | {
76 | "mark": "rect",
77 | "width": 300,
78 | "height": 300,
79 | "encoding": {
80 | "color": {
81 | "field": "percent_of_y",
82 | "type": "quantitative",
83 | "title": "",
84 | "scale": {
85 | "domain": [
86 | 0,
87 | 1
88 | ]
89 | }
90 | }
91 | }
92 | },
93 | {
94 | "mark": "text",
95 | "encoding": {
96 | "text": {
97 | "field": "percent_of_y",
98 | "type": "quantitative",
99 | "format": ".2f"
100 | },
101 | "color": {
102 | "condition": {
103 | "test": "datum.percent_of_y > 0.5",
104 | "value": "white"
105 | },
106 | "value": "black"
107 | }
108 | }
109 | }
110 | ]
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/plots/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
3 | "data": {
4 | "values": ""
5 | },
6 | "title": "",
7 | "width": 300,
8 | "height": 300,
9 | "mark": {
10 | "type": "line"
11 | },
12 | "encoding": {
13 | "x": {
14 | "field": "",
15 | "type": "quantitative",
16 | "title": ""
17 | },
18 | "y": {
19 | "field": "",
20 | "type": "quantitative",
21 | "title": "",
22 | "scale": {
23 | "zero": false
24 | }
25 | },
26 | "color": {
27 | "field": "rev",
28 | "type": "nominal"
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/plots/linear.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
3 | "data": {
4 | "values": ""
5 | },
6 | "title": "",
7 | "width": 300,
8 | "height": 300,
9 | "layer": [
10 | {
11 | "encoding": {
12 | "x": {
13 | "field": "",
14 | "type": "quantitative",
15 | "title": ""
16 | },
17 | "y": {
18 | "field": "",
19 | "type": "quantitative",
20 | "title": "",
21 | "scale": {
22 | "zero": false
23 | }
24 | },
25 | "color": {
26 | "field": "rev",
27 | "type": "nominal"
28 | }
29 | },
30 | "layer": [
31 | {
32 | "mark": "line"
33 | },
34 | {
35 | "selection": {
36 | "label": {
37 | "type": "single",
38 | "nearest": true,
39 | "on": "mouseover",
40 | "encodings": [
41 | "x"
42 | ],
43 | "empty": "none",
44 | "clear": "mouseout"
45 | }
46 | },
47 | "mark": "point",
48 | "encoding": {
49 | "opacity": {
50 | "condition": {
51 | "selection": "label",
52 | "value": 1
53 | },
54 | "value": 0
55 | }
56 | }
57 | }
58 | ]
59 | },
60 | {
61 | "transform": [
62 | {
63 | "filter": {
64 | "selection": "label"
65 | }
66 | }
67 | ],
68 | "layer": [
69 | {
70 | "mark": {
71 | "type": "rule",
72 | "color": "gray"
73 | },
74 | "encoding": {
75 | "x": {
76 | "field": "",
77 | "type": "quantitative"
78 | }
79 | }
80 | },
81 | {
82 | "encoding": {
83 | "text": {
84 | "type": "quantitative",
85 | "field": ""
86 | },
87 | "x": {
88 | "field": "",
89 | "type": "quantitative"
90 | },
91 | "y": {
92 | "field": "",
93 | "type": "quantitative"
94 | }
95 | },
96 | "layer": [
97 | {
98 | "mark": {
99 | "type": "text",
100 | "align": "left",
101 | "dx": 5,
102 | "dy": -5
103 | },
104 | "encoding": {
105 | "color": {
106 | "type": "nominal",
107 | "field": "rev"
108 | }
109 | }
110 | }
111 | ]
112 | }
113 | ]
114 | }
115 | ]
116 | }
117 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/plots/scatter.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
3 | "data": {
4 | "values": ""
5 | },
6 | "title": "",
7 | "width": 300,
8 | "height": 300,
9 | "layer": [
10 | {
11 | "encoding": {
12 | "x": {
13 | "field": "",
14 | "type": "quantitative",
15 | "title": ""
16 | },
17 | "y": {
18 | "field": "",
19 | "type": "quantitative",
20 | "title": "",
21 | "scale": {
22 | "zero": false
23 | }
24 | },
25 | "color": {
26 | "field": "rev",
27 | "type": "nominal"
28 | }
29 | },
30 | "layer": [
31 | {
32 | "mark": "point"
33 | },
34 | {
35 | "selection": {
36 | "label": {
37 | "type": "single",
38 | "nearest": true,
39 | "on": "mouseover",
40 | "encodings": [
41 | "x"
42 | ],
43 | "empty": "none",
44 | "clear": "mouseout"
45 | }
46 | },
47 | "mark": "point",
48 | "encoding": {
49 | "opacity": {
50 | "condition": {
51 | "selection": "label",
52 | "value": 1
53 | },
54 | "value": 0
55 | }
56 | }
57 | }
58 | ]
59 | },
60 | {
61 | "transform": [
62 | {
63 | "filter": {
64 | "selection": "label"
65 | }
66 | }
67 | ],
68 | "layer": [
69 | {
70 | "encoding": {
71 | "text": {
72 | "type": "quantitative",
73 | "field": ""
74 | },
75 | "x": {
76 | "field": "",
77 | "type": "quantitative"
78 | },
79 | "y": {
80 | "field": "",
81 | "type": "quantitative"
82 | }
83 | },
84 | "layer": [
85 | {
86 | "mark": {
87 | "type": "text",
88 | "align": "left",
89 | "dx": 5,
90 | "dy": -5
91 | },
92 | "encoding": {
93 | "color": {
94 | "type": "nominal",
95 | "field": "rev"
96 | }
97 | }
98 | }
99 | ]
100 | }
101 | ]
102 | }
103 | ]
104 | }
105 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvc/plots/smooth.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://vega.github.io/schema/vega-lite/v4.json",
3 | "data": {
4 | "values": ""
5 | },
6 | "title": "",
7 | "mark": {
8 | "type": "line"
9 | },
10 | "encoding": {
11 | "x": {
12 | "field": "",
13 | "type": "quantitative",
14 | "title": ""
15 | },
16 | "y": {
17 | "field": "",
18 | "type": "quantitative",
19 | "title": "",
20 | "scale": {
21 | "zero": false
22 | }
23 | },
24 | "color": {
25 | "field": "rev",
26 | "type": "nominal"
27 | }
28 | },
29 | "transform": [
30 | {
31 | "loess": "",
32 | "on": "",
33 | "groupby": [
34 | "rev"
35 | ],
36 | "bandwidth": 0.3
37 | }
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.dvcignore:
--------------------------------------------------------------------------------
1 | # Add patterns of files dvc should ignore, which could improve
2 | # the performance. Learn more at
3 | # https://dvc.org/doc/user-guide/dvcignore
4 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/.gitignore:
--------------------------------------------------------------------------------
1 | /iris.csv
2 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/data/iris.csv.dvc:
--------------------------------------------------------------------------------
1 | outs:
2 | - md5: 341a3b5244f213282b7b0920b729c592
3 | size: 4125
4 | path: iris.csv
5 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/infra/.gitignore:
--------------------------------------------------------------------------------
1 | /bin/
2 | /node_modules/
3 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/infra/Pulumi.yaml:
--------------------------------------------------------------------------------
1 | name: {{cookiecutter.project_slug}}-infra
2 | runtime: nodejs
3 | description: Serving infrastructure for {{cookiecutter.project_slug}}
4 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/infra/TraefikRoute.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from '@pulumi/pulumi';
2 | import * as k8s from '@pulumi/kubernetes';
3 |
4 | export interface TraefikRouteArgs {
5 | namespace: pulumi.Input;
6 | prefix: pulumi.Input;
7 | service: pulumi.Input;
8 | }
9 |
10 | export default class TraefikRoute extends pulumi.ComponentResource {
11 | constructor(name: string, args: TraefikRouteArgs, opts?: pulumi.ResourceOptions) {
12 | super("pkg:index:TraefikRoute", name, {}, opts);
13 |
14 | const trailingSlashMiddleware = new k8s.apiextensions.CustomResource(`${name}-trailing-slash`, {
15 | apiVersion: 'traefik.containo.us/v1alpha1',
16 | kind: 'Middleware',
17 | metadata: { namespace: args.namespace },
18 | spec: {
19 | redirectRegex: {
20 | regex: `^.*\\${args.prefix}$`,
21 | replacement: `${args.prefix}/`,
22 | permanent: false,
23 | },
24 | },
25 | }, { provider: opts?.provider });
26 |
27 | const stripPrefixMiddleware = new k8s.apiextensions.CustomResource(`${name}-strip-prefix`, {
28 | apiVersion: 'traefik.containo.us/v1alpha1',
29 | kind: 'Middleware',
30 | metadata: { namespace: args.namespace },
31 | spec: {
32 | stripPrefix: {
33 | prefixes: [args.prefix],
34 | },
35 | },
36 | }, { provider: opts?.provider });
37 |
38 | new k8s.apiextensions.CustomResource(`${name}-ingress-route`, {
39 | apiVersion: 'traefik.containo.us/v1alpha1',
40 | kind: 'IngressRoute',
41 | metadata: { namespace: args.namespace },
42 | spec: {
43 | entryPoints: ['web'],
44 | routes: [{
45 | match: `PathPrefix(\`${args.prefix}\`)`,
46 | kind: 'Rule',
47 | middlewares: [
48 | { name: trailingSlashMiddleware.metadata.name },
49 | { name: stripPrefixMiddleware.metadata.name },
50 | ],
51 | services: [{
52 | name: pulumi.output(args.service).metadata.name,
53 | port: pulumi.output(args.service).spec.ports[0].port,
54 | }],
55 | }]
56 | },
57 | }, { provider: opts?.provider, dependsOn: [trailingSlashMiddleware, stripPrefixMiddleware] });
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/infra/index.ts:
--------------------------------------------------------------------------------
1 | import * as pulumi from '@pulumi/pulumi';
2 | import * as awsx from '@pulumi/awsx';
3 | import * as k8s from '@pulumi/kubernetes';
4 | import * as kx from '@pulumi/kubernetesx';
5 | import TraefikRoute from './TraefikRoute';
6 |
7 | const config = new pulumi.Config();
8 | const baseStack = new pulumi.StackReference(config.require('baseStackName'))
9 |
10 | const provider = new k8s.Provider('provider', {
11 | kubeconfig: baseStack.requireOutput('kubeconfig'),
12 | })
13 |
14 | const image = awsx.ecr.buildAndPushImage('{{cookiecutter.project_slug}}-image', {
15 | context: '../',
16 | });
17 |
18 | const podBuilder = new kx.PodBuilder({
19 | containers: [{
20 | image: image.imageValue,
21 | ports: { http: 80 },
22 | env: {
23 | 'LISTEN_PORT': '80',
24 | 'MLFLOW_TRACKING_URI': baseStack.requireOutput('mlflowTrackingURI'),
25 | 'MLFLOW_RUN_ID': config.require('runID'),
26 | }
27 | }],
28 | serviceAccountName: baseStack.requireOutput('modelsServiceAccountName'),
29 | });
30 |
31 | const deployment = new kx.Deployment('{{cookiecutter.project_slug}}-serving', {
32 | spec: podBuilder.asDeploymentSpec({ replicas: 3 })
33 | }, { provider });
34 |
35 | const service = deployment.createService();
36 |
37 |
38 | // Expose model in Traefik
39 | new TraefikRoute('{{cookiecutter.project_slug}}', {
40 | prefix: '/models/{{cookiecutter.project_slug}}',
41 | service,
42 | namespace: 'default',
43 | }, { provider, dependsOn: [service] });
44 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/infra/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{cookiecutter.project_slug}}-infra",
3 | "lockfileVersion": 2,
4 | "requires": true,
5 | "packages": {
6 | "": {
7 | "name": "{{cookiecutter.project_slug}}-infra",
8 | "dependencies": {
9 | "@pulumi/aws": "^4.0.0",
10 | "@pulumi/awsx": "^0.30.0",
11 | "@pulumi/kubernetes": "^3.3.0",
12 | "@pulumi/kubernetesx": "^0.1.6",
13 | "@pulumi/pulumi": "^3.0.0"
14 | },
15 | "devDependencies": {
16 | "@types/node": "^10.0.0"
17 | }
18 | },
19 | "node_modules/@grpc/grpc-js": {
20 | "version": "1.3.2",
21 | "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz",
22 | "integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==",
23 | "dependencies": {
24 | "@types/node": ">=12.12.47"
25 | },
26 | "engines": {
27 | "node": "^8.13.0 || >=10.10.0"
28 | }
29 | },
30 | "node_modules/@grpc/grpc-js/node_modules/@types/node": {
31 | "version": "15.12.0",
32 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.0.tgz",
33 | "integrity": "sha512-+aHJvoCsVhO2ZCuT4o5JtcPrCPyDE3+1nvbDprYes+pPkEsbjH7AGUCNtjMOXS0fqH14t+B7yLzaqSz92FPWyw=="
34 | },
35 | "node_modules/@logdna/tail-file": {
36 | "version": "2.0.7",
37 | "resolved": "https://registry.npmjs.org/@logdna/tail-file/-/tail-file-2.0.7.tgz",
38 | "integrity": "sha512-ycw0OrbphtfGOnygF+J4J/kJELXifLUiQ/CSTMb9Ztqjnuq4h+Id3MEvt4FTyyyekYbzStx7TjkhqXFW6Mi9LA==",
39 | "engines": {
40 | "node": ">=10.3.0"
41 | }
42 | },
43 | "node_modules/@protobufjs/aspromise": {
44 | "version": "1.1.2",
45 | "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
46 | "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
47 | },
48 | "node_modules/@protobufjs/base64": {
49 | "version": "1.1.2",
50 | "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
51 | "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
52 | },
53 | "node_modules/@protobufjs/codegen": {
54 | "version": "2.0.4",
55 | "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
56 | "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
57 | },
58 | "node_modules/@protobufjs/eventemitter": {
59 | "version": "1.1.0",
60 | "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
61 | "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
62 | },
63 | "node_modules/@protobufjs/fetch": {
64 | "version": "1.1.0",
65 | "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
66 | "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
67 | "dependencies": {
68 | "@protobufjs/aspromise": "^1.1.1",
69 | "@protobufjs/inquire": "^1.1.0"
70 | }
71 | },
72 | "node_modules/@protobufjs/float": {
73 | "version": "1.0.2",
74 | "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
75 | "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
76 | },
77 | "node_modules/@protobufjs/inquire": {
78 | "version": "1.1.0",
79 | "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
80 | "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
81 | },
82 | "node_modules/@protobufjs/path": {
83 | "version": "1.1.2",
84 | "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
85 | "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
86 | },
87 | "node_modules/@protobufjs/pool": {
88 | "version": "1.1.0",
89 | "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
90 | "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
91 | },
92 | "node_modules/@protobufjs/utf8": {
93 | "version": "1.1.0",
94 | "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
95 | "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
96 | },
97 | "node_modules/@pulumi/aws": {
98 | "version": "4.6.0",
99 | "resolved": "https://registry.npmjs.org/@pulumi/aws/-/aws-4.6.0.tgz",
100 | "integrity": "sha512-it0Q9FUd7v/2PgAvoXxTrTT/kQM1iwLNrxnBDabByQsGIOpp4jj4C+sexOoMH4IbKz6mwkLUaPS84QU/qDfndg==",
101 | "hasInstallScript": true,
102 | "dependencies": {
103 | "@pulumi/pulumi": "^3.0.0",
104 | "aws-sdk": "^2.0.0",
105 | "builtin-modules": "3.0.0",
106 | "mime": "^2.0.0",
107 | "read-package-tree": "^5.2.1",
108 | "resolve": "^1.7.1"
109 | }
110 | },
111 | "node_modules/@pulumi/awsx": {
112 | "version": "0.30.0",
113 | "resolved": "https://registry.npmjs.org/@pulumi/awsx/-/awsx-0.30.0.tgz",
114 | "integrity": "sha512-QtYVDFSkZxJ/JkAxaSwms9i/tJU2rA9F/VncCN6e8D0r29C5t4eYQhmB4chsLww9AjWJPRM7CXosDJs8+gy1Zg==",
115 | "dependencies": {
116 | "@pulumi/docker": "^3.0.0",
117 | "@types/aws-lambda": "^8.10.23",
118 | "mime": "^2.0.0"
119 | },
120 | "peerDependencies": {
121 | "@pulumi/aws": "^4.0.0",
122 | "@pulumi/pulumi": "^3.0.0"
123 | }
124 | },
125 | "node_modules/@pulumi/docker": {
126 | "version": "3.0.0",
127 | "resolved": "https://registry.npmjs.org/@pulumi/docker/-/docker-3.0.0.tgz",
128 | "integrity": "sha512-AzPhb/ibuHBy+GGDHrY3rPJeaO5DIMqv/ABtenQdoAw8X00E3UTV+D9dDS/GRq0oJ2aDvZupIlSdrPD7eJ5jgA==",
129 | "hasInstallScript": true,
130 | "dependencies": {
131 | "@pulumi/pulumi": "^3.0.0",
132 | "semver": "^5.4.0"
133 | }
134 | },
135 | "node_modules/@pulumi/kubernetes": {
136 | "version": "3.3.0",
137 | "resolved": "https://registry.npmjs.org/@pulumi/kubernetes/-/kubernetes-3.3.0.tgz",
138 | "integrity": "sha512-iM5qYPs6iaa7Wti/cX17mNMMpVCMWo5aaF7RKydiy+FYFY+SJ1sk0wBoVj/A0RxteIVEYU+NiFrfUMGKe4HjQw==",
139 | "hasInstallScript": true,
140 | "dependencies": {
141 | "@pulumi/pulumi": "^3.0.0",
142 | "@types/glob": "^5.0.35",
143 | "@types/node-fetch": "^2.1.4",
144 | "@types/tmp": "^0.0.33",
145 | "glob": "^7.1.2",
146 | "node-fetch": "^2.3.0",
147 | "shell-quote": "^1.6.1",
148 | "tmp": "^0.0.33"
149 | }
150 | },
151 | "node_modules/@pulumi/kubernetesx": {
152 | "version": "0.1.6",
153 | "resolved": "https://registry.npmjs.org/@pulumi/kubernetesx/-/kubernetesx-0.1.6.tgz",
154 | "integrity": "sha512-9VL4Yi4b4aLC/obBarJuNkm86kABByUZICYPSTdV396MGZtOc066o2brsB+kWVQcVfkYVXTPrpjIkAwBXXnzGw==",
155 | "peerDependencies": {
156 | "@pulumi/kubernetes": "^3.0.0",
157 | "@pulumi/pulumi": "^3.0.0"
158 | }
159 | },
160 | "node_modules/@pulumi/pulumi": {
161 | "version": "3.3.1",
162 | "resolved": "https://registry.npmjs.org/@pulumi/pulumi/-/pulumi-3.3.1.tgz",
163 | "integrity": "sha512-W5HBFCQUY67QaPXtDSZ6Fe/K8mB+X7tJqi2pBU6UUUMtJVndcZ5BpLkZBznu+Nq/ZmitmGVaOpUqC5yK70D98A==",
164 | "dependencies": {
165 | "@grpc/grpc-js": "^1.2.7",
166 | "@logdna/tail-file": "^2.0.6",
167 | "@pulumi/query": "^0.3.0",
168 | "google-protobuf": "^3.5.0",
169 | "js-yaml": "^3.14.0",
170 | "minimist": "^1.2.0",
171 | "normalize-package-data": "^2.4.0",
172 | "protobufjs": "^6.8.6",
173 | "read-package-tree": "^5.3.1",
174 | "require-from-string": "^2.0.1",
175 | "semver": "^6.1.0",
176 | "source-map-support": "^0.4.16",
177 | "ts-node": "^7.0.1",
178 | "typescript": "~3.7.3",
179 | "upath": "^1.1.0"
180 | },
181 | "engines": {
182 | "node": ">=8.13.0 || >=10.10.0"
183 | }
184 | },
185 | "node_modules/@pulumi/pulumi/node_modules/semver": {
186 | "version": "6.3.0",
187 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
188 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
189 | "bin": {
190 | "semver": "bin/semver.js"
191 | }
192 | },
193 | "node_modules/@pulumi/query": {
194 | "version": "0.3.0",
195 | "resolved": "https://registry.npmjs.org/@pulumi/query/-/query-0.3.0.tgz",
196 | "integrity": "sha512-xfo+yLRM2zVjVEA4p23IjQWzyWl1ZhWOGobsBqRpIarzLvwNH/RAGaoehdxlhx4X92302DrpdIFgTICMN4P38w=="
197 | },
198 | "node_modules/@types/aws-lambda": {
199 | "version": "8.10.76",
200 | "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.76.tgz",
201 | "integrity": "sha512-lCTyeRm3NWqSwDnoji0z82Pl0tsOpr1p+33AiNeidgarloWXh3wdiVRUuxEa+sY9S5YLOYGz5X3N3Zvpibvm5w=="
202 | },
203 | "node_modules/@types/events": {
204 | "version": "3.0.0",
205 | "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
206 | "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
207 | },
208 | "node_modules/@types/glob": {
209 | "version": "5.0.36",
210 | "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.36.tgz",
211 | "integrity": "sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg==",
212 | "dependencies": {
213 | "@types/events": "*",
214 | "@types/minimatch": "*",
215 | "@types/node": "*"
216 | }
217 | },
218 | "node_modules/@types/long": {
219 | "version": "4.0.1",
220 | "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
221 | "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
222 | },
223 | "node_modules/@types/minimatch": {
224 | "version": "3.0.4",
225 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz",
226 | "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
227 | },
228 | "node_modules/@types/node": {
229 | "version": "10.17.60",
230 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
231 | "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
232 | },
233 | "node_modules/@types/node-fetch": {
234 | "version": "2.5.10",
235 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz",
236 | "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==",
237 | "dependencies": {
238 | "@types/node": "*",
239 | "form-data": "^3.0.0"
240 | }
241 | },
242 | "node_modules/@types/tmp": {
243 | "version": "0.0.33",
244 | "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz",
245 | "integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0="
246 | },
247 | "node_modules/argparse": {
248 | "version": "1.0.10",
249 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
250 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
251 | "dependencies": {
252 | "sprintf-js": "~1.0.2"
253 | }
254 | },
255 | "node_modules/arrify": {
256 | "version": "1.0.1",
257 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
258 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
259 | "engines": {
260 | "node": ">=0.10.0"
261 | }
262 | },
263 | "node_modules/asap": {
264 | "version": "2.0.6",
265 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
266 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
267 | },
268 | "node_modules/asynckit": {
269 | "version": "0.4.0",
270 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
271 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
272 | },
273 | "node_modules/aws-sdk": {
274 | "version": "2.920.0",
275 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.920.0.tgz",
276 | "integrity": "sha512-tbMZ/Y2rRo6R6TTBODJXTiil+MXaoT6Qzotws3yvI1IWGpYxKo7N/3L06XB8ul8tCG0TigxIOY70SMICM70Ppg==",
277 | "hasInstallScript": true,
278 | "dependencies": {
279 | "buffer": "4.9.2",
280 | "events": "1.1.1",
281 | "ieee754": "1.1.13",
282 | "jmespath": "0.15.0",
283 | "querystring": "0.2.0",
284 | "sax": "1.2.1",
285 | "url": "0.10.3",
286 | "uuid": "3.3.2",
287 | "xml2js": "0.4.19"
288 | },
289 | "engines": {
290 | "node": ">= 0.8.0"
291 | }
292 | },
293 | "node_modules/balanced-match": {
294 | "version": "1.0.2",
295 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
296 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
297 | },
298 | "node_modules/base64-js": {
299 | "version": "1.5.1",
300 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
301 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
302 | "funding": [
303 | {
304 | "type": "github",
305 | "url": "https://github.com/sponsors/feross"
306 | },
307 | {
308 | "type": "patreon",
309 | "url": "https://www.patreon.com/feross"
310 | },
311 | {
312 | "type": "consulting",
313 | "url": "https://feross.org/support"
314 | }
315 | ]
316 | },
317 | "node_modules/brace-expansion": {
318 | "version": "1.1.11",
319 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
320 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
321 | "dependencies": {
322 | "balanced-match": "^1.0.0",
323 | "concat-map": "0.0.1"
324 | }
325 | },
326 | "node_modules/buffer": {
327 | "version": "4.9.2",
328 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
329 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
330 | "dependencies": {
331 | "base64-js": "^1.0.2",
332 | "ieee754": "^1.1.4",
333 | "isarray": "^1.0.0"
334 | }
335 | },
336 | "node_modules/buffer-from": {
337 | "version": "1.1.1",
338 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
339 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
340 | },
341 | "node_modules/builtin-modules": {
342 | "version": "3.0.0",
343 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz",
344 | "integrity": "sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg==",
345 | "engines": {
346 | "node": ">=6"
347 | }
348 | },
349 | "node_modules/call-bind": {
350 | "version": "1.0.2",
351 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
352 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
353 | "dependencies": {
354 | "function-bind": "^1.1.1",
355 | "get-intrinsic": "^1.0.2"
356 | },
357 | "funding": {
358 | "url": "https://github.com/sponsors/ljharb"
359 | }
360 | },
361 | "node_modules/combined-stream": {
362 | "version": "1.0.8",
363 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
364 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
365 | "dependencies": {
366 | "delayed-stream": "~1.0.0"
367 | },
368 | "engines": {
369 | "node": ">= 0.8"
370 | }
371 | },
372 | "node_modules/concat-map": {
373 | "version": "0.0.1",
374 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
375 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
376 | },
377 | "node_modules/debuglog": {
378 | "version": "1.0.1",
379 | "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz",
380 | "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=",
381 | "engines": {
382 | "node": "*"
383 | }
384 | },
385 | "node_modules/define-properties": {
386 | "version": "1.1.3",
387 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
388 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
389 | "dependencies": {
390 | "object-keys": "^1.0.12"
391 | },
392 | "engines": {
393 | "node": ">= 0.4"
394 | }
395 | },
396 | "node_modules/delayed-stream": {
397 | "version": "1.0.0",
398 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
399 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
400 | "engines": {
401 | "node": ">=0.4.0"
402 | }
403 | },
404 | "node_modules/dezalgo": {
405 | "version": "1.0.3",
406 | "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz",
407 | "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=",
408 | "dependencies": {
409 | "asap": "^2.0.0",
410 | "wrappy": "1"
411 | }
412 | },
413 | "node_modules/diff": {
414 | "version": "3.5.0",
415 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
416 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
417 | "engines": {
418 | "node": ">=0.3.1"
419 | }
420 | },
421 | "node_modules/es-abstract": {
422 | "version": "1.18.3",
423 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
424 | "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
425 | "dependencies": {
426 | "call-bind": "^1.0.2",
427 | "es-to-primitive": "^1.2.1",
428 | "function-bind": "^1.1.1",
429 | "get-intrinsic": "^1.1.1",
430 | "has": "^1.0.3",
431 | "has-symbols": "^1.0.2",
432 | "is-callable": "^1.2.3",
433 | "is-negative-zero": "^2.0.1",
434 | "is-regex": "^1.1.3",
435 | "is-string": "^1.0.6",
436 | "object-inspect": "^1.10.3",
437 | "object-keys": "^1.1.1",
438 | "object.assign": "^4.1.2",
439 | "string.prototype.trimend": "^1.0.4",
440 | "string.prototype.trimstart": "^1.0.4",
441 | "unbox-primitive": "^1.0.1"
442 | },
443 | "engines": {
444 | "node": ">= 0.4"
445 | },
446 | "funding": {
447 | "url": "https://github.com/sponsors/ljharb"
448 | }
449 | },
450 | "node_modules/es-to-primitive": {
451 | "version": "1.2.1",
452 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
453 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
454 | "dependencies": {
455 | "is-callable": "^1.1.4",
456 | "is-date-object": "^1.0.1",
457 | "is-symbol": "^1.0.2"
458 | },
459 | "engines": {
460 | "node": ">= 0.4"
461 | },
462 | "funding": {
463 | "url": "https://github.com/sponsors/ljharb"
464 | }
465 | },
466 | "node_modules/esprima": {
467 | "version": "4.0.1",
468 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
469 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
470 | "bin": {
471 | "esparse": "bin/esparse.js",
472 | "esvalidate": "bin/esvalidate.js"
473 | },
474 | "engines": {
475 | "node": ">=4"
476 | }
477 | },
478 | "node_modules/events": {
479 | "version": "1.1.1",
480 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
481 | "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
482 | "engines": {
483 | "node": ">=0.4.x"
484 | }
485 | },
486 | "node_modules/form-data": {
487 | "version": "3.0.1",
488 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
489 | "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
490 | "dependencies": {
491 | "asynckit": "^0.4.0",
492 | "combined-stream": "^1.0.8",
493 | "mime-types": "^2.1.12"
494 | },
495 | "engines": {
496 | "node": ">= 6"
497 | }
498 | },
499 | "node_modules/fs.realpath": {
500 | "version": "1.0.0",
501 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
502 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
503 | },
504 | "node_modules/function-bind": {
505 | "version": "1.1.1",
506 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
507 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
508 | },
509 | "node_modules/get-intrinsic": {
510 | "version": "1.1.1",
511 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
512 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
513 | "dependencies": {
514 | "function-bind": "^1.1.1",
515 | "has": "^1.0.3",
516 | "has-symbols": "^1.0.1"
517 | },
518 | "funding": {
519 | "url": "https://github.com/sponsors/ljharb"
520 | }
521 | },
522 | "node_modules/glob": {
523 | "version": "7.1.7",
524 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
525 | "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
526 | "dependencies": {
527 | "fs.realpath": "^1.0.0",
528 | "inflight": "^1.0.4",
529 | "inherits": "2",
530 | "minimatch": "^3.0.4",
531 | "once": "^1.3.0",
532 | "path-is-absolute": "^1.0.0"
533 | },
534 | "engines": {
535 | "node": "*"
536 | },
537 | "funding": {
538 | "url": "https://github.com/sponsors/isaacs"
539 | }
540 | },
541 | "node_modules/google-protobuf": {
542 | "version": "3.17.2",
543 | "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.17.2.tgz",
544 | "integrity": "sha512-LlFVMhSkNy6C1MakEjiwbLxq5w+V+Go+mvt2EUoysrp8gXl903ic2W/3BwzM4/WnDMJP+u7UO2efUSl/0CJMzA=="
545 | },
546 | "node_modules/graceful-fs": {
547 | "version": "4.2.6",
548 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
549 | "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
550 | },
551 | "node_modules/has": {
552 | "version": "1.0.3",
553 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
554 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
555 | "dependencies": {
556 | "function-bind": "^1.1.1"
557 | },
558 | "engines": {
559 | "node": ">= 0.4.0"
560 | }
561 | },
562 | "node_modules/has-bigints": {
563 | "version": "1.0.1",
564 | "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
565 | "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
566 | "funding": {
567 | "url": "https://github.com/sponsors/ljharb"
568 | }
569 | },
570 | "node_modules/has-symbols": {
571 | "version": "1.0.2",
572 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
573 | "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
574 | "engines": {
575 | "node": ">= 0.4"
576 | },
577 | "funding": {
578 | "url": "https://github.com/sponsors/ljharb"
579 | }
580 | },
581 | "node_modules/hosted-git-info": {
582 | "version": "2.8.9",
583 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
584 | "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
585 | },
586 | "node_modules/ieee754": {
587 | "version": "1.1.13",
588 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
589 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
590 | },
591 | "node_modules/inflight": {
592 | "version": "1.0.6",
593 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
594 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
595 | "dependencies": {
596 | "once": "^1.3.0",
597 | "wrappy": "1"
598 | }
599 | },
600 | "node_modules/inherits": {
601 | "version": "2.0.4",
602 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
603 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
604 | },
605 | "node_modules/is-bigint": {
606 | "version": "1.0.2",
607 | "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz",
608 | "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==",
609 | "funding": {
610 | "url": "https://github.com/sponsors/ljharb"
611 | }
612 | },
613 | "node_modules/is-boolean-object": {
614 | "version": "1.1.1",
615 | "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
616 | "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
617 | "dependencies": {
618 | "call-bind": "^1.0.2"
619 | },
620 | "engines": {
621 | "node": ">= 0.4"
622 | },
623 | "funding": {
624 | "url": "https://github.com/sponsors/ljharb"
625 | }
626 | },
627 | "node_modules/is-callable": {
628 | "version": "1.2.3",
629 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
630 | "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
631 | "engines": {
632 | "node": ">= 0.4"
633 | },
634 | "funding": {
635 | "url": "https://github.com/sponsors/ljharb"
636 | }
637 | },
638 | "node_modules/is-core-module": {
639 | "version": "2.4.0",
640 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
641 | "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
642 | "dependencies": {
643 | "has": "^1.0.3"
644 | },
645 | "funding": {
646 | "url": "https://github.com/sponsors/ljharb"
647 | }
648 | },
649 | "node_modules/is-date-object": {
650 | "version": "1.0.4",
651 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz",
652 | "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==",
653 | "engines": {
654 | "node": ">= 0.4"
655 | },
656 | "funding": {
657 | "url": "https://github.com/sponsors/ljharb"
658 | }
659 | },
660 | "node_modules/is-negative-zero": {
661 | "version": "2.0.1",
662 | "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
663 | "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
664 | "engines": {
665 | "node": ">= 0.4"
666 | },
667 | "funding": {
668 | "url": "https://github.com/sponsors/ljharb"
669 | }
670 | },
671 | "node_modules/is-number-object": {
672 | "version": "1.0.5",
673 | "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
674 | "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
675 | "engines": {
676 | "node": ">= 0.4"
677 | },
678 | "funding": {
679 | "url": "https://github.com/sponsors/ljharb"
680 | }
681 | },
682 | "node_modules/is-regex": {
683 | "version": "1.1.3",
684 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
685 | "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
686 | "dependencies": {
687 | "call-bind": "^1.0.2",
688 | "has-symbols": "^1.0.2"
689 | },
690 | "engines": {
691 | "node": ">= 0.4"
692 | },
693 | "funding": {
694 | "url": "https://github.com/sponsors/ljharb"
695 | }
696 | },
697 | "node_modules/is-string": {
698 | "version": "1.0.6",
699 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
700 | "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
701 | "engines": {
702 | "node": ">= 0.4"
703 | },
704 | "funding": {
705 | "url": "https://github.com/sponsors/ljharb"
706 | }
707 | },
708 | "node_modules/is-symbol": {
709 | "version": "1.0.4",
710 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
711 | "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
712 | "dependencies": {
713 | "has-symbols": "^1.0.2"
714 | },
715 | "engines": {
716 | "node": ">= 0.4"
717 | },
718 | "funding": {
719 | "url": "https://github.com/sponsors/ljharb"
720 | }
721 | },
722 | "node_modules/isarray": {
723 | "version": "1.0.0",
724 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
725 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
726 | },
727 | "node_modules/jmespath": {
728 | "version": "0.15.0",
729 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
730 | "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=",
731 | "engines": {
732 | "node": ">= 0.6.0"
733 | }
734 | },
735 | "node_modules/js-yaml": {
736 | "version": "3.14.1",
737 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
738 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
739 | "dependencies": {
740 | "argparse": "^1.0.7",
741 | "esprima": "^4.0.0"
742 | },
743 | "bin": {
744 | "js-yaml": "bin/js-yaml.js"
745 | }
746 | },
747 | "node_modules/json-parse-even-better-errors": {
748 | "version": "2.3.1",
749 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
750 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
751 | },
752 | "node_modules/long": {
753 | "version": "4.0.0",
754 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
755 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
756 | },
757 | "node_modules/make-error": {
758 | "version": "1.3.6",
759 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
760 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
761 | },
762 | "node_modules/mime": {
763 | "version": "2.5.2",
764 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
765 | "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
766 | "bin": {
767 | "mime": "cli.js"
768 | },
769 | "engines": {
770 | "node": ">=4.0.0"
771 | }
772 | },
773 | "node_modules/mime-db": {
774 | "version": "1.48.0",
775 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
776 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
777 | "engines": {
778 | "node": ">= 0.6"
779 | }
780 | },
781 | "node_modules/mime-types": {
782 | "version": "2.1.31",
783 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
784 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
785 | "dependencies": {
786 | "mime-db": "1.48.0"
787 | },
788 | "engines": {
789 | "node": ">= 0.6"
790 | }
791 | },
792 | "node_modules/minimatch": {
793 | "version": "3.0.4",
794 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
795 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
796 | "dependencies": {
797 | "brace-expansion": "^1.1.7"
798 | },
799 | "engines": {
800 | "node": "*"
801 | }
802 | },
803 | "node_modules/minimist": {
804 | "version": "1.2.5",
805 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
806 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
807 | },
808 | "node_modules/mkdirp": {
809 | "version": "0.5.5",
810 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
811 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
812 | "dependencies": {
813 | "minimist": "^1.2.5"
814 | },
815 | "bin": {
816 | "mkdirp": "bin/cmd.js"
817 | }
818 | },
819 | "node_modules/node-fetch": {
820 | "version": "2.6.1",
821 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
822 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
823 | "engines": {
824 | "node": "4.x || >=6.0.0"
825 | }
826 | },
827 | "node_modules/normalize-package-data": {
828 | "version": "2.5.0",
829 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
830 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
831 | "dependencies": {
832 | "hosted-git-info": "^2.1.4",
833 | "resolve": "^1.10.0",
834 | "semver": "2 || 3 || 4 || 5",
835 | "validate-npm-package-license": "^3.0.1"
836 | }
837 | },
838 | "node_modules/npm-normalize-package-bin": {
839 | "version": "1.0.1",
840 | "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
841 | "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA=="
842 | },
843 | "node_modules/object-inspect": {
844 | "version": "1.10.3",
845 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
846 | "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
847 | "funding": {
848 | "url": "https://github.com/sponsors/ljharb"
849 | }
850 | },
851 | "node_modules/object-keys": {
852 | "version": "1.1.1",
853 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
854 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
855 | "engines": {
856 | "node": ">= 0.4"
857 | }
858 | },
859 | "node_modules/object.assign": {
860 | "version": "4.1.2",
861 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
862 | "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
863 | "dependencies": {
864 | "call-bind": "^1.0.0",
865 | "define-properties": "^1.1.3",
866 | "has-symbols": "^1.0.1",
867 | "object-keys": "^1.1.1"
868 | },
869 | "engines": {
870 | "node": ">= 0.4"
871 | },
872 | "funding": {
873 | "url": "https://github.com/sponsors/ljharb"
874 | }
875 | },
876 | "node_modules/object.getownpropertydescriptors": {
877 | "version": "2.1.2",
878 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz",
879 | "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==",
880 | "dependencies": {
881 | "call-bind": "^1.0.2",
882 | "define-properties": "^1.1.3",
883 | "es-abstract": "^1.18.0-next.2"
884 | },
885 | "engines": {
886 | "node": ">= 0.8"
887 | },
888 | "funding": {
889 | "url": "https://github.com/sponsors/ljharb"
890 | }
891 | },
892 | "node_modules/once": {
893 | "version": "1.4.0",
894 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
895 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
896 | "dependencies": {
897 | "wrappy": "1"
898 | }
899 | },
900 | "node_modules/os-tmpdir": {
901 | "version": "1.0.2",
902 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
903 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
904 | "engines": {
905 | "node": ">=0.10.0"
906 | }
907 | },
908 | "node_modules/path-is-absolute": {
909 | "version": "1.0.1",
910 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
911 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
912 | "engines": {
913 | "node": ">=0.10.0"
914 | }
915 | },
916 | "node_modules/path-parse": {
917 | "version": "1.0.7",
918 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
919 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
920 | },
921 | "node_modules/protobufjs": {
922 | "version": "6.11.2",
923 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz",
924 | "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==",
925 | "hasInstallScript": true,
926 | "dependencies": {
927 | "@protobufjs/aspromise": "^1.1.2",
928 | "@protobufjs/base64": "^1.1.2",
929 | "@protobufjs/codegen": "^2.0.4",
930 | "@protobufjs/eventemitter": "^1.1.0",
931 | "@protobufjs/fetch": "^1.1.0",
932 | "@protobufjs/float": "^1.0.2",
933 | "@protobufjs/inquire": "^1.1.0",
934 | "@protobufjs/path": "^1.1.2",
935 | "@protobufjs/pool": "^1.1.0",
936 | "@protobufjs/utf8": "^1.1.0",
937 | "@types/long": "^4.0.1",
938 | "@types/node": ">=13.7.0",
939 | "long": "^4.0.0"
940 | },
941 | "bin": {
942 | "pbjs": "bin/pbjs",
943 | "pbts": "bin/pbts"
944 | }
945 | },
946 | "node_modules/protobufjs/node_modules/@types/node": {
947 | "version": "15.12.0",
948 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.0.tgz",
949 | "integrity": "sha512-+aHJvoCsVhO2ZCuT4o5JtcPrCPyDE3+1nvbDprYes+pPkEsbjH7AGUCNtjMOXS0fqH14t+B7yLzaqSz92FPWyw=="
950 | },
951 | "node_modules/punycode": {
952 | "version": "1.3.2",
953 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
954 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
955 | },
956 | "node_modules/querystring": {
957 | "version": "0.2.0",
958 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
959 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
960 | "engines": {
961 | "node": ">=0.4.x"
962 | }
963 | },
964 | "node_modules/read-package-json": {
965 | "version": "2.1.2",
966 | "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz",
967 | "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==",
968 | "dependencies": {
969 | "glob": "^7.1.1",
970 | "json-parse-even-better-errors": "^2.3.0",
971 | "normalize-package-data": "^2.0.0",
972 | "npm-normalize-package-bin": "^1.0.0"
973 | }
974 | },
975 | "node_modules/read-package-tree": {
976 | "version": "5.3.1",
977 | "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz",
978 | "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==",
979 | "dependencies": {
980 | "read-package-json": "^2.0.0",
981 | "readdir-scoped-modules": "^1.0.0",
982 | "util-promisify": "^2.1.0"
983 | }
984 | },
985 | "node_modules/readdir-scoped-modules": {
986 | "version": "1.1.0",
987 | "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz",
988 | "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==",
989 | "dependencies": {
990 | "debuglog": "^1.0.1",
991 | "dezalgo": "^1.0.0",
992 | "graceful-fs": "^4.1.2",
993 | "once": "^1.3.0"
994 | }
995 | },
996 | "node_modules/require-from-string": {
997 | "version": "2.0.2",
998 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
999 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
1000 | "engines": {
1001 | "node": ">=0.10.0"
1002 | }
1003 | },
1004 | "node_modules/resolve": {
1005 | "version": "1.20.0",
1006 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
1007 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
1008 | "dependencies": {
1009 | "is-core-module": "^2.2.0",
1010 | "path-parse": "^1.0.6"
1011 | },
1012 | "funding": {
1013 | "url": "https://github.com/sponsors/ljharb"
1014 | }
1015 | },
1016 | "node_modules/sax": {
1017 | "version": "1.2.1",
1018 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
1019 | "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
1020 | },
1021 | "node_modules/semver": {
1022 | "version": "5.7.1",
1023 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1024 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1025 | "bin": {
1026 | "semver": "bin/semver"
1027 | }
1028 | },
1029 | "node_modules/shell-quote": {
1030 | "version": "1.7.2",
1031 | "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
1032 | "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg=="
1033 | },
1034 | "node_modules/source-map": {
1035 | "version": "0.5.7",
1036 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
1037 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
1038 | "engines": {
1039 | "node": ">=0.10.0"
1040 | }
1041 | },
1042 | "node_modules/source-map-support": {
1043 | "version": "0.4.18",
1044 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
1045 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
1046 | "dependencies": {
1047 | "source-map": "^0.5.6"
1048 | }
1049 | },
1050 | "node_modules/spdx-correct": {
1051 | "version": "3.1.1",
1052 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
1053 | "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
1054 | "dependencies": {
1055 | "spdx-expression-parse": "^3.0.0",
1056 | "spdx-license-ids": "^3.0.0"
1057 | }
1058 | },
1059 | "node_modules/spdx-exceptions": {
1060 | "version": "2.3.0",
1061 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
1062 | "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
1063 | },
1064 | "node_modules/spdx-expression-parse": {
1065 | "version": "3.0.1",
1066 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
1067 | "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
1068 | "dependencies": {
1069 | "spdx-exceptions": "^2.1.0",
1070 | "spdx-license-ids": "^3.0.0"
1071 | }
1072 | },
1073 | "node_modules/spdx-license-ids": {
1074 | "version": "3.0.9",
1075 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz",
1076 | "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ=="
1077 | },
1078 | "node_modules/sprintf-js": {
1079 | "version": "1.0.3",
1080 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
1081 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
1082 | },
1083 | "node_modules/string.prototype.trimend": {
1084 | "version": "1.0.4",
1085 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
1086 | "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
1087 | "dependencies": {
1088 | "call-bind": "^1.0.2",
1089 | "define-properties": "^1.1.3"
1090 | },
1091 | "funding": {
1092 | "url": "https://github.com/sponsors/ljharb"
1093 | }
1094 | },
1095 | "node_modules/string.prototype.trimstart": {
1096 | "version": "1.0.4",
1097 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
1098 | "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
1099 | "dependencies": {
1100 | "call-bind": "^1.0.2",
1101 | "define-properties": "^1.1.3"
1102 | },
1103 | "funding": {
1104 | "url": "https://github.com/sponsors/ljharb"
1105 | }
1106 | },
1107 | "node_modules/tmp": {
1108 | "version": "0.0.33",
1109 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
1110 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
1111 | "dependencies": {
1112 | "os-tmpdir": "~1.0.2"
1113 | },
1114 | "engines": {
1115 | "node": ">=0.6.0"
1116 | }
1117 | },
1118 | "node_modules/ts-node": {
1119 | "version": "7.0.1",
1120 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz",
1121 | "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==",
1122 | "dependencies": {
1123 | "arrify": "^1.0.0",
1124 | "buffer-from": "^1.1.0",
1125 | "diff": "^3.1.0",
1126 | "make-error": "^1.1.1",
1127 | "minimist": "^1.2.0",
1128 | "mkdirp": "^0.5.1",
1129 | "source-map-support": "^0.5.6",
1130 | "yn": "^2.0.0"
1131 | },
1132 | "bin": {
1133 | "ts-node": "dist/bin.js"
1134 | },
1135 | "engines": {
1136 | "node": ">=4.2.0"
1137 | }
1138 | },
1139 | "node_modules/ts-node/node_modules/source-map": {
1140 | "version": "0.6.1",
1141 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
1142 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
1143 | "engines": {
1144 | "node": ">=0.10.0"
1145 | }
1146 | },
1147 | "node_modules/ts-node/node_modules/source-map-support": {
1148 | "version": "0.5.19",
1149 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
1150 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
1151 | "dependencies": {
1152 | "buffer-from": "^1.0.0",
1153 | "source-map": "^0.6.0"
1154 | }
1155 | },
1156 | "node_modules/typescript": {
1157 | "version": "3.7.7",
1158 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.7.tgz",
1159 | "integrity": "sha512-MmQdgo/XenfZPvVLtKZOq9jQQvzaUAUpcKW8Z43x9B2fOm4S5g//tPtMweZUIP+SoBqrVPEIm+dJeQ9dfO0QdA==",
1160 | "bin": {
1161 | "tsc": "bin/tsc",
1162 | "tsserver": "bin/tsserver"
1163 | },
1164 | "engines": {
1165 | "node": ">=4.2.0"
1166 | }
1167 | },
1168 | "node_modules/unbox-primitive": {
1169 | "version": "1.0.1",
1170 | "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
1171 | "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
1172 | "dependencies": {
1173 | "function-bind": "^1.1.1",
1174 | "has-bigints": "^1.0.1",
1175 | "has-symbols": "^1.0.2",
1176 | "which-boxed-primitive": "^1.0.2"
1177 | },
1178 | "funding": {
1179 | "url": "https://github.com/sponsors/ljharb"
1180 | }
1181 | },
1182 | "node_modules/upath": {
1183 | "version": "1.2.0",
1184 | "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
1185 | "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
1186 | "engines": {
1187 | "node": ">=4",
1188 | "yarn": "*"
1189 | }
1190 | },
1191 | "node_modules/url": {
1192 | "version": "0.10.3",
1193 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
1194 | "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
1195 | "dependencies": {
1196 | "punycode": "1.3.2",
1197 | "querystring": "0.2.0"
1198 | }
1199 | },
1200 | "node_modules/util-promisify": {
1201 | "version": "2.1.0",
1202 | "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz",
1203 | "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=",
1204 | "dependencies": {
1205 | "object.getownpropertydescriptors": "^2.0.3"
1206 | }
1207 | },
1208 | "node_modules/uuid": {
1209 | "version": "3.3.2",
1210 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
1211 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
1212 | "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
1213 | "bin": {
1214 | "uuid": "bin/uuid"
1215 | }
1216 | },
1217 | "node_modules/validate-npm-package-license": {
1218 | "version": "3.0.4",
1219 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
1220 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
1221 | "dependencies": {
1222 | "spdx-correct": "^3.0.0",
1223 | "spdx-expression-parse": "^3.0.0"
1224 | }
1225 | },
1226 | "node_modules/which-boxed-primitive": {
1227 | "version": "1.0.2",
1228 | "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
1229 | "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
1230 | "dependencies": {
1231 | "is-bigint": "^1.0.1",
1232 | "is-boolean-object": "^1.1.0",
1233 | "is-number-object": "^1.0.4",
1234 | "is-string": "^1.0.5",
1235 | "is-symbol": "^1.0.3"
1236 | },
1237 | "funding": {
1238 | "url": "https://github.com/sponsors/ljharb"
1239 | }
1240 | },
1241 | "node_modules/wrappy": {
1242 | "version": "1.0.2",
1243 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1244 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
1245 | },
1246 | "node_modules/xml2js": {
1247 | "version": "0.4.19",
1248 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
1249 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
1250 | "dependencies": {
1251 | "sax": ">=0.6.0",
1252 | "xmlbuilder": "~9.0.1"
1253 | }
1254 | },
1255 | "node_modules/xmlbuilder": {
1256 | "version": "9.0.7",
1257 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
1258 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
1259 | "engines": {
1260 | "node": ">=4.0"
1261 | }
1262 | },
1263 | "node_modules/yn": {
1264 | "version": "2.0.0",
1265 | "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
1266 | "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
1267 | "engines": {
1268 | "node": ">=4"
1269 | }
1270 | }
1271 | },
1272 | "dependencies": {
1273 | "@grpc/grpc-js": {
1274 | "version": "1.3.2",
1275 | "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz",
1276 | "integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==",
1277 | "requires": {
1278 | "@types/node": ">=12.12.47"
1279 | },
1280 | "dependencies": {
1281 | "@types/node": {
1282 | "version": "15.12.0",
1283 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.0.tgz",
1284 | "integrity": "sha512-+aHJvoCsVhO2ZCuT4o5JtcPrCPyDE3+1nvbDprYes+pPkEsbjH7AGUCNtjMOXS0fqH14t+B7yLzaqSz92FPWyw=="
1285 | }
1286 | }
1287 | },
1288 | "@logdna/tail-file": {
1289 | "version": "2.0.7",
1290 | "resolved": "https://registry.npmjs.org/@logdna/tail-file/-/tail-file-2.0.7.tgz",
1291 | "integrity": "sha512-ycw0OrbphtfGOnygF+J4J/kJELXifLUiQ/CSTMb9Ztqjnuq4h+Id3MEvt4FTyyyekYbzStx7TjkhqXFW6Mi9LA=="
1292 | },
1293 | "@protobufjs/aspromise": {
1294 | "version": "1.1.2",
1295 | "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
1296 | "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
1297 | },
1298 | "@protobufjs/base64": {
1299 | "version": "1.1.2",
1300 | "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
1301 | "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
1302 | },
1303 | "@protobufjs/codegen": {
1304 | "version": "2.0.4",
1305 | "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
1306 | "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
1307 | },
1308 | "@protobufjs/eventemitter": {
1309 | "version": "1.1.0",
1310 | "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
1311 | "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
1312 | },
1313 | "@protobufjs/fetch": {
1314 | "version": "1.1.0",
1315 | "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
1316 | "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
1317 | "requires": {
1318 | "@protobufjs/aspromise": "^1.1.1",
1319 | "@protobufjs/inquire": "^1.1.0"
1320 | }
1321 | },
1322 | "@protobufjs/float": {
1323 | "version": "1.0.2",
1324 | "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
1325 | "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
1326 | },
1327 | "@protobufjs/inquire": {
1328 | "version": "1.1.0",
1329 | "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
1330 | "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
1331 | },
1332 | "@protobufjs/path": {
1333 | "version": "1.1.2",
1334 | "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
1335 | "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
1336 | },
1337 | "@protobufjs/pool": {
1338 | "version": "1.1.0",
1339 | "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
1340 | "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
1341 | },
1342 | "@protobufjs/utf8": {
1343 | "version": "1.1.0",
1344 | "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
1345 | "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
1346 | },
1347 | "@pulumi/aws": {
1348 | "version": "4.6.0",
1349 | "resolved": "https://registry.npmjs.org/@pulumi/aws/-/aws-4.6.0.tgz",
1350 | "integrity": "sha512-it0Q9FUd7v/2PgAvoXxTrTT/kQM1iwLNrxnBDabByQsGIOpp4jj4C+sexOoMH4IbKz6mwkLUaPS84QU/qDfndg==",
1351 | "requires": {
1352 | "@pulumi/pulumi": "^3.0.0",
1353 | "aws-sdk": "^2.0.0",
1354 | "builtin-modules": "3.0.0",
1355 | "mime": "^2.0.0",
1356 | "read-package-tree": "^5.2.1",
1357 | "resolve": "^1.7.1"
1358 | }
1359 | },
1360 | "@pulumi/awsx": {
1361 | "version": "0.30.0",
1362 | "resolved": "https://registry.npmjs.org/@pulumi/awsx/-/awsx-0.30.0.tgz",
1363 | "integrity": "sha512-QtYVDFSkZxJ/JkAxaSwms9i/tJU2rA9F/VncCN6e8D0r29C5t4eYQhmB4chsLww9AjWJPRM7CXosDJs8+gy1Zg==",
1364 | "requires": {
1365 | "@pulumi/docker": "^3.0.0",
1366 | "@types/aws-lambda": "^8.10.23",
1367 | "mime": "^2.0.0"
1368 | }
1369 | },
1370 | "@pulumi/docker": {
1371 | "version": "3.0.0",
1372 | "resolved": "https://registry.npmjs.org/@pulumi/docker/-/docker-3.0.0.tgz",
1373 | "integrity": "sha512-AzPhb/ibuHBy+GGDHrY3rPJeaO5DIMqv/ABtenQdoAw8X00E3UTV+D9dDS/GRq0oJ2aDvZupIlSdrPD7eJ5jgA==",
1374 | "requires": {
1375 | "@pulumi/pulumi": "^3.0.0",
1376 | "semver": "^5.4.0"
1377 | }
1378 | },
1379 | "@pulumi/kubernetes": {
1380 | "version": "3.3.0",
1381 | "resolved": "https://registry.npmjs.org/@pulumi/kubernetes/-/kubernetes-3.3.0.tgz",
1382 | "integrity": "sha512-iM5qYPs6iaa7Wti/cX17mNMMpVCMWo5aaF7RKydiy+FYFY+SJ1sk0wBoVj/A0RxteIVEYU+NiFrfUMGKe4HjQw==",
1383 | "requires": {
1384 | "@pulumi/pulumi": "^3.0.0",
1385 | "@types/glob": "^5.0.35",
1386 | "@types/node-fetch": "^2.1.4",
1387 | "@types/tmp": "^0.0.33",
1388 | "glob": "^7.1.2",
1389 | "node-fetch": "^2.3.0",
1390 | "shell-quote": "^1.6.1",
1391 | "tmp": "^0.0.33"
1392 | }
1393 | },
1394 | "@pulumi/kubernetesx": {
1395 | "version": "0.1.6",
1396 | "resolved": "https://registry.npmjs.org/@pulumi/kubernetesx/-/kubernetesx-0.1.6.tgz",
1397 | "integrity": "sha512-9VL4Yi4b4aLC/obBarJuNkm86kABByUZICYPSTdV396MGZtOc066o2brsB+kWVQcVfkYVXTPrpjIkAwBXXnzGw==",
1398 | "requires": {}
1399 | },
1400 | "@pulumi/pulumi": {
1401 | "version": "3.3.1",
1402 | "resolved": "https://registry.npmjs.org/@pulumi/pulumi/-/pulumi-3.3.1.tgz",
1403 | "integrity": "sha512-W5HBFCQUY67QaPXtDSZ6Fe/K8mB+X7tJqi2pBU6UUUMtJVndcZ5BpLkZBznu+Nq/ZmitmGVaOpUqC5yK70D98A==",
1404 | "requires": {
1405 | "@grpc/grpc-js": "^1.2.7",
1406 | "@logdna/tail-file": "^2.0.6",
1407 | "@pulumi/query": "^0.3.0",
1408 | "google-protobuf": "^3.5.0",
1409 | "js-yaml": "^3.14.0",
1410 | "minimist": "^1.2.0",
1411 | "normalize-package-data": "^2.4.0",
1412 | "protobufjs": "^6.8.6",
1413 | "read-package-tree": "^5.3.1",
1414 | "require-from-string": "^2.0.1",
1415 | "semver": "^6.1.0",
1416 | "source-map-support": "^0.4.16",
1417 | "ts-node": "^7.0.1",
1418 | "typescript": "~3.7.3",
1419 | "upath": "^1.1.0"
1420 | },
1421 | "dependencies": {
1422 | "semver": {
1423 | "version": "6.3.0",
1424 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
1425 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
1426 | }
1427 | }
1428 | },
1429 | "@pulumi/query": {
1430 | "version": "0.3.0",
1431 | "resolved": "https://registry.npmjs.org/@pulumi/query/-/query-0.3.0.tgz",
1432 | "integrity": "sha512-xfo+yLRM2zVjVEA4p23IjQWzyWl1ZhWOGobsBqRpIarzLvwNH/RAGaoehdxlhx4X92302DrpdIFgTICMN4P38w=="
1433 | },
1434 | "@types/aws-lambda": {
1435 | "version": "8.10.76",
1436 | "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.76.tgz",
1437 | "integrity": "sha512-lCTyeRm3NWqSwDnoji0z82Pl0tsOpr1p+33AiNeidgarloWXh3wdiVRUuxEa+sY9S5YLOYGz5X3N3Zvpibvm5w=="
1438 | },
1439 | "@types/events": {
1440 | "version": "3.0.0",
1441 | "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
1442 | "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
1443 | },
1444 | "@types/glob": {
1445 | "version": "5.0.36",
1446 | "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.36.tgz",
1447 | "integrity": "sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg==",
1448 | "requires": {
1449 | "@types/events": "*",
1450 | "@types/minimatch": "*",
1451 | "@types/node": "*"
1452 | }
1453 | },
1454 | "@types/long": {
1455 | "version": "4.0.1",
1456 | "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
1457 | "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
1458 | },
1459 | "@types/minimatch": {
1460 | "version": "3.0.4",
1461 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz",
1462 | "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA=="
1463 | },
1464 | "@types/node": {
1465 | "version": "10.17.60",
1466 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
1467 | "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
1468 | },
1469 | "@types/node-fetch": {
1470 | "version": "2.5.10",
1471 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.10.tgz",
1472 | "integrity": "sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==",
1473 | "requires": {
1474 | "@types/node": "*",
1475 | "form-data": "^3.0.0"
1476 | }
1477 | },
1478 | "@types/tmp": {
1479 | "version": "0.0.33",
1480 | "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz",
1481 | "integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0="
1482 | },
1483 | "argparse": {
1484 | "version": "1.0.10",
1485 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
1486 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
1487 | "requires": {
1488 | "sprintf-js": "~1.0.2"
1489 | }
1490 | },
1491 | "arrify": {
1492 | "version": "1.0.1",
1493 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
1494 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
1495 | },
1496 | "asap": {
1497 | "version": "2.0.6",
1498 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
1499 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
1500 | },
1501 | "asynckit": {
1502 | "version": "0.4.0",
1503 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
1504 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
1505 | },
1506 | "aws-sdk": {
1507 | "version": "2.920.0",
1508 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.920.0.tgz",
1509 | "integrity": "sha512-tbMZ/Y2rRo6R6TTBODJXTiil+MXaoT6Qzotws3yvI1IWGpYxKo7N/3L06XB8ul8tCG0TigxIOY70SMICM70Ppg==",
1510 | "requires": {
1511 | "buffer": "4.9.2",
1512 | "events": "1.1.1",
1513 | "ieee754": "1.1.13",
1514 | "jmespath": "0.15.0",
1515 | "querystring": "0.2.0",
1516 | "sax": "1.2.1",
1517 | "url": "0.10.3",
1518 | "uuid": "3.3.2",
1519 | "xml2js": "0.4.19"
1520 | }
1521 | },
1522 | "balanced-match": {
1523 | "version": "1.0.2",
1524 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1525 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
1526 | },
1527 | "base64-js": {
1528 | "version": "1.5.1",
1529 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
1530 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
1531 | },
1532 | "brace-expansion": {
1533 | "version": "1.1.11",
1534 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1535 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1536 | "requires": {
1537 | "balanced-match": "^1.0.0",
1538 | "concat-map": "0.0.1"
1539 | }
1540 | },
1541 | "buffer": {
1542 | "version": "4.9.2",
1543 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
1544 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
1545 | "requires": {
1546 | "base64-js": "^1.0.2",
1547 | "ieee754": "^1.1.4",
1548 | "isarray": "^1.0.0"
1549 | }
1550 | },
1551 | "buffer-from": {
1552 | "version": "1.1.1",
1553 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
1554 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
1555 | },
1556 | "builtin-modules": {
1557 | "version": "3.0.0",
1558 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz",
1559 | "integrity": "sha512-hMIeU4K2ilbXV6Uv93ZZ0Avg/M91RaKXucQ+4me2Do1txxBDyDZWCBa5bJSLqoNTRpXTLwEzIk1KmloenDDjhg=="
1560 | },
1561 | "call-bind": {
1562 | "version": "1.0.2",
1563 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
1564 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
1565 | "requires": {
1566 | "function-bind": "^1.1.1",
1567 | "get-intrinsic": "^1.0.2"
1568 | }
1569 | },
1570 | "combined-stream": {
1571 | "version": "1.0.8",
1572 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
1573 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
1574 | "requires": {
1575 | "delayed-stream": "~1.0.0"
1576 | }
1577 | },
1578 | "concat-map": {
1579 | "version": "0.0.1",
1580 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1581 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
1582 | },
1583 | "debuglog": {
1584 | "version": "1.0.1",
1585 | "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz",
1586 | "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI="
1587 | },
1588 | "define-properties": {
1589 | "version": "1.1.3",
1590 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
1591 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
1592 | "requires": {
1593 | "object-keys": "^1.0.12"
1594 | }
1595 | },
1596 | "delayed-stream": {
1597 | "version": "1.0.0",
1598 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
1599 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
1600 | },
1601 | "dezalgo": {
1602 | "version": "1.0.3",
1603 | "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz",
1604 | "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=",
1605 | "requires": {
1606 | "asap": "^2.0.0",
1607 | "wrappy": "1"
1608 | }
1609 | },
1610 | "diff": {
1611 | "version": "3.5.0",
1612 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
1613 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
1614 | },
1615 | "es-abstract": {
1616 | "version": "1.18.3",
1617 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
1618 | "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
1619 | "requires": {
1620 | "call-bind": "^1.0.2",
1621 | "es-to-primitive": "^1.2.1",
1622 | "function-bind": "^1.1.1",
1623 | "get-intrinsic": "^1.1.1",
1624 | "has": "^1.0.3",
1625 | "has-symbols": "^1.0.2",
1626 | "is-callable": "^1.2.3",
1627 | "is-negative-zero": "^2.0.1",
1628 | "is-regex": "^1.1.3",
1629 | "is-string": "^1.0.6",
1630 | "object-inspect": "^1.10.3",
1631 | "object-keys": "^1.1.1",
1632 | "object.assign": "^4.1.2",
1633 | "string.prototype.trimend": "^1.0.4",
1634 | "string.prototype.trimstart": "^1.0.4",
1635 | "unbox-primitive": "^1.0.1"
1636 | }
1637 | },
1638 | "es-to-primitive": {
1639 | "version": "1.2.1",
1640 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
1641 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
1642 | "requires": {
1643 | "is-callable": "^1.1.4",
1644 | "is-date-object": "^1.0.1",
1645 | "is-symbol": "^1.0.2"
1646 | }
1647 | },
1648 | "esprima": {
1649 | "version": "4.0.1",
1650 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
1651 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
1652 | },
1653 | "events": {
1654 | "version": "1.1.1",
1655 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
1656 | "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
1657 | },
1658 | "form-data": {
1659 | "version": "3.0.1",
1660 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
1661 | "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
1662 | "requires": {
1663 | "asynckit": "^0.4.0",
1664 | "combined-stream": "^1.0.8",
1665 | "mime-types": "^2.1.12"
1666 | }
1667 | },
1668 | "fs.realpath": {
1669 | "version": "1.0.0",
1670 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1671 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
1672 | },
1673 | "function-bind": {
1674 | "version": "1.1.1",
1675 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1676 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
1677 | },
1678 | "get-intrinsic": {
1679 | "version": "1.1.1",
1680 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
1681 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
1682 | "requires": {
1683 | "function-bind": "^1.1.1",
1684 | "has": "^1.0.3",
1685 | "has-symbols": "^1.0.1"
1686 | }
1687 | },
1688 | "glob": {
1689 | "version": "7.1.7",
1690 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
1691 | "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
1692 | "requires": {
1693 | "fs.realpath": "^1.0.0",
1694 | "inflight": "^1.0.4",
1695 | "inherits": "2",
1696 | "minimatch": "^3.0.4",
1697 | "once": "^1.3.0",
1698 | "path-is-absolute": "^1.0.0"
1699 | }
1700 | },
1701 | "google-protobuf": {
1702 | "version": "3.17.2",
1703 | "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.17.2.tgz",
1704 | "integrity": "sha512-LlFVMhSkNy6C1MakEjiwbLxq5w+V+Go+mvt2EUoysrp8gXl903ic2W/3BwzM4/WnDMJP+u7UO2efUSl/0CJMzA=="
1705 | },
1706 | "graceful-fs": {
1707 | "version": "4.2.6",
1708 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
1709 | "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
1710 | },
1711 | "has": {
1712 | "version": "1.0.3",
1713 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1714 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1715 | "requires": {
1716 | "function-bind": "^1.1.1"
1717 | }
1718 | },
1719 | "has-bigints": {
1720 | "version": "1.0.1",
1721 | "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
1722 | "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA=="
1723 | },
1724 | "has-symbols": {
1725 | "version": "1.0.2",
1726 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
1727 | "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
1728 | },
1729 | "hosted-git-info": {
1730 | "version": "2.8.9",
1731 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
1732 | "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
1733 | },
1734 | "ieee754": {
1735 | "version": "1.1.13",
1736 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
1737 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
1738 | },
1739 | "inflight": {
1740 | "version": "1.0.6",
1741 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1742 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1743 | "requires": {
1744 | "once": "^1.3.0",
1745 | "wrappy": "1"
1746 | }
1747 | },
1748 | "inherits": {
1749 | "version": "2.0.4",
1750 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1751 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1752 | },
1753 | "is-bigint": {
1754 | "version": "1.0.2",
1755 | "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz",
1756 | "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA=="
1757 | },
1758 | "is-boolean-object": {
1759 | "version": "1.1.1",
1760 | "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
1761 | "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
1762 | "requires": {
1763 | "call-bind": "^1.0.2"
1764 | }
1765 | },
1766 | "is-callable": {
1767 | "version": "1.2.3",
1768 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
1769 | "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ=="
1770 | },
1771 | "is-core-module": {
1772 | "version": "2.4.0",
1773 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
1774 | "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
1775 | "requires": {
1776 | "has": "^1.0.3"
1777 | }
1778 | },
1779 | "is-date-object": {
1780 | "version": "1.0.4",
1781 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz",
1782 | "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A=="
1783 | },
1784 | "is-negative-zero": {
1785 | "version": "2.0.1",
1786 | "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
1787 | "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w=="
1788 | },
1789 | "is-number-object": {
1790 | "version": "1.0.5",
1791 | "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
1792 | "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw=="
1793 | },
1794 | "is-regex": {
1795 | "version": "1.1.3",
1796 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
1797 | "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
1798 | "requires": {
1799 | "call-bind": "^1.0.2",
1800 | "has-symbols": "^1.0.2"
1801 | }
1802 | },
1803 | "is-string": {
1804 | "version": "1.0.6",
1805 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
1806 | "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w=="
1807 | },
1808 | "is-symbol": {
1809 | "version": "1.0.4",
1810 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
1811 | "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
1812 | "requires": {
1813 | "has-symbols": "^1.0.2"
1814 | }
1815 | },
1816 | "isarray": {
1817 | "version": "1.0.0",
1818 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1819 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1820 | },
1821 | "jmespath": {
1822 | "version": "0.15.0",
1823 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
1824 | "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc="
1825 | },
1826 | "js-yaml": {
1827 | "version": "3.14.1",
1828 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
1829 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
1830 | "requires": {
1831 | "argparse": "^1.0.7",
1832 | "esprima": "^4.0.0"
1833 | }
1834 | },
1835 | "json-parse-even-better-errors": {
1836 | "version": "2.3.1",
1837 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
1838 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
1839 | },
1840 | "long": {
1841 | "version": "4.0.0",
1842 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
1843 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
1844 | },
1845 | "make-error": {
1846 | "version": "1.3.6",
1847 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
1848 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
1849 | },
1850 | "mime": {
1851 | "version": "2.5.2",
1852 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
1853 | "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg=="
1854 | },
1855 | "mime-db": {
1856 | "version": "1.48.0",
1857 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
1858 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
1859 | },
1860 | "mime-types": {
1861 | "version": "2.1.31",
1862 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
1863 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
1864 | "requires": {
1865 | "mime-db": "1.48.0"
1866 | }
1867 | },
1868 | "minimatch": {
1869 | "version": "3.0.4",
1870 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
1871 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
1872 | "requires": {
1873 | "brace-expansion": "^1.1.7"
1874 | }
1875 | },
1876 | "minimist": {
1877 | "version": "1.2.5",
1878 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
1879 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
1880 | },
1881 | "mkdirp": {
1882 | "version": "0.5.5",
1883 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
1884 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
1885 | "requires": {
1886 | "minimist": "^1.2.5"
1887 | }
1888 | },
1889 | "node-fetch": {
1890 | "version": "2.6.1",
1891 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
1892 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
1893 | },
1894 | "normalize-package-data": {
1895 | "version": "2.5.0",
1896 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
1897 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
1898 | "requires": {
1899 | "hosted-git-info": "^2.1.4",
1900 | "resolve": "^1.10.0",
1901 | "semver": "2 || 3 || 4 || 5",
1902 | "validate-npm-package-license": "^3.0.1"
1903 | }
1904 | },
1905 | "npm-normalize-package-bin": {
1906 | "version": "1.0.1",
1907 | "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
1908 | "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA=="
1909 | },
1910 | "object-inspect": {
1911 | "version": "1.10.3",
1912 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
1913 | "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw=="
1914 | },
1915 | "object-keys": {
1916 | "version": "1.1.1",
1917 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
1918 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
1919 | },
1920 | "object.assign": {
1921 | "version": "4.1.2",
1922 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
1923 | "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
1924 | "requires": {
1925 | "call-bind": "^1.0.0",
1926 | "define-properties": "^1.1.3",
1927 | "has-symbols": "^1.0.1",
1928 | "object-keys": "^1.1.1"
1929 | }
1930 | },
1931 | "object.getownpropertydescriptors": {
1932 | "version": "2.1.2",
1933 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz",
1934 | "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==",
1935 | "requires": {
1936 | "call-bind": "^1.0.2",
1937 | "define-properties": "^1.1.3",
1938 | "es-abstract": "^1.18.0-next.2"
1939 | }
1940 | },
1941 | "once": {
1942 | "version": "1.4.0",
1943 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1944 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1945 | "requires": {
1946 | "wrappy": "1"
1947 | }
1948 | },
1949 | "os-tmpdir": {
1950 | "version": "1.0.2",
1951 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
1952 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
1953 | },
1954 | "path-is-absolute": {
1955 | "version": "1.0.1",
1956 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1957 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
1958 | },
1959 | "path-parse": {
1960 | "version": "1.0.7",
1961 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
1962 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
1963 | },
1964 | "protobufjs": {
1965 | "version": "6.11.2",
1966 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz",
1967 | "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==",
1968 | "requires": {
1969 | "@protobufjs/aspromise": "^1.1.2",
1970 | "@protobufjs/base64": "^1.1.2",
1971 | "@protobufjs/codegen": "^2.0.4",
1972 | "@protobufjs/eventemitter": "^1.1.0",
1973 | "@protobufjs/fetch": "^1.1.0",
1974 | "@protobufjs/float": "^1.0.2",
1975 | "@protobufjs/inquire": "^1.1.0",
1976 | "@protobufjs/path": "^1.1.2",
1977 | "@protobufjs/pool": "^1.1.0",
1978 | "@protobufjs/utf8": "^1.1.0",
1979 | "@types/long": "^4.0.1",
1980 | "@types/node": ">=13.7.0",
1981 | "long": "^4.0.0"
1982 | },
1983 | "dependencies": {
1984 | "@types/node": {
1985 | "version": "15.12.0",
1986 | "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.0.tgz",
1987 | "integrity": "sha512-+aHJvoCsVhO2ZCuT4o5JtcPrCPyDE3+1nvbDprYes+pPkEsbjH7AGUCNtjMOXS0fqH14t+B7yLzaqSz92FPWyw=="
1988 | }
1989 | }
1990 | },
1991 | "punycode": {
1992 | "version": "1.3.2",
1993 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
1994 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
1995 | },
1996 | "querystring": {
1997 | "version": "0.2.0",
1998 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
1999 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
2000 | },
2001 | "read-package-json": {
2002 | "version": "2.1.2",
2003 | "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.1.2.tgz",
2004 | "integrity": "sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==",
2005 | "requires": {
2006 | "glob": "^7.1.1",
2007 | "json-parse-even-better-errors": "^2.3.0",
2008 | "normalize-package-data": "^2.0.0",
2009 | "npm-normalize-package-bin": "^1.0.0"
2010 | }
2011 | },
2012 | "read-package-tree": {
2013 | "version": "5.3.1",
2014 | "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz",
2015 | "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==",
2016 | "requires": {
2017 | "read-package-json": "^2.0.0",
2018 | "readdir-scoped-modules": "^1.0.0",
2019 | "util-promisify": "^2.1.0"
2020 | }
2021 | },
2022 | "readdir-scoped-modules": {
2023 | "version": "1.1.0",
2024 | "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz",
2025 | "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==",
2026 | "requires": {
2027 | "debuglog": "^1.0.1",
2028 | "dezalgo": "^1.0.0",
2029 | "graceful-fs": "^4.1.2",
2030 | "once": "^1.3.0"
2031 | }
2032 | },
2033 | "require-from-string": {
2034 | "version": "2.0.2",
2035 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
2036 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
2037 | },
2038 | "resolve": {
2039 | "version": "1.20.0",
2040 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
2041 | "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
2042 | "requires": {
2043 | "is-core-module": "^2.2.0",
2044 | "path-parse": "^1.0.6"
2045 | }
2046 | },
2047 | "sax": {
2048 | "version": "1.2.1",
2049 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
2050 | "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
2051 | },
2052 | "semver": {
2053 | "version": "5.7.1",
2054 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
2055 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
2056 | },
2057 | "shell-quote": {
2058 | "version": "1.7.2",
2059 | "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
2060 | "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg=="
2061 | },
2062 | "source-map": {
2063 | "version": "0.5.7",
2064 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
2065 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
2066 | },
2067 | "source-map-support": {
2068 | "version": "0.4.18",
2069 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
2070 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
2071 | "requires": {
2072 | "source-map": "^0.5.6"
2073 | }
2074 | },
2075 | "spdx-correct": {
2076 | "version": "3.1.1",
2077 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
2078 | "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
2079 | "requires": {
2080 | "spdx-expression-parse": "^3.0.0",
2081 | "spdx-license-ids": "^3.0.0"
2082 | }
2083 | },
2084 | "spdx-exceptions": {
2085 | "version": "2.3.0",
2086 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
2087 | "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
2088 | },
2089 | "spdx-expression-parse": {
2090 | "version": "3.0.1",
2091 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
2092 | "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
2093 | "requires": {
2094 | "spdx-exceptions": "^2.1.0",
2095 | "spdx-license-ids": "^3.0.0"
2096 | }
2097 | },
2098 | "spdx-license-ids": {
2099 | "version": "3.0.9",
2100 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz",
2101 | "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ=="
2102 | },
2103 | "sprintf-js": {
2104 | "version": "1.0.3",
2105 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
2106 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
2107 | },
2108 | "string.prototype.trimend": {
2109 | "version": "1.0.4",
2110 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
2111 | "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
2112 | "requires": {
2113 | "call-bind": "^1.0.2",
2114 | "define-properties": "^1.1.3"
2115 | }
2116 | },
2117 | "string.prototype.trimstart": {
2118 | "version": "1.0.4",
2119 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
2120 | "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
2121 | "requires": {
2122 | "call-bind": "^1.0.2",
2123 | "define-properties": "^1.1.3"
2124 | }
2125 | },
2126 | "tmp": {
2127 | "version": "0.0.33",
2128 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
2129 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
2130 | "requires": {
2131 | "os-tmpdir": "~1.0.2"
2132 | }
2133 | },
2134 | "ts-node": {
2135 | "version": "7.0.1",
2136 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz",
2137 | "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==",
2138 | "requires": {
2139 | "arrify": "^1.0.0",
2140 | "buffer-from": "^1.1.0",
2141 | "diff": "^3.1.0",
2142 | "make-error": "^1.1.1",
2143 | "minimist": "^1.2.0",
2144 | "mkdirp": "^0.5.1",
2145 | "source-map-support": "^0.5.6",
2146 | "yn": "^2.0.0"
2147 | },
2148 | "dependencies": {
2149 | "source-map": {
2150 | "version": "0.6.1",
2151 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
2152 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
2153 | },
2154 | "source-map-support": {
2155 | "version": "0.5.19",
2156 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
2157 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
2158 | "requires": {
2159 | "buffer-from": "^1.0.0",
2160 | "source-map": "^0.6.0"
2161 | }
2162 | }
2163 | }
2164 | },
2165 | "typescript": {
2166 | "version": "3.7.7",
2167 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.7.tgz",
2168 | "integrity": "sha512-MmQdgo/XenfZPvVLtKZOq9jQQvzaUAUpcKW8Z43x9B2fOm4S5g//tPtMweZUIP+SoBqrVPEIm+dJeQ9dfO0QdA=="
2169 | },
2170 | "unbox-primitive": {
2171 | "version": "1.0.1",
2172 | "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
2173 | "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
2174 | "requires": {
2175 | "function-bind": "^1.1.1",
2176 | "has-bigints": "^1.0.1",
2177 | "has-symbols": "^1.0.2",
2178 | "which-boxed-primitive": "^1.0.2"
2179 | }
2180 | },
2181 | "upath": {
2182 | "version": "1.2.0",
2183 | "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
2184 | "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
2185 | },
2186 | "url": {
2187 | "version": "0.10.3",
2188 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
2189 | "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
2190 | "requires": {
2191 | "punycode": "1.3.2",
2192 | "querystring": "0.2.0"
2193 | }
2194 | },
2195 | "util-promisify": {
2196 | "version": "2.1.0",
2197 | "resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz",
2198 | "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=",
2199 | "requires": {
2200 | "object.getownpropertydescriptors": "^2.0.3"
2201 | }
2202 | },
2203 | "uuid": {
2204 | "version": "3.3.2",
2205 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
2206 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
2207 | },
2208 | "validate-npm-package-license": {
2209 | "version": "3.0.4",
2210 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
2211 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
2212 | "requires": {
2213 | "spdx-correct": "^3.0.0",
2214 | "spdx-expression-parse": "^3.0.0"
2215 | }
2216 | },
2217 | "which-boxed-primitive": {
2218 | "version": "1.0.2",
2219 | "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
2220 | "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
2221 | "requires": {
2222 | "is-bigint": "^1.0.1",
2223 | "is-boolean-object": "^1.1.0",
2224 | "is-number-object": "^1.0.4",
2225 | "is-string": "^1.0.5",
2226 | "is-symbol": "^1.0.3"
2227 | }
2228 | },
2229 | "wrappy": {
2230 | "version": "1.0.2",
2231 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
2232 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
2233 | },
2234 | "xml2js": {
2235 | "version": "0.4.19",
2236 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
2237 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
2238 | "requires": {
2239 | "sax": ">=0.6.0",
2240 | "xmlbuilder": "~9.0.1"
2241 | }
2242 | },
2243 | "xmlbuilder": {
2244 | "version": "9.0.7",
2245 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
2246 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
2247 | },
2248 | "yn": {
2249 | "version": "2.0.0",
2250 | "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
2251 | "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo="
2252 | }
2253 | }
2254 | }
2255 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/infra/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "{{cookiecutter.project_slug}}-infra",
3 | "devDependencies": {
4 | "@types/node": "^10.0.0"
5 | },
6 | "dependencies": {
7 | "@pulumi/aws": "^4.0.0",
8 | "@pulumi/awsx": "^0.30.0",
9 | "@pulumi/kubernetes": "^3.3.0",
10 | "@pulumi/kubernetesx": "^0.1.6",
11 | "@pulumi/pulumi": "^3.0.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/infra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "outDir": "bin",
5 | "target": "es2016",
6 | "module": "commonjs",
7 | "moduleResolution": "node",
8 | "sourceMap": true,
9 | "experimentalDecorators": true,
10 | "pretty": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "noImplicitReturns": true,
13 | "forceConsistentCasingInFileNames": true
14 | },
15 | "files": [
16 | "index.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.poetry]
2 | name = "{{cookiecutter.project_slug}}"
3 | version = "{{ cookiecutter.version }}"
4 | description = "{{ cookiecutter.project_short_description }}"
5 | authors = ["{{ cookiecutter.full_name.replace("\"", "\\\"") }} <{{ cookiecutter.email }}>"]
6 |
7 | [tool.poetry.dependencies]
8 | python = "^3.8"
9 | mlflow = "^1.17.0"
10 | lightgbm = "^3.2.1"
11 | matplotlib = "^3.4.2"
12 | scikit-learn = "^0.24.2"
13 | boto3 = "1.17.49"
14 | fastapi = "^0.65.1"
15 | uvicorn = "^0.14.0"
16 | dvc = {extras = ["s3"], version = "^2.3.0"}
17 |
18 | [tool.poetry.dev-dependencies]
19 | pytest = "^5.2"
20 |
21 | [tool.poetry.scripts]
22 | train = "src.{{cookiecutter.module_name}}.training.train:main"
23 | serve = "src.{{cookiecutter.module_name}}.serving.__main__:main"
24 |
25 | [build-system]
26 | requires = ["poetry>=0.12"]
27 | build-backend = "poetry.masonry.api"
28 |
29 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/__init__.py:
--------------------------------------------------------------------------------
1 | __version__ = '{{ cookiecutter.version }}'
2 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/serving/EXAMPLES.md:
--------------------------------------------------------------------------------
1 | Should be Setosa:
2 |
3 | {
4 | "sepal": { "length": 4.9, "width": 3.1 },
5 | "petal": { "length": 1.5, "width": 0.1 }
6 | }
7 |
8 |
9 | Should be Virginica:
10 |
11 | {
12 | "sepal": { "length": 6.8, "width": 3 },
13 | "petal": { "length": 5.5, "width": 2.1 }
14 | }
15 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/serving/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aporia-ai/mlplatform-workshop/268141ed1d2d6c3b18c743680945bda92265cef1/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/serving/__init__.py
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/serving/__main__.py:
--------------------------------------------------------------------------------
1 | import os
2 | import uvicorn
3 | import mlflow
4 | import numpy as np
5 | import pandas as pd
6 | from fastapi import FastAPI, Request
7 | from pydantic import BaseModel
8 |
9 |
10 | class Size(BaseModel):
11 | length: float
12 | width: float
13 |
14 | class PredictRequest(BaseModel):
15 | sepal: Size
16 | petal: Size
17 |
18 |
19 | app = FastAPI()
20 |
21 | model = mlflow.lightgbm.load_model(f'runs:/{os.environ["MLFLOW_RUN_ID"]}/model')
22 | flower_name_by_index = {0: 'Setosa', 1: 'Versicolor', 2: 'Virginica'}
23 |
24 |
25 | @app.post("/predict")
26 | def predict(request: PredictRequest):
27 | df = pd.DataFrame(columns=['sepal.length', 'sepal.width', 'petal.length', 'petal.width'],
28 | data=[[request.sepal.length, request.sepal.width, request.petal.length, request.petal.width]])
29 |
30 | y_pred = np.argmax(model.predict(df))
31 | return {"flower": flower_name_by_index[y_pred]}
32 |
33 |
34 | def main():
35 | uvicorn.run(app, host="0.0.0.0", port=8000)
36 |
37 | if __name__ == "__main__":
38 | main()
39 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/training/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aporia-ai/mlplatform-workshop/268141ed1d2d6c3b18c743680945bda92265cef1/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/training/__init__.py
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/src/{{cookiecutter.module_name}}/training/train.py:
--------------------------------------------------------------------------------
1 | from sklearn.model_selection import train_test_split
2 | from sklearn.metrics import accuracy_score, log_loss
3 | import pandas as pd
4 | import lightgbm as lgb
5 | import mlflow
6 | import mlflow.lightgbm
7 |
8 |
9 | # Enable auto logging
10 | mlflow.set_tracking_uri('http://ml.mycompany.com/mlflow')
11 | mlflow.lightgbm.autolog()
12 |
13 |
14 | # Prepare training data
15 | df = pd.read_csv('data/iris.csv')
16 | flower_names = {'Setosa': 0, 'Versicolor': 1, 'Virginica': 2}
17 |
18 |
19 | X = df[['sepal.length', 'sepal.width', 'petal.length', 'petal.width']]
20 | y = df['variety'].map(flower_names)
21 |
22 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
23 |
24 | train_data = lgb.Dataset(X_train, label=y_train)
25 |
26 | def main():
27 | with mlflow.start_run() as run:
28 | # Train model
29 | params = {
30 | "objective": "multiclass",
31 | "num_class": 3,
32 | "learning_rate": 0.2,
33 | "metric": "multi_logloss",
34 | "feature_fraction": 0.8,
35 | "bagging_fraction": 0.9,
36 | "seed": 42,
37 | }
38 |
39 | model = lgb.train(params, train_data, valid_sets=[train_data])
40 |
41 | # Evaluate model
42 | y_proba = model.predict(X_test)
43 | y_pred = y_proba.argmax(axis=1)
44 |
45 | loss = log_loss(y_test, y_proba)
46 | acc = accuracy_score(y_test, y_pred)
47 |
48 | # Log metrics
49 | mlflow.log_metrics({
50 | "log_loss": loss,
51 | "accuracy": acc
52 | })
53 |
54 | print("Run ID:", run.info.run_id)
55 |
56 | if __name__ == "__main__":
57 | main()
58 |
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aporia-ai/mlplatform-workshop/268141ed1d2d6c3b18c743680945bda92265cef1/model-template/{{cookiecutter.project_slug}}/tests/__init__.py
--------------------------------------------------------------------------------
/model-template/{{cookiecutter.project_slug}}/tests/test_{{cookiecutter.module_name}}.py:
--------------------------------------------------------------------------------
1 | from {{cookiecutter.module_name}} import __version__
2 |
3 |
4 | def test_version():
5 | assert __version__ == '0.1.0'
6 |
--------------------------------------------------------------------------------