diff --git a/.github/workflows/dockerimgs.yml b/.github/workflows/dockerimgs.yml new file mode 100644 index 0000000..c9332f9 --- /dev/null +++ b/.github/workflows/dockerimgs.yml @@ -0,0 +1,90 @@ +name: '[docker image]' + +on: + push: + branches: + - feat_workerFrontend + # release: + # types: + # - published + +jobs: + build-docker-img: + runs-on: ubuntu-latest + + strategy: + matrix: + dockerfile: ['./http.server.dockerfile', './http.worker.dockerfile'] + include: + - dockerfile: ./http.server.dockerfile + dockerimg: siibra-jugex-server + - dockerfile: ./http.worker.dockerfile + dockerimg: siibra-jugex-worker + steps: + - uses: actions/checkout@v2 + - name: 'Setup tags' + run: | + VERSION=$(grep -Po '^__version__.*?"\K[\w.]+' http_wrapper/__init__.py) + echo "Setting version to $VERSION" + echo "VERSION=$VERSION" >> $GITHUB_ENV + + DOCKER_IMGSTREAM=${{ secrets.EBRAINS_DOCKER_REG_SIIBRA_TOOLBOX_NSP }}/${{ matrix.dockerimg }} + echo "Setting docker image stream to $DOCKER_IMGSTREAM" + echo "DOCKER_IMGSTREAM=$DOCKER_IMGSTREAM" >> $GITHUB_ENV + + - name: 'Build docker image' + run: | + DOCKER_BUILT_TAG=$DOCKER_IMGSTREAM:$VERSION + echo "Building $DOCKER_BUILT_TAG" + docker build \ + -t $DOCKER_BUILT_TAG \ + -f ${{ matrix.dockerfile }} \ + . + echo "Successfully built $DOCKER_BUILT_TAG" + echo "DOCKER_BUILT_TAG=$DOCKER_BUILT_TAG" >> $GITHUB_ENV + + - name: 'Push to docker registry' + run: | + echo "Login to docker registry" + docker login \ + -u '${{ secrets.EBRAINS_DOCKER_REG_SIIBRA_TOOLBOX_PUSHER_USER }}' \ + -p '${{ secrets.EBRAINS_DOCKER_REG_SIIBRA_TOOLBOX_PUSHER_PWSD }}' \ + ${{ secrets.EBRAINS_DOCKER_REG }} + echo "Pushing $DOCKER_BUILT_TAG" + docker push $DOCKER_BUILT_TAG + + - name: 'Tag versioned tag to registry' + run: | + + echo "Login to docker registry" + docker login \ + -u '${{ secrets.EBRAINS_DOCKER_REG_SIIBRA_TOOLBOX_PUSHER_USER }}' \ + -p '${{ secrets.EBRAINS_DOCKER_REG_SIIBRA_TOOLBOX_PUSHER_PWSD }}' \ + ${{ secrets.EBRAINS_DOCKER_REG }} + + BREAK=5 + while [[ "$VERSION" == *"."* ]] + do + if [[ "$BREAK" == "0" ]] + then + echo "Fuse broke!" + exit 1 + fi + VERSIONED_DOCKERTAG=$DOCKER_IMGSTREAM:$VERSION + echo "tagging and pushing $VERSIONED_DOCKERTAG" + docker tag $DOCKER_BUILT_TAG $VERSIONED_DOCKERTAG + docker push $VERSIONED_DOCKERTAG + + echo "Push successful... Incrementing version & break" + VERSION=$(echo $VERSION | sed -e 's/\.\w*$//g') + BREAK=$(( "$BREAK" - 1 )) + done + echo "Done" + + + deploy-on-ebrains: + runs-on: ubuntu-latest + needs: build-docker-img + steps: + - name: "skip for now" + run: "echo skip for now" \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..11507d8 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,38 @@ +name: '[unit test]' + +on: [ push ] + +jobs: + unit-tests: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + test_path: ['siibra_jugex', 'http_wrapper'] + include: + - test_path: siibra_jugex + pip_install: '.' + - test_path: http_wrapper + pip_install: '-r ./http_wrapper/requirements-server.txt' + pip_install_extra: 'requests .' + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-python@v3 + with: + python-version: '3.10' + + - name: "Install testing libraries" + run: pip install pytest + + - name: "Install dependencies defined in matrix.pip_install" + if: ${{ matrix.pip_install }} + run: pip install ${{ matrix.pip_install }} + + - name: "Install dependencies defined in matrix.pip_install_extra" + if: ${{ matrix.pip_install_extra }} + run: pip install ${{ matrix.pip_install_extra }} + + - name: "Run tests at test/${{ matrix.test_path }}" + run: pytest test/${{ matrix.test_path }} diff --git a/.gitignore b/.gitignore index 74036ef..ef8c7be 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ dist examples/*.json upload_to_pypi.sh venv +.vscode +.env +secret* diff --git a/.helm/adhoc/cert.yaml b/.helm/adhoc/cert.yaml new file mode 100644 index 0000000..dbdfcb8 --- /dev/null +++ b/.helm/adhoc/cert.yaml @@ -0,0 +1,42 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: siibra-jugex-certificate +spec: + isCA: false + commonName: siibra-jugex.apps.tc.humanbrainproject.eu + dnsNames: + - siibra-jugex.apps.tc.humanbrainproject.eu + issuerRef: + kind: ClusterIssuer + name: letsencrypt-production-issuer-1 + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + renewBefore: 120h0m0s + secretName: siibra-jugex-prod-secret + usages: + - server auth +--- + +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: neurogenpy-certificate +spec: + isCA: false + commonName: ngpy.apps.hbp.eu + dnsNames: + - ngpy.apps.hbp.eu + issuerRef: + kind: ClusterIssuer + name: letsencrypt-production-issuer-1 + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + renewBefore: 120h0m0s + secretName: neurogenpy-prod-secret + usages: + - server auth \ No newline at end of file diff --git a/.helm/adhoc/configmap.yaml b/.helm/adhoc/configmap.yaml new file mode 100644 index 0000000..22913c6 --- /dev/null +++ b/.helm/adhoc/configmap.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: jugex-toolbox +data: + SIIBRA_TOOLBOX_LOG_DIR: /siibra-tool-log + SIIBRA_TOOLBOX_DATA_DIR: /siibra-tool-data + SIIBRA_JURGEX_CELERY_BROKER: redis://redis:6379 + SIIBRA_JURGEX_CELERY_RESULT: redis://redis:6379 + SIIBRA_CACHEDIR: /siibra-tool-data/tmp diff --git a/.helm/adhoc/cron.yaml b/.helm/adhoc/cron.yaml new file mode 100644 index 0000000..067cb56 --- /dev/null +++ b/.helm/adhoc/cron.yaml @@ -0,0 +1,30 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: cronjob-trim-old-log-usage +spec: + # run two month + schedule: "41 1 */5 */2 *" + concurrencyPolicy: Replace + jobTemplate: + spec: + template: + spec: + containers: + - name: cronjob-trim-old-log-usage + image: docker-registry.ebrains.eu/monitoring/kubectl:v1.29.2 + imagePullPolicy: Always + command: + - /bin/ash + - -c + # delete all files over 30 days of modification date + - "find /siibra-tool-log -mindepth 1 -maxdepth 1 -mtime +30 -delete" + volumeMounts: + - mountPath: /siibra-tool-log + name: log-volume + + restartPolicy: OnFailure + volumes: + - name: log-volume + persistentVolumeClaim: + claimName: log-volume-claim-2 diff --git a/.helm/adhoc/deployment.yaml b/.helm/adhoc/deployment.yaml new file mode 100644 index 0000000..194d952 --- /dev/null +++ b/.helm/adhoc/deployment.yaml @@ -0,0 +1,60 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app: redis + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + labels: + app: redis + spec: + containers: + - image: docker-registry.ebrains.eu/monitoring/redis:alpine3.17 + imagePullPolicy: IfNotPresent + livenessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 3 + periodSeconds: 30 + successThreshold: 1 + timeoutSeconds: 1 + name: redis + ports: + - containerPort: 6379 + protocol: TCP + readinessProbe: + exec: + command: + - redis-cli + - ping + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + resources: + limits: + cpu: 200m + memory: 1Gi + requests: + cpu: 100m + memory: 128Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/.helm/adhoc/ingress.yaml b/.helm/adhoc/ingress.yaml new file mode 100644 index 0000000..c86fa3f --- /dev/null +++ b/.helm/adhoc/ingress.yaml @@ -0,0 +1,33 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: jugex-toolbox +spec: + rules: + - host: siibra-jugex.apps.tc.humanbrainproject.eu + http: + paths: + - backend: + service: + name: jugex-toolbox + port: + number: 6001 + path: / + pathType: ImplementationSpecific + - host: ngpy.apps.hbp.eu + http: + paths: + - backend: + service: + name: neurogenpy-toolbox + port: + number: 6001 + path: / + pathType: ImplementationSpecific + tls: + - hosts: + - siibra-jugex.apps.tc.humanbrainproject.eu + secretName: siibra-jugex-prod-secret + - hosts: + - ngpy.apps.hbp.eu + secretName: neurogenpy-prod-secret diff --git a/.helm/adhoc/pvc.yaml b/.helm/adhoc/pvc.yaml new file mode 100644 index 0000000..f01a2c6 --- /dev/null +++ b/.helm/adhoc/pvc.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + type: longhorn-pvc + name: data-volume-claim +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 16Gi + storageClassName: longhorn-1 +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + labels: + type: longhorn-pvc + name: log-volume-claim-2 +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 4Gi + storageClassName: longhorn-1 \ No newline at end of file diff --git a/.helm/adhoc/service.yaml b/.helm/adhoc/service.yaml new file mode 100644 index 0000000..effbac2 --- /dev/null +++ b/.helm/adhoc/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: redis + name: redis +spec: + ports: + - port: 6379 + protocol: TCP + targetPort: 6379 + selector: + app: redis + type: ClusterIP \ No newline at end of file diff --git a/.helm/deploy_neurogenpy.sh b/.helm/deploy_neurogenpy.sh new file mode 100755 index 0000000..92dad14 --- /dev/null +++ b/.helm/deploy_neurogenpy.sh @@ -0,0 +1,16 @@ +#! /bin/bash + +SERVER_IMG="docker-registry.ebrains.eu/siibra-toolbox/neurogenpy" +WORKER_IMG="docker-registry.ebrains.eu/siibra-toolbox/neurogenpy" +SERVER_TAG="server" +WORKER_TAG="worker" + +helm install neurogenpy ./toolbox \ + --set image.serverRepository=$SERVER_IMG \ + --set image.workerRepository=$WORKER_IMG \ + --set image.serverTag=$SERVER_TAG \ + --set image.workerTag=$WORKER_TAG \ + --set workerResources.limits.memory=4Gi \ + --set envObj.NEUROGENPY_CELERY_BROKER=redis://redis:6379 \ + --set envObj.NEUROGENPY_CELERY_RESULT=redis://redis:6379 + \ No newline at end of file diff --git a/.helm/toolbox/.helmignore b/.helm/toolbox/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/.helm/toolbox/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/.helm/toolbox/Chart.yaml b/.helm/toolbox/Chart.yaml new file mode 100644 index 0000000..36ab714 --- /dev/null +++ b/.helm/toolbox/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: toolbox +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.0.2" diff --git a/.helm/toolbox/templates/NOTES.txt b/.helm/toolbox/templates/NOTES.txt new file mode 100644 index 0000000..3d4da44 --- /dev/null +++ b/.helm/toolbox/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "toolbox.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "toolbox.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "toolbox.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "toolbox.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/.helm/toolbox/templates/_helpers.tpl b/.helm/toolbox/templates/_helpers.tpl new file mode 100644 index 0000000..eb4b86f --- /dev/null +++ b/.helm/toolbox/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "toolbox.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "toolbox.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "toolbox.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "toolbox.labels" -}} +helm.sh/chart: {{ include "toolbox.chart" . }} +{{ include "toolbox.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "toolbox.selectorLabels" -}} +app.kubernetes.io/name: {{ include "toolbox.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "toolbox.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "toolbox.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/.helm/toolbox/templates/hpa.yaml b/.helm/toolbox/templates/hpa.yaml new file mode 100644 index 0000000..e1cbb58 --- /dev/null +++ b/.helm/toolbox/templates/hpa.yaml @@ -0,0 +1,32 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "toolbox.fullname" . }} + labels: + {{- include "toolbox.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "toolbox.fullname" . }}-worker + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/.helm/toolbox/templates/ingress.yaml b/.helm/toolbox/templates/ingress.yaml new file mode 100644 index 0000000..5ccb94f --- /dev/null +++ b/.helm/toolbox/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "toolbox.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "toolbox.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/.helm/toolbox/templates/server-deployment.yaml b/.helm/toolbox/templates/server-deployment.yaml new file mode 100644 index 0000000..e5a87ed --- /dev/null +++ b/.helm/toolbox/templates/server-deployment.yaml @@ -0,0 +1,78 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "toolbox.fullname" . }}-server + labels: + {{- include "toolbox.labels" . | nindent 4 }} + role: server +spec: + replicas: 1 + selector: + matchLabels: + {{- include "toolbox.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "toolbox.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + role: server + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "toolbox.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.serverRepository }}:{{ .Values.image.serverTag | default .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + envFrom: + - configMapRef: + name: jugex-toolbox + - secretRef: + name: ebrains-lab-integration + env: + {{- range $key, $val := .Values.envObj }} + - name: {{ $key }} + value: {{ $val }} + {{- end }} + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.serverResources | nindent 12 }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/.helm/toolbox/templates/service.yaml b/.helm/toolbox/templates/service.yaml new file mode 100644 index 0000000..188dd25 --- /dev/null +++ b/.helm/toolbox/templates/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "toolbox.fullname" . }} + labels: + {{- include "toolbox.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + role: server + {{- include "toolbox.selectorLabels" . | nindent 4 }} diff --git a/.helm/toolbox/templates/serviceaccount.yaml b/.helm/toolbox/templates/serviceaccount.yaml new file mode 100644 index 0000000..458bcdc --- /dev/null +++ b/.helm/toolbox/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "toolbox.serviceAccountName" . }} + labels: + {{- include "toolbox.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/.helm/toolbox/templates/tests/test-connection.yaml b/.helm/toolbox/templates/tests/test-connection.yaml new file mode 100644 index 0000000..79a5768 --- /dev/null +++ b/.helm/toolbox/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "toolbox.fullname" . }}-test-connection" + labels: + {{- include "toolbox.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "toolbox.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/.helm/toolbox/templates/worker-deployment.yaml b/.helm/toolbox/templates/worker-deployment.yaml new file mode 100644 index 0000000..18b1527 --- /dev/null +++ b/.helm/toolbox/templates/worker-deployment.yaml @@ -0,0 +1,71 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "toolbox.fullname" . }}-worker + labels: + {{- include "toolbox.labels" . | nindent 4 }} + role: worker +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "toolbox.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "toolbox.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + role: worker + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "toolbox.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + envFrom: + - configMapRef: + name: jugex-toolbox + env: + {{- range $key, $val := .Values.envObj }} + - name: {{ $key }} + value: {{ $val }} + {{- end }} + + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.workerRepository }}:{{ .Values.image.workerTag | default .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.workerResources | nindent 12 }} + {{- with .Values.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.volumes }} + volumes: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/.helm/toolbox/values.yaml b/.helm/toolbox/values.yaml new file mode 100644 index 0000000..cee9367 --- /dev/null +++ b/.helm/toolbox/values.yaml @@ -0,0 +1,119 @@ +# Default values for toolbox. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + serverRepository: docker-registry.ebrains.eu/siibra-toolbox/siibra-jugex-server + workerRepository: docker-registry.ebrains.eu/siibra-toolbox/siibra-jugex-worker + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + serverTag: "" + workerTag: "" + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} +podLabels: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 6001 + +ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +serverResources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi + +workerResources: + limits: + cpu: 1500m + memory: 1Gi + requests: + cpu: 600m + memory: 512Mi + +livenessProbe: + httpGet: + path: / + port: http +readinessProbe: + httpGet: + path: / + port: http + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# Additional volumes on the output Deployment definition. +volumes: +- name: log-volume + persistentVolumeClaim: + claimName: log-volume-claim +- name: data-volume + persistentVolumeClaim: + claimName: data-volume-claim + +# Additional volumeMounts on the output Deployment definition. +volumeMounts: +- mountPath: /siibra-tool-log + name: log-volume +- mountPath: /siibra-tool-data + name: data-volume + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +envObj: {} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c27bcd7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +version: '3' + +services: + redis: + image: redis:6-alpine + web: + depends_on: + - redis + image: siibra-jugex-server:local-dev + build: + context: . + dockerfile: ./http.server.dockerfile + environment: + SIIBRA_JURGEX_CELERY_BROKER: redis://redis:6379 + SIIBRA_JURGEX_CELERY_RESULT: redis://redis:6379 + ports: + - "6001:6001" + worker: + depends_on: + - redis + image: siibra-jugex-worker:local-dev + build: + context: . + dockerfile: ./http.worker.dockerfile + environment: + SIIBRA_JURGEX_CELERY_BROKER: redis://redis:6379 + SIIBRA_JURGEX_CELERY_RESULT: redis://redis:6379 \ No newline at end of file diff --git a/examples/siibra-jugex.ipynb b/examples/siibra-jugex.ipynb index 54fad0f..3bf975d 100644 --- a/examples/siibra-jugex.ipynb +++ b/examples/siibra-jugex.ipynb @@ -28,7 +28,19 @@ "metadata": {}, "outputs": [], "source": [ - "import siibra, siibra_jugex" + "!pip install 'siibra>=0.3a17,<0.4' 'siibra-jugex==1.0.1'" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import siibra, siibra_jugex\n", + "from packaging import version\n", + "assert version.parse('0.3a30') > version.parse( siibra.__version__ ) and version.parse( siibra.__version__ ) >= version.parse('0.3a17')\n", + "assert version.parse( siibra_jugex.__version__ ) >= version.parse('0.2')" ] }, { @@ -57,10 +69,13 @@ "metadata": {}, "outputs": [], "source": [ + "# set analysis parameters\n", "candidate_regions = [\"v1 right\",\"v2 right\"]\n", "candidate_genes = [\"MAOA\",\"TAC1\"]\n", - "jugex.add_candidate_genes(candidate_genes)\n", "threshold=0.2\n", + "permutations=1000\n", + "\n", + "jugex.add_candidate_genes(candidate_genes)\n", "jugex.define_roi1(candidate_regions[0], maptype=siibra.MapType.CONTINUOUS, threshold=threshold)\n", "jugex.define_roi2(candidate_regions[1], maptype=siibra.MapType.CONTINUOUS, threshold=threshold)" ] @@ -78,7 +93,7 @@ "metadata": {}, "outputs": [], "source": [ - "result = jugex.run(permutations=1000)\n", + "result = jugex.run(permutations=permutations)\n", "print(result['p-values'])" ] }, diff --git a/http.server.dockerfile b/http.server.dockerfile new file mode 100644 index 0000000..536e98c --- /dev/null +++ b/http.server.dockerfile @@ -0,0 +1,34 @@ +# viewer plugin builder +# uncomment if plugin is required + +FROM node:16-alpine as builder +COPY ./viewer_plugin /viewer_plugin +WORKDIR /viewer_plugin +RUN mkdir -p public/build +RUN npm i +RUN npm run build + +# server image +FROM python:3.10-alpine +RUN pip install -U pip + +RUN mkdir /requirements +COPY ./http_wrapper/requirements-server.txt /requirements/ +RUN pip install -r /requirements/requirements-server.txt + + +# NB +# the path is chosen deliberately to allow for proper config mapping +# modify this at your own peril +COPY . /siibra_toolbox +WORKDIR /siibra_toolbox + +# copy built artefact to deployment +# uncomment if plugin is required + +COPY --from=builder /viewer_plugin/public /siibra_toolbox/public +ENV SIIBRA_TOOLBOX_VIEWER_PLUGIN_STATIC_DIR=/siibra_toolbox/public + +USER nobody +EXPOSE 6001 +ENTRYPOINT uvicorn http_wrapper.server:app --port 6001 --host 0.0.0.0 diff --git a/http.worker.dockerfile b/http.worker.dockerfile new file mode 100644 index 0000000..579966d --- /dev/null +++ b/http.worker.dockerfile @@ -0,0 +1,24 @@ +FROM python:3.8-slim +RUN pip install -U pip + +RUN mkdir /requirements + +# install requirements for worker (celery etc) +COPY ./http_wrapper/requirements-worker.txt /requirements/ +RUN pip install -r /requirements/requirements-worker.txt + +# install requirements for toolbox (numpy, etc) +COPY ./requirements.txt /requirements/requirements.txt +RUN pip install -r /requirements/requirements.txt + +# NB +# the path is chosen deliberately to allow for proper config mapping +# modify this at your own peril +COPY . /siibra_toolbox +WORKDIR /siibra_toolbox +RUN pip install . + +WORKDIR /siibra_toolbox +USER nobody + +ENTRYPOINT celery -A http_wrapper.scheduling.worker.app worker -l INFO diff --git a/http_wrapper/.gitignore b/http_wrapper/.gitignore new file mode 100644 index 0000000..f5e96db --- /dev/null +++ b/http_wrapper/.gitignore @@ -0,0 +1 @@ +venv \ No newline at end of file diff --git a/http_wrapper/__init__.py b/http_wrapper/__init__.py new file mode 100644 index 0000000..3b93d0b --- /dev/null +++ b/http_wrapper/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.2" diff --git a/http_wrapper/conf/celeryconfig.py b/http_wrapper/conf/celeryconfig.py new file mode 100644 index 0000000..cc6ed36 --- /dev/null +++ b/http_wrapper/conf/celeryconfig.py @@ -0,0 +1,7 @@ +import os + +broker_url=os.getenv("SIIBRA_JURGEX_CELERY_BROKER", "redis://127.0.0.1:6379") +result_backend=os.getenv("SIIBRA_JURGEX_CELERY_RESULT", "redis://127.0.0.1:6379") + +worker_send_task_events = True +task_send_sent_event = True \ No newline at end of file diff --git a/http_wrapper/conf/siibra_jugex_conf.py b/http_wrapper/conf/siibra_jugex_conf.py new file mode 100644 index 0000000..523870e --- /dev/null +++ b/http_wrapper/conf/siibra_jugex_conf.py @@ -0,0 +1,9 @@ +import os + +SIIBRA_TOOLBOX_VIEWER_PLUGIN_STATIC_DIR = os.getenv("SIIBRA_TOOLBOX_VIEWER_PLUGIN_STATIC_DIR") + +HBP_GITLAB_HOST = os.getenv("HBP_GITLAB_HOST") +HBP_GITLAB_TOKEN = os.getenv("HBP_GITLAB_TOKEN") +HBP_GITLAB_PROJECT_ID = os.getenv("HBP_GITLAB_PROJECT_ID") + +CHANNEL = os.getenv("SIIBRA_JURGEX_CELERY_CHANNEL", "siibra_jugex_http") \ No newline at end of file diff --git a/http_wrapper/exceptions.py b/http_wrapper/exceptions.py new file mode 100644 index 0000000..298f34f --- /dev/null +++ b/http_wrapper/exceptions.py @@ -0,0 +1 @@ +class SiibraJugexExceptions(Exception): pass \ No newline at end of file diff --git a/http_wrapper/jugex_logger.py b/http_wrapper/jugex_logger.py new file mode 100644 index 0000000..8bb4530 --- /dev/null +++ b/http_wrapper/jugex_logger.py @@ -0,0 +1,34 @@ +import logging +import os + +main_logger = logging.getLogger(__name__) +main_logger.setLevel(logging.INFO) + +logger = logging.getLogger(__name__ + '.general') +access_logger = logging.getLogger(__name__ + '.access') + +log_dir = os.environ.get("SIIBRA_TOOLBOX_LOG_DIR") + +if log_dir: + from logging.handlers import TimedRotatingFileHandler + import socket + + general_filename = os.path.join(log_dir, f"{socket.gethostname()}.general.log") + general_log_handler = TimedRotatingFileHandler(general_filename, when="d", encoding="utf-8") + + access_filename = os.path.join(log_dir, f"{socket.gethostname()}.access.log") + access_log_handler = TimedRotatingFileHandler(access_filename, when="d", encoding="utf-8") + +else: + general_log_handler = logging.StreamHandler() + access_log_handler = logging.StreamHandler() + +formatter = logging.Formatter('[%(name)s:%(levelname)s] %(message)s') +general_log_handler.setFormatter(formatter) +logger.addHandler(general_log_handler) + +access_log_formatter = logging.Formatter('%(asctime)s - %(status)s - %(process_time_ms)s - %(message)s') +access_log_handler.setFormatter(access_log_formatter) +access_logger.addHandler(access_log_handler) + +__version__ = "0.1.0" diff --git a/http_wrapper/models.py b/http_wrapper/models.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/http_wrapper/models.py @@ -0,0 +1 @@ + diff --git a/http_wrapper/requirements-server.txt b/http_wrapper/requirements-server.txt new file mode 100644 index 0000000..ee91be1 --- /dev/null +++ b/http_wrapper/requirements-server.txt @@ -0,0 +1,7 @@ +celery[redis]==5.1.2 +fastapi==0.75.2 +uvicorn==0.16.0 +ipython_genutils==0.2.0 # required by nbconvert, but absent if jupyter is not installed +nbconvert==6.0.7 +jinja2==3.0.3 +python-gitlab diff --git a/http_wrapper/requirements-worker.txt b/http_wrapper/requirements-worker.txt new file mode 100644 index 0000000..6026508 --- /dev/null +++ b/http_wrapper/requirements-worker.txt @@ -0,0 +1,2 @@ +celery[redis]==5.1.2 +# also need to install siibra-jugex diff --git a/http_wrapper/routes/__init__.py b/http_wrapper/routes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/http_wrapper/routes/analysis.py b/http_wrapper/routes/analysis.py new file mode 100644 index 0000000..a4692e5 --- /dev/null +++ b/http_wrapper/routes/analysis.py @@ -0,0 +1,70 @@ +from enum import Enum +from typing import Dict, List, Optional +from fastapi import APIRouter +from pydantic import Field + +from http_wrapper.routes.common import PostReqModel, BModel +from http_wrapper.scheduling.worker import analysis + +router = APIRouter() + +class PostRespModel(BModel): + poll_url: str + +class ResultStatus(str, Enum): + SUCCESS="SUCCESS" + FAILURE="FAILURE" + PENDING="PENDING" + + +class JugexAnalysisResult(BModel): + race: List[str] + age: List[int] + specimen: List[str] + area: List[str] + zscores: Dict[str, List[float]] + p_values: Dict[str, float] = Field(..., alias="p-values") + + +class JugexMNICoord(BModel): + roi: str + mnicoord: List[List[float]] + + +class JugexResult(BModel): + result: JugexAnalysisResult + mnicoords: List[JugexMNICoord] + + +class ResultModel(BModel): + status: ResultStatus + result: Optional[JugexResult] + + +@router.post('/analysis', response_model=PostRespModel) +def post_analysis(post_req: PostReqModel): + + res = analysis.delay(**post_req.dict()) + return PostRespModel( + poll_url=res.id + ) + +@router.get('/analysis/{analysis_id}', response_model=ResultModel) +def get_analysis_with_id(analysis_id: str): + + res = analysis.AsyncResult(analysis_id) + if res.state == "FAILURE": + res.forget() + return ResultModel( + status=ResultStatus.FAILURE + ) + if res.state == "SUCCESS": + result = res.get() + res.forget() + return ResultModel( + status=ResultStatus.SUCCESS, + result=JugexResult(**result) + ) + return ResultModel( + status=ResultStatus.PENDING + ) \ No newline at end of file diff --git a/http_wrapper/routes/common.py b/http_wrapper/routes/common.py new file mode 100644 index 0000000..e25bea3 --- /dev/null +++ b/http_wrapper/routes/common.py @@ -0,0 +1,42 @@ +from typing import List +from pydantic import BaseModel, Field + +class BModel(BaseModel): + class Config: + use_enum_values: True + allow_population_by_field_name = True + +class PostReqModel(BModel): + parcellation_id: str + roi_1: str + roi_2: str + genes: List[str] + permutations: int = Field(1000) + threshold: float = Field(0.2) + +def reverse_param(post_req: PostReqModel): + return { + 'parcellation_id': post_req.parcellation_id, + 'roi_1': post_req.roi_1, + 'roi_2': post_req.roi_2, + 'comma_delimited_genes': ','.join(post_req.genes), + 'permutations': post_req.permutations, + 'threshold': post_req.threshold, + } + +def common_params( + parcellation_id:str, + roi_1:str, + roi_2:str, + comma_delimited_genes:str, + permutations:int=100, + threshold:float=0.2, +): + return PostReqModel( + parcellation_id=parcellation_id, + roi_1=roi_1, + roi_2=roi_2, + genes=comma_delimited_genes.split(','), + permutations=permutations, + threshold=threshold, + ) diff --git a/http_wrapper/routes/git.py b/http_wrapper/routes/git.py new file mode 100644 index 0000000..c44a8bb --- /dev/null +++ b/http_wrapper/routes/git.py @@ -0,0 +1,22 @@ +from fastapi import APIRouter, Request +from fastapi.responses import PlainTextResponse +from fastapi.exceptions import HTTPException + +router = APIRouter() + +# @router.get("/{repo}.git/info/refs") +# def info_refs(): +# return PlainTextResponse( +# """db53a06240ccf01b51eefa3ee348a12e360db2bd\trefs/heads/master""" +# ) + +# @router.get("/{repo}.git/HEAD") +# def head(): +# return PlainTextResponse( +# """ref: refs/heads/master\n""" +# ) + +# @router.get("/objects/{head}/{rest}") +# def get_obj(): +# print("foo") +# raise HTTPException(404) \ No newline at end of file diff --git a/http_wrapper/routes/notebook.py b/http_wrapper/routes/notebook.py new file mode 100644 index 0000000..310b88f --- /dev/null +++ b/http_wrapper/routes/notebook.py @@ -0,0 +1,175 @@ +from os import path +from fastapi import APIRouter, Depends, Request, BackgroundTasks +from fastapi.responses import HTMLResponse, FileResponse, Response, RedirectResponse +from fastapi.templating import Jinja2Templates +import nbformat +from nbconvert import HTMLExporter +from enum import Enum +import os +from uuid import uuid4 +from urllib.parse import quote, quote_plus +from http_wrapper.routes.common import PostReqModel, common_params, reverse_param +from http_wrapper.conf.siibra_jugex_conf import HBP_GITLAB_HOST, HBP_GITLAB_TOKEN, HBP_GITLAB_PROJECT_ID + +run_now_enabled = (HBP_GITLAB_HOST is not None + and HBP_GITLAB_TOKEN is not None + and HBP_GITLAB_PROJECT_ID is not None) + +class NotebookExecutionSite(Enum): + EBRAINS_LAB="EBRAINS_LAB" + MY_BINDER="MY_BINDER" + +def get_jupyterhub_link(site: NotebookExecutionSite, git_url: str, branch: str, filename: str) -> str: + if site == NotebookExecutionSite.EBRAINS_LAB: + return "https://lab.ebrains.eu/hub/user-redirect/git-pull?repo={repo}&urlpath={urlpath}&branch={branch}&targetPath={branch}".format( + repo=quote(git_url), + urlpath=quote(f'lab/tree/{branch}/{filename}'), + branch=quote(branch), + ) + if site == NotebookExecutionSite.MY_BINDER: + return "https://mybinder.org/v2/git/{repo}/{branch}?labpath={filename}".format( + repo=quote_plus(git_url), + branch=quote_plus(branch), + filename=quote_plus(filename) + ) + raise ValueError(f"site {site} not defined.") + +html_exporter = HTMLExporter(template_name="classic") +router = APIRouter() + +root_dir=path.abspath( + path.join( + path.dirname(__file__), + "../.." + ) +) +templates = Jinja2Templates(directory=path.join(root_dir, "http_wrapper/templates/")) + +def get_notebook(post_req:PostReqModel): + path_to_notebook = path.join(root_dir, "examples/siibra-jugex.ipynb") + with open(path_to_notebook, "r") as fp: + notebook = nbformat.read(fp, as_version=4) + + for cell in notebook.cells: + if cell.get("cell_type") != "code": + continue + if "# set analysis parameters" not in cell.get("source"): + continue + cell_source = cell["source"] + import re, json + cell_source = re.sub(r"\ncandidate_regions.*?\n", f"\ncandidate_regions = { json.dumps([post_req.roi_1, post_req.roi_2]) }\n", cell_source) + cell_source = re.sub(r"\ncandidate_genes.*?\n", f"\ncandidate_genes = { json.dumps(post_req.genes) }\n", cell_source) + cell_source = re.sub(r"\nthreshold.*?\n", f"\nthreshold = { post_req.threshold }\n", cell_source) + cell_source = re.sub(r"\npermutations.*?\n", f"\npermutations = { post_req.permutations }\n", cell_source) + cell["source"] = cell_source + break + return notebook + +TAGS = ["notebook"] + +def get_notebook_name(post_req: PostReqModel): + def sanitize(input: str): + import re + return re.sub(r"\W", "_", input) + return_dict = { + "r1": sanitize(post_req.roi_1), + "r2": sanitize(post_req.roi_2), + "g": sanitize('_'.join(post_req.genes)), + "p": sanitize(str(post_req.permutations)), + "th": sanitize(str(post_req.threshold)), + } + return "__".join([f"{key}_{return_dict[key]}" for key in return_dict]) + +@router.get('/view', response_class=HTMLResponse, tags=TAGS) +def show_notebook(request: Request, post_req:PostReqModel = Depends(common_params)): + from urllib.parse import urlencode + + run_now_context = { + "run_ebrains_lab": f"run?site=EBRAINS_LAB&{urlencode(reverse_param(post_req))}", + "run_my_binder": f"run?site=MY_BINDER&{urlencode(reverse_param(post_req))}", + } if run_now_enabled else {} + return templates.TemplateResponse( + "preview_nb.jinja", + context={ + "request": request, + "notebook_name": f"{get_notebook_name(post_req)}.ipynb", + "download_notebook_url": f"download?{urlencode(reverse_param(post_req))}", + "view_notebook_url": f"notebook?{urlencode(reverse_param(post_req))}", + "user": None, + **run_now_context, + } + ) + + +@router.get('/notebook', response_class=HTMLResponse, tags=TAGS) +def show_notebook(post_req:PostReqModel = Depends(common_params)): + notebook = get_notebook(post_req) + (body, resources) = html_exporter.from_notebook_node(notebook) + return HTMLResponse(content=body) + + +@router.get('/download', response_class=FileResponse, tags=TAGS) +def download_notebook(post_req:PostReqModel = Depends(common_params)): + notebook = get_notebook(post_req) + import json + resp = Response( + content=json.dumps(notebook, indent=4), + headers={ + "Content-Disposition": f"attachment; filename={get_notebook_name(post_req)}.ipynb" + }, + status_code=200, + media_type="application/json" + ) + return resp + +branches_to_delete = [] + +def on_exit(): + for branch in branches_to_delete: + delete_branch(branch) + +# Only add run endpoint if the necesary env vars are defined +if run_now_enabled: + + # Do not use async, or else it will be blocking + def delete_branch(branch: str): + + from gitlab import Gitlab + gl = Gitlab(url=HBP_GITLAB_HOST, private_token=HBP_GITLAB_TOKEN) + project = gl.projects.get(HBP_GITLAB_PROJECT_ID) + project.branches.delete(branch) + + @router.get("/redirect") + def redirect(): + return RedirectResponse("https://lab.ebrains.eu/") + + @router.get("/run", tags=TAGS) + def run_notebook(site: NotebookExecutionSite, post_req:PostReqModel = Depends(common_params)): + notebook = get_notebook(post_req) + notebook_filename = f"{get_notebook_name(post_req)}.ipynb" + + from gitlab import Gitlab + import json + + gl = Gitlab(url=HBP_GITLAB_HOST, private_token=HBP_GITLAB_TOKEN) + project = gl.projects.get(HBP_GITLAB_PROJECT_ID) + + branch_name = f"tmp-{uuid4()}" + project.branches.create({ + 'branch': branch_name, + 'ref': 'main' + }) + + project.files.create({ + 'file_path': notebook_filename, + 'branch': branch_name, + 'content': json.dumps(notebook, indent=4), + # 'encoding': 'utf-8', + 'commit_message': 'creating file' + }) + redirect_url = get_jupyterhub_link(site, project.attributes.get("http_url_to_repo"), branch_name, notebook_filename) + + branches_to_delete.append(branch_name) + + print(f"DEBUG: Redirecting: {redirect_url}") + return RedirectResponse(redirect_url) diff --git a/http_wrapper/scheduling/__init__.py b/http_wrapper/scheduling/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/http_wrapper/scheduling/worker.py b/http_wrapper/scheduling/worker.py new file mode 100644 index 0000000..38d645f --- /dev/null +++ b/http_wrapper/scheduling/worker.py @@ -0,0 +1,51 @@ +from typing import List +import os +import logging +from http_wrapper.conf.siibra_jugex_conf import CHANNEL + +logger = logging.getLogger(__name__) + +try: + from celery import Celery +except ImportError as e: + logger.critical(f"Importing celery error") + raise e + +default_config="http_wrapper.conf.celeryconfig" +app = Celery(CHANNEL) +app.config_from_object(default_config) + +@app.task +def analysis(parcellation_id: str, roi_1:str, roi_2: str, genes: List[str], permutations: int, threshold: float): + from siibra_jugex import DifferentialGeneExpression + import siibra + import socket + + hostname = socket.gethostname() + logger.info(f"{hostname}:task:rec") + logger.debug(f"{hostname}:task:rec_param {parcellation_id} {roi_1} {roi_2}, {','.join(genes)}") + + try: + parc = siibra.parcellations[parcellation_id] + + jugex = DifferentialGeneExpression(parc) + jugex.add_candidate_genes(genes) + jugex.define_roi1(roi_1, maptype=siibra.MapType.CONTINUOUS, threshold=threshold) + jugex.define_roi2(roi_2, maptype=siibra.MapType.CONTINUOUS, threshold=threshold) + + result = jugex.run(permutations) + + mnicoords = [{ + "roi": roi, + "mnicoord": [s["mnicoord"] for s in jugex.get_samples(roi).values()] + } for roi in [roi_1, roi_2]] + + logger.info(f"{hostname}:task:success") + logger.debug(f"{hostname}:task:success_result {result}") + return { + "result": result, + "mnicoords": mnicoords + } + except Exception as e: + logger.critical(f"{hostname}:task:failed {str(e)}") + raise e diff --git a/http_wrapper/server.py b/http_wrapper/server.py new file mode 100644 index 0000000..4d22656 --- /dev/null +++ b/http_wrapper/server.py @@ -0,0 +1,71 @@ +from http_wrapper.routes.analysis import router as analysis_router +from http_wrapper.routes.notebook import router as notebook_router, on_exit +from http_wrapper.routes.git import router as git_router +from http_wrapper.jugex_logger import access_logger +from http_wrapper.conf.siibra_jugex_conf import SIIBRA_TOOLBOX_VIEWER_PLUGIN_STATIC_DIR + +from fastapi import FastAPI, Request +from fastapi.staticfiles import StaticFiles +from fastapi.middleware.cors import CORSMiddleware +import time + +app = FastAPI() + +# Allow CORS +origins = ['*'] +app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_methods=['GET', 'POST'], +) + +@app.get('/', include_in_schema=False) +def hello(): + return 'world' + +@app.get('/ready', include_in_schema=False) +def hello(): + return 'OK' + +@app.middleware('http') +async def access_log(request: Request, call_next): + start_time = time.time() + resp = await call_next(request) + process_time = (time.time() - start_time) * 1000 + access_logger.info(f'{request.method.upper()} {str(request.url)}', extra={ + 'status': str(resp.status_code), + 'process_time_ms': str(round(process_time)) + }) + return resp + +app.include_router(analysis_router, prefix="/analysis") +app.include_router(notebook_router, prefix="/notebook") +app.include_router(git_router, prefix="/git") + +if SIIBRA_TOOLBOX_VIEWER_PLUGIN_STATIC_DIR: + path_to_viewer_plugin = SIIBRA_TOOLBOX_VIEWER_PLUGIN_STATIC_DIR + app.mount('/viewer_plugin', StaticFiles(directory=path_to_viewer_plugin)) + +from threading import Event + +@app.on_event("shutdown") +def shutdown_event(): + # TODO doesn't work quite right + # shutdown handler isn't called until ctrl+c is hit twice + on_exit() + + +do_not_logs = ( + "GET / HTTP", +) + +import logging +class EndpointLoggingFilter(logging.Filter): + """Custom logger filter. Do not log metrics, ready endpoint.""" + def filter(self, record: logging.LogRecord) -> bool: + message = record.getMessage() + return all( + message.find(do_not_log) == -1 for do_not_log in do_not_logs + ) + +logging.getLogger("uvicorn.access").addFilter(EndpointLoggingFilter()) diff --git a/http_wrapper/templates/preview_nb.jinja b/http_wrapper/templates/preview_nb.jinja new file mode 100644 index 0000000..7f875a4 --- /dev/null +++ b/http_wrapper/templates/preview_nb.jinja @@ -0,0 +1,102 @@ + + + + + + + + + siibra-jugex workbook + + + + +
+
+

+ siibra-jugex notebook previewer +

+
+ + +
+
+ + + + + + Download + + + + {% if run_ebrains_lab %} + + + Run on lab.ebrains.eu + + {% endif %} + + {% if run_my_binder %} + + + Run on my binder + + + {% endif %} +
+
+ + + +
+ +
+
+
+ +
+ +
+ + + diff --git a/requirements.txt b/requirements.txt index 5f00a89..54a0ab7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ -siibra>=0.2a0 +siibra>=0.3a17,<0.4 statsmodels scipy + diff --git a/setup.py b/setup.py index de214ee..9e9b813 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,6 @@ def find_version(): 'Intended Audience :: Developers', ], python_requires='>=3.6', - install_requires=['siibra>=0.3a17','statsmodels','scipy'] + install_requires=['siibra>=0.3a17,<0.4','statsmodels','scipy'] ) diff --git a/siibra_jugex/__init__.py b/siibra_jugex/__init__.py index 3be972c..e282cfd 100644 --- a/siibra_jugex/__init__.py +++ b/siibra_jugex/__init__.py @@ -1,4 +1,4 @@ -__version__="0.2" +__version__="0.2.1" import logging logger = logging.getLogger(__name__) diff --git a/siibra_jugex/jugex.py b/siibra_jugex/jugex.py index 8d27927..dac2382 100644 --- a/siibra_jugex/jugex.py +++ b/siibra_jugex/jugex.py @@ -17,7 +17,7 @@ from . import logger import siibra -MNI152SPACE = siibra.spaces.MNI152_2009C_NONL_ASYM +MNI152SPACE = siibra.spaces['mni152'] MIN_SIIBRA_VERSION=0.2 import re @@ -297,7 +297,7 @@ def _retrieve_samples(self,regionspec,maptype:siibra.MapType,threshold:float): samples[key]['mnicoord'] = tuple(f.location) samples[key]['region'] = region samples[key][gene_name] = np.mean( - winsorize(f.z_scores, limits=0.1)) + winsorize(np.array(f.z_scores), limits=0.1)) logger.info('{} samples found for region {}.'.format( len(samples), regionspec)) return samples diff --git a/test/__init__.py b/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/http_wrapper/__init__.py b/test/http_wrapper/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/http_wrapper/test_e2e.py b/test/http_wrapper/test_e2e.py new file mode 100644 index 0000000..2f517c8 --- /dev/null +++ b/test/http_wrapper/test_e2e.py @@ -0,0 +1,37 @@ +from fastapi.testclient import TestClient + +from http_wrapper.server import app + +client = TestClient(app) + +def test_getting_notebook(): + from urllib.parse import urlencode + import random, string + + def get_random_string(): + return "".join(random.choices(string.ascii_uppercase, k=8)) + + roi_1 = get_random_string() + roi_2 = get_random_string() + genes = [ get_random_string(), get_random_string() ] + perm = round(random.random() * 1000) + threshold = random.random() + encoded_url = urlencode({ + 'parcellation_id': '2.9', + 'roi_1': roi_1, + 'roi_2': roi_2, + 'comma_delimited_genes': ",".join(genes), + 'permutations': perm, + 'threshold': threshold, + }) + resp = client.get(f"/notebook/download?{encoded_url}") + + resp.raise_for_status() + text = resp.text + assert roi_1 in text + assert roi_2 in text + assert all( + gene in text for gene in genes + ) + assert f'permutations = {perm}' in text + assert f"threshold = {threshold}" in text diff --git a/viewer_plugin/.gitignore b/viewer_plugin/.gitignore new file mode 100644 index 0000000..0c5b278 --- /dev/null +++ b/viewer_plugin/.gitignore @@ -0,0 +1,5 @@ +./node_modules/ +./public/build/ + +.DS_Store +node_modules diff --git a/viewer_plugin/README.md b/viewer_plugin/README.md new file mode 100644 index 0000000..cfc2182 --- /dev/null +++ b/viewer_plugin/README.md @@ -0,0 +1 @@ +# siibra-jugex-viewer-plugin \ No newline at end of file diff --git a/viewer_plugin/package-lock.json b/viewer_plugin/package-lock.json new file mode 100644 index 0000000..cf2fd09 --- /dev/null +++ b/viewer_plugin/package-lock.json @@ -0,0 +1,4167 @@ +{ + "name": "siibra-jugex-viewer-plugin", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "siibra-jugex-viewer-plugin", + "version": "1.0.0", + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "@smui-extra/autocomplete": "^6.0.0-beta.16", + "@smui/button": "^6.0.0-beta.16", + "@smui/card": "^6.0.0-beta.16", + "@smui/chips": "^6.0.0-beta.16", + "@smui/circular-progress": "^6.0.0-beta.16", + "@smui/data-table": "^6.0.0-beta.16", + "@smui/form-field": "^6.0.0-beta.16", + "@smui/icon-button": "^6.0.0-beta.16", + "@smui/slider": "^6.0.0-beta.16", + "@smui/switch": "^6.0.0-beta.16", + "rollup": "^2.3.4", + "rollup-plugin-css-only": "^3.1.0", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-svelte": "^7.0.0", + "rollup-plugin-terser": "^7.0.0", + "sirv-cli": "^2.0.0", + "smui-theme": "^6.0.0-beta.16", + "svelte": "^3.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", + "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@material/animation": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-13.0.0.tgz", + "integrity": "sha512-YR0/u4u56qXDjKYolQ7F+IvlPkaSBhMl/dZv8DK0FbD6PH4ckOPd3bEXNRndXtprsxwknQQP2pttjPImylkl0g==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/base": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-13.0.0.tgz", + "integrity": "sha512-vFx0JryRfcvUNX3cZ2u32wUMvxzd+c/YW0LFOXNgqCDWlubHcMm0Y6Wz371LhfQo80/NE69u+/4Joo99yKnVeg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/button": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/button/-/button-13.0.0.tgz", + "integrity": "sha512-lYorht6fcEd4P+dsLVp2BGtaY5cGYNp71LMajuDe71GZX3dZPoKeVvb+Ie1S7vcB+o+WLTeaisMk9/vA4gfi8A==", + "dev": true, + "dependencies": { + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/tokens": "^13.0.0", + "@material/touch-target": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/card": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/card/-/card-13.0.0.tgz", + "integrity": "sha512-ooJUOt1Viv99Dyz4rhz9ZZbfa996eHh3RUuXkPRkT66Btd5TzpdqsQWKwOVc5bgbgWqzhDWQ6A/aQdYqH97ccg==", + "dev": true, + "dependencies": { + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/checkbox": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/checkbox/-/checkbox-13.0.0.tgz", + "integrity": "sha512-tRC6n9Jq7GgdU0d1F8NOvUy6WiRZR58tUgL1QqoiQK9PGKSt0dAF3Aa48uubO7/Lt9K4NqgwV6/OeHv8pHaM/w==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/touch-target": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/chips": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/chips/-/chips-13.0.0.tgz", + "integrity": "sha512-Ov4runDbrROUpMqKyCi3lpknfrLzGwtV+/rfYIgTYUkEVpCHXHddxXxcjP4zqh3QLXnE6ma92PLGcxCb/zzogQ==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/checkbox": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/tokens": "^13.0.0", + "@material/touch-target": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/circular-progress": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-13.0.0.tgz", + "integrity": "sha512-jSbr0ywY2N6s05tyqTXl/cG339C+qU3ck3FwXUq5SJup8CWT0AoJ8EG/CD10CEhNH8nH9Iwstve95oNgIt8G4g==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/progress-indicator": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/data-table": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-13.0.0.tgz", + "integrity": "sha512-Z3yEq1T6Om/A3ntPw0bd40dqtOR4H3++pvchgW35kq+V9xDLL0hfzmuiy0QH4plA2ZsFYJxjt02k/SRvnkjKPQ==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/checkbox": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/icon-button": "^13.0.0", + "@material/linear-progress": "^13.0.0", + "@material/list": "^13.0.0", + "@material/menu": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/select": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/touch-target": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/density": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-13.0.0.tgz", + "integrity": "sha512-ppJTzOsuhjQam5GvHaq/XZocZNUr+41XQ2sd5nONAmQ0wwzXgqG0FaxtF1EXqK3uZFadz+vAu6enagre9DXhTA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/dom": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-13.0.0.tgz", + "integrity": "sha512-M9HLAYBZtkTUvf66FL+jAEvUOdhji1HkGA1mV6oyE+HY9gkCkmso+mngvzlLd5+uaAVE9I3WQFhSb9gp0cpXnw==", + "dev": true, + "dependencies": { + "@material/feature-targeting": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/elevation": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-13.0.0.tgz", + "integrity": "sha512-hzdblgamVRbC0UwKafcvUVDvKzMiOSveDiwGgFk+EAg/tZRdwMlQPyf/9I6Lr8Cw/pNGnEOPhmCDOYPOHimr0w==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/feature-targeting": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-13.0.0.tgz", + "integrity": "sha512-QJClfeaA4EMyAxKJy9WR0Nx+/VwSZCkhGLUVBG9NhxqYGfl/LtaeaidrNm32vYEoNZAofN92VD2RwQTRwp/dMQ==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/floating-label": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-13.0.0.tgz", + "integrity": "sha512-imAPamD97QrizVCOpxjr3UfQJyDBpEEhDBSbEbKLrCpqG3jQx4/My5rNKKVGWjxUiBYgBA1dhkn98RRX5tGBtQ==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/form-field": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/form-field/-/form-field-13.0.0.tgz", + "integrity": "sha512-cXs5uYA89KgrXrU1UYkl52JizeIK3Mx9LjBw4ZYiyQJzFaBTPYsYWGSJMad1HZhWlRiigGTyN1M9ePIxtBpi0Q==", + "dev": true, + "dependencies": { + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/icon-button": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-13.0.0.tgz", + "integrity": "sha512-SdxFytWvbfN0fj7jHFq3DqK5/Zoms+Ipuv6fI8AzwgDFe7mXJ2euPahN+3XcmJ3BaSMyfYsdbcYdCWs8bgHW1w==", + "dev": true, + "dependencies": { + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/touch-target": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/line-ripple": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-13.0.0.tgz", + "integrity": "sha512-5djBRXrd1+SiMVUTWr4rD6xv+/qTaGGmgUS5GytBE5mczvnEwcPmM4PzF+HNj2TS+wvNvIfRjRmUzWO2Z6w2lA==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/linear-progress": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-13.0.0.tgz", + "integrity": "sha512-FJpP6flSME5QRPfkB616uA5bk9aMKJBqkklrHk6dSMZaTKbiHRmc6faxMIZ4w9W49JFMXaSwzC39y96tQTiRQg==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/progress-indicator": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/list": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/list/-/list-13.0.0.tgz", + "integrity": "sha512-poq4WNDEfW6Z3YPAn3wdBX4RSkj3A83Pht6984MmG8YJZMlq34ftHECw37VcdmFJIyRPdpZqywJo/i7CxsSAgQ==", + "dev": true, + "dependencies": { + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/menu": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/menu/-/menu-13.0.0.tgz", + "integrity": "sha512-RY9R2ubYU6a7WRJW3nWr/AoSzdrxwUGqkfJSx0U9M/wK1vbXYYcJ7eCXFzSpa5VrstE7of7PbyYtQ8V61tILEQ==", + "dev": true, + "dependencies": { + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/list": "^13.0.0", + "@material/menu-surface": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/menu-surface": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-13.0.0.tgz", + "integrity": "sha512-Irfnk0l8AO7z8ucilbBzZI8izbFV/aK1GbiPpT1SmZuKkL1z+04rB2HpB+OqwaBixdLTDq70AyawcnQ0MACeXQ==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/notched-outline": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-13.0.0.tgz", + "integrity": "sha512-BHdxr1x2AN4oqycTNg0FGisG3rMHf50z3MuyUoQsJJ3WGjxBMWKd0yK/xl4m38nFKPg1vQnzyHIYTJdRpCaE7A==", + "dev": true, + "dependencies": { + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/floating-label": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/progress-indicator": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-13.0.0.tgz", + "integrity": "sha512-IfhAMn03gWg/Rl0Bg26Q1g+DrMnaULllz+ZJeIY7BXZC5qFYq1fLq4+RiQmfPGlJfURUjrWNLcI1VDVyXUHHzg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/ripple": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-13.0.0.tgz", + "integrity": "sha512-hx4B40hB2rRfsGwf1jwo2GGlYDq0yUQjcMcMmXfQipPJNpQhy8ylmXKc1DBjmWf7EQ/MgbfCSYwPrYXrbGP31w==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/rtl": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-13.0.0.tgz", + "integrity": "sha512-nFGy3iQg7k+xLs67eb86mRFVLwa0yi7MusqRK4OM8DXcLO5yoVfUTPKpdSykcbRryp9imVHsxutox2tZawR4og==", + "dev": true, + "dependencies": { + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/select": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/select/-/select-13.0.0.tgz", + "integrity": "sha512-wVprsSMicU/l+LAqXdOU+qdzzdHupLXpWWQo2Rsk8G6AxL1Zna+/+ETnRlDdr2wHHK/KNDXSBdmuCcoEIRshcA==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/floating-label": "^13.0.0", + "@material/line-ripple": "^13.0.0", + "@material/list": "^13.0.0", + "@material/menu": "^13.0.0", + "@material/menu-surface": "^13.0.0", + "@material/notched-outline": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/shape": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/shape/-/shape-13.0.0.tgz", + "integrity": "sha512-exk96+iCjzCujk3aSrvIMhmW773s1Tc0h+MbQKbt6Iv3nHJCyLSiRbxclCHXWHrVwG/9KZRkrt/g2qk7P3VRBg==", + "dev": true, + "dependencies": { + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/slider": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/slider/-/slider-13.0.0.tgz", + "integrity": "sha512-PW+3X9MiOoWmXhirYo/Mk2UYW00Tnsihrx5YJQ4+IxwbrUI75/8yUsO8kVr7YC+Eqhldz8oXzhIXglQFtbpolQ==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/switch": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/switch/-/switch-13.0.0.tgz", + "integrity": "sha512-zbdo6nKEOAx24ILCBobZlQqU2WZ+KuPgdAc1VTI1q1BCKN3rDIfm9RnsCuYiZa9iaq4UUgdYuhH8KVEYGP7Lrw==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/tokens": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/textfield": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-13.0.0.tgz", + "integrity": "sha512-CzodrOqx8wzj2AQngMpISURJID4jVOHf4CtiPoj32LG8bWLn5ZfAAX2aA2rO6NPyDYsFm0aEnlfMhnDwQyPoYw==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/floating-label": "^13.0.0", + "@material/line-ripple": "^13.0.0", + "@material/notched-outline": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/theme": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-13.0.0.tgz", + "integrity": "sha512-KAe1s0MvvfCGAwJliDVTvgAKuD3ESwhl7F7br4Iam4IPdqME2rWl8NPhKHFfaWqTG7PyCgMMngYEYuA8cLNTsA==", + "dev": true, + "dependencies": { + "@material/feature-targeting": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/tokens": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-13.0.0.tgz", + "integrity": "sha512-t55CKVeAjABdSQCKjsvYvqrA6Z4f5varLpLloai8ZQU0giSl7qbUczV1i8y2pSOzpRTswD5JKM7a19qfsl/TCA==", + "dev": true, + "dependencies": { + "@material/elevation": "^13.0.0" + } + }, + "node_modules/@material/touch-target": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-13.0.0.tgz", + "integrity": "sha512-2BMjj+nwKIYG7cZZGcNuRSKo53knqDu9ksv9wLidxjLgzqXBd1v9gdXsqMRQXepoOqftWGmYMaRYI0xMnxt6lA==", + "dev": true, + "dependencies": { + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/typography": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/typography/-/typography-13.0.0.tgz", + "integrity": "sha512-UfaK4vT3LmGiiySf2RVIrf7fJZa6EJadFwo4YUMJx9bvUMRlBm1oI8Vo9fYpKdLfuSTeA+2BlgbwYVObj3laFw==", + "dev": true, + "dependencies": { + "@material/feature-targeting": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, + "node_modules/@rollup/plugin-commonjs": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", + "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^2.30.0" + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/@smui-extra/autocomplete": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui-extra/autocomplete/-/autocomplete-6.0.0-beta.16.tgz", + "integrity": "sha512-ENmfOy4SNj68tDYNjCmwkDIU/dDWu3X7YghcrFkxsJdNinvlzwKnX1dvRvFc9Ov8V2n8V6oNQZsw7f9yhGcOBQ==", + "dev": true, + "dependencies": { + "@smui/common": "^6.0.0-beta.16", + "@smui/list": "^6.0.0-beta.16", + "@smui/menu": "^6.0.0-beta.16", + "@smui/menu-surface": "^6.0.0-beta.16", + "@smui/textfield": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/button": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/button/-/button-6.0.0-beta.16.tgz", + "integrity": "sha512-+sBnqo8PlbvV7R3sHUOu+/y2xqiDwcpjLkW7BVvbK0r3Rit87yKCb5Octa0DnnTmNh9W6bHGe162v760drcSfw==", + "dev": true, + "dependencies": { + "@material/button": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/theme": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/card": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/card/-/card-6.0.0-beta.16.tgz", + "integrity": "sha512-QCFM7EuM0mH0hxzRbFbforgGFP9q8SLLUHIqW4D17QA5EYiVAuGrputlT4Zx8ujTDSs7/Glax+qCSL3WnF2L3g==", + "dev": true, + "dependencies": { + "@material/card": "^13.0.0", + "@smui/button": "^6.0.0-beta.16", + "@smui/common": "^6.0.0-beta.16", + "@smui/icon-button": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/checkbox": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/checkbox/-/checkbox-6.0.0-beta.16.tgz", + "integrity": "sha512-gasHsQjgpPoYfOPl7hCibBiv6PWG8I1VzRrdmSQMbv9H0HI2Nn8Oo3DpYCnAUd6z4JhVk6UWCzqaO+La/tUAHw==", + "dev": true, + "dependencies": { + "@material/checkbox": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/chips": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/chips/-/chips-6.0.0-beta.16.tgz", + "integrity": "sha512-mfkVFAna0qsyYcyKL8LuqGxIteclKDm4PJ+yXUUk3VbsUcKFFf6FZqvM0xsjZt4QIKkrnDaALtCOviheHQNH7A==", + "dev": true, + "dependencies": { + "@material/chips": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/rtl": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/circular-progress": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/circular-progress/-/circular-progress-6.0.0-beta.16.tgz", + "integrity": "sha512-d4iLP6pZFB2hbXA04ykBI8fAOHRd8kdvEZnPbFDbyV97BqXVuuQP+TMlqL0a/NppDD9gaC09ZWnGaijlpEAfHg==", + "dev": true, + "dependencies": { + "@material/circular-progress": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/common": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/common/-/common-6.0.0-beta.16.tgz", + "integrity": "sha512-Ual6505AOP75T+IneOQ6e1tnlhDflJX+yxa9T8Hx5X00MOiULvWACg/RW3c8UEQAc96YnEsA3utv5qDy8tZpmg==", + "dev": true, + "dependencies": { + "@material/dom": "^13.0.0", + "@tsconfig/svelte": "^3.0.0", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/data-table": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/data-table/-/data-table-6.0.0-beta.16.tgz", + "integrity": "sha512-nNHIGbGMviTDGivOeaIwV6RnP/Lq7XZqs72gmX40ncLYIu1c//HNhIrcL3qbF+Ne/8gq7cuuKC4F26VUPEPD0g==", + "dev": true, + "dependencies": { + "@material/data-table": "^13.0.0", + "@material/dom": "^13.0.0", + "@smui/checkbox": "^6.0.0-beta.16", + "@smui/common": "^6.0.0-beta.16", + "@smui/icon-button": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "@smui/select": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/floating-label": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/floating-label/-/floating-label-6.0.0-beta.16.tgz", + "integrity": "sha512-9Vk7NPoWgL7r7Sk88iWfq+rW/BKL1rQ6S0rJimspsoUIgPpUQYFeBRZFaQiOMJZJrJEGisJbqdKVpsXqqnNq/w==", + "dev": true, + "dependencies": { + "@material/floating-label": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/form-field": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/form-field/-/form-field-6.0.0-beta.16.tgz", + "integrity": "sha512-sNzmim4HDM07feYaqRZGy0VwNH6PuerSl6Ha5cxAFaTLN8SIzfNUEJ7iNX1eBImTlrRNHsR6VwUySXX60xUyQA==", + "dev": true, + "dependencies": { + "@material/feature-targeting": "^13.0.0", + "@material/form-field": "^13.0.0", + "@material/rtl": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/icon-button": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/icon-button/-/icon-button-6.0.0-beta.16.tgz", + "integrity": "sha512-2OwRT3smK5S5V+sI2c8URij0Z91/FVeGKZHy4V5q/GYSlaPu1WJtgFY1O/9wNYEYq0PkP4ohwq16ZiURy+rYTQ==", + "dev": true, + "dependencies": { + "@material/density": "^13.0.0", + "@material/icon-button": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/line-ripple": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/line-ripple/-/line-ripple-6.0.0-beta.16.tgz", + "integrity": "sha512-+o3lvnmpudOl4CKvCq2B99PKJHQgdLnyFqd1/x75IwhQjuV2El5yuqE+rC5hAVzo6vKqJmWME/1+bNfkPvIvaA==", + "dev": true, + "dependencies": { + "@material/line-ripple": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/list": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/list/-/list-6.0.0-beta.16.tgz", + "integrity": "sha512-eMzbQPk9F07rxvynLalNqlrc6WwIGVJna6eotBYB2JELpSU+oB86xicgKK08d1w3TLY8zwVUmcigSEWmM843mw==", + "dev": true, + "dependencies": { + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/list": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/menu": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/menu/-/menu-6.0.0-beta.16.tgz", + "integrity": "sha512-Kh4aaf217ZGBIX0ZFqK5BxdII/KoYRfsKrpQNH9wIXShKUUH4uPIbIINYCkpzcoJ2ximzmpHJC0OfHvXfkipbA==", + "dev": true, + "dependencies": { + "@material/dom": "^13.0.0", + "@material/menu": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/list": "^6.0.0-beta.16", + "@smui/menu-surface": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/menu-surface": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/menu-surface/-/menu-surface-6.0.0-beta.16.tgz", + "integrity": "sha512-a8hLHBcu6+XDgdcdcR22arjsPr1G/4cpFLToWirSYfhk2pEfK9a/gkQiNOII0LHwZlreIgo/1FeUeAClJGCqhA==", + "dev": true, + "dependencies": { + "@material/animation": "^13.0.0", + "@material/menu-surface": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/notched-outline": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/notched-outline/-/notched-outline-6.0.0-beta.16.tgz", + "integrity": "sha512-2z01cpWNhqFbNJTnXfR2sBF/icEJnDGfVE9KZwU3OLZSBeoBoXFc9opc+HGKkWt678AS50VRoOMHSkxShk5q9g==", + "dev": true, + "dependencies": { + "@material/notched-outline": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/floating-label": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/ripple": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/ripple/-/ripple-6.0.0-beta.16.tgz", + "integrity": "sha512-9vlsFn8ZL0tpWKHmDfZPPzQzdusLNZaA3CzpJKnnMIWvlUZVixR780iHa1YXg0cEEQ2lPlSK4CFJEdiGMFRAow==", + "dev": true, + "dependencies": { + "@material/dom": "^13.0.0", + "@material/ripple": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/select": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/select/-/select-6.0.0-beta.16.tgz", + "integrity": "sha512-GexYE2oRjywdcpo3XGCbzduR13Bp9LYPnV8Guax+i4wpJlG288lem2tDWmsodnNXQTGQ+sVqICz0QLnDmPSvUQ==", + "dev": true, + "dependencies": { + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/select": "^13.0.0", + "@material/theme": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/floating-label": "^6.0.0-beta.16", + "@smui/line-ripple": "^6.0.0-beta.16", + "@smui/list": "^6.0.0-beta.16", + "@smui/menu": "^6.0.0-beta.16", + "@smui/menu-surface": "^6.0.0-beta.16", + "@smui/notched-outline": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/slider": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/slider/-/slider-6.0.0-beta.16.tgz", + "integrity": "sha512-kGrl1UCOdukMngP5R7fLDNpMBBCm6EI3+jutiLR+NT9RhmwUN5befs8edHotkWxPK1xzLN/KSezzKUFaWK4OCg==", + "dev": true, + "dependencies": { + "@material/dom": "^13.0.0", + "@material/slider": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/switch": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/switch/-/switch-6.0.0-beta.16.tgz", + "integrity": "sha512-z14p7DE4ZF0D2ir+qQ3wgA3khexztSY3Z7xbNV0+yO5rIW24l2Sg/uFrZSNDfQuiIUHSf1aP9zHCPrxmm74OLA==", + "dev": true, + "dependencies": { + "@material/feature-targeting": "^13.0.0", + "@material/switch": "^13.0.0", + "@material/theme": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@smui/textfield": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/textfield/-/textfield-6.0.0-beta.16.tgz", + "integrity": "sha512-lzW9oZ2PTuJRwtJoxxMlbElv6ZaAqT2W4tJAMs6hI8R0iotEyahcZNm8YxilOHIVLiCkeXOqd2LB4QBeq+vvVQ==", + "dev": true, + "dependencies": { + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/textfield": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/floating-label": "^6.0.0-beta.16", + "@smui/line-ripple": "^6.0.0-beta.16", + "@smui/notched-outline": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "node_modules/@tsconfig/svelte": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-3.0.0.tgz", + "integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/console-clear": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz", + "integrity": "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/dedent-js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", + "integrity": "sha1-vuX7fJ5yfYXf+iRZDRDsGrElUwU=", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/kleur": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz", + "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/livereload": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", + "opts": ">= 1.2.0", + "ws": "^7.4.3" + }, + "bin": { + "livereload": "bin/livereload.js" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/livereload-js": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.3.tgz", + "integrity": "sha512-a7Jipme3XIBIryJluWP5LQrEAvhobDPyScBe+q+MYwxBiMT2Ck7msy4tAdF8TAa33FMdJqX4guP81Yhiu6BkmQ==", + "dev": true + }, + "node_modules/local-access": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/local-access/-/local-access-1.1.0.tgz", + "integrity": "sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", + "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opts": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", + "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", + "dev": true + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "2.70.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", + "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-css-only": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz", + "integrity": "sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "4" + }, + "engines": { + "node": ">=10.12.0" + }, + "peerDependencies": { + "rollup": "1 || 2" + } + }, + "node_modules/rollup-plugin-css-only/node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/rollup-plugin-livereload": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.5.tgz", + "integrity": "sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==", + "dev": true, + "dependencies": { + "livereload": "^0.9.1" + }, + "engines": { + "node": ">=8.3" + } + }, + "node_modules/rollup-plugin-svelte": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz", + "integrity": "sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==", + "dev": true, + "dependencies": { + "require-relative": "^0.8.7", + "rollup-pluginutils": "^2.8.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "rollup": ">=2.0.0", + "svelte": ">=3.5.0" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "dependencies": { + "estree-walker": "^0.6.1" + } + }, + "node_modules/rollup-pluginutils/node_modules/estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sass": { + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.1.tgz", + "integrity": "sha512-noTnY41KnlW2A9P8sdwESpDmo+KBNkukI1i8+hOK3footBUcohNHtdOJbckp46XO95nuvcHDDZ+4tmOnpK3hjw==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/semiver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", + "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/sirv": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz", + "integrity": "sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sirv-cli": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-2.0.2.tgz", + "integrity": "sha512-OtSJDwxsF1NWHc7ps3Sa0s+dPtP15iQNJzfKVz+MxkEo3z72mCD+yu30ct79rPr0CaV1HXSOBp+MIY5uIhHZ1A==", + "dev": true, + "dependencies": { + "console-clear": "^1.1.0", + "get-port": "^3.2.0", + "kleur": "^4.1.4", + "local-access": "^1.0.1", + "sade": "^1.6.0", + "semiver": "^1.0.0", + "sirv": "^2.0.0", + "tinydate": "^1.0.0" + }, + "bin": { + "sirv": "bin.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/smui-theme": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/smui-theme/-/smui-theme-6.0.0-beta.16.tgz", + "integrity": "sha512-koh62ENvVp7ure62NUHTTaLudH1nxdL/YJt5u0rLuBSs53UPg8L8hdmcGqmTawj3h2dlD+yuHnyx8lpT1y8EWQ==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.7", + "sass": "^1.49.9", + "yargs": "^17.3.1" + }, + "bin": { + "smui-theme": "smui-theme" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svelte": { + "version": "3.58.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.58.0.tgz", + "integrity": "sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/svelte2tsx": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.5.9.tgz", + "integrity": "sha512-xTDASjlh+rKo4QRhTRYSH87sS7fRoyX67xhGIMPKa3FYqftRHRmMes6nVgEskiuhBovslNHYYpMMg5YM5n/STg==", + "dev": true, + "dependencies": { + "dedent-js": "^1.0.1", + "pascal-case": "^3.1.1" + }, + "peerDependencies": { + "svelte": "^3.24", + "typescript": "^4.1.2" + } + }, + "node_modules/terser": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", + "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tinydate": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", + "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz", + "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", + "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true, + "engines": { + "node": ">=12" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.9.tgz", + "integrity": "sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + }, + "dependencies": { + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + } + } + }, + "@material/animation": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-13.0.0.tgz", + "integrity": "sha512-YR0/u4u56qXDjKYolQ7F+IvlPkaSBhMl/dZv8DK0FbD6PH4ckOPd3bEXNRndXtprsxwknQQP2pttjPImylkl0g==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@material/base": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-13.0.0.tgz", + "integrity": "sha512-vFx0JryRfcvUNX3cZ2u32wUMvxzd+c/YW0LFOXNgqCDWlubHcMm0Y6Wz371LhfQo80/NE69u+/4Joo99yKnVeg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@material/button": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/button/-/button-13.0.0.tgz", + "integrity": "sha512-lYorht6fcEd4P+dsLVp2BGtaY5cGYNp71LMajuDe71GZX3dZPoKeVvb+Ie1S7vcB+o+WLTeaisMk9/vA4gfi8A==", + "dev": true, + "requires": { + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/tokens": "^13.0.0", + "@material/touch-target": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/card": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/card/-/card-13.0.0.tgz", + "integrity": "sha512-ooJUOt1Viv99Dyz4rhz9ZZbfa996eHh3RUuXkPRkT66Btd5TzpdqsQWKwOVc5bgbgWqzhDWQ6A/aQdYqH97ccg==", + "dev": true, + "requires": { + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/checkbox": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/checkbox/-/checkbox-13.0.0.tgz", + "integrity": "sha512-tRC6n9Jq7GgdU0d1F8NOvUy6WiRZR58tUgL1QqoiQK9PGKSt0dAF3Aa48uubO7/Lt9K4NqgwV6/OeHv8pHaM/w==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/touch-target": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/chips": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/chips/-/chips-13.0.0.tgz", + "integrity": "sha512-Ov4runDbrROUpMqKyCi3lpknfrLzGwtV+/rfYIgTYUkEVpCHXHddxXxcjP4zqh3QLXnE6ma92PLGcxCb/zzogQ==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/checkbox": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/tokens": "^13.0.0", + "@material/touch-target": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/circular-progress": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-13.0.0.tgz", + "integrity": "sha512-jSbr0ywY2N6s05tyqTXl/cG339C+qU3ck3FwXUq5SJup8CWT0AoJ8EG/CD10CEhNH8nH9Iwstve95oNgIt8G4g==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/progress-indicator": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/data-table": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-13.0.0.tgz", + "integrity": "sha512-Z3yEq1T6Om/A3ntPw0bd40dqtOR4H3++pvchgW35kq+V9xDLL0hfzmuiy0QH4plA2ZsFYJxjt02k/SRvnkjKPQ==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/checkbox": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/icon-button": "^13.0.0", + "@material/linear-progress": "^13.0.0", + "@material/list": "^13.0.0", + "@material/menu": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/select": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/touch-target": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/density": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-13.0.0.tgz", + "integrity": "sha512-ppJTzOsuhjQam5GvHaq/XZocZNUr+41XQ2sd5nONAmQ0wwzXgqG0FaxtF1EXqK3uZFadz+vAu6enagre9DXhTA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@material/dom": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-13.0.0.tgz", + "integrity": "sha512-M9HLAYBZtkTUvf66FL+jAEvUOdhji1HkGA1mV6oyE+HY9gkCkmso+mngvzlLd5+uaAVE9I3WQFhSb9gp0cpXnw==", + "dev": true, + "requires": { + "@material/feature-targeting": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/elevation": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-13.0.0.tgz", + "integrity": "sha512-hzdblgamVRbC0UwKafcvUVDvKzMiOSveDiwGgFk+EAg/tZRdwMlQPyf/9I6Lr8Cw/pNGnEOPhmCDOYPOHimr0w==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/feature-targeting": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-13.0.0.tgz", + "integrity": "sha512-QJClfeaA4EMyAxKJy9WR0Nx+/VwSZCkhGLUVBG9NhxqYGfl/LtaeaidrNm32vYEoNZAofN92VD2RwQTRwp/dMQ==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@material/floating-label": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-13.0.0.tgz", + "integrity": "sha512-imAPamD97QrizVCOpxjr3UfQJyDBpEEhDBSbEbKLrCpqG3jQx4/My5rNKKVGWjxUiBYgBA1dhkn98RRX5tGBtQ==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/form-field": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/form-field/-/form-field-13.0.0.tgz", + "integrity": "sha512-cXs5uYA89KgrXrU1UYkl52JizeIK3Mx9LjBw4ZYiyQJzFaBTPYsYWGSJMad1HZhWlRiigGTyN1M9ePIxtBpi0Q==", + "dev": true, + "requires": { + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/icon-button": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-13.0.0.tgz", + "integrity": "sha512-SdxFytWvbfN0fj7jHFq3DqK5/Zoms+Ipuv6fI8AzwgDFe7mXJ2euPahN+3XcmJ3BaSMyfYsdbcYdCWs8bgHW1w==", + "dev": true, + "requires": { + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/touch-target": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/line-ripple": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-13.0.0.tgz", + "integrity": "sha512-5djBRXrd1+SiMVUTWr4rD6xv+/qTaGGmgUS5GytBE5mczvnEwcPmM4PzF+HNj2TS+wvNvIfRjRmUzWO2Z6w2lA==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/linear-progress": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-13.0.0.tgz", + "integrity": "sha512-FJpP6flSME5QRPfkB616uA5bk9aMKJBqkklrHk6dSMZaTKbiHRmc6faxMIZ4w9W49JFMXaSwzC39y96tQTiRQg==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/progress-indicator": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/list": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/list/-/list-13.0.0.tgz", + "integrity": "sha512-poq4WNDEfW6Z3YPAn3wdBX4RSkj3A83Pht6984MmG8YJZMlq34ftHECw37VcdmFJIyRPdpZqywJo/i7CxsSAgQ==", + "dev": true, + "requires": { + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/menu": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/menu/-/menu-13.0.0.tgz", + "integrity": "sha512-RY9R2ubYU6a7WRJW3nWr/AoSzdrxwUGqkfJSx0U9M/wK1vbXYYcJ7eCXFzSpa5VrstE7of7PbyYtQ8V61tILEQ==", + "dev": true, + "requires": { + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/list": "^13.0.0", + "@material/menu-surface": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/menu-surface": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-13.0.0.tgz", + "integrity": "sha512-Irfnk0l8AO7z8ucilbBzZI8izbFV/aK1GbiPpT1SmZuKkL1z+04rB2HpB+OqwaBixdLTDq70AyawcnQ0MACeXQ==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/notched-outline": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-13.0.0.tgz", + "integrity": "sha512-BHdxr1x2AN4oqycTNg0FGisG3rMHf50z3MuyUoQsJJ3WGjxBMWKd0yK/xl4m38nFKPg1vQnzyHIYTJdRpCaE7A==", + "dev": true, + "requires": { + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/floating-label": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/progress-indicator": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-13.0.0.tgz", + "integrity": "sha512-IfhAMn03gWg/Rl0Bg26Q1g+DrMnaULllz+ZJeIY7BXZC5qFYq1fLq4+RiQmfPGlJfURUjrWNLcI1VDVyXUHHzg==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "@material/ripple": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-13.0.0.tgz", + "integrity": "sha512-hx4B40hB2rRfsGwf1jwo2GGlYDq0yUQjcMcMmXfQipPJNpQhy8ylmXKc1DBjmWf7EQ/MgbfCSYwPrYXrbGP31w==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/rtl": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-13.0.0.tgz", + "integrity": "sha512-nFGy3iQg7k+xLs67eb86mRFVLwa0yi7MusqRK4OM8DXcLO5yoVfUTPKpdSykcbRryp9imVHsxutox2tZawR4og==", + "dev": true, + "requires": { + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/select": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/select/-/select-13.0.0.tgz", + "integrity": "sha512-wVprsSMicU/l+LAqXdOU+qdzzdHupLXpWWQo2Rsk8G6AxL1Zna+/+ETnRlDdr2wHHK/KNDXSBdmuCcoEIRshcA==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/floating-label": "^13.0.0", + "@material/line-ripple": "^13.0.0", + "@material/list": "^13.0.0", + "@material/menu": "^13.0.0", + "@material/menu-surface": "^13.0.0", + "@material/notched-outline": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/shape": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/shape/-/shape-13.0.0.tgz", + "integrity": "sha512-exk96+iCjzCujk3aSrvIMhmW773s1Tc0h+MbQKbt6Iv3nHJCyLSiRbxclCHXWHrVwG/9KZRkrt/g2qk7P3VRBg==", + "dev": true, + "requires": { + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/slider": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/slider/-/slider-13.0.0.tgz", + "integrity": "sha512-PW+3X9MiOoWmXhirYo/Mk2UYW00Tnsihrx5YJQ4+IxwbrUI75/8yUsO8kVr7YC+Eqhldz8oXzhIXglQFtbpolQ==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/switch": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/switch/-/switch-13.0.0.tgz", + "integrity": "sha512-zbdo6nKEOAx24ILCBobZlQqU2WZ+KuPgdAc1VTI1q1BCKN3rDIfm9RnsCuYiZa9iaq4UUgdYuhH8KVEYGP7Lrw==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/tokens": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/textfield": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-13.0.0.tgz", + "integrity": "sha512-CzodrOqx8wzj2AQngMpISURJID4jVOHf4CtiPoj32LG8bWLn5ZfAAX2aA2rO6NPyDYsFm0aEnlfMhnDwQyPoYw==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/base": "^13.0.0", + "@material/density": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/floating-label": "^13.0.0", + "@material/line-ripple": "^13.0.0", + "@material/notched-outline": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/shape": "^13.0.0", + "@material/theme": "^13.0.0", + "@material/typography": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/theme": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-13.0.0.tgz", + "integrity": "sha512-KAe1s0MvvfCGAwJliDVTvgAKuD3ESwhl7F7br4Iam4IPdqME2rWl8NPhKHFfaWqTG7PyCgMMngYEYuA8cLNTsA==", + "dev": true, + "requires": { + "@material/feature-targeting": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/tokens": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-13.0.0.tgz", + "integrity": "sha512-t55CKVeAjABdSQCKjsvYvqrA6Z4f5varLpLloai8ZQU0giSl7qbUczV1i8y2pSOzpRTswD5JKM7a19qfsl/TCA==", + "dev": true, + "requires": { + "@material/elevation": "^13.0.0" + } + }, + "@material/touch-target": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-13.0.0.tgz", + "integrity": "sha512-2BMjj+nwKIYG7cZZGcNuRSKo53knqDu9ksv9wLidxjLgzqXBd1v9gdXsqMRQXepoOqftWGmYMaRYI0xMnxt6lA==", + "dev": true, + "requires": { + "@material/base": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/rtl": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@material/typography": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@material/typography/-/typography-13.0.0.tgz", + "integrity": "sha512-UfaK4vT3LmGiiySf2RVIrf7fJZa6EJadFwo4YUMJx9bvUMRlBm1oI8Vo9fYpKdLfuSTeA+2BlgbwYVObj3laFw==", + "dev": true, + "requires": { + "@material/feature-targeting": "^13.0.0", + "@material/theme": "^13.0.0", + "tslib": "^2.1.0" + } + }, + "@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, + "@rollup/plugin-commonjs": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-17.1.0.tgz", + "integrity": "sha512-PoMdXCw0ZyvjpCMT5aV4nkL0QywxP29sODQsSGeDpr/oI49Qq9tRtAsb/LbYbDzFlOydVEqHmmZWFtXJEAX9ew==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "commondir": "^1.0.1", + "estree-walker": "^2.0.1", + "glob": "^7.1.6", + "is-reference": "^1.2.1", + "magic-string": "^0.25.7", + "resolve": "^1.17.0" + } + }, + "@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "dependencies": { + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + } + } + }, + "@smui-extra/autocomplete": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui-extra/autocomplete/-/autocomplete-6.0.0-beta.16.tgz", + "integrity": "sha512-ENmfOy4SNj68tDYNjCmwkDIU/dDWu3X7YghcrFkxsJdNinvlzwKnX1dvRvFc9Ov8V2n8V6oNQZsw7f9yhGcOBQ==", + "dev": true, + "requires": { + "@smui/common": "^6.0.0-beta.16", + "@smui/list": "^6.0.0-beta.16", + "@smui/menu": "^6.0.0-beta.16", + "@smui/menu-surface": "^6.0.0-beta.16", + "@smui/textfield": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/button": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/button/-/button-6.0.0-beta.16.tgz", + "integrity": "sha512-+sBnqo8PlbvV7R3sHUOu+/y2xqiDwcpjLkW7BVvbK0r3Rit87yKCb5Octa0DnnTmNh9W6bHGe162v760drcSfw==", + "dev": true, + "requires": { + "@material/button": "^13.0.0", + "@material/elevation": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/theme": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/card": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/card/-/card-6.0.0-beta.16.tgz", + "integrity": "sha512-QCFM7EuM0mH0hxzRbFbforgGFP9q8SLLUHIqW4D17QA5EYiVAuGrputlT4Zx8ujTDSs7/Glax+qCSL3WnF2L3g==", + "dev": true, + "requires": { + "@material/card": "^13.0.0", + "@smui/button": "^6.0.0-beta.16", + "@smui/common": "^6.0.0-beta.16", + "@smui/icon-button": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/checkbox": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/checkbox/-/checkbox-6.0.0-beta.16.tgz", + "integrity": "sha512-gasHsQjgpPoYfOPl7hCibBiv6PWG8I1VzRrdmSQMbv9H0HI2Nn8Oo3DpYCnAUd6z4JhVk6UWCzqaO+La/tUAHw==", + "dev": true, + "requires": { + "@material/checkbox": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/chips": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/chips/-/chips-6.0.0-beta.16.tgz", + "integrity": "sha512-mfkVFAna0qsyYcyKL8LuqGxIteclKDm4PJ+yXUUk3VbsUcKFFf6FZqvM0xsjZt4QIKkrnDaALtCOviheHQNH7A==", + "dev": true, + "requires": { + "@material/chips": "^13.0.0", + "@material/dom": "^13.0.0", + "@material/rtl": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/circular-progress": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/circular-progress/-/circular-progress-6.0.0-beta.16.tgz", + "integrity": "sha512-d4iLP6pZFB2hbXA04ykBI8fAOHRd8kdvEZnPbFDbyV97BqXVuuQP+TMlqL0a/NppDD9gaC09ZWnGaijlpEAfHg==", + "dev": true, + "requires": { + "@material/circular-progress": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/common": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/common/-/common-6.0.0-beta.16.tgz", + "integrity": "sha512-Ual6505AOP75T+IneOQ6e1tnlhDflJX+yxa9T8Hx5X00MOiULvWACg/RW3c8UEQAc96YnEsA3utv5qDy8tZpmg==", + "dev": true, + "requires": { + "@material/dom": "^13.0.0", + "@tsconfig/svelte": "^3.0.0", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/data-table": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/data-table/-/data-table-6.0.0-beta.16.tgz", + "integrity": "sha512-nNHIGbGMviTDGivOeaIwV6RnP/Lq7XZqs72gmX40ncLYIu1c//HNhIrcL3qbF+Ne/8gq7cuuKC4F26VUPEPD0g==", + "dev": true, + "requires": { + "@material/data-table": "^13.0.0", + "@material/dom": "^13.0.0", + "@smui/checkbox": "^6.0.0-beta.16", + "@smui/common": "^6.0.0-beta.16", + "@smui/icon-button": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "@smui/select": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/floating-label": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/floating-label/-/floating-label-6.0.0-beta.16.tgz", + "integrity": "sha512-9Vk7NPoWgL7r7Sk88iWfq+rW/BKL1rQ6S0rJimspsoUIgPpUQYFeBRZFaQiOMJZJrJEGisJbqdKVpsXqqnNq/w==", + "dev": true, + "requires": { + "@material/floating-label": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/form-field": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/form-field/-/form-field-6.0.0-beta.16.tgz", + "integrity": "sha512-sNzmim4HDM07feYaqRZGy0VwNH6PuerSl6Ha5cxAFaTLN8SIzfNUEJ7iNX1eBImTlrRNHsR6VwUySXX60xUyQA==", + "dev": true, + "requires": { + "@material/feature-targeting": "^13.0.0", + "@material/form-field": "^13.0.0", + "@material/rtl": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/icon-button": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/icon-button/-/icon-button-6.0.0-beta.16.tgz", + "integrity": "sha512-2OwRT3smK5S5V+sI2c8URij0Z91/FVeGKZHy4V5q/GYSlaPu1WJtgFY1O/9wNYEYq0PkP4ohwq16ZiURy+rYTQ==", + "dev": true, + "requires": { + "@material/density": "^13.0.0", + "@material/icon-button": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/line-ripple": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/line-ripple/-/line-ripple-6.0.0-beta.16.tgz", + "integrity": "sha512-+o3lvnmpudOl4CKvCq2B99PKJHQgdLnyFqd1/x75IwhQjuV2El5yuqE+rC5hAVzo6vKqJmWME/1+bNfkPvIvaA==", + "dev": true, + "requires": { + "@material/line-ripple": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/list": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/list/-/list-6.0.0-beta.16.tgz", + "integrity": "sha512-eMzbQPk9F07rxvynLalNqlrc6WwIGVJna6eotBYB2JELpSU+oB86xicgKK08d1w3TLY8zwVUmcigSEWmM843mw==", + "dev": true, + "requires": { + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/list": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/menu": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/menu/-/menu-6.0.0-beta.16.tgz", + "integrity": "sha512-Kh4aaf217ZGBIX0ZFqK5BxdII/KoYRfsKrpQNH9wIXShKUUH4uPIbIINYCkpzcoJ2ximzmpHJC0OfHvXfkipbA==", + "dev": true, + "requires": { + "@material/dom": "^13.0.0", + "@material/menu": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/list": "^6.0.0-beta.16", + "@smui/menu-surface": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/menu-surface": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/menu-surface/-/menu-surface-6.0.0-beta.16.tgz", + "integrity": "sha512-a8hLHBcu6+XDgdcdcR22arjsPr1G/4cpFLToWirSYfhk2pEfK9a/gkQiNOII0LHwZlreIgo/1FeUeAClJGCqhA==", + "dev": true, + "requires": { + "@material/animation": "^13.0.0", + "@material/menu-surface": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/notched-outline": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/notched-outline/-/notched-outline-6.0.0-beta.16.tgz", + "integrity": "sha512-2z01cpWNhqFbNJTnXfR2sBF/icEJnDGfVE9KZwU3OLZSBeoBoXFc9opc+HGKkWt678AS50VRoOMHSkxShk5q9g==", + "dev": true, + "requires": { + "@material/notched-outline": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/floating-label": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/ripple": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/ripple/-/ripple-6.0.0-beta.16.tgz", + "integrity": "sha512-9vlsFn8ZL0tpWKHmDfZPPzQzdusLNZaA3CzpJKnnMIWvlUZVixR780iHa1YXg0cEEQ2lPlSK4CFJEdiGMFRAow==", + "dev": true, + "requires": { + "@material/dom": "^13.0.0", + "@material/ripple": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/select": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/select/-/select-6.0.0-beta.16.tgz", + "integrity": "sha512-GexYE2oRjywdcpo3XGCbzduR13Bp9LYPnV8Guax+i4wpJlG288lem2tDWmsodnNXQTGQ+sVqICz0QLnDmPSvUQ==", + "dev": true, + "requires": { + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/select": "^13.0.0", + "@material/theme": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/floating-label": "^6.0.0-beta.16", + "@smui/line-ripple": "^6.0.0-beta.16", + "@smui/list": "^6.0.0-beta.16", + "@smui/menu": "^6.0.0-beta.16", + "@smui/menu-surface": "^6.0.0-beta.16", + "@smui/notched-outline": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/slider": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/slider/-/slider-6.0.0-beta.16.tgz", + "integrity": "sha512-kGrl1UCOdukMngP5R7fLDNpMBBCm6EI3+jutiLR+NT9RhmwUN5befs8edHotkWxPK1xzLN/KSezzKUFaWK4OCg==", + "dev": true, + "requires": { + "@material/dom": "^13.0.0", + "@material/slider": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/switch": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/switch/-/switch-6.0.0-beta.16.tgz", + "integrity": "sha512-z14p7DE4ZF0D2ir+qQ3wgA3khexztSY3Z7xbNV0+yO5rIW24l2Sg/uFrZSNDfQuiIUHSf1aP9zHCPrxmm74OLA==", + "dev": true, + "requires": { + "@material/feature-targeting": "^13.0.0", + "@material/switch": "^13.0.0", + "@material/theme": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@smui/textfield": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/@smui/textfield/-/textfield-6.0.0-beta.16.tgz", + "integrity": "sha512-lzW9oZ2PTuJRwtJoxxMlbElv6ZaAqT2W4tJAMs6hI8R0iotEyahcZNm8YxilOHIVLiCkeXOqd2LB4QBeq+vvVQ==", + "dev": true, + "requires": { + "@material/dom": "^13.0.0", + "@material/feature-targeting": "^13.0.0", + "@material/ripple": "^13.0.0", + "@material/rtl": "^13.0.0", + "@material/textfield": "^13.0.0", + "@smui/common": "^6.0.0-beta.16", + "@smui/floating-label": "^6.0.0-beta.16", + "@smui/line-ripple": "^6.0.0-beta.16", + "@smui/notched-outline": "^6.0.0-beta.16", + "@smui/ripple": "^6.0.0-beta.16", + "svelte2tsx": "^0.5.5" + } + }, + "@tsconfig/svelte": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-3.0.0.tgz", + "integrity": "sha512-pYrtLtOwku/7r1i9AMONsJMVYAtk3hzOfiGNekhtq5tYBGA7unMve8RvUclKLMT3PrihvJqUmzsRGh0RP84hKg==", + "dev": true + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/node": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz", + "integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==", + "dev": true + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "console-clear": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/console-clear/-/console-clear-1.1.1.tgz", + "integrity": "sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==", + "dev": true + }, + "dedent-js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", + "integrity": "sha1-vuX7fJ5yfYXf+iRZDRDsGrElUwU=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dev": true, + "requires": { + "@types/estree": "*" + } + }, + "jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "kleur": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz", + "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==", + "dev": true + }, + "livereload": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", + "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", + "dev": true, + "requires": { + "chokidar": "^3.5.0", + "livereload-js": "^3.3.1", + "opts": ">= 1.2.0", + "ws": "^7.4.3" + } + }, + "livereload-js": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.3.3.tgz", + "integrity": "sha512-a7Jipme3XIBIryJluWP5LQrEAvhobDPyScBe+q+MYwxBiMT2Ck7msy4tAdF8TAa33FMdJqX4guP81Yhiu6BkmQ==", + "dev": true + }, + "local-access": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/local-access/-/local-access-1.1.0.tgz", + "integrity": "sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw==", + "dev": true + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true + }, + "mrmime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", + "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", + "dev": true + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opts": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", + "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", + "dev": true + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "2.70.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", + "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "rollup-plugin-css-only": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-3.1.0.tgz", + "integrity": "sha512-TYMOE5uoD76vpj+RTkQLzC9cQtbnJNktHPB507FzRWBVaofg7KhIqq1kGbcVOadARSozWF883Ho9KpSPKH8gqA==", + "dev": true, + "requires": { + "@rollup/pluginutils": "4" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + } + } + }, + "rollup-plugin-livereload": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.5.tgz", + "integrity": "sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==", + "dev": true, + "requires": { + "livereload": "^0.9.1" + } + }, + "rollup-plugin-svelte": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.0.tgz", + "integrity": "sha512-vopCUq3G+25sKjwF5VilIbiY6KCuMNHP1PFvx2Vr3REBNMDllKHFZN2B9jwwC+MqNc3UPKkjXnceLPEjTjXGXg==", + "dev": true, + "requires": { + "require-relative": "^0.8.7", + "rollup-pluginutils": "^2.8.2" + } + }, + "rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + } + }, + "rollup-pluginutils": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + } + } + }, + "sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "requires": { + "mri": "^1.1.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "sass": { + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.1.tgz", + "integrity": "sha512-noTnY41KnlW2A9P8sdwESpDmo+KBNkukI1i8+hOK3footBUcohNHtdOJbckp46XO95nuvcHDDZ+4tmOnpK3hjw==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "semiver": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semiver/-/semiver-1.1.0.tgz", + "integrity": "sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg==", + "dev": true + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "sirv": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.2.tgz", + "integrity": "sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==", + "dev": true, + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^3.0.0" + } + }, + "sirv-cli": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/sirv-cli/-/sirv-cli-2.0.2.tgz", + "integrity": "sha512-OtSJDwxsF1NWHc7ps3Sa0s+dPtP15iQNJzfKVz+MxkEo3z72mCD+yu30ct79rPr0CaV1HXSOBp+MIY5uIhHZ1A==", + "dev": true, + "requires": { + "console-clear": "^1.1.0", + "get-port": "^3.2.0", + "kleur": "^4.1.4", + "local-access": "^1.0.1", + "sade": "^1.6.0", + "semiver": "^1.0.0", + "sirv": "^2.0.0", + "tinydate": "^1.0.0" + } + }, + "smui-theme": { + "version": "6.0.0-beta.16", + "resolved": "https://registry.npmjs.org/smui-theme/-/smui-theme-6.0.0-beta.16.tgz", + "integrity": "sha512-koh62ENvVp7ure62NUHTTaLudH1nxdL/YJt5u0rLuBSs53UPg8L8hdmcGqmTawj3h2dlD+yuHnyx8lpT1y8EWQ==", + "dev": true, + "requires": { + "node-fetch": "^2.6.7", + "sass": "^1.49.9", + "yargs": "^17.3.1" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "svelte": { + "version": "3.58.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.58.0.tgz", + "integrity": "sha512-brIBNNB76mXFmU/Kerm4wFnkskBbluBDCjx/8TcpYRb298Yh2dztS2kQ6bhtjMcvUhd5ynClfwpz5h2gnzdQ1A==", + "dev": true + }, + "svelte2tsx": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.5.9.tgz", + "integrity": "sha512-xTDASjlh+rKo4QRhTRYSH87sS7fRoyX67xhGIMPKa3FYqftRHRmMes6nVgEskiuhBovslNHYYpMMg5YM5n/STg==", + "dev": true, + "requires": { + "dedent-js": "^1.0.1", + "pascal-case": "^3.1.1" + } + }, + "terser": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.1.tgz", + "integrity": "sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "tinydate": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", + "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "totalist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.0.tgz", + "integrity": "sha512-eM+pCBxXO/njtF7vdFsHuqb+ElbxqtI4r5EAvk6grfAFyJ6IvWlSkfZ5T9ozC6xWw3Fj1fGoSmrl0gUs46JVIw==", + "dev": true + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "peer": true + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "dev": true, + "requires": {} + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.4.1.tgz", + "integrity": "sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true + } + } +} diff --git a/viewer_plugin/package.json b/viewer_plugin/package.json new file mode 100644 index 0000000..f525abe --- /dev/null +++ b/viewer_plugin/package.json @@ -0,0 +1,35 @@ +{ + "name": "siibra-jugex-viewer-plugin", + "version": "1.0.0", + "scripts": { + "build": "npm run theme && npm run theme:dark && rollup -c", + "dev": "rollup -c -w", + "start": "sirv public --no-clear -p 8000", + "theme": "npm run theme:light && npm run theme:dark", + "theme:light": "smui-theme compile public/build/smui.css -i src/theme", + "theme:dark": "smui-theme compile public/build/smui-dark.css -i src/theme/dark" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.0.0", + "@rollup/plugin-node-resolve": "^11.0.0", + "@smui-extra/autocomplete": "^6.0.0-beta.16", + "@smui/button": "^6.0.0-beta.16", + "@smui/card": "^6.0.0-beta.16", + "@smui/chips": "^6.0.0-beta.16", + "@smui/circular-progress": "^6.0.0-beta.16", + "@smui/data-table": "^6.0.0-beta.16", + "@smui/form-field": "^6.0.0-beta.16", + "@smui/icon-button": "^6.0.0-beta.16", + "@smui/slider": "^6.0.0-beta.16", + "@smui/switch": "^6.0.0-beta.16", + "rollup": "^2.3.4", + "rollup-plugin-css-only": "^3.1.0", + "rollup-plugin-livereload": "^2.0.0", + "rollup-plugin-svelte": "^7.0.0", + "rollup-plugin-terser": "^7.0.0", + "sirv-cli": "^2.0.0", + "smui-theme": "^6.0.0-beta.16", + "svelte": "^3.0.0" + }, + "dependencies": {} +} diff --git a/viewer_plugin/public/favicon.png b/viewer_plugin/public/favicon.png new file mode 100644 index 0000000..7e6f5eb Binary files /dev/null and b/viewer_plugin/public/favicon.png differ diff --git a/viewer_plugin/public/global.css b/viewer_plugin/public/global.css new file mode 100644 index 0000000..67e5900 --- /dev/null +++ b/viewer_plugin/public/global.css @@ -0,0 +1,62 @@ +html, body { + position: relative; + width: 100%; + height: 100%; +} + +body { + margin: 0; + padding: 8px; + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +} + +a { + color: rgb(0,100,200); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:visited { + color: rgb(0,80,160); +} + +label { + display: block; +} + +input, button, select, textarea { + font-family: inherit; + font-size: inherit; + -webkit-padding: 0.4em 0; + padding: 0.4em; + margin: 0 0 0.5em 0; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 2px; +} + +input:disabled { + color: #ccc; +} + +button { + color: #333; + background-color: #f4f4f4; + outline: none; +} + +button:disabled { + color: #999; +} + +button:not(:disabled):active { + background-color: #ddd; +} + +button:focus { + border-color: #666; +} diff --git a/viewer_plugin/public/index.html b/viewer_plugin/public/index.html new file mode 100644 index 0000000..a1668a3 --- /dev/null +++ b/viewer_plugin/public/index.html @@ -0,0 +1,39 @@ + + + + + + + siibra-jugex + + + + + + + + + + + + + + + + + + + + diff --git a/viewer_plugin/public/manifest.json b/viewer_plugin/public/manifest.json new file mode 100644 index 0000000..e79dcfa --- /dev/null +++ b/viewer_plugin/public/manifest.json @@ -0,0 +1,5 @@ +{ + "siibra-explorer": true, + "name": "siibra-jugex", + "iframeUrl": "index.html" +} diff --git a/viewer_plugin/rollup.config.js b/viewer_plugin/rollup.config.js new file mode 100644 index 0000000..e8965ec --- /dev/null +++ b/viewer_plugin/rollup.config.js @@ -0,0 +1,76 @@ +import svelte from 'rollup-plugin-svelte'; +import commonjs from '@rollup/plugin-commonjs'; +import resolve from '@rollup/plugin-node-resolve'; +import livereload from 'rollup-plugin-livereload'; +import { terser } from 'rollup-plugin-terser'; +import css from 'rollup-plugin-css-only'; + +const production = !process.env.ROLLUP_WATCH; + +function serve() { + let server; + + function toExit() { + if (server) server.kill(0); + } + + return { + writeBundle() { + if (server) return; + server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { + stdio: ['ignore', 'inherit', 'inherit'], + shell: true + }); + + process.on('SIGTERM', toExit); + process.on('exit', toExit); + } + }; +} + +export default { + input: 'src/main.js', + output: { + sourcemap: true, + format: 'iife', + name: 'app', + file: 'public/build/bundle.js' + }, + plugins: [ + svelte({ + compilerOptions: { + // enable run-time checks when not in production + dev: !production + } + }), + // we'll extract any component CSS out into + // a separate file - better for performance + css({ output: 'bundle.css' }), + + // If you have external dependencies installed from + // npm, you'll most likely need these plugins. In + // some cases you'll need additional configuration - + // consult the documentation for details: + // https://github.com/rollup/plugins/tree/master/packages/commonjs + resolve({ + browser: true, + dedupe: ['svelte'] + }), + commonjs(), + + // In dev mode, call `npm run start` once + // the bundle has been generated + !production && serve(), + + // Watch the `public` directory and refresh the + // browser on changes when not in production + !production && livereload('public'), + + // If we're building for production (npm run build + // instead of npm run dev), minify + production && terser() + ], + watch: { + clearScreen: false + } +}; diff --git a/viewer_plugin/scripts/setupTypeScript.js b/viewer_plugin/scripts/setupTypeScript.js new file mode 100644 index 0000000..133658a --- /dev/null +++ b/viewer_plugin/scripts/setupTypeScript.js @@ -0,0 +1,121 @@ +// @ts-check + +/** This script modifies the project to support TS code in .svelte files like: + + + + As well as validating the code for CI. + */ + +/** To work on this script: + rm -rf test-template template && git clone sveltejs/template test-template && node scripts/setupTypeScript.js test-template +*/ + +const fs = require("fs") +const path = require("path") +const { argv } = require("process") + +const projectRoot = argv[2] || path.join(__dirname, "..") + +// Add deps to pkg.json +const packageJSON = JSON.parse(fs.readFileSync(path.join(projectRoot, "package.json"), "utf8")) +packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, { + "svelte-check": "^2.0.0", + "svelte-preprocess": "^4.0.0", + "@rollup/plugin-typescript": "^8.0.0", + "typescript": "^4.0.0", + "tslib": "^2.0.0", + "@tsconfig/svelte": "^2.0.0" +}) + +// Add script for checking +packageJSON.scripts = Object.assign(packageJSON.scripts, { + "check": "svelte-check --tsconfig ./tsconfig.json" +}) + +// Write the package JSON +fs.writeFileSync(path.join(projectRoot, "package.json"), JSON.stringify(packageJSON, null, " ")) + +// mv src/main.js to main.ts - note, we need to edit rollup.config.js for this too +const beforeMainJSPath = path.join(projectRoot, "src", "main.js") +const afterMainTSPath = path.join(projectRoot, "src", "main.ts") +fs.renameSync(beforeMainJSPath, afterMainTSPath) + +// Switch the app.svelte file to use TS +const appSveltePath = path.join(projectRoot, "src", "App.svelte") +let appFile = fs.readFileSync(appSveltePath, "utf8") +appFile = appFile.replace(" + + \ No newline at end of file diff --git a/viewer_plugin/src/GeneSelection.svelte b/viewer_plugin/src/GeneSelection.svelte new file mode 100644 index 0000000..756c0b1 --- /dev/null +++ b/viewer_plugin/src/GeneSelection.svelte @@ -0,0 +1,73 @@ +
+ geneSelected(ev.detail)} + on:keydown={handleKeydown} + > + + +
+
+ + + {chip} + cancel + + +
+ + diff --git a/viewer_plugin/src/JugexSlider.svelte b/viewer_plugin/src/JugexSlider.svelte new file mode 100644 index 0000000..d2e467d --- /dev/null +++ b/viewer_plugin/src/JugexSlider.svelte @@ -0,0 +1,54 @@ + + +
+
+ +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/viewer_plugin/src/RoiSelection.svelte b/viewer_plugin/src/RoiSelection.svelte new file mode 100644 index 0000000..a9c0951 --- /dev/null +++ b/viewer_plugin/src/RoiSelection.svelte @@ -0,0 +1,144 @@ + + +
+ regionSelected(ev.detail)}> + + + + + + + + + {#if hasDataSrcFlag} + + {/if} +
+ +{#if !!selectedRegionName} + + + {selectedRegionName} + + +{/if} + + + + \ No newline at end of file diff --git a/viewer_plugin/src/ShowResult.svelte b/viewer_plugin/src/ShowResult.svelte new file mode 100644 index 0000000..c44b3f2 --- /dev/null +++ b/viewer_plugin/src/ShowResult.svelte @@ -0,0 +1,92 @@ + + + Annotate + + +{#if redText && whiteText} +
Legend
+ +{/if} + + + diff --git a/viewer_plugin/src/main.js b/viewer_plugin/src/main.js new file mode 100644 index 0000000..5ff9825 --- /dev/null +++ b/viewer_plugin/src/main.js @@ -0,0 +1,14 @@ +import App from './App.svelte'; + +const app = new App({ + target: document.body, + props: { + + } +}); + +window.addEventListener('pagehide', () => { + app.$destroy() +}) + +export default app; \ No newline at end of file diff --git a/viewer_plugin/src/store.js b/viewer_plugin/src/store.js new file mode 100644 index 0000000..e63a7d5 --- /dev/null +++ b/viewer_plugin/src/store.js @@ -0,0 +1,21 @@ +import { writable } from "svelte/store" + +export const hasDataSrc = writable(false) + +export const SIIBRA_API_ENDPOINT = `https://siibra-api-stable.apps.hbp.eu` +export const SIIBRA_JUGEX_ENDPOINT = `` + +export const getGeneNames = async () => { + const res = await fetch(`${SIIBRA_API_ENDPOINT}/v2_0/genes`).then() + return await res.json() +} + +export const parcellationId = "minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579-290" +export const searchRegion = async input => { + const url = new URL(`${SIIBRA_API_ENDPOINT}/v3_0/regions`) + url.searchParams.set("parcellation_id", parcellationId) + url.searchParams.set('find', input) + const res = await fetch(url) + const respJson = await res.json() + return respJson.items +} diff --git a/viewer_plugin/src/theme/_smui-theme.scss b/viewer_plugin/src/theme/_smui-theme.scss new file mode 100644 index 0000000..464064b --- /dev/null +++ b/viewer_plugin/src/theme/_smui-theme.scss @@ -0,0 +1,25 @@ +@use 'sass:color'; + +@use '@material/theme/color-palette'; + +// Svelte Colors! +@use '@material/theme/index' as theme with ( + $primary: #ff3e00, + $secondary: #676778, + $surface: #fff, + $background: #fff, + $error: color-palette.$red-900 +); + +html, +body { + background-color: theme.$surface; + color: theme.$on-surface; +} + +a { + color: #40b3ff; +} +a:visited { + color: color.scale(#40b3ff, $lightness: -35%); +} diff --git a/viewer_plugin/src/theme/dark/_smui-theme.scss b/viewer_plugin/src/theme/dark/_smui-theme.scss new file mode 100644 index 0000000..72e649d --- /dev/null +++ b/viewer_plugin/src/theme/dark/_smui-theme.scss @@ -0,0 +1,28 @@ +@use 'sass:color'; + +@use '@material/theme/color-palette'; + + +$darkmode-bg-color: #424242; + +// Svelte Colors! (Dark Theme) +@use '@material/theme/index' as theme with ( + $primary: #ff3e00, + $secondary: color.scale(#676778, $whiteness: -10%), + $surface: color.adjust(color-palette.$grey-900, $blue: +4), + $background: $darkmode-bg-color, + $error: color-palette.$red-700 +); + +html, +body { + background-color: $darkmode-bg-color; + color: theme.$on-surface; +} + +a { + color: #40b3ff; +} +a:visited { + color: color.scale(#40b3ff, $lightness: -35%); +}