Commit 05946fa5 authored by Marcelo Rivera's avatar Marcelo Rivera
Browse files

Merge branch 'epic/minds-pro' into feat/media-modal-for-pro

# Conflicts:
#	src/app/modules/media/media.module.ts
parents 98e64949 5597f068
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@
      "scripts": [
        "../node_modules/material-design-lite/dist/material.min.js",
        "../node_modules/medium-editor/dist/js/medium-editor.min.js",
        "shims/fontawesome.js",
        "shims/jitsi-api.min.js"
      ],
      "environmentSource": "environments/environment.ts",
+117 −93
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ stages:
  - test:e2e
  - deploy:canary
  - deploy:production
  - cleanup

variables:
  CYPRESS_INSTALL_BINARY: 0 # Speeds up the install process
@@ -25,33 +26,6 @@ test:
    - npm ci
    - npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI

e2e:base:
  image: cypress/base:10
  stage: test:e2e
  variables:
    CYPRESS_INSTALL_BINARY: 3.4.1
  script:
    - npm ci
    - >
      if [ "$CI_BUILD_REF_NAME" == "master" ]; then
        export E2E_DOMAIN=https://www.minds.com
      else
        export E2E_DOMAIN=https://$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN
      fi
    - export CYPRESS_baseUrl=$E2E_DOMAIN
    - echo "E2E tests for $CI_BUILD_REF_NAME running against $E2E_DOMAIN with user $CYPRESS_username"
    - $(npm bin)/cypress run --record --key $CYPRESS_RECORD_ID --config CYPRESS_baseUrl=$E2E_DOMAIN
  artifacts:
    when: always
    paths:
      - cypress/screenshots
      - cypress/videos
  cache:
    paths:
      - .npm
      - cache/Cypress
  allow_failure: true #manual inspection in case of timeouts

e2e:chrome:
  image: cypress/browsers:chrome67
  stage: test:e2e
@@ -79,8 +53,14 @@ e2e:chrome:
      - cache/Cypress
  allow_failure: true #manual inspection in case of timeouts

###############
# Build Stage #
###############

build:review:
  stage: build
  before_script:
    - sed -ri "s|\"VERSION\"|\"$CI_PIPELINE_ID\"|" src/environments/environment.prod.ts
  script:
    - npm ci && npm install -g gulp-cli
    - npm run postinstall
@@ -97,6 +77,8 @@ build:review:

build:production:en:
  stage: build
  before_script:
    - sed -ri "s|\"VERSION\"|\"$CI_PIPELINE_ID\"|" src/environments/environment.prod.ts
  script:
    - npm ci && npm install -g gulp-cli
    - npm run postinstall
@@ -113,6 +95,8 @@ build:production:en:

build:production:i18n:
  stage: build
  before_script:
    - sed -ri "s|\"VERSION\"|\"$CI_PIPELINE_ID\"|" src/environments/environment.prod.ts
  script:
    - npm ci && npm install -g gulp-cli
    - npm run postinstall
@@ -127,13 +111,28 @@ build:production:i18n:
      - master
      - test/gitlab-ci

#################
# Prepare Stage #
#################

.sentry_prepare: &sentry_prepare
  stage: prepare
  image: getsentry/sentry-cli
  script:
    - echo "Create a new release $CI_PIPELINE_ID"
    - sentry-cli releases new $CI_PIPELINE_ID
    - sentry-cli releases set-commits --auto $CI_PIPELINE_ID
    - sentry-cli releases files $CI_PIPELINE_ID upload-sourcemaps $CI_PROJECT_DIR/dist/en -x .js -x .map --validate --url-prefix $SOURCEMAP_PREFIX
    - sentry-cli releases finalize $CI_PIPELINE_ID
    - echo "Finalized release for $CI_PIPELINE_ID"

prepare:review:
  stage: prepare
  image: minds/ci:latest
  script:
    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} 
    - docker build -t $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF -f containers/front-init/Dockerfile dist/.
    - docker push $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF
    - docker build -t $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID -f containers/front-init/Dockerfile dist/.
    - docker push $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID
  dependencies:
    - build:review
  except:
@@ -141,13 +140,36 @@ prepare:review:
      - master
      - test/gitlab-ci

prepare:review:sentry:
  <<: *sentry_prepare
  variables:
    SOURCEMAP_PREFIX: "~/en"
  except:
    refs:
      - master
      - test/gitlab-ci
  dependencies:
    - build:review

prepare:production:
  stage: prepare
  image: minds/ci:latest
  script:
    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} 
    - docker build -t $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF -f containers/front-init/Dockerfile dist/.
    - docker push $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF
    - docker build -t $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID -f containers/front-init/Dockerfile dist/.
    - docker push $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID
  only:
    refs:
      - master
      - test/gitlab-ci
  dependencies:
    - build:production:en
    - build:production:i18n

prepare:production:sentry:
  <<: *sentry_prepare
  variables:
    SOURCEMAP_PREFIX: "~/front/dist/en"
  only:
    refs:
      - master
@@ -156,6 +178,26 @@ prepare:production:
    - build:production:en
    - build:production:i18n
  
################
# Review Stage #
################

.cleanup_review: &cleanup_review
  image: minds/helm-eks:latest
  script:
    - aws eks update-kubeconfig --name=sandbox
    - helm del --purge $CI_BUILD_REF_SLUG
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN
    action: stop
  variables:
    GIT_STRATEGY: none
  except: 
    refs:
      - master
      - test/gitlab-ci

review:start:
  stage: review
  image: minds/helm-eks:latest
@@ -166,12 +208,14 @@ review:start:
        --install \
        --reuse-values \
        --set frontInit.image.repository=$CI_REGISTRY_IMAGE/front-init \
        --set frontInit.image.tag=$CI_BUILD_REF \
        --set-string frontInit.image.tag=$CI_PIPELINE_ID \
        --set domain=$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN \
        --set elasticsearch.clusterName=$CI_BUILD_REF_SLUG--elasticsearch \
        --wait \
        $CI_BUILD_REF_SLUG \
        ./helm-charts/minds"
    # Update sentry
    - sentry-cli releases deploys $CI_PIPELINE_ID new -e review-$CI_COMMIT_REF_SLUG
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN
@@ -182,71 +226,53 @@ review:start:
      - test/gitlab-ci

review:stop:
  <<: *cleanup_review
  stage: review
  image: minds/helm-eks:latest
  script:
    - aws eks update-kubeconfig --name=sandbox
    - helm del --purge $CI_BUILD_REF_SLUG
  environment:
    name: review/$CI_COMMIT_REF_NAME
    url: https://$CI_BUILD_REF_SLUG.$KUBE_INGRESS_BASE_DOMAIN
    action: stop
  variables:
    GIT_STRATEGY: none
  when: manual
  except: 
    refs:
      - master
      - test/gitlab-ci

staging:fpm:
  stage: deploy:staging
################
# Deploy Stage #
################

.deploy: &deploy
  image: minds/ci:latest
  script:
    - IMAGE_LABEL="staging"
    ## Sync assets with CDN
    - aws s3 sync dist $S3_REPOSITORY_URL
    - $(aws ecr get-login --no-include-email --region us-east-1)
    ## Update docker front-init container
    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} 
    - docker pull $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF
    - docker tag $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF $ECR_REPOSITORY_URL:$IMAGE_LABEL
    - docker pull $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID
    - docker tag $CI_REGISTRY_IMAGE/front-init:$CI_PIPELINE_ID $ECR_REPOSITORY_URL:$IMAGE_LABEL
    - docker push $ECR_REPOSITORY_URL:$IMAGE_LABEL
    ## Deploy the new container in rolling restart
    - aws ecs update-service --service=$ECS_APP_STAGING_SERVICE --force-new-deployment --region us-east-1 --cluster=$ECS_CLUSTER
    - aws ecs update-service --service=$ECS_SERVICE --force-new-deployment --region us-east-1 --cluster=$ECS_CLUSTER
    ## Update sentry
    - sentry-cli releases deploys $CI_PIPELINE_ID new -e $IMAGE_LABEL
  dependencies:
    - build:production:en
    - build:production:i18n
  only:
    refs:
      - master
      - test/gitlab-ci
  dependencies:
    - build:production:en
    - build:production:i18n

staging:fpm:
  <<: *deploy
  stage: deploy:staging
  variables:
    IMAGE_LABEL: "staging"
    ECS_SERVICE: $ECS_APP_STAGING_SERVICE
  environment:
    name: staging
    url: https://www.minds.com # requires staging cookie

deploy:canary:
  <<: *deploy
  stage: deploy:canary
  image: minds/ci:latest
  script:
    - IMAGE_LABEL="canary"
    ## Sync assets with CDN
    - aws s3 sync dist $S3_REPOSITORY_URL
    - $(aws ecr get-login --no-include-email --region us-east-1)
    ## Update docker front-init container
    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} 
    - docker pull $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF
    - docker tag $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF $ECR_REPOSITORY_URL:$IMAGE_LABEL
    - docker push $ECR_REPOSITORY_URL:$IMAGE_LABEL
    ## Deploy the new container in rolling restart
    - aws ecs update-service --service=$ECS_APP_CANARY_SERVICE --force-new-deployment --region us-east-1 --cluster=$ECS_CLUSTER
  only:
    refs:
      - master
      - test/gitlab-ci
  dependencies:
    - build:production:en
    - build:production:i18n
  variables:
    IMAGE_LABEL: "canary"
    ECS_SERVICE: $ECS_APP_CANARY_SERVICE
  environment:
    name: canary
    url: https://www.minds.com/?canary=1 # requires canary cookie
@@ -254,27 +280,25 @@ deploy:canary:
  allow_failure: false # prevents auto deploy to full production

deploy:production:
  <<: *deploy
  stage: deploy:production
  image: minds/ci:latest
  script:
    - IMAGE_LABEL="production"
    - $(aws ecr get-login --no-include-email --region us-east-1)
    ## Update docker front-init container
    - docker login -u gitlab-ci-token -p ${CI_BUILD_TOKEN} ${CI_REGISTRY} 
    - docker pull $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF
    - docker tag $CI_REGISTRY_IMAGE/front-init:$CI_BUILD_REF $ECR_REPOSITORY_URL:$IMAGE_LABEL
    - docker push $ECR_REPOSITORY_URL:$IMAGE_LABEL
    ## Deploy the new container in rolling restart
    - aws ecs update-service --service=$ECS_APP_PRODUCTION_SERVICE --force-new-deployment --region us-east-1 --cluster=$ECS_CLUSTER
  only:
    refs:
      - master
      - test/gitlab-ci
  dependencies:
    - build:production:en
    - build:production:i18n
  variables:
    IMAGE_LABEL: "production"
    ECS_SERVICE: $ECS_APP_PRODUCTION_SERVICE
  environment:
    name: production
    url: https://www.minds.com
  when: delayed
  start_in: 2 hours # reduce? can always be deployed manually earlier too

#################
# Cleanup stage #
#################

cleanup:review: # We stop the review site after the e2e tests have run
  <<: *cleanup_review
  stage: cleanup
  except: 
    refs:
      - master
      - test/gitlab-ci
 No newline at end of file
+5 −3
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@
            "scripts": [
              "node_modules/material-design-lite/dist/material.min.js",
              "node_modules/medium-editor/dist/js/medium-editor.min.js",
              "src/shims/fontawesome.js",
              "src/shims/jitsi-api.min.js"
            ]
          },
@@ -36,7 +35,11 @@
            "production": {
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "sourceMap": {
			    "hidden": true,
			    "scripts": true,
			    "styles": true
			  },
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
@@ -78,7 +81,6 @@
            "scripts": [
              "node_modules/material-design-lite/dist/material.min.js",
              "node_modules/medium-editor/dist/js/medium-editor.min.js",
              "src/shims/fontawesome.js",
              "src/shims/jitsi-api.min.js"
            ],
            "assets": [
+1 −1
Original line number Diff line number Diff line
#!/bin/sh
export NODE_OPTIONS="--max-old-space-size=3584"
ng build --prod --vendor-chunk --output-path="$1/en/" --deploy-url="$2/en/" --build-optimizer=false --source-map=false
ng build --prod --vendor-chunk --output-path="$1/en/" --deploy-url="$2/en/" --build-optimizer=false 
+69 −12
Original line number Diff line number Diff line
@@ -1866,6 +1866,63 @@
        }
      }
    },
    "@sentry/browser": {
      "version": "5.6.2",
      "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.6.2.tgz",
      "integrity": "sha512-Nm/W/5ra6+OQCWQkdd86vHjcYUjHCVqCzQyPasd6HE7SNlWe5euGVfFfDuUFsiDrMAG5uKfGYw5u/AqoweiQkQ==",
      "requires": {
        "@sentry/core": "5.6.2",
        "@sentry/types": "5.6.1",
        "@sentry/utils": "5.6.1",
        "tslib": "^1.9.3"
      }
    },
    "@sentry/core": {
      "version": "5.6.2",
      "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.6.2.tgz",
      "integrity": "sha512-grbjvNmyxP5WSPR6UobN2q+Nss7Hvz+BClBT8QTr7VTEG5q89TwNddn6Ej3bGkaUVbct/GpVlI3XflWYDsnU6Q==",
      "requires": {
        "@sentry/hub": "5.6.1",
        "@sentry/minimal": "5.6.1",
        "@sentry/types": "5.6.1",
        "@sentry/utils": "5.6.1",
        "tslib": "^1.9.3"
      }
    },
    "@sentry/hub": {
      "version": "5.6.1",
      "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.6.1.tgz",
      "integrity": "sha512-m+OhkIV5yTAL3R1+XfCwzUQka0UF/xG4py8sEfPXyYIcoOJ2ZTX+1kQJLy8QQJ4RzOBwZA+DzRKP0cgzPJ3+oQ==",
      "requires": {
        "@sentry/types": "5.6.1",
        "@sentry/utils": "5.6.1",
        "tslib": "^1.9.3"
      }
    },
    "@sentry/minimal": {
      "version": "5.6.1",
      "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.6.1.tgz",
      "integrity": "sha512-ercCKuBWHog6aS6SsJRuKhJwNdJ2oRQVWT2UAx1zqvsbHT9mSa8ZRjdPHYOtqY3DoXKk/pLUFW/fkmAnpdMqRw==",
      "requires": {
        "@sentry/hub": "5.6.1",
        "@sentry/types": "5.6.1",
        "tslib": "^1.9.3"
      }
    },
    "@sentry/types": {
      "version": "5.6.1",
      "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.6.1.tgz",
      "integrity": "sha512-Kub8TETefHpdhvtnDj3kKfhCj0u/xn3Zi2zIC7PB11NJHvvPXENx97tciz4roJGp7cLRCJsFqCg4tHXniqDSnQ=="
    },
    "@sentry/utils": {
      "version": "5.6.1",
      "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.6.1.tgz",
      "integrity": "sha512-rfgha+UsHW816GqlSRPlniKqAZylOmQWML2JsujoUP03nPu80zdN43DK9Poy/d9OxBxv0gd5K2n+bFdM2kqLQQ==",
      "requires": {
        "@sentry/types": "5.6.1",
        "tslib": "^1.9.3"
      }
    },
    "@types/jasmine": {
      "version": "2.8.14",
      "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.14.tgz",
@@ -2756,7 +2813,7 @@
    "async-limiter": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
      "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg="
      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
    },
    "async-settle": {
      "version": "1.0.0",
@@ -3104,7 +3161,7 @@
    "bencode": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.0.tgz",
      "integrity": "sha1-5y5rNpHYJL0D6nqp11LNHUmlACc=",
      "integrity": "sha512-wr2HwwrUpfB5c68zmAudOltC7rZ1G0+lQOcnuEcfIM3AWAVnB3rHI3nlgd/2CWTfQ3w3zagKt89zni/M+VLZ8g==",
      "requires": {
        "safe-buffer": "^5.1.1"
      }
@@ -11188,7 +11245,7 @@
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        },
        "useragent": {
@@ -11872,7 +11929,7 @@
    "lodash.mergewith": {
      "version": "4.6.1",
      "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
      "integrity": "sha1-Y5BX5ybDr72z59QnQcqo1uQzWSc=",
      "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==",
      "dev": true
    },
    "lodash.once": {
@@ -12531,7 +12588,7 @@
    "mimic-fn": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
      "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=",
      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
      "dev": true
    },
    "mimic-response": {
@@ -12636,7 +12693,7 @@
    "mixin-deep": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
      "integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=",
      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
      "dev": true,
      "requires": {
        "for-in": "^1.0.2",
@@ -12646,7 +12703,7 @@
        "is-extendable": {
          "version": "1.0.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
          "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
          "dev": true,
          "requires": {
            "is-plain-object": "^2.0.4"
@@ -12762,7 +12819,7 @@
    "mp4-stream": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/mp4-stream/-/mp4-stream-2.0.3.tgz",
      "integrity": "sha1-MKzuB3CdMj+NzYegezzpw8S/s2Q=",
      "integrity": "sha512-5NzgI0+bGakoZEwnIYINXqB3mnewkt3Y7jcvkXsTubnCNUSdM8cpP0Vemxf6FLg0qUN8fydTgNMVAc3QU8B92g==",
      "requires": {
        "buffer-alloc": "^1.1.0",
        "inherits": "^2.0.1",
@@ -13282,7 +13339,7 @@
    "normalize-package-data": {
      "version": "2.4.0",
      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
      "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=",
      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
      "dev": true,
      "requires": {
        "hosted-git-info": "^2.1.4",
@@ -15036,7 +15093,7 @@
    "random-access-file": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-2.0.1.tgz",
      "integrity": "sha1-3CLeeScOmoTLNqJBm3WXJZMNyus=",
      "integrity": "sha512-nb4fClpzoUY+v1SHrro+9yykN90eMA1rc+xM39tnZ5R3BgFY+J/NxPZ0KuUpishEsvnwou9Fvm2wa3cjeuG7vg==",
      "requires": {
        "mkdirp": "^0.5.1",
        "random-access-storage": "^1.1.1"
@@ -16201,7 +16258,7 @@
    "set-value": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
      "integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=",
      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
      "dev": true,
      "requires": {
        "extend-shallow": "^2.0.1",
@@ -18460,7 +18517,7 @@
    "type-is": {
      "version": "1.6.16",
      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
      "integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=",
      "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
      "dev": true,
      "requires": {
        "media-typer": "0.3.0",
Loading