From 5cd33ecf884f8175e8bd86e8213689f804ac8de9 Mon Sep 17 00:00:00 2001 From: Philippe Morier Date: Fri, 6 Mar 2020 10:39:31 +0100 Subject: [PATCH] Release v0.0.5 (#39) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * build(dep): `@babylonjs` & `@types/node`: - @babylonjs:4.1.0-beta.9 - @types/node:12.12.16 * feat(apps/frontend): select initial tool * fix(apps/frontend): import hammerjs * refactor(frontend): scene-viewer into container * feat(frontend): dispatch `pointerPick` action * feat(frontend): dispatch `add|removeVoxel` action * build(packaging): simplify `prettier:check` command * doc(frontend): add readme with ngrx resources * feat(frontend): support adding voxel * refactor(frontend): don't inject `GridService` * feat(frontend): effects for when app goes on/offline * test(frontend): on/offline effects * test(vdb): remove `normals` from test * feat(vdb): add `setValueOff` & `isValueOn` * test(frontend): set expected position to pass * fix(frontend): make public for use in template * build(dep): `@types/node` & `core-js` * feat(frontend): enable `removeVoxel` * build(dep): `@babylonjs/*` * build(github): keep `develop` after PR merge * build(dep): `cypress` to `v3.8.0` * build(dep): `cypress` to `v3.7.0` * test(vdb): set value with float coordinates: - coordinates get always rounded down * build(dep): `cypress` to `v3.7.0` * feat(frontend): support adding and removing voxels * test(ui): remove unused imported components * build(CircleCi): use `13.3.0` due failing tests: - Test suite failed to run - Call retries were exceeded at ChildProcessWorker.initialize() - https://github.com/jest-community/vscode-jest/issues/486#issuecomment-563164125 * fix(frontend): add voxel on positive normal - but negative position * test(frontend): set `setupFilesAfterEnv` - to run in Jest tests within WebStorm - https://github.com/nrwl/nx/issues/1439#issuecomment-561268656 * test(frontend): set `globals`>`tsConfig` - to run in Jest tests within WebStorm with SCSS imports in component * build(CircleCi): use `13.4.0` * build(dep): update diverse dependencies: - @ngrx/effects, @ngrx/store - core-js, mnemonist, codelyzer - @types/jest, @types/node * doc(readme): record macro & git setup * build(dep): `@angular-devkit/build-angular` & `@angular/cli` * feat(frontend): draw separate mesh per InternalNode1 (#9) * feat(frontend): add multiple voxels * feat(ui): add output for dropped files * doc(readme): add openVDB repo link * feat(vdb): implement `beginLeafOn` iterator * feat(frontend/vdb): draw InternalNode1 chunks * feat(frontend/vdb): don't return LeafNode * feat(frontend/vdb): don't return `LeafNode` in `setValueAndCache` * feat(frontend/vdb): use only key from accessor * feat(frontend/vdb): remove `getLeafNodeAndCache` * feat(frontend/vdb): remove `beginLeafOn` * feat(frontend/vdb): remove `getLeafNodeAndCache` & `beginLeafOn` * fix(frontend/vdb): dispose mesh instead of just remove it: - so we resolve memory issue * refactor(frontend): optimize scene & mesh - https://doc.babylonjs.com/how_to/optimizing_your_scene * refactor(frontend): remove unused method & obj loader * refactor(vdb): increase `InternalNode1` size to reduce draw calls * refactor(vdb): remove inspector & loading obj * refactor(vdb): align to `probeNode` & `probeNodeAndCache` * refactor(vdb): s/grid-to-mesh/node-to-mesh * refactor(vdb): use un-indexed mesh * fix(ui): read normal directly from picked mesh * refactor(frontend): remove `objFileLoader` * refactor(frontend): s/updateGridMesh/updateNodeMesh & key/Node1Origin * feat(benchmark): test single vs. multiple `array.push()` * build(CircleCi): update node to `13.5.0` & cypress `3.8.1` * build(nx): nx migrate @nrwl/workspace (v8.11.0) - nx migrate --run-migrations=migrations.json * fix(benchmark): add `.nxignore` to get benchmark through linter * build(dep): update dependencies * feat(frontend): add undo/redo & enable `strictNullChecks` (#10) * feat(frontend): add undo/redo & enforce `strictNullChecks` * feat(frontend): undo/redo with max buffer size * test(frontend): handle possible `undefined` * feat(frontend): make remove a voxel undoable * feat(frontend): place initial voxel at [0, 0, 0] * fix(frontend): dispose previous history if new `addUndo` * refactor(frontend): extract method for creating `addUndo` * feat(frontend): set active state of voxel, return color when deleting (#11) * feat(ui/frontend): add menu-bar (#12) * feat(frontend): add menu-bar * feat(frontend): add menu-bar-container * test(frontend): inject mock store for menu-bar-container * refactor(frontend): add missing `menu-bar.component` * test(frontend): import `MenuBarModule` * feat(frontend): undo/redo with start/end actions (#13) * feat(frontend): undo/redo with start/end actions * test(frontend): provide `valueToColor()` * feat(frontend): set random color when adding a voxel * test(frontend): add same color of voxel * refactor(frontend): use directly `props` * refactor(frontend): throw error when coord&values not same length * build(dep): update dependencies * build(dep): update cypress to `v3.8.2` * build(dep): update stylelint to `v13.0.0` * refactor(ui): prefix UI components with `Ui` like Angular does with `Mat` (#14) * refactor(ui): prefix `MenuBar` with `Ui` like Angular does with `Mat` * refactor(ui): prefix `SceneViewer` with `Ui` as Angular does with `Mat` * test(ui): check `menu-bar` menus & items * refactor(ui): remove ctor & onInit * test(ui): check if sidnav has left & right navigation * refactor(ui): prefix `SidenavShell` with `Ui` as Angular does with `Mat` * refactor(ui): prefix `SceneViewerService` with `Ui` (ng with `Mat`) * refactor(ui): prefix `SceneViewerTestModule` with `Ui` (ng with `Mat`) * refactor(ui): prefix `ToolbarModule` with `Ui` (ng with `Mat`) * refactor(ui): prefix `UiPointer[Button|PickInfo]` with `Ui` * build(dep): update handlebars to `v4.7.2` due to security issues * test(ui): should emit `value` of clicked menu items * test(ui): should emit on tool select * test(ui): should close left & right sidenav * test(frontend): should dispatch action * test(frontend): check `scene-viewer-container.reducer` * test(frontend): check `scene-viewer-container.reducer` selector * refactor(ui): import `hammerjs` to remove warning in test run * test(frontend): check `tools-panel.reducer` * test(frontend): check `undo-redo.reducer` * test(frontend): check `undo-redo.reducer` with `stepX` * test(frontend): check `undo-redo.reducer` too many undo/redo's * style(prettier): fix imports * test(vdb): add tests for `tree` * test(vdb): improve coverage * test(vdb): check coord * test(vdb): check grid * test(vdb): check `nodeToMesh` * feat(ui): add `Storybook` (#16) * feat(ui): add `Storybook` * feat(ui): add `Storybook` e2e test * doc(ui): how to watch e2e * build(dep): update storybook to `v5.3.6` * build(dep): back to storybook `v5.3.2` due to: - info => Using angular project 'frontend' for configuring Storybook. * build(dep): back to storybook `v5.3.6` since it works * test(ui-e2e): open/close `menu-bar` * ci(storybook): run, build & deploy storybook for `ui-e2e` (#17) * ci(storybook): build storybook * ci(storybook): move `frontend e2e` step down * ci(storybook): store storybook & deploy to gh-pages * ci(storybook): extract git(hub) configs * ci(storybook): extract deploy to gh-pages * ci(storybook): change to `test-results` folder & use `junit` reporter * ci(storybook): run `ui-e2e` and store test-results & artifacts * ci(storybook): run `ui-e2e` only on `master` & `develop` * fix(ui): to high/large canvas by setting `display: block;` * feat(frontend): paint voxel (#18) * feat(frontend): dispatch paint-voxel action * feat(frontend): set voxel on paint * feat(frontend): finish renaming `addVoxel` to `setVoxel` * feat(frontend): save old/new values and undo/redo painting * refactor(frontend): s/positions/coord * refactor(frontend): fix prettier issue * refactor(frontend): s/position/xyz * build(dep): update `@nrwl` to `v8.11.2` * build(dep): update `@angular/(cli|core)` to `v8.3.22` - `ng update @angular/cli @angular/core` * build(dep): update @babylonjs, @babel, @storybook, @types * feat(ui): color-dialog (#19) * feat(ui): color-dialog * refactor(ui): always open dialog in story * refactor(ui): flatten config to just menus & type safety in story * feat(ui): pass colors to color-dialog * refactor(ui): make data & return value type-safe. * refactor(ui): extract interface `UiColorDialogData` * refactor(ui): extract open into `UiColorDialogService` * test(ui): s/UiMenuBarConfig/UiMenuBarMenu * refactor(ui): provide `selectedColorIndex` * build(dep): update `circleci/node` to `v13.6.0` * feat(frontend): use color-dialog (#20) * feat(frontend): use color-dialog * refactor(ui): s/draggable-dialog/color-dialog * feat(frontend): open (empty) color-dialog * feat(frontend): provide some first colors * feat(frontend): use effects to open color-dialog * feat(frontend): use effects to set selected color in store * feat(frontend): temp. consider just `color.r` * feat(frontend): save colors and selected-index * refactor(frontend): move `tool.model.ts` to `model` (put in lib later) * feat(frontend): `intToRgba` & `rgbaToInt` * refactor(frontend): s/model/value * refactor(frontend): use `Rgba` and `rgbaToInt` to set voxel in grid * refactor(frontend): provide selector for retrieving CSS colors * refactor(frontend): move comment `Front` * refactor(vdb): define all colors * refactor(frontend): fix prettier * test(frontend): import `OptionsPanelModule` * refactor(frontend): prettier * refactor(ui): `forceDepthWrite` for transparent cubes - there are still some artifacts (seeing through cubes behind) * refactor(ui): use `rgba` to set initial voxel at [0, 0, 0] * test(frontend): provide stub component in `AppComponent` test * test(frontend): provide `initialMockState` * test(frontend): mock & expect proper `Rgba` values * test(ui): fix type of dialog result (`UiColorDialogColor` to `number`) * feat(frontend): support dark & light theme (#21) * feat(ui): add theme toggle to storybook (#22) * feat(ui): remove `mat-button` from story * build(dep): update `@storybook` to `v5.3.8` * build(dep): update `tslint` to `v6.0.0` * build(dep): back to `tslint` `v5.20.1` * refactor(model): extract `Rgba` & `Tool` to lib `model` (#24) * refactor(model): extract `Rgba` & `Tool` to lib `model` * refactor(model): remove mapping path to non-existing `@talus/math` * refactor(vdb): use `eslint` over `tslint` (#25) * refactor(benchmark): use `eslint` over `tslint` (#26) * refactor(benchmark): use `eslint` over `tslint` * refactor(benchmark): s/benchmarkjs/Benchmark * ci(circle): `git pull` before `gh-pages` deploy * refactor(frontend): prefix unused variables with `_` * refactor(frontend): register pointer events * refactor(frontend): draw initial chessboard * docs(talus): add ui-e2e command & update deploy url * docs(frontend): add most used commands * docs(vdb): move install & test to blog * docs(ui): clean-up storybook commands * feat(vdb): implement raytracing (#27) * refactor(vdb): move `ValueType` & `Index` to `types.ts` * feat(vdb): add delta value * feat(vdb): add `floor()` to `Coord` * feat(vdb): add `Vec3` * feat(vdb): add `minValue` to `Vec3` * feat(vdb): add `Ray` * feat(vdb): implement `probeLeafNodeAndCache` * test(vdb): improve comments about cache misses * test(vdb): check if correct cache level was hit * feat(frontend): add selection tool & stop moving camera on voxel hit * refactor(benchmark): reduce amount of values (CircleCI) * build(dep): update `node` to `v13.7.0` * ci: start using `yarn nx ...` * refactor(benchmark): set `--maxWorkers` to 10 (was 32 on CircleCI) * ci: uniform calls by using `yarn nx ...` * doc: add debug CircleCI via `ssh` * feat(vdb): add `empty()` & `numBackgroundTiles()` * feat(vdb): add `keyToCoord()` * feat(vdb): `expand()` on `CoordBBox` * feat(vdb): `isInside()` on `CoordBBox` * feat(vdb): add `offset`, `expand`, `reset`, `translate` * feat(vdb): add `add`, `divide` to `Vec3` * feat(vdb): add `clip`, `intersects` & `setTimes` to `Ray` * test(vdb): add C++ tests for `VolumeRayIntersector`, `Ray`, `Coord` * feat(vdb): add `VolumeRayIntersector` * style(vdb): eslint-disable @typescript-eslint/no-explicit-any * test(vdb): min coord is `Number.MIN_SAFE_INTEGER` * test(vdb): remove `console.log()` * refactor(vdb): export `VolumeRayIntersector` * test(vdb): add test with checking all voxels intersecting given ray * refactor(vdb): organize imports with barrel files (1) * feat(frontend): add basic line drawing (#28) * refactor(frontend/vdb): remove `colors` & comments for `beginValueOn()` * feat(vdb): add `removeFraction()` * feat(frontend): add `Select line point` tool * feat(frontend): add basic line drawing * test(model): improve test description for `Rgba` * style(frontend): fix prettier (imports) * refactor(frontend): extract methods * refactor(frontend): move declaration `dda` to usage * build(dep): update @storybook, @types, @typescript-eslint, eslint * build(CircleCI): `git co gh-pages` before pull and commit * build(CircleCI): use `checkout` over not-existing `co` alias * build(dep): migrate to `@nrwl` `v8.12.1` * build(dep): keep `cypress` `v3.8.3` * build(dep): `ng update @angular/cli` `v8.3.24` * build(dep): `@babel/core` `v7.8.4` * build(CircleCI): deploy in `$DEPLOY_CONTEXT` folder on `gh-pages` * build(CircleCI): echo variables and `git fetch origin gh-pages:gh-pages` * build(CircleCI): echo variables and `git pull` * build(CircleCI): don't `echo` variables * feat(ui): `pointUnderPointer$` emitting when hover over mesh * build(CircleCI): adjust base-path (`apps/frontend` * fix(frontend): return all `VoxelChange` & filter dupl. origins in effect * test(vdb): check if accessor returns background * test(vdb): should fill buffer with `0` * test(vdb): should initialise with `0` * test(vdb): check if accessor returns background * feat(frontend): bg value = -1, `removeVoxel` uses `setValueOff` * fix(frontned): import `VoxelChange` * feat(frontend): preview line (#29) * feat(frontend): preview line * style(frontned): prettier * test(frontend): provide `GridService` * test(vdb): add C++ tests `testSetActiveState` * feat(frontend): start & finish line drawing * feat(frontend): temporary set start & end voxel of line * feat(frontend): use `voxelsSet` action * feat(frontend): support undo line drawing * feat(frontend): pass position to chessboard * refactor(frontend): use only one coord `selectedLineStartCoord` * test(frontend): check `scene-viewer-container.reducer.ts` * test(frontend): check filter out duplicate origins in effect * test(frontend): check `setVoxel(s)` & `setVoxel(s)Failed` * doc(frontend): update readme with 'Angular Update Guide' * test(frontend): extract voxel change * refactor: update to @angular 9.0.0 & cypress 4.0.0 (#30) * refactor(ui/frontend): import deeply to specific material component * build(dep): update `@angular/cli` to `v8.3.25` * build(dep): update `@nrwl/*` to `v8.12.2` * build(dep): update `@angular/*` to `v9` * build(dep): update `@angular/material` to `v9` * build(dep): update `@storybook`, `@typescript-eslint` * build(dep): update `cypress` to `v4.0.0` * build(dep): remove `handlebars` * build(dep): update `@babylonjs` * feat(vdb): add `touchLeafAndCache()` (#31) * feat(vdb): add `touchLeafAndCache()` * refactor(frontend): only set `end` temporary in `selectLine()` * refactor(frontend): don't initialize with chessboard * fix(frontend): not drawing of line in same node: - probe for InternalNode1 for affected origin, don't use accessor * refactor(frontend): use `tap` over `map` * build(dep): update to `nx` `v9.0.0` (#34) * build(dep): update to `nx` `v9.0.0` * build(dep): update @storybook, @typescript-eslint, cypress, stylelint * build(dep): update @babylonjs & conform to newly created nx workspace * style(frontend): disable stylelint for angular theme color keys * build(dep): update @angular to `9.0.1` * build(dep): @storybook/*, @types/node, stylelint * feat(ui): add basic status-bar with connection status * feat(frontend): add empty status-bar * feat(ui): use outlined icon for changing theme & put icon at bottom * test(frontend): include `UiStatusBarModule` * build(CircleCi): set upstream * feat(ui): session-dialog with radio-group (#37) * feat(ui): add basic skeleton for session-dialog * feat(ui): session-dialog with radio-group * test(ui): fix providers for session-dialog spec * feat(frontend): open session-dialog via menu-bar * test(frontend): check emitted action `selectSession` * refactor(lib): s/session/topic * refactor(lib): select or create a topic * fix(frontend): voxels on wrong position due unresized canvas * test(frontend): mock dialog result `UiTopicDialogSelectionResult` * feat(kafka): add kafka-proxy (websocket) & kafka with docker-comp… (#38) * feat(kafka): use `docker-compose` to start `kafka` & `Kafdrop` * feat(kafka): start kafka, use kafka-proxy to send msg via WS to kafka * feat(kafka): start kafka, use kafka-proxy to send msg via WS to kafka 2 * feat(kafka): compress ws data & regsiter to connection state * fix(frontend): missing dep. & comment out initial ws test emit * feat(frontend): use `connectionStatus$` for status-bar * feat(frontend): basic synchronisation of actions between ws-connections * feat(frontend): sync editor & undo/redo actions * feat(frontend): set `needsSync` in effect * feat(frontend): set `needsSync` in effect * feat(kafka-proxy): remove `identity` method * test(frontend): mock & check dispatch * test(frontend): add `needsSync: true` * refactor(kafka): add project to nx ignore since it's not a real nx-app * doc(kafka-proxy): add readme * test(frontend): add generic parameter to fix error: - Error: connect ECONNREFUSED 127.0.0.1:80 * test(frontend): put correct describe name (MenuBarContainerComponent) * test(ui): import relative * test(frontend/ui): specify globals in `jest.config.js` - preventing `Error: connect ECONNREFUSED 127.0.0.1:80` when started from WebStorm * test(frontend/kafka-proxy): use `socket.broadcast` (send to all but me) * test(frontend): prefer `io.connect` for readability * refactor(kafka-proxy): extract kafka logic into `KafkaService` + tests * refactor(frontend/kafka-proxy): basic create/delete/get topic(s) * refactor(frontend/kafka-proxy): make topics an observable * refactor(frontend): don't wrap observable with `new Actions()` * refactor(frontend): emit `updateTopics` action when `kafkaPrSer.topics$` * test(frontend): add `sessions` to state & update tests * feat(frontend): set sessions in store & provide it in session-dialog * feat(frontend): set `session` * feat(frontend): s/AllActions/SyncAction * feat(frontend/kafka-proxy): Consume topic & emit actions for viewer * feat(kafka-proxy): remove old consumers on connection close * refactor(frontend/kafka-proxy): extract `EventName` to `@talus/model` * refactor(shared): extract `notNil()` to `@talus/shared` * refactor(kafka-proxy): remove scaffolded files * test(kafka-proxy): update gate tests * fix(frontend): s/session(s)/topic(s) after rebase * refactor(frontend): s/session/topic * feat(kafka): start-up 'kafka-manager' to have more info * refactor(frontend): extract `initialize()` for reuse * feat(kafka-proxy): provide `resetOffsets()` * feat(frontend): add `createTopic` action * feat(ui): provide `disposeSceneAndRestartRendering()` * feat(frontend/kafka-proxy): consumption of different topics * fix(frontend): don't sync start/end-line action (effects emit them) * fix(frontend): only emit action from kafka which have a diff. socket-id * fix(frontend): load all messages from current "session" when re-open it * refactor(frontend): remove `AfterViewInit` and order ctor arguments * refactor(kafka): add (commented) `kafka-magic` UI as alternative * refactor(kafka-proxy): move consumer management into `kafka.service.ts` * doc(kafka-proxy): add links about REST proxy & kafkajs issue to readme * style(kafka): fix prettier * fix(frontend): filter `__consumer_offsets` from topics * feat(frontend): get topics with total topic offset * feat(ui): support status text in status-bar * refactor(frontend): remove voxel count from state/reducer/specs * refactor(frontend): update state if connection-status changed & fix test * refactor(frontend): don't sync undo/redo, but setVoxels action * fix(frontend): remove old parameter for undo action * refactor(frontend): remove duplicated undo/redo action * doc: add last generation step, macro & release links * refactor(frontend): use `Promise.resolve()` * fix(frontend): don't add initial voxel when existing topic loaded * fix(kafka-proxy): return observable, so frontend gets new topic names * test(frontend): adapt test for `needsSync` & initial action * build(dep): update `@nrwl/workspace` to `v9.0.4` * build(dep): update `@angular` to `v9.0.4` * build(dep): update `@babylonjs` to `v4.1.0` * build(dep): update `@babel` & '@nestjs' and use `--async=false` (CI) * build(dep): update `tslib`, `@storybook`, `@types`, `@typescript-eslint` * build(dep): update `cypress` * test(kafka-proxy): mock `disconnectConsumer()` * build(dep): update `@angular` to `v9.0.5` * feat(ui): leaf empty space on top/bottom of sidenav panel * refactor(frontend): use h6 and materials typography * refactor(ui): make collapse button smaller * feat(ui): add story for sidenav-shell component * build(dep): update `@babel/core` to `v7.8.7` * refactor(frontend): remove unused `Nil` type (moved to shared) * refactor(kafka): specify specific image versions * refactor(ui): make canvas background color transparent * feat(frontend): get `lastLoadedMessageOffset` for future loading status --- .circleci/config.yml | 2 +- .nxignore | 3 + README.md | 60 +- angular.json | 97 +- apps/frontend/jest.config.js | 15 + apps/frontend/proxy.conf.json | 6 + apps/frontend/src/app/app.actions.ts | 16 +- apps/frontend/src/app/app.component.scss | 8 + apps/frontend/src/app/app.component.ts | 24 +- apps/frontend/src/app/app.effects.spec.ts | 60 +- apps/frontend/src/app/app.effects.ts | 59 +- apps/frontend/src/app/app.module.ts | 3 +- apps/frontend/src/app/app.reducer.ts | 4 +- .../menu-bar-container.actions.ts | 17 +- .../menu-bar-container.component.spec.ts | 2 +- .../menu-bar-container.component.ts | 23 +- .../options-panel/options-panel.effects.ts | 4 +- .../scene-viewer-container/grid.service.ts | 14 +- .../scene-viewer-container.actions.ts | 17 +- .../scene-viewer-container.component.spec.ts | 12 +- .../scene-viewer-container.component.ts | 36 +- .../scene-viewer-container.effects.spec.ts | 44 +- .../scene-viewer-container.effects.ts | 62 +- .../scene-viewer-container.module.ts | 3 +- .../scene-viewer-container.reducer.spec.ts | 27 +- .../scene-viewer-container.reducer.ts | 63 +- apps/frontend/src/app/typings/nil.d.ts | 1 - .../src/app/undo-redo/undo-redo.actions.ts | 9 - .../src/app/undo-redo/undo-redo.effects.ts | 26 +- .../app/undo-redo/undo-redo.reducer.spec.ts | 3 +- .../src/app/undo-redo/undo-redo.reducer.ts | 6 +- .../src/app/web-socket/kafka-proxy.service.ts | 63 + .../src/app/web-socket/web-socket.service.ts | 58 + apps/kafka-proxy/.eslintrc | 1 + apps/kafka-proxy/README.md | 16 + apps/kafka-proxy/jest.config.js | 5 + apps/kafka-proxy/src/app/.gitkeep | 0 apps/kafka-proxy/src/app/app.module.ts | 9 + .../src/app/kafka/kafka.gateway.spec.ts | 89 + .../src/app/kafka/kafka.gateway.ts | 106 + .../kafka-proxy/src/app/kafka/kafka.module.ts | 8 + .../src/app/kafka/kafka.service.ts | 120 ++ apps/kafka-proxy/src/assets/.gitkeep | 0 .../src/environments/environment.prod.ts | 3 + .../src/environments/environment.ts | 3 + apps/kafka-proxy/src/main.ts | 19 + apps/kafka-proxy/tsconfig.app.json | 9 + apps/kafka-proxy/tsconfig.json | 8 + apps/kafka-proxy/tsconfig.spec.json | 9 + apps/kafka/README.md | 18 + apps/kafka/docker-compose.yml | 64 + jest.config.js | 1 - libs/model/src/index.ts | 3 + .../src/lib/decoded-kafka-message.value.ts | 19 + libs/model/src/lib/event-name.value.ts | 7 + libs/model/src/lib/topic.value.ts | 11 + libs/shared/.eslintrc | 1 + libs/shared/README.md | 8 + libs/shared/jest.config.js | 22 + libs/shared/src/index.ts | 1 + .../app => libs/shared/src/lib}/rxjs/nil.ts | 1 + libs/shared/tsconfig.json | 7 + libs/shared/tsconfig.lib.json | 9 + libs/shared/tsconfig.spec.json | 9 + libs/ui/jest.config.js | 5 +- libs/ui/src/index.ts | 1 + .../color-dialog.component.stories.ts | 2 +- .../color-dialog/color-dialog.component.ts | 2 +- .../ui/src/lib/menu-bar/menu-bar.component.ts | 4 +- .../scene-viewer/scene-viewer.component.scss | 5 + .../lib/scene-viewer/scene-viewer.service.ts | 17 + .../sidenav-shell.component.scss | 30 +- .../sidenav-shell.component.stories.ts | 41 + .../lib/status-bar/status-bar.component.scss | 1 + .../status-bar/status-bar.component.spec.ts | 3 +- .../status-bar.component.stories.ts | 3 +- .../lib/status-bar/status-bar.component.ts | 6 + libs/ui/src/lib/topic-dialog/index.ts | 3 + .../topic-dialog/topic-dialog.component.scss | 27 + .../topic-dialog.component.spec.ts | 30 + .../topic-dialog.component.stories.ts | 49 + .../topic-dialog/topic-dialog.component.ts | 95 + .../lib/topic-dialog/topic-dialog.module.ts | 34 + .../lib/topic-dialog/topic-dialog.service.ts | 22 + nx.json | 6 + package.json | 84 +- tsconfig.json | 3 +- tslint.json | 4 + yarn.lock | 1761 +++++++++++------ 89 files changed, 2931 insertions(+), 740 deletions(-) create mode 100644 apps/frontend/proxy.conf.json delete mode 100644 apps/frontend/src/app/typings/nil.d.ts create mode 100644 apps/frontend/src/app/web-socket/kafka-proxy.service.ts create mode 100644 apps/frontend/src/app/web-socket/web-socket.service.ts create mode 100644 apps/kafka-proxy/.eslintrc create mode 100644 apps/kafka-proxy/README.md create mode 100644 apps/kafka-proxy/jest.config.js create mode 100644 apps/kafka-proxy/src/app/.gitkeep create mode 100644 apps/kafka-proxy/src/app/app.module.ts create mode 100644 apps/kafka-proxy/src/app/kafka/kafka.gateway.spec.ts create mode 100644 apps/kafka-proxy/src/app/kafka/kafka.gateway.ts create mode 100644 apps/kafka-proxy/src/app/kafka/kafka.module.ts create mode 100644 apps/kafka-proxy/src/app/kafka/kafka.service.ts create mode 100644 apps/kafka-proxy/src/assets/.gitkeep create mode 100644 apps/kafka-proxy/src/environments/environment.prod.ts create mode 100644 apps/kafka-proxy/src/environments/environment.ts create mode 100644 apps/kafka-proxy/src/main.ts create mode 100644 apps/kafka-proxy/tsconfig.app.json create mode 100644 apps/kafka-proxy/tsconfig.json create mode 100644 apps/kafka-proxy/tsconfig.spec.json create mode 100644 apps/kafka/README.md create mode 100644 apps/kafka/docker-compose.yml create mode 100644 libs/model/src/lib/decoded-kafka-message.value.ts create mode 100644 libs/model/src/lib/event-name.value.ts create mode 100644 libs/model/src/lib/topic.value.ts create mode 100644 libs/shared/.eslintrc create mode 100644 libs/shared/README.md create mode 100644 libs/shared/jest.config.js create mode 100644 libs/shared/src/index.ts rename {apps/frontend/src/app => libs/shared/src/lib}/rxjs/nil.ts (92%) create mode 100644 libs/shared/tsconfig.json create mode 100644 libs/shared/tsconfig.lib.json create mode 100644 libs/shared/tsconfig.spec.json create mode 100644 libs/ui/src/lib/sidenav-shell/sidenav-shell.component.stories.ts create mode 100644 libs/ui/src/lib/topic-dialog/index.ts create mode 100644 libs/ui/src/lib/topic-dialog/topic-dialog.component.scss create mode 100644 libs/ui/src/lib/topic-dialog/topic-dialog.component.spec.ts create mode 100644 libs/ui/src/lib/topic-dialog/topic-dialog.component.stories.ts create mode 100644 libs/ui/src/lib/topic-dialog/topic-dialog.component.ts create mode 100644 libs/ui/src/lib/topic-dialog/topic-dialog.module.ts create mode 100644 libs/ui/src/lib/topic-dialog/topic-dialog.service.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index e33f4e6e..8b651bf7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ aliases: # https://github.com/cypress-io/cypress-docker-images/tree/master/included - &use_docker_cypress_included docker: - - image: cypress/included:4.0.1 + - image: cypress/included:4.1.0 - &workspace ~/talus diff --git a/.nxignore b/.nxignore index 34902dd4..bbcf4701 100644 --- a/.nxignore +++ b/.nxignore @@ -1,2 +1,5 @@ # Hack for getting benchmark app (generated with ng g @nrwl/node:application) through linting /apps/benchmark + +# kafka app is not a real @nrwl/nx app +/apps/kafka diff --git a/README.md b/README.md index 9c9beb9a..763c40ef 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ This project was generated using [Nx](https://nx.dev) with the following command 11. `nx g @nrwl/angular:storybook-configuration ui` +12. `ng generate @nrwl/workspace:library shared --linter=eslint` + ## Installations ### Node @@ -117,13 +119,15 @@ Setting up a macro which will fix all the linting issues, optimizes the imports 2. Record macro (Edit > Macros > Start Macro Recording) in this order - - Action: TsLintFileFixAction (with opened \*.ts file) - - Action: OptimizeImports - - Action: ReformatWithPrettierAction - - Action: FileWatcher.runForFiles (with opened \*.scss file) - - Action: SaveAll + - Action: `OptimizeImports` + - Action: `TsLintFileFixAction` (with opened \*.ts file) + - Action: `Javascript.Linters.EsLint.Fix` + - Action: `ReformatWithPrettierAction` + - Action: `FileWatcher.runForFiles` (with opened \*.scss file) + - Action: `SaveAll` -3. Save macro as e.g. `Fix & Save` +3. Save macro as e.g. `Fix & Save` + (macros are saved under `/home//.WebStorm2019.3/config/options/macros.xml`) 4. Assign Keyboard shortcut `Ctrl` + `S` to macro `Fix & Save` (search for macro) @@ -191,11 +195,49 @@ See scripts on [nx.dev](https://nx.dev/angular/api/workspace/npmscripts) - `ngc -p ./apps/frontend/tsconfig.app.json` (output: `./dist/out-tsc`) +## Backend + +### NestJS + +- `yarn add --dev @nrwl/nest` +- `nx g @nrwl/nest:application kafka-proxy --frontend-project frontend --linter eslint` + +### Docker + +### Docker Engine - Community + +https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-using-the-repository + +- `sudo apt-get update` +- `sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common` +- `curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -` +- `sudo apt-key fingerprint 0EBFCD88` +- `sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) eoan test"` + (https://unix.stackexchange.com/a/363058) +- `sudo apt-get update` + +### Docker Compose binary + +https://docs.docker.com/compose/install/ + +- `sudo curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose` +- `sudo chmod +x /usr/local/bin/docker-compose` + +### Docker Command-line completion + +https://docs.docker.com/compose/completion/ + +- `sudo curl -L https://raw.githubusercontent.com/docker/compose/1.25.3/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose` + ## Github Pages -CircleCI pushes every build onto the +CircleCI pushes every develop/master branch build (frontend & storybook of ui) onto the [gh-pages branch](https://github.com/PhilippeMorier/talus/tree/gh-pages) which gets published on GitHub under: -- Schema: `https://philippemorier.github.io/talus///frontend/` -- Example: `https://philippemorier.github.io/talus/develop/56c699a/frontend/` +Example: + +- frontend: `https://philippemorier.github.io/talus/master/d632e97/apps/frontend/` +- storybook of ui: `https://philippemorier.github.io/talus/master/d632e97/storybook/ui/` + +See also the [releases page](https://github.com/PhilippeMorier/talus/releases) for older versions. diff --git a/angular.json b/angular.json index 2f091041..8b0431d8 100644 --- a/angular.json +++ b/angular.json @@ -62,7 +62,8 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "frontend:build" + "browserTarget": "frontend:build", + "proxyConfig": "apps/frontend/proxy.conf.json" }, "configurations": { "production": { @@ -88,7 +89,8 @@ "options": { "jestConfig": "apps/frontend/jest.config.js", "tsConfig": "apps/frontend/tsconfig.spec.json", - "setupFile": "apps/frontend/src/test-setup.ts" + "setupFile": "apps/frontend/src/test-setup.ts", + "passWithNoTests": true } } } @@ -138,7 +140,8 @@ "options": { "jestConfig": "libs/ui/jest.config.js", "tsConfig": "libs/ui/tsconfig.spec.json", - "setupFile": "libs/ui/src/test-setup.ts" + "setupFile": "libs/ui/src/test-setup.ts", + "passWithNoTests": true } }, "storybook": { @@ -243,7 +246,8 @@ "builder": "@nrwl/jest:jest", "options": { "jestConfig": "libs/vdb/jest.config.js", - "tsConfig": "libs/vdb/tsconfig.spec.json" + "tsConfig": "libs/vdb/tsconfig.spec.json", + "passWithNoTests": true } } } @@ -294,7 +298,90 @@ "builder": "@nrwl/jest:jest", "options": { "jestConfig": "libs/model/jest.config.js", - "tsConfig": "libs/model/tsconfig.spec.json" + "tsConfig": "libs/model/tsconfig.spec.json", + "passWithNoTests": true + } + } + } + }, + "kafka-proxy": { + "root": "apps/kafka-proxy", + "sourceRoot": "apps/kafka-proxy/src", + "projectType": "application", + "prefix": "kafka-proxy", + "schematics": {}, + "architect": { + "build": { + "builder": "@nrwl/node:build", + "options": { + "outputPath": "dist/apps/kafka-proxy", + "main": "apps/kafka-proxy/src/main.ts", + "tsConfig": "apps/kafka-proxy/tsconfig.app.json", + "assets": ["apps/kafka-proxy/src/assets"] + }, + "configurations": { + "production": { + "optimization": true, + "extractLicenses": true, + "inspect": false, + "fileReplacements": [ + { + "replace": "apps/kafka-proxy/src/environments/environment.ts", + "with": "apps/kafka-proxy/src/environments/environment.prod.ts" + } + ] + } + } + }, + "serve": { + "builder": "@nrwl/node:execute", + "options": { + "buildTarget": "kafka-proxy:build" + } + }, + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "config": "apps/kafka-proxy/.eslintrc", + "tsConfig": [ + "apps/kafka-proxy/tsconfig.app.json", + "apps/kafka-proxy/tsconfig.spec.json" + ], + "exclude": ["**/node_modules/**", "!apps/kafka-proxy/**"] + } + }, + "test": { + "builder": "@nrwl/jest:jest", + "options": { + "jestConfig": "apps/kafka-proxy/jest.config.js", + "tsConfig": "apps/kafka-proxy/tsconfig.spec.json", + "passWithNoTests": true + } + } + } + }, + "shared": { + "root": "libs/shared", + "sourceRoot": "libs/shared/src", + "projectType": "library", + "schematics": {}, + "architect": { + "lint": { + "builder": "@nrwl/linter:lint", + "options": { + "linter": "eslint", + "config": "libs/shared/.eslintrc", + "tsConfig": ["libs/shared/tsconfig.lib.json", "libs/shared/tsconfig.spec.json"], + "exclude": ["**/node_modules/**", "!libs/shared/**"] + } + }, + "test": { + "builder": "@nrwl/jest:jest", + "options": { + "jestConfig": "libs/shared/jest.config.js", + "tsConfig": "libs/shared/tsconfig.spec.json", + "passWithNoTests": true } } } diff --git a/apps/frontend/jest.config.js b/apps/frontend/jest.config.js index 52ff9790..98347263 100644 --- a/apps/frontend/jest.config.js +++ b/apps/frontend/jest.config.js @@ -24,4 +24,19 @@ module.exports = { // When using `Run test` directly in WebStorm, change the used config to // this file i.e. `./frontend/jest.config.js` and not `/jest.config.js`. setupFilesAfterEnv: ['./src/test-setup.ts'], + + // https://github.com/thymikee/jest-preset-angular/issues/293#issuecomment-513544717 + // When using `Run test` directly in WebStorm, the scss couldn't be loaded. + // - Error: connect ECONNREFUSED 127.0.0.1:80 + // - Error: Uncaught (in promise): Failed to load *.component.scss + globals: { + 'ts-jest': { + tsConfig: '/tsconfig.spec.json', + // stringifyContentPathRegex: '\\.html$', + // astTransformers: [ + // 'jest-preset-angular/build/InlineFilesTransformer', + // 'jest-preset-angular/build/StripStylesTransformer', + // ], + }, + }, }; diff --git a/apps/frontend/proxy.conf.json b/apps/frontend/proxy.conf.json new file mode 100644 index 00000000..62a1e7b7 --- /dev/null +++ b/apps/frontend/proxy.conf.json @@ -0,0 +1,6 @@ +{ + "/api": { + "target": "http://localhost:3333", + "secure": false + } +} diff --git a/apps/frontend/src/app/app.actions.ts b/apps/frontend/src/app/app.actions.ts index d2d34e5c..64aac095 100644 --- a/apps/frontend/src/app/app.actions.ts +++ b/apps/frontend/src/app/app.actions.ts @@ -1,6 +1,20 @@ -import { createAction } from '@ngrx/store'; +import { createAction, props } from '@ngrx/store'; +import { Topic } from '@talus/model'; const actionTypePrefix = '[app]'; export const wentOnline = createAction(`${actionTypePrefix} Went online`); export const wentOffline = createAction(`${actionTypePrefix} Went offline`); + +export const updateTopics = createAction( + `${actionTypePrefix} Update topics`, + props<{ topics: Topic[] }>(), +); +export const updateConnectionStatus = createAction( + `${actionTypePrefix} Update connection status`, + props<{ isConnectedToKafkaProxy: boolean }>(), +); +export const updateLastLoadedMessageOffset = createAction( + `${actionTypePrefix} Update last loaded message offset`, + props<{ offset: number }>(), +); diff --git a/apps/frontend/src/app/app.component.scss b/apps/frontend/src/app/app.component.scss index f2cbf979..a97251e9 100644 --- a/apps/frontend/src/app/app.component.scss +++ b/apps/frontend/src/app/app.component.scss @@ -9,3 +9,11 @@ main { // https://stackoverflow.com/a/38383437 min-height: 0; } + +h6 { + margin-bottom: 0; + + &:not(:first-child) { + margin-top: 1rem; + } +} diff --git a/apps/frontend/src/app/app.component.ts b/apps/frontend/src/app/app.component.ts index 6715dc02..82e38c72 100644 --- a/apps/frontend/src/app/app.component.ts +++ b/apps/frontend/src/app/app.component.ts @@ -16,10 +16,10 @@ import * as fromApp from './app.reducer';
-
Tools
+
Tools
-
Options
+
Options
@@ -33,7 +33,11 @@ import * as fromApp from './app.reducer';
- + `, changeDetection: ChangeDetectionStrategy.OnPush, styleUrls: ['./app.component.scss'], @@ -46,6 +50,20 @@ export class AppComponent { map(state => state.isDarkTheme), ); + topicName$: Observable = this.store.pipe( + select(fromApp.selectSceneViewerContainerState), + map(state => state.topic), + ); + + isConnectedToKafkaProxy$: Observable = this.store.pipe( + select(fromApp.selectSceneViewerContainerState), + map(state => state.isConnectedToKafkaProxy), + ); + + topicLoadingProgressValue$: Observable = this.store.pipe( + select(fromApp.selectTopicLoadingProgressValue), + ); + constructor(private store: Store, private renderer: Renderer2) {} setTheme(isDarkTheme: boolean): void { diff --git a/apps/frontend/src/app/app.effects.spec.ts b/apps/frontend/src/app/app.effects.spec.ts index c67d1211..45ccf908 100644 --- a/apps/frontend/src/app/app.effects.spec.ts +++ b/apps/frontend/src/app/app.effects.spec.ts @@ -1,12 +1,58 @@ +import { Injectable } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { Action } from '@ngrx/store'; +import { provideMockStore } from '@ngrx/store/testing'; +import { DecodedKafkaMessage } from '@talus/model'; import { hot } from 'jasmine-marbles'; +import { Observable, of } from 'rxjs'; import { wentOffline, wentOnline } from './app.actions'; import { AppEffects } from './app.effects'; +import * as fromApp from './app.reducer'; +import { removeVoxel } from './scene-viewer-container/scene-viewer-container.actions'; +import { featureKey } from './scene-viewer-container/scene-viewer-container.reducer'; +import { initialMockState } from './testing'; +import { KafkaProxyService, SyncableAction } from './web-socket/kafka-proxy.service'; + +@Injectable() +class KafkaProxyServiceMock { + topics$: Observable = of([]); + + messages$: Observable> = of(); + + connectionStatus$: Observable = of(true); + + createTopic(): void { + return; + } + + syncAction(): void { + return; + } +} describe('AppEffects', () => { + let actions$: Observable; let effects: AppEffects; + let kafkaProxyService: KafkaProxyService; beforeEach(() => { - effects = new AppEffects(); + TestBed.configureTestingModule({ + providers: [ + AppEffects, + { provide: KafkaProxyService, useClass: KafkaProxyServiceMock }, + provideMockStore({ + initialState: { + ...initialMockState, + sceneViewerContainer: { ...initialMockState[featureKey], topic: 'test-topic' }, + }, + }), + provideMockActions(() => actions$), + ], + }); + + effects = TestBed.inject(AppEffects); + kafkaProxyService = TestBed.inject(KafkaProxyService); Object.defineProperty(navigator, 'onLine', { value: false }); }); @@ -26,4 +72,16 @@ describe('AppEffects', () => { expect(effects.onlineStateChange$).toBeObservable(expected); }); + + it('should sync action', () => { + spyOn(kafkaProxyService, 'syncAction'); + + actions$ = hot('r', { + r: removeVoxel({ xyz: [0, 0, 0], needsSync: true }), + }); + + expect(effects.syncActionToKafka$).toBeObservable(actions$); + + expect(kafkaProxyService.syncAction).toBeCalledTimes(1); + }); }); diff --git a/apps/frontend/src/app/app.effects.ts b/apps/frontend/src/app/app.effects.ts index 61488e36..9efc0f01 100644 --- a/apps/frontend/src/app/app.effects.ts +++ b/apps/frontend/src/app/app.effects.ts @@ -1,11 +1,26 @@ import { Injectable } from '@angular/core'; -import { createEffect } from '@ngrx/effects'; +import { Actions, createEffect } from '@ngrx/effects'; +import { select, Store } from '@ngrx/store'; import { fromEvent, merge, of } from 'rxjs'; -import { map, mapTo } from 'rxjs/operators'; -import { wentOffline, wentOnline } from './app.actions'; +import { filter, map, mapTo, switchMap, tap, withLatestFrom } from 'rxjs/operators'; +import { + updateConnectionStatus, + updateLastLoadedMessageOffset, + updateTopics, + wentOffline, + wentOnline, +} from './app.actions'; +import * as fromApp from './app.reducer'; +import { KafkaProxyService, SyncableAction } from './web-socket/kafka-proxy.service'; @Injectable() export class AppEffects { + constructor( + private readonly actions$: Actions, + private readonly kafkaProxyService: KafkaProxyService, + private readonly store: Store, + ) {} + // @source: https://indepth.dev/start-using-ngrx-effects-for-this/#1externalsources onlineStateChange$ = createEffect(() => { return merge( @@ -14,4 +29,42 @@ export class AppEffects { fromEvent(window, 'offline').pipe(mapTo(false)), ).pipe(map(isOnline => (isOnline ? wentOnline() : wentOffline()))); }); + + syncActionToKafka$ = createEffect( + () => + this.actions$.pipe( + filter(action => action.needsSync), + withLatestFrom(this.store.pipe(select(fromApp.selectSceneViewerContainerState))), + tap( + ([action, state]) => + state.topic && this.kafkaProxyService.syncAction(action, state.topic), + ), + // Map it to single action just for making testing easier + map(([action]) => action), + ), + { dispatch: false }, + ); + + emitActionFromKafka$ = createEffect(() => + this.kafkaProxyService.messages$.pipe( + switchMap(message => { + return [ + { ...message.value, needsSync: false }, + updateLastLoadedMessageOffset({ offset: message.offset }), + ]; + }), + ), + ); + + updateTopics$ = createEffect(() => + this.kafkaProxyService.topics$.pipe(map(topics => updateTopics({ topics }))), + ); + + updateConnectionStatus$ = createEffect(() => + this.kafkaProxyService.connectionStatus$.pipe( + map(connectedKafkaProxy => + updateConnectionStatus({ isConnectedToKafkaProxy: connectedKafkaProxy }), + ), + ), + ); } diff --git a/apps/frontend/src/app/app.module.ts b/apps/frontend/src/app/app.module.ts index 8406ead6..e7aef958 100644 --- a/apps/frontend/src/app/app.module.ts +++ b/apps/frontend/src/app/app.module.ts @@ -13,6 +13,7 @@ import { OptionsPanelModule } from './options-panel/options-panel.module'; import { SceneViewerContainerModule } from './scene-viewer-container'; import { ToolsPanelModule } from './tools-panel/tools-panel.module'; import { UndoRedoModule } from './undo-redo/undo-redo.module'; +import { KafkaProxyService } from './web-socket/kafka-proxy.service'; @NgModule({ declarations: [AppComponent], @@ -47,7 +48,7 @@ import { UndoRedoModule } from './undo-redo/undo-redo.module'; ToolsPanelModule, UndoRedoModule, ], - providers: [], + providers: [KafkaProxyService], bootstrap: [AppComponent], }) export class AppModule {} diff --git a/apps/frontend/src/app/app.reducer.ts b/apps/frontend/src/app/app.reducer.ts index 16a61285..e2e5fb83 100644 --- a/apps/frontend/src/app/app.reducer.ts +++ b/apps/frontend/src/app/app.reducer.ts @@ -68,9 +68,9 @@ export const selectSceneViewerContainerState = createFeatureSelector< fromSceneViewerContainer.State >(fromSceneViewerContainer.featureKey); -export const selectVoxelCount = createSelector( +export const selectTopicLoadingProgressValue = createSelector( selectSceneViewerContainerState, - fromSceneViewerContainer.selectVoxelCount, + fromSceneViewerContainer.selectTopicLoadingProgressValue, ); /** diff --git a/apps/frontend/src/app/menu-bar-container/menu-bar-container.actions.ts b/apps/frontend/src/app/menu-bar-container/menu-bar-container.actions.ts index c70a8e98..de822c0b 100644 --- a/apps/frontend/src/app/menu-bar-container/menu-bar-container.actions.ts +++ b/apps/frontend/src/app/menu-bar-container/menu-bar-container.actions.ts @@ -1,4 +1,5 @@ -import { createAction } from '@ngrx/store'; +import { createAction, props } from '@ngrx/store'; +import { Topic } from '@talus/model'; const actionTypePrefix = `[menuBarContainer]`; @@ -7,3 +8,17 @@ export const redo = createAction(`${actionTypePrefix} Redo`); export const setDarkTheme = createAction(`${actionTypePrefix} Set dark theme`); export const setLightTheme = createAction(`${actionTypePrefix} Set light theme`); + +export const openTopicDialog = createAction( + `${actionTypePrefix} Open topic dialog`, + props<{ topics: Topic[] }>(), +); +export const openTopicDialogFailed = createAction(`${actionTypePrefix} Open topic dialog failed`); +export const selectTopic = createAction( + `${actionTypePrefix} Select topic`, + props<{ topic: string; isNewTopic: boolean }>(), +); +export const createTopic = createAction( + `${actionTypePrefix} Create topic`, + props<{ topic: string }>(), +); diff --git a/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.spec.ts b/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.spec.ts index b8bc23ba..3dadce76 100644 --- a/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.spec.ts +++ b/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.spec.ts @@ -6,7 +6,7 @@ import { undo } from './menu-bar-container.actions'; import { MenuBarContainerComponent } from './menu-bar-container.component'; import { MenuBarContainerModule } from './menu-bar-container.module'; -describe('MenuBarComponent', () => { +describe('MenuBarContainerComponent', () => { let component: MenuBarContainerComponent; let fixture: ComponentFixture; diff --git a/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.ts b/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.ts index 84422dcc..3551840a 100644 --- a/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.ts +++ b/apps/frontend/src/app/menu-bar-container/menu-bar-container.component.ts @@ -3,7 +3,13 @@ import { Action, select, Store } from '@ngrx/store'; import { UiMenuBarMenu } from '@talus/ui'; import { map } from 'rxjs/operators'; import * as fromApp from '../app.reducer'; -import { redo, setDarkTheme, setLightTheme, undo } from './menu-bar-container.actions'; +import { + openTopicDialog, + redo, + setDarkTheme, + setLightTheme, + undo, +} from './menu-bar-container.actions'; @Component({ selector: 'fe-menu-bar-container', @@ -33,13 +39,22 @@ export class MenuBarContainerComponent { menus$ = this.store.pipe( select(fromApp.selectSceneViewerContainerState), - map(state => state.isDarkTheme), - map(isDarkTheme => [ + map(state => [ + { + label: 'File', + menuItems: [ + { + icon: 'note_add', + label: 'Open/New', + value: openTopicDialog({ topics: state.topics }), + }, + ], + }, ...this.menus, { label: 'View', menuItems: [ - ...(isDarkTheme + ...(state.isDarkTheme ? [ { icon: 'brightness_5', diff --git a/apps/frontend/src/app/options-panel/options-panel.effects.ts b/apps/frontend/src/app/options-panel/options-panel.effects.ts index 08de9e1a..e095bf07 100644 --- a/apps/frontend/src/app/options-panel/options-panel.effects.ts +++ b/apps/frontend/src/app/options-panel/options-panel.effects.ts @@ -1,9 +1,9 @@ import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { notNil } from '@talus/shared'; import { UiColorDialogService } from '@talus/ui'; import { of } from 'rxjs'; import { catchError, flatMap, map } from 'rxjs/operators'; -import { notNil } from '../rxjs/nil'; import { openColorDialog, openColorDialogFailed, selectColor } from './options-panel.actions'; @Injectable() @@ -18,7 +18,7 @@ export class OptionsPanelEffects { ), flatMap(dialogRef => dialogRef.beforeClosed()), notNil(), - map(selectedColorIndex => selectColor({ colorIndex: selectedColorIndex })), + map(colorIndex => selectColor({ colorIndex })), catchError(() => of(openColorDialogFailed())), ), ); diff --git a/apps/frontend/src/app/scene-viewer-container/grid.service.ts b/apps/frontend/src/app/scene-viewer-container/grid.service.ts index 8b349b31..a28c2aac 100644 --- a/apps/frontend/src/app/scene-viewer-container/grid.service.ts +++ b/apps/frontend/src/app/scene-viewer-container/grid.service.ts @@ -11,6 +11,7 @@ import { nodeToMesh, Ray, TimeSpan, + ValueAccessor3, Vec3, VolumeRayIntersector, Voxel, @@ -26,8 +27,17 @@ const COLOR_FACTOR = 1 / 255; */ @Injectable() export class GridService { - grid = new Grid(-1); - accessor = this.grid.getAccessor(); + grid: Grid; + accessor: ValueAccessor3; + + constructor() { + this.initialize(); + } + + initialize(): void { + this.grid = new Grid(-1); + this.accessor = this.grid.getAccessor(); + } get background(): number { return this.grid.background; diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.actions.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.actions.ts index 58039110..e47603fd 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.actions.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.actions.ts @@ -7,7 +7,7 @@ const actionTypePrefix = `[sceneViewerContainer]`; // Set voxel export const setVoxel = createAction( `${actionTypePrefix} Set voxel`, - props<{ xyz: Coord; newValue: number }>(), + props<{ xyz: Coord; newValue: number; needsSync?: boolean }>(), ); export const setVoxelFailed = createAction(`${actionTypePrefix} Set voxel failed`); export const voxelSet = createAction(`${actionTypePrefix} Voxel set`, props()); @@ -15,7 +15,7 @@ export const voxelSet = createAction(`${actionTypePrefix} Voxel set`, props(), + props<{ coords: Coord[]; newValues: number[]; needsSync?: boolean }>(), ); export const setVoxelsFailed = createAction(`${actionTypePrefix} Set voxels failed`); export const voxelsSet = createAction( @@ -26,7 +26,7 @@ export const voxelsSet = createAction( // Remove voxel export const removeVoxel = createAction( `${actionTypePrefix} Remove voxel`, - props<{ xyz: Coord }>(), + props<{ xyz: Coord; needsSync?: boolean }>(), ); export const removeVoxelFailed = createAction(`${actionTypePrefix} Remove voxel failed`); export const voxelRemoved = createAction(`${actionTypePrefix} Voxel removed`, props()); @@ -34,7 +34,7 @@ export const voxelRemoved = createAction(`${actionTypePrefix} Voxel removed`, pr // Paint voxel export const paintVoxel = createAction( `${actionTypePrefix} Paint voxel`, - props<{ xyz: Coord; newValue: number }>(), + props<{ xyz: Coord; newValue: number; needsSync?: boolean }>(), ); export const paintVoxelFailed = createAction(`${actionTypePrefix} Paint voxel failed`); export const voxelPainted = createAction(`${actionTypePrefix} Voxel painted`, props()); @@ -42,7 +42,7 @@ export const voxelPainted = createAction(`${actionTypePrefix} Voxel painted`, pr // Draw line export const setLineCoord = createAction( `${actionTypePrefix} Set line coord`, - props<{ xyz: Coord; newValue: number }>(), + props<{ xyz: Coord; newValue: number; needsSync?: boolean }>(), ); export const startLine = createAction( `${actionTypePrefix} Start line`, @@ -63,5 +63,10 @@ export const setLineChanges = createAction( export const voxelUnderCursorChange = createAction( `${actionTypePrefix} Voxel under cursor change`, - props<{ toAddPosition: Coord; underPointerPosition: Coord; color: number }>(), + props<{ + toAddPosition: Coord; + underPointerPosition: Coord; + color: number; + needsSync?: boolean; + }>(), ); diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.spec.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.spec.ts index 91ef0fda..17c88913 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.spec.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.spec.ts @@ -4,7 +4,7 @@ import { By } from '@angular/platform-browser'; import { MemoizedSelector, Store } from '@ngrx/store'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { rgbaToInt, Tool } from '@talus/model'; -import { UiPointerButton, UiPointerPickInfo } from '@talus/ui'; +import { UiPointerButton, UiPointerPickInfo, UiSceneViewerService } from '@talus/ui'; import { Coord } from '@talus/vdb'; import { Subject } from 'rxjs'; import * as fromApp from '../app.reducer'; @@ -36,6 +36,7 @@ describe('SceneViewerContainerComponent', () => { declarations: [SceneViewerContainerComponent, SceneViewerStubComponent], providers: [ GridService, + { provide: UiSceneViewerService, useValue: { resizeView: () => {} } }, provideMockStore({ initialState: initialMockState, }), @@ -136,6 +137,7 @@ describe('SceneViewerContainerComponent', () => { b: 255, a: 255, }), + needsSync: true, }); stubComponent.pointerPick.next({ @@ -192,7 +194,12 @@ describe('SceneViewerContainerComponent', () => { mockStore.refreshState(); fixture.detectChanges(); - const action = removeVoxel({ xyz }); + const initialAction = setVoxel({ + xyz: [0, 0, 0], + newValue: rgbaToInt({ r: 0, g: 255, b: 0, a: 255 }), + }); + + const action = removeVoxel({ xyz, needsSync: true }); stubComponent.pointerPick.next({ pickedPoint, @@ -200,6 +207,7 @@ describe('SceneViewerContainerComponent', () => { normal, }); + expect(mockStore.dispatch).toHaveBeenCalledWith(initialAction); expect(mockStore.dispatch).toHaveBeenCalledWith(action); }, ); diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.ts index bf941f0d..4977fdb4 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.component.ts @@ -3,7 +3,12 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, ViewChild } from '@a // import '@babylonjs/core/Rendering/outlineRenderer'; import { select, Store } from '@ngrx/store'; import { rgbaToInt, Tool } from '@talus/model'; -import { UiPointerButton, UiPointerPickInfo, UiSceneViewerComponent } from '@talus/ui'; +import { + UiPointerButton, + UiPointerPickInfo, + UiSceneViewerComponent, + UiSceneViewerService, +} from '@talus/ui'; import { areEqual, Coord, createMaxCoord, removeFraction } from '@talus/vdb'; import { combineLatest, Observable } from 'rxjs'; import * as fromApp from '../app.reducer'; @@ -39,9 +44,15 @@ export class SceneViewerContainerComponent implements AfterViewInit { private lastUnderPointerPosition: Coord = createMaxCoord(); - constructor(private store: Store) {} + constructor( + private sceneViewerService: UiSceneViewerService, + private store: Store, + ) {} ngAfterViewInit(): void { + // Due to the status-bar being on the bottom of the screen a resizing is needed. + this.sceneViewerService.resizeView(); + this.store.dispatch( setVoxel({ xyz: [0, 0, 0], newValue: rgbaToInt({ r: 0, g: 255, b: 0, a: 255 }) }), ); @@ -75,6 +86,7 @@ export class SceneViewerContainerComponent implements AfterViewInit { toAddPosition, underPointerPosition, color: selectedColor, + needsSync: true, }), ); } @@ -93,7 +105,7 @@ export class SceneViewerContainerComponent implements AfterViewInit { } } - this.store.dispatch(setVoxels({ coords, newValues })); + this.store.dispatch(setVoxels({ coords, newValues, needsSync: true })); } private dispatchPickAction( @@ -107,17 +119,27 @@ export class SceneViewerContainerComponent implements AfterViewInit { switch (selectedToolId) { case Tool.SelectLinePoint: - this.store.dispatch(setLineCoord({ xyz: this.calcVoxelToAddPosition(pickInfo), newValue })); + this.store.dispatch( + setLineCoord({ xyz: this.calcVoxelToAddPosition(pickInfo), newValue, needsSync: true }), + ); break; case Tool.SetVoxel: - this.store.dispatch(setVoxel({ xyz: this.calcVoxelToAddPosition(pickInfo), newValue })); + this.store.dispatch( + setVoxel({ xyz: this.calcVoxelToAddPosition(pickInfo), newValue, needsSync: true }), + ); break; case Tool.RemoveVoxel: - this.store.dispatch(removeVoxel({ xyz: this.calcVoxelUnderPointerPosition(pickInfo) })); + this.store.dispatch( + removeVoxel({ xyz: this.calcVoxelUnderPointerPosition(pickInfo), needsSync: true }), + ); break; case Tool.PaintVoxel: this.store.dispatch( - paintVoxel({ xyz: this.calcVoxelUnderPointerPosition(pickInfo), newValue }), + paintVoxel({ + xyz: this.calcVoxelUnderPointerPosition(pickInfo), + newValue, + needsSync: true, + }), ); break; } diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.spec.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.spec.ts index ca932ebb..ef0538ee 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.spec.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.spec.ts @@ -3,11 +3,14 @@ import { TestBed } from '@angular/core/testing'; import { provideMockActions } from '@ngrx/effects/testing'; import { Action } from '@ngrx/store'; import { provideMockStore } from '@ngrx/store/testing'; -import { UiSceneViewerService } from '@talus/ui'; +import { Topic } from '@talus/model'; +import { UiSceneViewerService, UiTopicDialogService } from '@talus/ui'; import { hot } from 'jasmine-marbles'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import * as fromApp from '../app.reducer'; +import { openTopicDialog, selectTopic } from '../menu-bar-container/menu-bar-container.actions'; import { initialMockState } from '../testing'; +import { KafkaProxyService } from '../web-socket/kafka-proxy.service'; import { GridService, VoxelChange } from './grid.service'; import { addFirstLineChange, @@ -51,16 +54,36 @@ class UiSceneViewerServiceMock { } } +@Injectable() +class UiTopicDialogServiceMock { + open(): void { + return; + } +} + +@Injectable() +class KafkaProxyServiceMock { + createTopic(): void { + return; + } + setTopic(): void { + return; + } +} + describe('SceneViewerContainerEffects', () => { let actions$: Observable; let effects: SceneViewerContainerEffects; let gridService: GridService; + let topicService: UiTopicDialogService; beforeEach(() => { TestBed.configureTestingModule({ providers: [ { provide: GridService, useClass: GridServiceMock }, { provide: UiSceneViewerService, useClass: UiSceneViewerServiceMock }, + { provide: UiTopicDialogService, useClass: UiTopicDialogServiceMock }, + { provide: KafkaProxyService, useClass: KafkaProxyServiceMock }, SceneViewerContainerEffects, provideMockActions(() => actions$), provideMockStore({ @@ -71,6 +94,7 @@ describe('SceneViewerContainerEffects', () => { effects = TestBed.inject(SceneViewerContainerEffects); gridService = TestBed.inject(GridService); + topicService = TestBed.inject(UiTopicDialogService); }); it(`should dispatch 'voxelSet' after 'setVoxel'`, () => { @@ -153,4 +177,20 @@ describe('SceneViewerContainerEffects', () => { expect(gridService.computeInternalNode1Mesh).toHaveBeenCalledWith([0, 0, 0]); expect(gridService.computeInternalNode1Mesh).toHaveBeenCalledWith([8, 0, 0]); }); + + it(`should dispatch 'selectSession' after 'openSessionDialog'`, () => { + const topics: Topic[] = [ + { name: 'topic-1', offsets: [] }, + { name: 'topic-2', offsets: [] }, + ]; + actions$ = hot('o', { o: openTopicDialog({ topics }) }); + + spyOn(topicService, 'open').and.returnValue({ + beforeClosed: () => of({ topicName: topics[0].name, isNewTopic: false }), + }); + const expected$ = hot('s', { s: selectTopic({ topic: topics[0].name, isNewTopic: false }) }); + + expect(effects.openTopicDialog$).toBeObservable(expected$); + expect(topicService.open).toHaveBeenCalledTimes(1); + }); }); diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.ts index 56e2893a..fcbb9c48 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.effects.ts @@ -1,11 +1,20 @@ import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { select, Store } from '@ngrx/store'; -import { UiSceneViewerService } from '@talus/ui'; +import { rgbaToInt } from '@talus/model'; +import { notNil } from '@talus/shared'; +import { UiSceneViewerService, UiTopicDialogService } from '@talus/ui'; import { areEqual, Coord } from '@talus/vdb'; import { of } from 'rxjs'; -import { catchError, filter, map, switchMap, tap, withLatestFrom } from 'rxjs/operators'; +import { catchError, filter, flatMap, map, switchMap, tap, withLatestFrom } from 'rxjs/operators'; import * as fromApp from '../app.reducer'; +import { + createTopic, + openTopicDialog, + openTopicDialogFailed, + selectTopic, +} from '../menu-bar-container/menu-bar-container.actions'; +import { KafkaProxyService } from '../web-socket/kafka-proxy.service'; import { GridService, VoxelChange } from './grid.service'; import { addFirstLineChange, @@ -33,8 +42,10 @@ export class SceneViewerContainerEffects { constructor( private actions$: Actions, private gridService: GridService, + private kafkaProxyService: KafkaProxyService, private sceneViewerService: UiSceneViewerService, private store: Store, + private topicDialogService: UiTopicDialogService, ) {} setVoxel$ = createEffect(() => @@ -80,7 +91,7 @@ export class SceneViewerContainerEffects { map(([action, state]) => state.selectedLineStartCoord ? finishLine({ voxelChanges: state.selectedLineChanges }) - : startLine(action), + : startLine({ newValue: action.newValue, xyz: action.xyz }), ), ), ); @@ -170,6 +181,51 @@ export class SceneViewerContainerEffects { { dispatch: false }, ); + openTopicDialog$ = createEffect(() => + this.actions$.pipe( + ofType(openTopicDialog), + map(({ topics }) => this.topicDialogService.open(topics.map(topic => topic.name))), + flatMap(dialogRef => dialogRef.beforeClosed()), + notNil(), + map(({ topicName, isNewTopic }) => + isNewTopic + ? createTopic({ topic: topicName }) + : selectTopic({ topic: topicName, isNewTopic }), + ), + catchError(() => of(openTopicDialogFailed())), + ), + ); + + createTopicInKafka$ = createEffect(() => + this.actions$.pipe( + ofType(createTopic), + tap(({ topic }) => this.kafkaProxyService.createTopic(topic)), + map(({ topic }) => selectTopic({ topic, isNewTopic: true })), + ), + ); + + restartSceneViewer$ = createEffect(() => + this.actions$.pipe( + ofType(selectTopic), + tap(() => this.sceneViewerService.disposeSceneAndRestartRendering()), + tap(() => this.gridService.initialize()), + tap(({ topic }) => this.kafkaProxyService.setTopic(topic)), + filter(({ isNewTopic }) => isNewTopic), + map(() => + setVoxel({ + xyz: [0, 0, 0], + newValue: rgbaToInt({ + r: 0, + g: 255, + b: 0, + a: 255, + }), + needsSync: true, + }), + ), + ), + ); + private getUniqueNodeOrigins(voxelChanges: VoxelChange[]): Coord[] { const origins = new Map(); voxelChanges.forEach(change => { diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.module.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.module.ts index 2c2622fe..a7949430 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.module.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.module.ts @@ -1,7 +1,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { EffectsModule } from '@ngrx/effects'; -import { UiSceneViewerModule } from '@talus/ui'; +import { UiSceneViewerModule, UiTopicDialogModule } from '@talus/ui'; import { GridService } from './grid.service'; import { SceneViewerContainerComponent } from './scene-viewer-container.component'; import { SceneViewerContainerEffects } from './scene-viewer-container.effects'; @@ -12,6 +12,7 @@ import { SceneViewerContainerEffects } from './scene-viewer-container.effects'; CommonModule, EffectsModule.forFeature([SceneViewerContainerEffects]), UiSceneViewerModule, + UiTopicDialogModule, ], exports: [SceneViewerContainerComponent], providers: [GridService], diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.spec.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.spec.ts index d096d4c8..3a6f9685 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.spec.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.spec.ts @@ -5,10 +5,8 @@ import { finishLine, setLineChanges, startLine, - voxelRemoved, - voxelSet, } from './scene-viewer-container.actions'; -import { reducer, selectVoxelCount } from './scene-viewer-container.reducer'; +import { reducer } from './scene-viewer-container.reducer'; describe('SceneViewerContainerReducer', () => { const voxelChange: VoxelChange = { @@ -18,25 +16,6 @@ describe('SceneViewerContainerReducer', () => { newValue: 42, }; - it('should increment counter', () => { - const stateWithOneVoxel = reducer(undefined, voxelSet(voxelChange)); - - expect(stateWithOneVoxel.voxelCount).toEqual(1); - }); - - it('should decrement counter', () => { - const stateWithOneVoxel = reducer(undefined, voxelSet(voxelChange)); - const stateWithNoVoxel = reducer(stateWithOneVoxel, voxelRemoved(voxelChange)); - - expect(stateWithNoVoxel.voxelCount).toEqual(0); - }); - - it('should select voxel count', () => { - const stateWithOneVoxel = reducer(undefined, voxelSet(voxelChange)); - - expect(selectVoxelCount(stateWithOneVoxel)).toEqual(1); - }); - it('should set first line coord', () => { const stateWithOneLineCoord = reducer(undefined, startLine({ xyz: [0, 0, 0], newValue: 42 })); @@ -46,10 +25,12 @@ describe('SceneViewerContainerReducer', () => { it('should reset selected line changes and start coord', () => { const stateWithNoStartCoord = reducer( { + isConnectedToKafkaProxy: true, isDarkTheme: true, + lastLoadedMessageOffset: 0, selectedLineChanges: [voxelChange, voxelChange, voxelChange], selectedLineStartCoord: [0, 0, 0], - voxelCount: 0, + topics: [], }, finishLine({ voxelChanges: [] }), ); diff --git a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.ts b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.ts index f7dde590..2b13bec5 100644 --- a/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.ts +++ b/apps/frontend/src/app/scene-viewer-container/scene-viewer-container.reducer.ts @@ -1,5 +1,11 @@ import { createReducer, on } from '@ngrx/store'; +import { Topic } from '@talus/model'; import { Coord } from '@talus/vdb'; +import { + updateConnectionStatus, + updateLastLoadedMessageOffset, + updateTopics, +} from '../app.actions'; import * as menuBarContainerActions from '../menu-bar-container/menu-bar-container.actions'; import { VoxelChange } from './grid.service'; import { @@ -7,39 +13,30 @@ import { finishLine, setLineChanges, startLine, - voxelRemoved, - voxelSet, } from './scene-viewer-container.actions'; export const featureKey = 'sceneViewerContainer'; export interface State { + isConnectedToKafkaProxy: boolean; isDarkTheme: boolean; + lastLoadedMessageOffset: number; selectedLineChanges: VoxelChange[]; selectedLineStartCoord?: Coord; - voxelCount: number; + topic?: string; + topics: Topic[]; } export const initialState: State = { + isConnectedToKafkaProxy: false, isDarkTheme: true, + lastLoadedMessageOffset: 0, selectedLineChanges: [], - voxelCount: 0, + topics: [], }; export const reducer = createReducer( initialState, - on(voxelSet, state => { - return { - ...state, - voxelCount: state.voxelCount + 1, - }; - }), - on(voxelRemoved, state => { - return { - ...state, - voxelCount: state.voxelCount - 1, - }; - }), on( startLine, @@ -91,6 +88,38 @@ export const reducer = createReducer( return { ...state, isDarkTheme: false }; }, ), + + on( + updateTopics, + (state, { topics }): State => { + return { ...state, topics }; + }, + ), + on( + updateLastLoadedMessageOffset, + (state, { offset }): State => { + return { ...state, lastLoadedMessageOffset: offset }; + }, + ), + on( + updateConnectionStatus, + (state, { isConnectedToKafkaProxy }): State => { + return { ...state, isConnectedToKafkaProxy }; + }, + ), + + on( + menuBarContainerActions.selectTopic, + (state, { topic }): State => { + return { + ...state, + lastLoadedMessageOffset: 0, + selectedLineChanges: initialState.selectedLineChanges, + selectedLineStartCoord: initialState.selectedLineStartCoord, + topic, + }; + }, + ), ); -export const selectVoxelCount = (state: State) => state.voxelCount; +export const selectTopicLoadingProgressValue = (state: State) => state.lastLoadedMessageOffset; diff --git a/apps/frontend/src/app/typings/nil.d.ts b/apps/frontend/src/app/typings/nil.d.ts deleted file mode 100644 index ed96da46..00000000 --- a/apps/frontend/src/app/typings/nil.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare type Nil = undefined | null; diff --git a/apps/frontend/src/app/undo-redo/undo-redo.actions.ts b/apps/frontend/src/app/undo-redo/undo-redo.actions.ts index a797592b..44440ae5 100644 --- a/apps/frontend/src/app/undo-redo/undo-redo.actions.ts +++ b/apps/frontend/src/app/undo-redo/undo-redo.actions.ts @@ -12,15 +12,6 @@ export const addUndo = createAction( }>(), ); -export const undo = createAction(`${actionTypePrefix} Undo`); - export const undone = createAction(`${actionTypePrefix} Undone`); -export const addRedo = createAction( - `${actionTypePrefix} Add redo`, - props<{ redoAction: Action }>(), -); - -export const redo = createAction(`${actionTypePrefix} Redo`); - export const redone = createAction(`${actionTypePrefix} Redone`); diff --git a/apps/frontend/src/app/undo-redo/undo-redo.effects.ts b/apps/frontend/src/app/undo-redo/undo-redo.effects.ts index db7d318d..6cead785 100644 --- a/apps/frontend/src/app/undo-redo/undo-redo.effects.ts +++ b/apps/frontend/src/app/undo-redo/undo-redo.effects.ts @@ -15,7 +15,7 @@ import { voxelSet, voxelsSet, } from '../scene-viewer-container/scene-viewer-container.actions'; -import { addUndo, redo, redone, undo, undone } from './undo-redo.actions'; +import { addUndo, redone, undone } from './undo-redo.actions'; @Injectable() export class UndoRedoEffects { @@ -23,7 +23,7 @@ export class UndoRedoEffects { undo$ = createEffect(() => this.actions$.pipe( - ofType(undo, menuBarContainerActions.undo), + ofType(menuBarContainerActions.undo), withLatestFrom(this.store.pipe(select(fromApp.selectCurrentUndoStartAction))), switchMap(([_action, currentUndoAction]) => currentUndoAction ? [currentUndoAction] : [undone()], @@ -33,7 +33,7 @@ export class UndoRedoEffects { redo$ = createEffect(() => this.actions$.pipe( - ofType(redo, menuBarContainerActions.redo), + ofType(menuBarContainerActions.redo), withLatestFrom(this.store.pipe(select(fromApp.selectCurrentRedoStartAction))), switchMap(([_action, currentRedoAction]) => currentRedoAction ? [currentRedoAction] : [redone()], @@ -79,9 +79,9 @@ export class UndoRedoEffects { this.userTriggeredActions$.pipe( ofType(voxelSet), map(voxelChange => ({ - redoStartAction: setVoxel(voxelChange), + redoStartAction: setVoxel({ ...voxelChange, needsSync: true }), redoEndActionType: voxelSet.type, - undoStartAction: removeVoxel(voxelChange), + undoStartAction: removeVoxel({ ...voxelChange, needsSync: true }), undoEndActionType: voxelRemoved.type, })), map(addUndo), @@ -92,9 +92,9 @@ export class UndoRedoEffects { this.userTriggeredActions$.pipe( ofType(voxelRemoved), map(voxelChange => ({ - redoStartAction: removeVoxel(voxelChange), + redoStartAction: removeVoxel({ ...voxelChange, needsSync: true }), redoEndActionType: voxelRemoved.type, - undoStartAction: setVoxel(voxelChange), + undoStartAction: setVoxel({ ...voxelChange, needsSync: true }), undoEndActionType: voxelSet.type, })), map(addUndo), @@ -105,9 +105,13 @@ export class UndoRedoEffects { this.userTriggeredActions$.pipe( ofType(voxelPainted), map(voxelChange => ({ - redoStartAction: paintVoxel(voxelChange), + redoStartAction: paintVoxel({ ...voxelChange, needsSync: true }), redoEndActionType: voxelPainted.type, - undoStartAction: paintVoxel({ xyz: voxelChange.xyz, newValue: voxelChange.oldValue }), + undoStartAction: paintVoxel({ + xyz: voxelChange.xyz, + newValue: voxelChange.oldValue, + needsSync: true, + }), undoEndActionType: voxelPainted.type, })), map(addUndo), @@ -123,9 +127,9 @@ export class UndoRedoEffects { const oldValues = voxelChanges.map(c => c.oldValue); return { - redoStartAction: setVoxels({ coords, newValues }), + redoStartAction: setVoxels({ coords, newValues, needsSync: true }), redoEndActionType: voxelsSet.type, - undoStartAction: setVoxels({ coords, newValues: oldValues }), + undoStartAction: setVoxels({ coords, newValues: oldValues, needsSync: true }), undoEndActionType: setVoxels.type, }; }), diff --git a/apps/frontend/src/app/undo-redo/undo-redo.reducer.spec.ts b/apps/frontend/src/app/undo-redo/undo-redo.reducer.spec.ts index 96307c37..ca67f60b 100644 --- a/apps/frontend/src/app/undo-redo/undo-redo.reducer.spec.ts +++ b/apps/frontend/src/app/undo-redo/undo-redo.reducer.spec.ts @@ -1,5 +1,6 @@ import { Action } from '@ngrx/store'; import { Coord } from '@talus/vdb'; +import { redo, undo } from '../menu-bar-container/menu-bar-container.actions'; import { VoxelChange } from '../scene-viewer-container/grid.service'; import { removeVoxel, @@ -7,7 +8,7 @@ import { voxelRemoved, voxelSet, } from '../scene-viewer-container/scene-viewer-container.actions'; -import { addUndo, redo, redone, undo, undone } from './undo-redo.actions'; +import { addUndo, redone, undone } from './undo-redo.actions'; import { reducer, selectCurrentRedoEndAction, diff --git a/apps/frontend/src/app/undo-redo/undo-redo.reducer.ts b/apps/frontend/src/app/undo-redo/undo-redo.reducer.ts index 565251e3..8fe795d3 100644 --- a/apps/frontend/src/app/undo-redo/undo-redo.reducer.ts +++ b/apps/frontend/src/app/undo-redo/undo-redo.reducer.ts @@ -1,6 +1,6 @@ import { Action, createReducer, on } from '@ngrx/store'; import * as menuBarContainerActions from '../menu-bar-container/menu-bar-container.actions'; -import { addUndo, redo, redone, undo, undone } from './undo-redo.actions'; +import { addUndo, redone, undone } from './undo-redo.actions'; /** * Use normal reducer instead of meta-reducer, to have the state in the normal store @@ -57,14 +57,14 @@ export const reducer = createReducer( }, ), - on(undo, menuBarContainerActions.undo, state => { + on(menuBarContainerActions.undo, state => { return { ...state, isUndoing: true, }; }), - on(redo, menuBarContainerActions.redo, state => { + on(menuBarContainerActions.redo, state => { return { ...state, isRedoing: true, diff --git a/apps/frontend/src/app/web-socket/kafka-proxy.service.ts b/apps/frontend/src/app/web-socket/kafka-proxy.service.ts new file mode 100644 index 00000000..26aaea2b --- /dev/null +++ b/apps/frontend/src/app/web-socket/kafka-proxy.service.ts @@ -0,0 +1,63 @@ +import { Injectable } from '@angular/core'; +import { Action } from '@ngrx/store'; +import { DecodedKafkaMessage, EventName, Topic } from '@talus/model'; +import { Observable, Subject } from 'rxjs'; +import { filter, flatMap, map, withLatestFrom } from 'rxjs/operators'; +import { WebSocketService } from './web-socket.service'; + +export interface SyncableAction extends Action { + needsSync: boolean; +} + +@Injectable() +export class KafkaProxyService { + private readonly uri: string = 'ws://localhost:3333/kafka'; + private readonly webSocketService: WebSocketService; + + connectionStatus$: Observable; + socketId$: Observable; + topics$: Observable; + private topicSubject = new Subject(); + messages$: Observable>; + + constructor() { + this.webSocketService = new WebSocketService(this.uri); + this.webSocketService.connect(); + this.connectionStatus$ = this.webSocketService.connectionStatus$; + this.socketId$ = this.webSocketService.socketId$; + this.topics$ = this.webSocketService + .emitAndListen(EventName.GetTopics) + // https://kafka.apache.org/0110/documentation.html#impl_offsettracking + .pipe(map(topics => topics.filter(topic => topic.name !== '__consumer_offsets'))); + + this.messages$ = this.topicSubject.pipe( + flatMap(topic => + this.webSocketService.emitAndListen>( + EventName.ConsumeTopic, + topic, + ), + ), + withLatestFrom(this.socketId$), + filter(([message, socketId]) => socketId !== message.headers.socketId), + map(([message, _socketId]) => message), + ); + } + + createTopic(topicName: string): void { + this.webSocketService.emit(EventName.CreateTopic, topicName); + } + + deleteTopic(topicName: string): void { + this.webSocketService.emit(EventName.DeleteTopic, topicName); + } + + syncAction(action: Action, topic: string): void { + this.webSocketService.emit(EventName.SyncAction, { action, topic }); + } + + setTopic(topic: string): void { + // Reconnect to get a new socket-id so all the messages from the topic get received + this.webSocketService.reconnect(); + this.topicSubject.next(topic); + } +} diff --git a/apps/frontend/src/app/web-socket/web-socket.service.ts b/apps/frontend/src/app/web-socket/web-socket.service.ts new file mode 100644 index 00000000..9730645b --- /dev/null +++ b/apps/frontend/src/app/web-socket/web-socket.service.ts @@ -0,0 +1,58 @@ +import { EventName } from '@talus/model'; +import { fromEvent, Observable, Subject } from 'rxjs'; +import { map } from 'rxjs/operators'; +import io from 'socket.io-client'; + +export class WebSocketService { + private socket: SocketIOClient.Socket; + + private readonly connectionStatusSubject = new Subject(); + connectionStatus$ = this.connectionStatusSubject.asObservable(); + + socketId$ = this.connectionStatus$.pipe(map(() => this.socket.id)); + + constructor(private uri: string) {} + + connect(): void { + this.socket = io.connect(this.uri); + this.registerConnectionEvents(); + } + + reconnect(): void { + this.socket.disconnect(); + this.connect(); + } + + listen(eventName: EventName): Observable { + return fromEvent(this.socket, eventName); + } + + emit(eventName: string, data?: T, ackCallback?: (ackData: any) => void): void { + ackCallback + ? // if `ackCallback` undefined, array [{...action}, null] gets emitted + // instead of only the `action` object. + this.socket.emit(eventName, data, ackCallback) + : this.socket.emit(eventName, data); + } + + emitAndListen( + eventName: EventName, + data?: DataType, + ): Observable { + this.emit(eventName, data); + + return this.listen(eventName); + } + + private registerConnectionEvents(): void { + this.socket.on('connect_error', () => { + this.connectionStatusSubject.next(this.socket.connected); + }); + this.socket.on('connect', () => { + this.connectionStatusSubject.next(this.socket.connected); + }); + this.socket.on('disconnect', () => { + this.connectionStatusSubject.next(this.socket.connected); + }); + } +} diff --git a/apps/kafka-proxy/.eslintrc b/apps/kafka-proxy/.eslintrc new file mode 100644 index 00000000..6d9db271 --- /dev/null +++ b/apps/kafka-proxy/.eslintrc @@ -0,0 +1 @@ +{ "extends": "../../.eslintrc", "rules": {} } diff --git a/apps/kafka-proxy/README.md b/apps/kafka-proxy/README.md new file mode 100644 index 00000000..c0710cce --- /dev/null +++ b/apps/kafka-proxy/README.md @@ -0,0 +1,16 @@ +# kafka-proxy + +Same idea as [Confluent REST proxy](https://docs.confluent.io/current/kafka-rest/) but using +WebSockets. + +- https://docs.confluent.io/current/kafka-rest/ +- https://github.com/tulios/kafkajs/issues/36#issuecomment-449953932 + +## Debug in WebStorm + +- https://www.jetbrains.com/help/webstorm/running-and-debugging-node-js.html#cc8ea8a7 + +Just run the application with `yarn nx serve kafka-proxy` and then attach WebStorm to it. Be sure to +use correct port (e.g. 7777). + +> `Debugger listening on ws://localhost:7777/44ed7046-cad0-414c-b138-05e8a9ae7da3` diff --git a/apps/kafka-proxy/jest.config.js b/apps/kafka-proxy/jest.config.js new file mode 100644 index 00000000..9c5ac846 --- /dev/null +++ b/apps/kafka-proxy/jest.config.js @@ -0,0 +1,5 @@ +module.exports = { + name: 'kafka-proxy', + preset: '../../jest.config.js', + coverageDirectory: '../../coverage/apps/kafka-proxy', +}; diff --git a/apps/kafka-proxy/src/app/.gitkeep b/apps/kafka-proxy/src/app/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/apps/kafka-proxy/src/app/app.module.ts b/apps/kafka-proxy/src/app/app.module.ts new file mode 100644 index 00000000..360e3430 --- /dev/null +++ b/apps/kafka-proxy/src/app/app.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { KafkaModule } from './kafka/kafka.module'; + +@Module({ + imports: [KafkaModule], + controllers: [], + providers: [], +}) +export class AppModule {} diff --git a/apps/kafka-proxy/src/app/kafka/kafka.gateway.spec.ts b/apps/kafka-proxy/src/app/kafka/kafka.gateway.spec.ts new file mode 100644 index 00000000..0aff878d --- /dev/null +++ b/apps/kafka-proxy/src/app/kafka/kafka.gateway.spec.ts @@ -0,0 +1,89 @@ +import { INestApplication, Injectable } from '@nestjs/common'; +import { Test, TestingModule } from '@nestjs/testing'; +import { EventName } from '@talus/model'; +import { of } from 'rxjs'; +import io from 'socket.io-client'; +import { KafkaGateway } from './kafka.gateway'; +import { KafkaService } from './kafka.service'; + +@Injectable() +class KafkaServiceMock { + send(): void { + return; + } + runConsumer(): void { + return; + } + connectConsumer(): void { + return; + } + disconnectConsumer(): void { + return; + } + resetOffsets(): void { + return; + } +} + +describe('KafkaGateway', () => { + let testingModule: TestingModule; + let app: INestApplication; + let ws: SocketIOClient.Socket; + + let kafkaServiceMock: KafkaService; + + beforeAll(async () => { + testingModule = await Test.createTestingModule({ + providers: [{ provide: KafkaService, useClass: KafkaServiceMock }, KafkaGateway], + }).compile(); + + app = await testingModule.createNestApplication(); + await app.listenAsync(3334); + + kafkaServiceMock = testingModule.get(KafkaService); + }); + + afterEach(() => app.close()); + + describe('actions()', () => { + // Inspired by: + // https://github.com/nestjs/nest/blob/master/integration/websockets/e2e/gateway.spec.ts + it('should send message to via KafkaService', async () => { + spyOn(kafkaServiceMock, 'send'); + spyOn(kafkaServiceMock, 'connectConsumer').and.returnValue( + Promise.resolve({ stop: () => Promise.resolve({}) }), + ); + spyOn(kafkaServiceMock, 'disconnectConsumer').and.returnValue( + Promise.resolve({ stop: () => Promise.resolve({}) }), + ); + spyOn(kafkaServiceMock, 'resetOffsets').and.returnValue(of({})); + spyOn(kafkaServiceMock, 'runConsumer').and.returnValue(of({})); + + ws = io.connect('http://localhost:3334/kafka'); + + const fakeMessageBody = { action: { type: '[Test] Test action type' }, topic: 'test-topic' }; + + ws.emit(EventName.SyncAction, fakeMessageBody); + ws.emit(EventName.ConsumeTopic, 'to-consume-topic'); + + await new Promise(resolve => + ws.on(EventName.ConsumeTopic, () => { + expect(kafkaServiceMock.send).toBeCalledWith( + 'test-topic', + 'action', + fakeMessageBody.action, + expect.objectContaining({ socketId: expect.any(String) }), + ); + + expect(kafkaServiceMock.runConsumer).toHaveBeenCalledWith( + expect.anything(), + 'to-consume-topic', + true, + ); + + resolve(); + }), + ); + }); + }); +}); diff --git a/apps/kafka-proxy/src/app/kafka/kafka.gateway.ts b/apps/kafka-proxy/src/app/kafka/kafka.gateway.ts new file mode 100644 index 00000000..d6340422 --- /dev/null +++ b/apps/kafka-proxy/src/app/kafka/kafka.gateway.ts @@ -0,0 +1,106 @@ +import { + ConnectedSocket, + MessageBody, + OnGatewayConnection, + OnGatewayDisconnect, + SubscribeMessage, + WebSocketGateway, + WebSocketServer, + WsResponse, +} from '@nestjs/websockets'; +import { Action } from '@ngrx/store'; +import { DecodedKafkaMessage, EventName, Topic } from '@talus/model'; +import { RecordMetadata } from 'kafkajs'; +import { Observable, Subject } from 'rxjs'; +import { fromPromise } from 'rxjs/internal-compatibility'; +import { flatMap, map, startWith } from 'rxjs/operators'; +import { Client, Server, Socket } from 'socket.io'; +import { KafkaService } from './kafka.service'; + +@WebSocketGateway({ namespace: 'kafka' }) +export class KafkaGateway implements OnGatewayConnection, OnGatewayDisconnect { + @WebSocketServer() + server: Server; + + readonly getTopicsSubject = new Subject(); + + constructor(private readonly kafkaService: KafkaService) {} + + handleConnection(client: Client): void { + this.kafkaService + .connectConsumer(client.id) + .then(() => console.log('New connection for:', client.id)); + } + + handleDisconnect(client: Client): void { + this.kafkaService + .disconnectConsumer(client.id) + .then(() => console.log('Connection closed for:', client.id)); + } + + @SubscribeMessage(EventName.SyncAction) + async syncAction( + @MessageBody() { action, topic }: { action: Action; topic: string }, + @ConnectedSocket() socket: Socket, + ): Promise { + console.log(`Action '${action.type}' for topic '${topic}' from '${socket.id}' received.`); + + return this.kafkaService.send(topic, 'action', action, { socketId: socket.id }); + } + + @SubscribeMessage(EventName.GetTopics) + getTopics(): Observable> { + return this.getTopicsSubject.pipe( + startWith(this.getTopicsAsWsResponse()), + flatMap(() => this.getTopicsAsWsResponse()), + ); + } + + @SubscribeMessage(EventName.CreateTopic) + async createTopics(@MessageBody() topicName: string): Promise { + const topicCreated = await this.kafkaService.createTopic(topicName); + + if (topicCreated) { + console.log('Topic created:', topicName); + this.getTopicsSubject.next(); + } + + return topicCreated; + } + + @SubscribeMessage(EventName.ConsumeTopic) + consumeTopic( + @MessageBody() topicName: string, + @ConnectedSocket() socket: Socket, + ): Observable>> { + const consumer$ = fromPromise(this.kafkaService.connectConsumer(socket.id)); + + return consumer$.pipe( + flatMap(consumer => + // The consumer group must have no running instances when performing the reset. + // https://kafka.js.org/docs/admin#a-name-reset-offsets-a-reset-consumer-group-offsets + fromPromise(consumer.stop()).pipe( + flatMap(() => this.kafkaService.resetOffsets(socket.id, topicName)), + flatMap(() => this.kafkaService.runConsumer(consumer, topicName, true)), + ), + ), + map(message => ({ event: EventName.ConsumeTopic, data: message })), + ); + } + + /** + * Requires `delete.topic.enable=true`, i.e.: `KAFKA_CFG_DELETE_TOPIC_ENABLE=true` + */ + @SubscribeMessage(EventName.DeleteTopic) + async deleteTopics(@MessageBody() topicName: string): Promise { + await this.kafkaService.deleteTopic(topicName); + + this.getTopicsSubject.next(); + } + + private async getTopicsAsWsResponse(): Promise> { + const topics = await this.kafkaService.getTopics(); + + return { event: EventName.GetTopics, data: topics }; + } +} diff --git a/apps/kafka-proxy/src/app/kafka/kafka.module.ts b/apps/kafka-proxy/src/app/kafka/kafka.module.ts new file mode 100644 index 00000000..8813e085 --- /dev/null +++ b/apps/kafka-proxy/src/app/kafka/kafka.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { KafkaGateway } from './kafka.gateway'; +import { KafkaService } from './kafka.service'; + +@Module({ + providers: [KafkaGateway, KafkaService], +}) +export class KafkaModule {} diff --git a/apps/kafka-proxy/src/app/kafka/kafka.service.ts b/apps/kafka-proxy/src/app/kafka/kafka.service.ts new file mode 100644 index 00000000..d36a9c49 --- /dev/null +++ b/apps/kafka-proxy/src/app/kafka/kafka.service.ts @@ -0,0 +1,120 @@ +import { Injectable } from '@nestjs/common'; +import { Action } from '@ngrx/store'; +import { DecodedKafkaMessage, Topic } from '@talus/model'; +import { + CompressionTypes, + Consumer, + EachMessagePayload, + IHeaders, + Kafka, + logLevel, + RecordMetadata, +} from 'kafkajs'; +import { Observable } from 'rxjs'; +import { fromPromise } from 'rxjs/internal-compatibility'; +import { flatMap, map } from 'rxjs/operators'; + +@Injectable() +export class KafkaService { + readonly kafka = new Kafka({ + logLevel: logLevel.ERROR, + clientId: 'kafka-proxy', + brokers: ['localhost:29092'], + }); + + readonly producer = this.kafka.producer({ + // https://blog.softwaremill.com/does-kafka-really-guarantee-the-order-of-messages-3ca849fd19d2#f700 + maxInFlightRequests: 1, + }); + readonly admin = this.kafka.admin(); + private readonly consumers: Map = new Map(); + + constructor() { + this.producer + .connect() + .then(() => console.log('Producer connected')) + .catch(error => error); + } + + send(topic: string, key: string, data: T, headers?: IHeaders): Promise { + return this.producer.send({ + topic, + compression: CompressionTypes.GZIP, + messages: [{ key, value: JSON.stringify(data), headers }], + }); + } + + runConsumer( + consumer: Consumer, + topic: string, + fromBeginning: boolean = true, + ): Observable> { + const subscribe$ = fromPromise(consumer.subscribe({ topic, fromBeginning })); + + const runEachMessage$ = new Observable(subscriber => { + consumer.run({ eachMessage: async payload => subscriber.next(payload) }); + }); + + return subscribe$.pipe( + flatMap(() => runEachMessage$), + map(({ message }) => DecodedKafkaMessage.fromKafkaMessage(message)), + ); + } + + resetOffsets(groupId: string, topic: string): Observable { + return fromPromise(this.admin.resetOffsets({ groupId, topic, earliest: true })); + } + + async getTopics(): Promise { + const { topics } = await this.admin.fetchTopicMetadata({ topics: [] }); + + const topicPromises = topics.map(topic => this.getTopic(topic.name)); + + return Promise.all(topicPromises); + } + + async getTopic(topicName: string): Promise { + const offsets = await this.admin.fetchTopicOffsets(topicName); + return { + name: topicName, + offsets: offsets.map(offset => ({ + high: Number(offset.high), + low: Number(offset.low), + offset: Number(offset.offset), + partition: offset.partition, + })), + }; + } + + async createTopic(topicName: string): Promise { + return this.admin.createTopics({ + topics: [{ topic: topicName, configEntries: [] }], + }); + } + + async deleteTopic(topicName: string): Promise { + return this.admin.deleteTopics({ topics: [topicName] }); + } + + async connectConsumer(groupId: string): Promise { + let consumer = this.consumers.get(groupId); + + if (!consumer) { + consumer = this.kafka.consumer({ groupId }); + this.consumers.set(groupId, consumer); + } + + await consumer.connect(); + + return consumer; + } + + async disconnectConsumer(groupId: string): Promise { + const consumer = this.consumers.get(groupId); + + if (consumer) { + await consumer.disconnect(); + this.consumers.delete(groupId); + } + } +} diff --git a/apps/kafka-proxy/src/assets/.gitkeep b/apps/kafka-proxy/src/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/apps/kafka-proxy/src/environments/environment.prod.ts b/apps/kafka-proxy/src/environments/environment.prod.ts new file mode 100644 index 00000000..c9669790 --- /dev/null +++ b/apps/kafka-proxy/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true, +}; diff --git a/apps/kafka-proxy/src/environments/environment.ts b/apps/kafka-proxy/src/environments/environment.ts new file mode 100644 index 00000000..a20cfe55 --- /dev/null +++ b/apps/kafka-proxy/src/environments/environment.ts @@ -0,0 +1,3 @@ +export const environment = { + production: false, +}; diff --git a/apps/kafka-proxy/src/main.ts b/apps/kafka-proxy/src/main.ts new file mode 100644 index 00000000..6676eb19 --- /dev/null +++ b/apps/kafka-proxy/src/main.ts @@ -0,0 +1,19 @@ +/** + * This is not a production server yet! + * This is only a minimal backend to get started. + */ + +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app/app.module'; + +async function bootstrap(): Promise { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api'; + app.setGlobalPrefix(globalPrefix); + const port = process.env.port || 3333; + await app.listen(port, () => { + console.log('Listening at http://localhost:' + port + '/' + globalPrefix); + }); +} + +bootstrap(); diff --git a/apps/kafka-proxy/tsconfig.app.json b/apps/kafka-proxy/tsconfig.app.json new file mode 100644 index 00000000..bb717c5e --- /dev/null +++ b/apps/kafka-proxy/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["node"] + }, + "exclude": ["**/*.spec.ts"], + "include": ["**/*.ts"] +} diff --git a/apps/kafka-proxy/tsconfig.json b/apps/kafka-proxy/tsconfig.json new file mode 100644 index 00000000..8e9487cb --- /dev/null +++ b/apps/kafka-proxy/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["node", "jest"], + "emitDecoratorMetadata": true + }, + "include": ["**/*.ts"] +} diff --git a/apps/kafka-proxy/tsconfig.spec.json b/apps/kafka-proxy/tsconfig.spec.json new file mode 100644 index 00000000..29efa430 --- /dev/null +++ b/apps/kafka-proxy/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["**/*.spec.ts", "**/*.d.ts"] +} diff --git a/apps/kafka/README.md b/apps/kafka/README.md new file mode 100644 index 00000000..37ce370e --- /dev/null +++ b/apps/kafka/README.md @@ -0,0 +1,18 @@ +## Kafka + +https://wurstmeister.github.io/kafka-docker/ +https://medium.com/big-data-engineering/hello-kafka-world-the-complete-guide-to-kafka-with-docker-and-python-f788e2588cfc + +https://github.com/obsidiandynamics/kafdrop + +https://github.com/bitnami/bitnami-docker-kafka +https://rmoff.net/2018/08/02/kafka-listeners-explained/ + +- set docker host ip (docker0) in `docker-compose.yml` (e.g. 172.17.0.1, check with + `ip add | grep docker0`) +- Start kafka: `sudo docker-compose up` or `sudo docker-compose up --scale kafka=2` +- Check running processes: `sudo docker-compose ps` +- Stop kafka evironment: `sudo docker-compose stop` +- Access Kafdrop: http://localhost:9000/ +- Clean up docker: `sudo docker system prune` + - E.g. if Kafdrop can't start diff --git a/apps/kafka/docker-compose.yml b/apps/kafka/docker-compose.yml new file mode 100644 index 00000000..2d7abeca --- /dev/null +++ b/apps/kafka/docker-compose.yml @@ -0,0 +1,64 @@ +version: '2' +services: + kafdrop: + image: obsidiandynamics/kafdrop:3.23.0 + restart: 'no' + ports: + - '9090:9090' + environment: + KAFKA_BROKERCONNECT: 'kafka:9092' + SERVER_PORT: 9090 + depends_on: + - kafka + + kafka_manager: + image: hlebalbau/kafka-manager:stable + ports: + - '9000:9000' + environment: + ZK_HOSTS: 'zookeeper:2181' + APPLICATION_SECRET: 'random-secret' + command: -Dpidfile.path=/dev/null + depends_on: + - zookeeper + + # magic: + # image: digitsy/kafka-magic + # ports: + # - '8080:9999' + # environment: + # KMAGIC_ALLOW_TOPIC_DELETE: 'true' + # depends_on: + # - zookeeper + + zookeeper: + image: 'bitnami/zookeeper:3.5.7' + ports: + - '2181:2181' + volumes: + - 'zookeeper_data:/bitnami' + environment: + - ALLOW_ANONYMOUS_LOGIN=yes + + kafka: + image: 'bitnami/kafka:2.4.0' + ports: + - '9092' + - '29092:29092' + volumes: + - 'kafka_data:/bitnami' + environment: + - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181 + - ALLOW_PLAINTEXT_LISTENER=yes + - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + - KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,PLAINTEXT_HOST://:29092 + - KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 + - KAFKA_CFG_DELETE_TOPIC_ENABLE=true + depends_on: + - zookeeper + +volumes: + zookeeper_data: + driver: local + kafka_data: + driver: local diff --git a/jest.config.js b/jest.config.js index cc91ef03..4f64d597 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,7 +6,6 @@ module.exports = { resolver: '@nrwl/jest/plugins/resolver', moduleFileExtensions: ['ts', 'js', 'html'], coverageReporters: ['html'], - passWithNoTests: true, moduleNameMapper: { '@babylonjs': 'babylonjs', }, diff --git a/libs/model/src/index.ts b/libs/model/src/index.ts index 5f398800..5331eb77 100644 --- a/libs/model/src/index.ts +++ b/libs/model/src/index.ts @@ -1,2 +1,5 @@ +export * from './lib/decoded-kafka-message.value'; +export * from './lib/event-name.value'; export * from './lib/rgba.value'; export * from './lib/tool.value'; +export * from './lib/topic.value'; diff --git a/libs/model/src/lib/decoded-kafka-message.value.ts b/libs/model/src/lib/decoded-kafka-message.value.ts new file mode 100644 index 00000000..e7ec9c96 --- /dev/null +++ b/libs/model/src/lib/decoded-kafka-message.value.ts @@ -0,0 +1,19 @@ +import { KafkaMessage } from 'kafkajs'; + +export class DecodedKafkaMessage { + headers: { + socketId?: string; + }; + key: string; + offset: number; + value: T; + + static fromKafkaMessage(message: KafkaMessage): DecodedKafkaMessage { + return { + key: message.key.toString(), + value: JSON.parse(message.value.toString()), + headers: { socketId: message.headers && message.headers['socketId'].toString() }, + offset: Number(message.offset), + }; + } +} diff --git a/libs/model/src/lib/event-name.value.ts b/libs/model/src/lib/event-name.value.ts new file mode 100644 index 00000000..7649cf58 --- /dev/null +++ b/libs/model/src/lib/event-name.value.ts @@ -0,0 +1,7 @@ +export enum EventName { + SyncAction = 'SyncAction', + ConsumeTopic = 'ConsumeTopic', + CreateTopic = 'CreateTopic', + DeleteTopic = 'DeleteTopic', + GetTopics = 'GetTopics', +} diff --git a/libs/model/src/lib/topic.value.ts b/libs/model/src/lib/topic.value.ts new file mode 100644 index 00000000..b7391946 --- /dev/null +++ b/libs/model/src/lib/topic.value.ts @@ -0,0 +1,11 @@ +export class Topic { + name: string; + offsets: KafkaTopicOffset[]; +} + +interface KafkaTopicOffset { + partition: number; + offset: number; + high: number; + low: number; +} diff --git a/libs/shared/.eslintrc b/libs/shared/.eslintrc new file mode 100644 index 00000000..6d9db271 --- /dev/null +++ b/libs/shared/.eslintrc @@ -0,0 +1 @@ +{ "extends": "../../.eslintrc", "rules": {} } diff --git a/libs/shared/README.md b/libs/shared/README.md new file mode 100644 index 00000000..3427b57e --- /dev/null +++ b/libs/shared/README.md @@ -0,0 +1,8 @@ +# shared + +This library was generated with `ng generate @nrwl/workspace:library shared --linter=eslint` of +[Nx](https://nx.dev). + +## Running unit tests + +Run `ng test shared` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/shared/jest.config.js b/libs/shared/jest.config.js new file mode 100644 index 00000000..89c90445 --- /dev/null +++ b/libs/shared/jest.config.js @@ -0,0 +1,22 @@ +module.exports = { + name: 'shared', + preset: '../../jest.config.js', + // https://github.com/nrwl/nx/issues/837#issuecomment-501188633 + reporters: [ + 'default', + [ + 'jest-junit', + { + outputDirectory: './test-results/jest', + outputName: 'libs-shared.junit.xml', + classNameTemplate: '{classname}', + titleTemplate: '{title}', + }, + ], + ], + transform: { + '^.+\\.[tj]sx?$': 'ts-jest', + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], + coverageDirectory: '../../coverage/libs/shared', +}; diff --git a/libs/shared/src/index.ts b/libs/shared/src/index.ts new file mode 100644 index 00000000..34d0f2bc --- /dev/null +++ b/libs/shared/src/index.ts @@ -0,0 +1 @@ +export * from './lib/rxjs/nil'; diff --git a/apps/frontend/src/app/rxjs/nil.ts b/libs/shared/src/lib/rxjs/nil.ts similarity index 92% rename from apps/frontend/src/app/rxjs/nil.ts rename to libs/shared/src/lib/rxjs/nil.ts index a82a84ad..ceb8c457 100644 --- a/apps/frontend/src/app/rxjs/nil.ts +++ b/libs/shared/src/lib/rxjs/nil.ts @@ -21,6 +21,7 @@ export function nil(): (o: Observable) => Observable { }; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any function isNil(value: any): boolean { return value == null; } diff --git a/libs/shared/tsconfig.json b/libs/shared/tsconfig.json new file mode 100644 index 00000000..e5decd5e --- /dev/null +++ b/libs/shared/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["node", "jest"] + }, + "include": ["**/*.ts"] +} diff --git a/libs/shared/tsconfig.lib.json b/libs/shared/tsconfig.lib.json new file mode 100644 index 00000000..7096f230 --- /dev/null +++ b/libs/shared/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [] + }, + "exclude": ["**/*.spec.ts"], + "include": ["**/*.ts"] +} diff --git a/libs/shared/tsconfig.spec.json b/libs/shared/tsconfig.spec.json new file mode 100644 index 00000000..515f3c22 --- /dev/null +++ b/libs/shared/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/*.d.ts"] +} diff --git a/libs/ui/jest.config.js b/libs/ui/jest.config.js index e9c307b4..8c6ac403 100644 --- a/libs/ui/jest.config.js +++ b/libs/ui/jest.config.js @@ -36,7 +36,10 @@ module.exports = { 'ts-jest': { tsConfig: '/tsconfig.spec.json', // stringifyContentPathRegex: '\\.html$', - // astTransformers: [require.resolve('jest-preset-angular/InlineHtmlStripStylesTransformer')], + // astTransformers: [ + // 'jest-preset-angular/build/InlineFilesTransformer', + // 'jest-preset-angular/build/StripStylesTransformer', + // ], }, }, }; diff --git a/libs/ui/src/index.ts b/libs/ui/src/index.ts index 530b504d..6f52b75a 100644 --- a/libs/ui/src/index.ts +++ b/libs/ui/src/index.ts @@ -4,3 +4,4 @@ export * from './lib/scene-viewer'; export * from './lib/sidenav-shell'; export * from './lib/status-bar'; export * from './lib/toolbar'; +export * from './lib/topic-dialog'; diff --git a/libs/ui/src/lib/color-dialog/color-dialog.component.stories.ts b/libs/ui/src/lib/color-dialog/color-dialog.component.stories.ts index 31a89085..f0d3d560 100644 --- a/libs/ui/src/lib/color-dialog/color-dialog.component.stories.ts +++ b/libs/ui/src/lib/color-dialog/color-dialog.component.stories.ts @@ -2,7 +2,7 @@ import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { number, object } from '@storybook/addon-knobs'; import { Observable } from 'rxjs'; -import { UiColorDialogColor, UiColorDialogComponent } from './color-dialog.component'; +import { UiColorDialogColor } from './color-dialog.component'; import { UiColorDialogModule } from './color-dialog.module'; import { UiColorDialogService } from './color-dialog.service'; diff --git a/libs/ui/src/lib/color-dialog/color-dialog.component.ts b/libs/ui/src/lib/color-dialog/color-dialog.component.ts index 5e398cbb..187a1dfc 100644 --- a/libs/ui/src/lib/color-dialog/color-dialog.component.ts +++ b/libs/ui/src/lib/color-dialog/color-dialog.component.ts @@ -25,7 +25,7 @@ export interface UiColorDialogData { Color Selector - drag_indicator + open_with diff --git a/libs/ui/src/lib/menu-bar/menu-bar.component.ts b/libs/ui/src/lib/menu-bar/menu-bar.component.ts index ca6f0a29..c67fbe1e 100644 --- a/libs/ui/src/lib/menu-bar/menu-bar.component.ts +++ b/libs/ui/src/lib/menu-bar/menu-bar.component.ts @@ -36,7 +36,9 @@ interface UiMenuBarMenuItem { export class UiMenuBarComponent { @Input() menus: UiMenuBarMenu[] = []; - @Output() menuItemClick = new EventEmitter(); + // Without `` on `EventEmitter` test don't run and throw + // Error: connect ECONNREFUSED 127.0.0.1:80 + @Output() menuItemClick = new EventEmitter(); onMenuItemClick(value: any): void { this.menuItemClick.emit(value); diff --git a/libs/ui/src/lib/scene-viewer/scene-viewer.component.scss b/libs/ui/src/lib/scene-viewer/scene-viewer.component.scss index d132385d..3649c4cb 100644 --- a/libs/ui/src/lib/scene-viewer/scene-viewer.component.scss +++ b/libs/ui/src/lib/scene-viewer/scene-viewer.component.scss @@ -2,4 +2,9 @@ canvas { display: block; // otherwise canvas is 4px too high height: 100%; width: 100%; + + &:focus { + // remove blue border of canvas when focused + outline: none; + } } diff --git a/libs/ui/src/lib/scene-viewer/scene-viewer.service.ts b/libs/ui/src/lib/scene-viewer/scene-viewer.service.ts index 4434bdf9..7c469e18 100644 --- a/libs/ui/src/lib/scene-viewer/scene-viewer.service.ts +++ b/libs/ui/src/lib/scene-viewer/scene-viewer.service.ts @@ -7,6 +7,7 @@ import { PickingInfo } from '@babylonjs/core/Collisions/pickingInfo'; import { Engine } from '@babylonjs/core/Engines/engine'; import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight'; import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial'; +import { Color4 } from '@babylonjs/core/Maths/math.color'; import { Vector3 } from '@babylonjs/core/Maths/math.vector'; import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh'; import { VertexBuffer } from '@babylonjs/core/Meshes/buffer'; @@ -57,6 +58,7 @@ export class CameraFactory { export class UiSceneViewerService { private actionManager: ActionManager; private camera: ArcRotateCamera; + private canvas?: HTMLCanvasElement; private engine: Engine; private gridNode: TransformNode; private light: HemisphericLight; @@ -72,6 +74,7 @@ export class UiSceneViewerService { constructor(private cameraFactory: CameraFactory, private engineFactory: EngineFactory) {} initialize(canvas: HTMLCanvasElement): void { + this.canvas = canvas; this.engine = this.engineFactory.create(canvas); this.createScene(); this.createCamera(); @@ -104,6 +107,17 @@ export class UiSceneViewerService { } } + disposeSceneAndRestartRendering(): void { + if (this.scene) { + this.scene.dispose(); + } + + if (this.canvas) { + this.initialize(this.canvas); + this.startRendering(); + } + } + private createScene(): void { // https://doc.babylonjs.com/how_to/optimizing_your_scene this.scene = new Scene(this.engine, { @@ -111,6 +125,9 @@ export class UiSceneViewerService { useClonedMeshMap: true, }); + // Make background of canvas transparent + this.scene.clearColor = new Color4(0, 0, 0, 0); + // An as transparent flagged mesh does not write to the depth buffer when rendering. // This can lead to potential artifacts. // https://forum.babylonjs.com/t/hasvertexalpha-causes-problems-when-unindexed-is-used-directly diff --git a/libs/ui/src/lib/sidenav-shell/sidenav-shell.component.scss b/libs/ui/src/lib/sidenav-shell/sidenav-shell.component.scss index 62b77cef..61ad3aa1 100644 --- a/libs/ui/src/lib/sidenav-shell/sidenav-shell.component.scss +++ b/libs/ui/src/lib/sidenav-shell/sidenav-shell.component.scss @@ -4,30 +4,40 @@ mat-sidenav-container { } mat-sidenav { - min-width: 1rem; + min-width: 4rem; overflow: visible; + top: 10%; + bottom: 10%; + + &[position='start'] { + border-radius: 0 4px 4px 0; + } + + &[position='end'] { + border-radius: 4px 0 0 4px; + } } button { position: absolute; visibility: visible; - width: 24px; top: 50%; + width: 1.5rem; + + mat-icon { + font-size: 1.5rem; + height: 1.5rem; + width: 1.5rem; + } } #left-sidenav-button { left: 100%; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 0; - border-top-left-radius: 0; + border-radius: 0 4px 4px 0; transform: translate(0, -50%); } #right-sidenav-button { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 4px; - border-top-left-radius: 4px; + border-radius: 4px 0 0 4px; transform: translate(-100%, -50%); } diff --git a/libs/ui/src/lib/sidenav-shell/sidenav-shell.component.stories.ts b/libs/ui/src/lib/sidenav-shell/sidenav-shell.component.stories.ts new file mode 100644 index 00000000..8488ab84 --- /dev/null +++ b/libs/ui/src/lib/sidenav-shell/sidenav-shell.component.stories.ts @@ -0,0 +1,41 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { UiSidenavShellModule } from './sidenav-shell.module'; + +// noinspection AngularMissingOrInvalidDeclarationInModule +@Component({ + template: ` + + Left + + Right + + +
Content
+
+
+ `, + styles: [ + ` + div { + height: 100px; + width: 100px; + margin: 50px auto; + background-color: green; + } + `, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +class UiSidenavShellTestComponent {} + +export default { + title: 'UiSidenavShellComponent', +}; + +export const primary = () => ({ + moduleMetadata: { + declarations: [UiSidenavShellTestComponent], + imports: [UiSidenavShellModule], + }, + component: UiSidenavShellTestComponent, +}); diff --git a/libs/ui/src/lib/status-bar/status-bar.component.scss b/libs/ui/src/lib/status-bar/status-bar.component.scss index 4c0a7a5c..2ec9d698 100644 --- a/libs/ui/src/lib/status-bar/status-bar.component.scss +++ b/libs/ui/src/lib/status-bar/status-bar.component.scss @@ -1,6 +1,7 @@ mat-toolbar { height: 2rem; font-size: 1rem; + line-height: 2rem; } mat-icon { diff --git a/libs/ui/src/lib/status-bar/status-bar.component.spec.ts b/libs/ui/src/lib/status-bar/status-bar.component.spec.ts index f3995614..5972d391 100644 --- a/libs/ui/src/lib/status-bar/status-bar.component.spec.ts +++ b/libs/ui/src/lib/status-bar/status-bar.component.spec.ts @@ -1,7 +1,6 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { UiStatusBarModule } from '@talus/ui'; - import { UiStatusBarComponent } from './status-bar.component'; +import { UiStatusBarModule } from './status-bar.module'; describe('StatusBarComponent', () => { let component: UiStatusBarComponent; diff --git a/libs/ui/src/lib/status-bar/status-bar.component.stories.ts b/libs/ui/src/lib/status-bar/status-bar.component.stories.ts index 15b5de0f..fb45408e 100644 --- a/libs/ui/src/lib/status-bar/status-bar.component.stories.ts +++ b/libs/ui/src/lib/status-bar/status-bar.component.stories.ts @@ -1,4 +1,4 @@ -import { boolean } from '@storybook/addon-knobs'; +import { boolean, text } from '@storybook/addon-knobs'; import { UiStatusBarComponent } from './status-bar.component'; import { UiStatusBarModule } from './status-bar.module'; @@ -13,5 +13,6 @@ export const primary = () => ({ component: UiStatusBarComponent, props: { connected: boolean('connected', false), + status: text('status', 'Your status text'), }, }); diff --git a/libs/ui/src/lib/status-bar/status-bar.component.ts b/libs/ui/src/lib/status-bar/status-bar.component.ts index 30b90e92..3ba8daf5 100644 --- a/libs/ui/src/lib/status-bar/status-bar.component.ts +++ b/libs/ui/src/lib/status-bar/status-bar.component.ts @@ -4,6 +4,10 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; selector: 'ui-status-bar', template: ` + {{ status }} + + + {{ progressValue }} cloud_queue @@ -15,4 +19,6 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; }) export class UiStatusBarComponent { @Input() connected = false; + @Input() status: string; + @Input() progressValue: number; } diff --git a/libs/ui/src/lib/topic-dialog/index.ts b/libs/ui/src/lib/topic-dialog/index.ts new file mode 100644 index 00000000..82c92a16 --- /dev/null +++ b/libs/ui/src/lib/topic-dialog/index.ts @@ -0,0 +1,3 @@ +export * from './topic-dialog.component'; +export * from './topic-dialog.module'; +export * from './topic-dialog.service'; diff --git a/libs/ui/src/lib/topic-dialog/topic-dialog.component.scss b/libs/ui/src/lib/topic-dialog/topic-dialog.component.scss new file mode 100644 index 00000000..928ab171 --- /dev/null +++ b/libs/ui/src/lib/topic-dialog/topic-dialog.component.scss @@ -0,0 +1,27 @@ +h1 { + margin-left: -2rem; + margin-right: -2rem; + margin-top: -2rem; + + mat-icon { + cursor: move; + } +} + +.spacer { + flex: 1 1 auto; +} + +.topic-radio-group { + display: flex; + flex-direction: column; + margin: 15px 0; +} + +.topic-radio-button { + margin: 5px; +} + +#existingTopicsLabel { + margin: 1rem 0 1rem 0; +} diff --git a/libs/ui/src/lib/topic-dialog/topic-dialog.component.spec.ts b/libs/ui/src/lib/topic-dialog/topic-dialog.component.spec.ts new file mode 100644 index 00000000..ed2ea5f9 --- /dev/null +++ b/libs/ui/src/lib/topic-dialog/topic-dialog.component.spec.ts @@ -0,0 +1,30 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { UiTopicDialogComponent } from './topic-dialog.component'; +import { UiTopicDialogModule } from './topic-dialog.module'; + +describe('UiTopicDialogComponent', () => { + let component: UiTopicDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [UiTopicDialogModule], + providers: [ + // https://github.com/angular/components/issues/8419#issuecomment-361972699 + { provide: MatDialogRef, useValue: { close: () => {} } }, + { provide: MAT_DIALOG_DATA, useValue: [] }, + ], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(UiTopicDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/libs/ui/src/lib/topic-dialog/topic-dialog.component.stories.ts b/libs/ui/src/lib/topic-dialog/topic-dialog.component.stories.ts new file mode 100644 index 00000000..2fa53495 --- /dev/null +++ b/libs/ui/src/lib/topic-dialog/topic-dialog.component.stories.ts @@ -0,0 +1,49 @@ +import { CommonModule } from '@angular/common'; +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { array } from '@storybook/addon-knobs'; +import { Observable } from 'rxjs'; +import { UiTopicDialogSelectionResult } from './topic-dialog.component'; +import { UiTopicDialogModule } from './topic-dialog.module'; +import { UiTopicDialogService } from './topic-dialog.service'; + +// noinspection AngularMissingOrInvalidDeclarationInModule +@Component({ + template: ` + + +
Selected topic: {{ results$ | async | json }}
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +class TopicDialogTestComponent implements OnInit { + @Input() topics: string[]; + + results$: Observable; + + constructor(private readonly dialogService: UiTopicDialogService) {} + + ngOnInit(): void { + this.onOpenClick(); + } + + onOpenClick(): void { + const dialogRef = this.dialogService.open(this.topics); + + this.results$ = dialogRef.afterClosed(); + } +} + +export default { + title: 'UiTopicDialogComponent', +}; + +export const primary = () => ({ + moduleMetadata: { + declarations: [TopicDialogTestComponent], + imports: [CommonModule, UiTopicDialogModule], + }, + component: TopicDialogTestComponent, + props: { + topics: array('topics', ['topic-1', 'topic-2']), + }, +}); diff --git a/libs/ui/src/lib/topic-dialog/topic-dialog.component.ts b/libs/ui/src/lib/topic-dialog/topic-dialog.component.ts new file mode 100644 index 00000000..23e65efa --- /dev/null +++ b/libs/ui/src/lib/topic-dialog/topic-dialog.component.ts @@ -0,0 +1,95 @@ +import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { FormBuilder, Validators } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +export interface UiTopicDialogSelectionResult { + isNewTopic: boolean; + topicName: string; +} + +@Component({ + template: ` +
+

+ + Topic selection + + open_with + +

+ +
+
+ + + + + + + + + + + + + {{ topic }} + + +
+
+ +
+ + +
+
+ `, + styleUrls: ['./topic-dialog.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class UiTopicDialogComponent { + topicFrom = this.fb.group({ + topicName: ['', Validators.required], + }); + + isNewTopic = true; + + constructor( + private readonly dialogRef: MatDialogRef, + private readonly fb: FormBuilder, + @Inject(MAT_DIALOG_DATA) public topics: string[], + ) {} + + onCancelClick(): void { + this.dialogRef.close(); + } + + onOkClick(): void { + const topicNameControl = this.topicFrom.get('topicName'); + + if (topicNameControl) { + this.dialogRef.close({ topicName: topicNameControl.value, isNewTopic: this.isNewTopic }); + } + } +} diff --git a/libs/ui/src/lib/topic-dialog/topic-dialog.module.ts b/libs/ui/src/lib/topic-dialog/topic-dialog.module.ts new file mode 100644 index 00000000..2c62d3e2 --- /dev/null +++ b/libs/ui/src/lib/topic-dialog/topic-dialog.module.ts @@ -0,0 +1,34 @@ +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { UiTopicDialogComponent } from './topic-dialog.component'; +import { UiTopicDialogService } from './topic-dialog.service'; + +@NgModule({ + declarations: [UiTopicDialogComponent], + imports: [ + BrowserAnimationsModule, + CommonModule, + DragDropModule, + MatButtonModule, + MatCheckboxModule, + MatDialogModule, + MatIconModule, + MatInputModule, + MatRadioModule, + MatToolbarModule, + ReactiveFormsModule, + ], + providers: [UiTopicDialogService], + entryComponents: [UiTopicDialogComponent], +}) +export class UiTopicDialogModule {} diff --git a/libs/ui/src/lib/topic-dialog/topic-dialog.service.ts b/libs/ui/src/lib/topic-dialog/topic-dialog.service.ts new file mode 100644 index 00000000..013fdaf8 --- /dev/null +++ b/libs/ui/src/lib/topic-dialog/topic-dialog.service.ts @@ -0,0 +1,22 @@ +import { Injectable } from '@angular/core'; +import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { UiTopicDialogComponent, UiTopicDialogSelectionResult } from './topic-dialog.component'; + +@Injectable() +export class UiTopicDialogService { + constructor(public dialog: MatDialog) {} + + open(topics: string[]): MatDialogRef { + const dialogRef = this.dialog.open< + UiTopicDialogComponent, + string[], + UiTopicDialogSelectionResult + >(UiTopicDialogComponent, { + autoFocus: false, + data: topics, + width: '350px', + }); + + return dialogRef; + } +} diff --git a/nx.json b/nx.json index 32ba7452..1ef2bf6d 100644 --- a/nx.json +++ b/nx.json @@ -34,6 +34,12 @@ }, "model": { "tags": ["scope:libs"] + }, + "kafka-proxy": { + "tags": ["scope:backend"] + }, + "shared": { + "tags": ["scope:libs"] } } } diff --git a/package.json b/package.json index 0d49eb72..3c2a1bcc 100644 --- a/package.json +++ b/package.json @@ -18,11 +18,13 @@ "format:check": "nx format:check", "format:write": "nx format:write", "help": "nx help", + "kafka": "sudo docker-compose --file ./apps/kafka/docker-compose.yml up", + "kafka:ps": "sudo docker-compose --file ./apps/kafka/docker-compose.yml ps", "lint": "nx workspace-lint && ng lint && yarn lint:styles", "lint:styles": "stylelint \"{apps,libs}/**/*.{css,scss}\"", "ng": "ng", "nx": "nx", - "postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points", + "postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points --async=false", "prettier:check": "yarn prettier --check --config ./.prettierrc --ignore-path ./.prettierignore '{*,\\.circleci,apps,libs}/**/*.{ts,scss,json,html,yml}'", "start": "ng serve", "test": "ng test", @@ -33,51 +35,65 @@ }, "private": true, "dependencies": { - "@angular/animations": "9.0.1", - "@angular/cdk": "9.0.0", - "@angular/common": "9.0.1", - "@angular/compiler": "9.0.1", - "@angular/core": "9.0.1", - "@angular/forms": "9.0.1", - "@angular/material": "9.0.0", - "@angular/platform-browser": "9.0.1", - "@angular/platform-browser-dynamic": "9.0.1", - "@angular/router": "9.0.1", - "@babylonjs/core": "4.1.0-beta.24", - "@babylonjs/materials": "4.1.0-beta.24", + "@angular/animations": "9.0.5", + "@angular/cdk": "9.1.1", + "@angular/common": "9.0.5", + "@angular/compiler": "9.0.5", + "@angular/core": "9.0.5", + "@angular/forms": "9.0.5", + "@angular/material": "9.1.1", + "@angular/platform-browser": "9.0.5", + "@angular/platform-browser-dynamic": "9.0.5", + "@angular/router": "9.0.5", + "@babylonjs/core": "4.1.0", + "@babylonjs/materials": "4.1.0", + "@nestjs/common": "6.11.11", + "@nestjs/core": "6.11.11", + "@nestjs/platform-express": "6.11.11", + "@nestjs/platform-socket.io": "6.11.11", + "@nestjs/websockets": "6.11.11", "@ngrx/effects": "8.6.0", "@ngrx/store": "8.6.0", - "@nrwl/angular": "9.0.0", + "@nrwl/angular": "9.0.4", + "kafkajs": "1.12.0", "mnemonist": "0.32.0", + "reflect-metadata": "0.1.13", "rxjs": "6.5.4", - "tslib": "1.10.0", + "socket.io": "2.3.0", + "socket.io-client": "2.3.0", + "tslib": "1.11.1", "zone.js": "0.10.2" }, "devDependencies": { - "@angular-devkit/build-angular": "0.900.2", - "@angular/cli": "9.0.2", - "@angular/compiler-cli": "9.0.1", - "@angular/language-service": "9.0.1", - "@babel/core": "7.8.4", - "@babylonjs/inspector": "4.1.0-beta.24", - "@nrwl/cypress": "9.0.0", - "@nrwl/eslint-plugin-nx": "9.0.0", - "@nrwl/jest": "9.0.0", - "@nrwl/node": "9.0.0", - "@nrwl/storybook": "9.0.0", - "@nrwl/workspace": "9.0.0", - "@storybook/addon-knobs": "5.3.13", - "@storybook/angular": "5.3.13", + "@angular-devkit/build-angular": "0.900.5", + "@angular/cli": "9.0.5", + "@angular/compiler-cli": "9.0.5", + "@angular/language-service": "9.0.5", + "@babel/core": "7.8.7", + "@babylonjs/inspector": "4.1.0", + "@nestjs/schematics": "6.9.4", + "@nestjs/testing": "6.11.11", + "@nrwl/cypress": "9.0.4", + "@nrwl/eslint-plugin-nx": "9.0.4", + "@nrwl/jest": "9.0.4", + "@nrwl/nest": "9.0.4", + "@nrwl/node": "9.0.4", + "@nrwl/storybook": "9.0.4", + "@nrwl/workspace": "9.0.4", + "@storybook/addon-knobs": "5.3.14", + "@storybook/angular": "5.3.14", "@types/benchmark": "1.0.31", "@types/jest": "24.9.0", - "@types/node": "13.7.1", - "@typescript-eslint/eslint-plugin": "2.19.2", - "@typescript-eslint/parser": "2.19.2", + "@types/node": "13.7.7", + "@types/socket.io": "2.1.4", + "@types/socket.io-client": "1.4.32", + "@typescript-eslint/eslint-plugin": "2.22.0", + "@typescript-eslint/parser": "2.22.0", "babel-loader": "8.0.6", - "babylonjs": "4.1.0-beta.24", + "babylonjs": "4.1.0", "benchmark": "2.1.4", "codelyzer": "5.2.1", - "cypress": "4.0.1", + "cypress": "4.1.0", "dotenv": "8.2.0", "eslint": "6.8.0", "eslint-config-prettier": "6.10.0", diff --git a/tsconfig.json b/tsconfig.json index 72d52e89..fa67863d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,7 +13,8 @@ "paths": { "@talus/model": ["libs/model/src/index.ts"], "@talus/ui": ["libs/ui/src/index.ts"], - "@talus/vdb": ["libs/vdb/src/index.ts"] + "@talus/vdb": ["libs/vdb/src/index.ts"], + "@talus/shared": ["libs/shared/src/index.ts"] }, "rootDir": ".", "skipDefaultLibCheck": true, diff --git a/tslint.json b/tslint.json index ec16bdeb..51160f2b 100644 --- a/tslint.json +++ b/tslint.json @@ -67,6 +67,10 @@ "sourceTag": "scope:frontend", "onlyDependOnLibsWithTags": ["scope:libs", "scope:frontend"] }, + { + "sourceTag": "scope:backend", + "onlyDependOnLibsWithTags": ["scope:libs", "scope:backend"] + }, { "sourceTag": "scope:benchmark", "onlyDependOnLibsWithTags": ["scope:libs", "scope:benchmark"] diff --git a/yarn.lock b/yarn.lock index aed7bbb3..b08cd7b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,35 +2,35 @@ # yarn lockfile v1 -"@angular-devkit/architect@0.900.1": - version "0.900.1" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.1.tgz#60a39a388d1af24b64f01c16d852777e955d76da" - integrity sha512-zzB3J0fXFoYeJpgF5tsmZ7byygzjJn1IPiXBdnbNqcMbil1OPOhq+KdD4ZFPyXNwBQ3w02kOwPdNqB++jbPmlQ== +"@angular-devkit/architect@0.900.4", "@angular-devkit/architect@~0.900.1": + version "0.900.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.4.tgz#6daf95b9c2ec51c38ca451c3ff7cf64e5404a04a" + integrity sha512-qbD7q+5lKgxpA+hGPfBLQRZukNO1Ok4YePevi7xt6pdfNatIqjxqYch7w/Ce0GvrOeimzSR1yC7STV5gjdoL3A== dependencies: - "@angular-devkit/core" "9.0.1" + "@angular-devkit/core" "9.0.4" rxjs "6.5.3" -"@angular-devkit/architect@0.900.2": - version "0.900.2" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.2.tgz#54fa9a8d8ec3765fa2efbf28243309d07d22b842" - integrity sha512-uClqp4QEY/m6CB7SsNZGdVNTEgMzkI1Fkt0TOdE9huN1iCi/0+h3nQb+NZ1vBqD2afg9EqDwIPu2KCU0p1BR2A== +"@angular-devkit/architect@0.900.5": + version "0.900.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.5.tgz#c6de20d512cb4dbc1179ec236d310b5d6314164b" + integrity sha512-4du29cYI5awsZ34xoS9WWSbEv7HazIlsQWaee/fRdvv4WmyB1w6geLMLHveGT2cYL/lhxsMUdYyDMa6sXcYeFA== dependencies: - "@angular-devkit/core" "9.0.2" + "@angular-devkit/core" "9.0.5" rxjs "6.5.3" -"@angular-devkit/build-angular@0.900.2": - version "0.900.2" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.2.tgz#c95fb341631458b573ec3b7e254b81fda8eea715" - integrity sha512-w1FHd+Ub0YO1/Xlz+SrSxbFWbJVW0jmR++fABWreh04XHGtC8kqsqP6VY8DUYBO9PcD5JyB5uG9TBxVLVR/G/w== +"@angular-devkit/build-angular@0.900.5": + version "0.900.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-0.900.5.tgz#7285fb7ec0186b7813d4368988620715f07d0832" + integrity sha512-WCfmQNTzQNgdh8baeNJm5uIhXbWp62e+upsZzh6eJ1ZrIeJSPJxE5mI1VvqBoAQH3hKjuAaAW3axpWGar4kJjw== dependencies: - "@angular-devkit/architect" "0.900.2" - "@angular-devkit/build-optimizer" "0.900.2" - "@angular-devkit/build-webpack" "0.900.2" - "@angular-devkit/core" "9.0.2" + "@angular-devkit/architect" "0.900.5" + "@angular-devkit/build-optimizer" "0.900.5" + "@angular-devkit/build-webpack" "0.900.5" + "@angular-devkit/core" "9.0.5" "@babel/core" "7.7.7" "@babel/generator" "7.7.7" "@babel/preset-env" "7.7.7" - "@ngtools/webpack" "9.0.2" + "@ngtools/webpack" "9.0.5" ajv "6.10.2" autoprefixer "9.7.1" babel-loader "8.0.6" @@ -39,7 +39,7 @@ caniuse-lite "1.0.30001020" circular-dependency-plugin "5.2.0" copy-webpack-plugin "5.1.1" - core-js "3.6.0" + core-js "3.6.4" coverage-istanbul-loader "2.0.3" cssnano "4.1.10" file-loader "4.2.0" @@ -85,10 +85,10 @@ webpack-subresource-integrity "1.3.4" worker-plugin "3.2.0" -"@angular-devkit/build-optimizer@0.900.2": - version "0.900.2" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.2.tgz#661aaca89f9ae6dbfc2256ab4822f08370bf5a15" - integrity sha512-4jcjYKjGvUj1Q4vqQSUU0JT1LXOh7qC7vWCK+bbAsW77wAavtbKFt2mDjB2DMIRFzt9lSULi0Z+JVOD9KUzk2g== +"@angular-devkit/build-optimizer@0.900.5": + version "0.900.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.900.5.tgz#7b105b7389d2f2cba7829b4816ea8a3cfda9c0e8" + integrity sha512-BdmvD58DnAAf6/o/fRzU2l+2g4IwuIJf8x/rd9AGWd7fHrcwgJDhB9rYetB7JqYR8uOWk+AFElDpvNOj8YUy0w== dependencies: loader-utils "1.2.3" source-map "0.7.3" @@ -96,28 +96,39 @@ typescript "3.6.4" webpack-sources "1.4.3" -"@angular-devkit/build-webpack@0.900.1": - version "0.900.1" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.1.tgz#1b90c9c87ec26fa8b471ecc17175c5bc5f6c74a4" - integrity sha512-GwV+jht42S2XZZbvy07mXqZ5us9ppbIi/gCL5SiUh+xtSdZGbfE6RoFZXmeOuxBn9FY0vUMTFtKCK5Mx8O3WYg== +"@angular-devkit/build-webpack@0.900.5": + version "0.900.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.5.tgz#bd8e2fecfb3b8ca119b8c152d5f459475ffdcd15" + integrity sha512-4fYZNg8X73wTjlXV37m0BRVMa27GSwhAupgv5cb9Q3Vys9sYxEUL+GJetXDxypA5YbMj5xX/xqyU9TPtvXhgRg== dependencies: - "@angular-devkit/architect" "0.900.1" - "@angular-devkit/core" "9.0.1" + "@angular-devkit/architect" "0.900.5" + "@angular-devkit/core" "9.0.5" rxjs "6.5.3" -"@angular-devkit/build-webpack@0.900.2": - version "0.900.2" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.2.tgz#25b2fd2e472486d25b69b1c608fd25d884127759" - integrity sha512-DiHUSO352NV9OcXB8cZY8gLijrUg0SIbPwrKUTjx1prZMJKa+MqWDpwhleVsM1VRyUH3qMTzhaUFmw+hqdR0BQ== +"@angular-devkit/build-webpack@~0.900.1": + version "0.900.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.900.4.tgz#af99221fe4f50e8326978caae67312f46557a897" + integrity sha512-eGWK7jl1XC6OW2LRmUoX/6yqYT6N2dF1BuBrymwRx9I3BzWr64YyDIy5m3GomQVrSWpQ1uDSCpuPX2xWlwpeLw== dependencies: - "@angular-devkit/architect" "0.900.2" - "@angular-devkit/core" "9.0.2" + "@angular-devkit/architect" "0.900.4" + "@angular-devkit/core" "9.0.4" rxjs "6.5.3" -"@angular-devkit/core@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.1.tgz#ef107b0e9eee1a28924cdf92108cdd5ab8df9b69" - integrity sha512-HboJI/x+SJD9clSOAMjHRv0eXAGRAdEaqJGmjDfdFMP2wznfsBiC6cgcHC17oM4jRWFhmWMR8Omc7CjLZJawJg== +"@angular-devkit/core@7.3.8": + version "7.3.8" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-7.3.8.tgz#702b0944a69c71cce3a1492e0d62de18df22a993" + integrity sha512-3X9uzaZXFpm5o2TSzhD6wEOtVU32CgeytKjD1Scxj+uMMVo48SWLlKiFh312T+smI9ko7tOT8VqxglwYkWosgg== + dependencies: + ajv "6.9.1" + chokidar "2.0.4" + fast-json-stable-stringify "2.0.0" + rxjs "6.3.3" + source-map "0.7.3" + +"@angular-devkit/core@9.0.4", "@angular-devkit/core@~9.0.1": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.4.tgz#e137052eea491f3bc0d50a2571c4449c620c2f80" + integrity sha512-7+/vDm+zh7wTJbBeSdTHGhE+TQj6JOriCPl8Pj8HZU1TtNLvIFR4vhClWavPvhb8xWSbndalvQyOWOsLmuDnEA== dependencies: ajv "6.10.2" fast-json-stable-stringify "2.0.0" @@ -125,10 +136,10 @@ rxjs "6.5.3" source-map "0.7.3" -"@angular-devkit/core@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.2.tgz#5febb2810531834ebfe4b52ea0db7144d30ea9e3" - integrity sha512-lEmfYs7+oHmXEQ3y97QGm73zs7i6chpx+ZSaBUvMM9oCKj/lytcn+diVG+t4hMavH6TK0lai7DO1rAbYkbmdrA== +"@angular-devkit/core@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.5.tgz#4ac28d94af02a24e84165a36142efc0e8a88f76f" + integrity sha512-9TPQPzfSRbV5wVEnfo1d1CS+oVXROfE7VnBRuRMilFnNhuc29wX3zvBQRTreDVyxJetLBEb9sRlcKYGaJzpKPw== dependencies: ajv "6.10.2" fast-json-stable-stringify "2.0.0" @@ -136,51 +147,54 @@ rxjs "6.5.3" source-map "0.7.3" -"@angular-devkit/schematics@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.1.tgz#a27a2ba2b5fec92b33564bc5078c5f13c969931a" - integrity sha512-Cuub9eJm1TWygKTOowRbxMASA8QWeHWzNEU2V3TqUF1Tqy/iPf4cpuMijkFysXjTn2bi2HA9t26AwQkwymbliA== +"@angular-devkit/schematics@7.3.8": + version "7.3.8" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-7.3.8.tgz#70bfc7876f7924ff53ab9310a00b62f20acf2f5c" + integrity sha512-mvaKoORZIaW/h0VNZ3IQWP0qThRCZRX6869FNlzV0jlW0mhn07XbiIGHCGGSCDRxS7qJ0VbuIVnKXntF+iDeWw== + dependencies: + "@angular-devkit/core" "7.3.8" + rxjs "6.3.3" + +"@angular-devkit/schematics@9.0.4", "@angular-devkit/schematics@~9.0.1": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.4.tgz#fc20fe40a575ee72ed6bee90608dbd0d0579f135" + integrity sha512-D6M77r8J/rrK86RQ1kvumSYAnlbOKxDDcwsac4mPAHYyOOmueheecjpTVTqSVpNjkI6jHb6haOVFEGMiDMA/Jg== dependencies: - "@angular-devkit/core" "9.0.1" + "@angular-devkit/core" "9.0.4" ora "4.0.2" rxjs "6.5.3" -"@angular-devkit/schematics@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.2.tgz#4df0e4ccfcd4beb444af0fb5d9411c826f0b3778" - integrity sha512-+MiSBWErz8hxcbyHioCQtTnFpbqaoCEQEknK0vCb15fFEY2Hi3u2TXK59QNKsqn8w+Mye5dHYhwmpsAC8Wcgtw== +"@angular-devkit/schematics@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.5.tgz#fd2b8d94de3e037e75c5221d4283fb57221d39db" + integrity sha512-PbOYoy4YyEbR6f1jO18Rt3fJuyaaTJ3bFmws5qWGGNK2yZiP/hnSaM3VffOwoL4sgyKkI2FNKSPiQZgTl8b0Tg== dependencies: - "@angular-devkit/core" "9.0.2" + "@angular-devkit/core" "9.0.5" ora "4.0.2" rxjs "6.5.3" -"@angular-eslint/builder@0.0.1-alpha.18": - version "0.0.1-alpha.18" - resolved "https://registry.yarnpkg.com/@angular-eslint/builder/-/builder-0.0.1-alpha.18.tgz#3a3ac2d93782ce24a99457df93b4755912cca8a9" - integrity sha512-xDipFDGxtY0Hjy2ua2BwsuxFKdC9eZBdXr+HXXXvbLCGn9DTHT5RbPinZJ4bMPJz4QE6yIrg6EhoB4CWHLZvhw== - -"@angular/animations@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.0.1.tgz#7daaaab1ab518fe90689672f4845281a2c002492" - integrity sha512-R0FLhAfylFIiRArhtLOUokOAVtWCH20ocRXo6E8HHOc3fbaUS9ci3rIbFZQkaAv9RgZfKewrcV6Wa3TY905w5g== +"@angular/animations@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-9.0.5.tgz#ac64c9f702e78d5e2d6bff645daf047c4865cc02" + integrity sha512-WGs4Jxw5sr8GCpxMcwEVuZnDIkdNp9qtmuI2j13v/XAaMjvJ7jssCj9+JG5uI8joCi7PFVAWokPT1DdPwWb13Q== -"@angular/cdk@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-9.0.0.tgz#5734817ae97044f90d304fa0f25c9c1a7fa0bf96" - integrity sha512-2kYpyYbewIB6fubSIDMvSprJLNplRZoL/AtXW3od4dLyRxtzX+7iWTAtzUG/dhq8CKev0lpd1HENh5lLR/Lhjw== +"@angular/cdk@9.1.1": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-9.1.1.tgz#343901c5d6c0d6c502ccbd075cb9e17ea3bc05f5" + integrity sha512-yzssAqbllGYgX+WeSYLjmEWtXVG5UPZwA0+dPlh+g85nG7b70DVRVYBi8PJySydsfPX/JMherFUU9h0QOWhhZw== optionalDependencies: parse5 "^5.0.0" -"@angular/cli@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.2.tgz#ae5a8d8f29a5e629bc4f262e6284a54f4d55bd2f" - integrity sha512-ih3bnvav94MXI9YpwJ4AaETfUGwzc+S2jg4vkfYMuBeWO8kJ7Ma4f2ZriIwWyfHWHlBLHDF6OjAVdisBKPpQag== - dependencies: - "@angular-devkit/architect" "0.900.2" - "@angular-devkit/core" "9.0.2" - "@angular-devkit/schematics" "9.0.2" - "@schematics/angular" "9.0.2" - "@schematics/update" "0.900.2" +"@angular/cli@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-9.0.5.tgz#ba3dc3051f1aa8884f037c7246256439ee2fe814" + integrity sha512-hRGpmIwnm908eW5sA4zrVkCGaIUHYLSNu5koaLulK0jj5Iy+vkieDiBuAkD2uVvG7M59s4s4u+L0DMetIpvZQg== + dependencies: + "@angular-devkit/architect" "0.900.5" + "@angular-devkit/core" "9.0.5" + "@angular-devkit/schematics" "9.0.5" + "@schematics/angular" "9.0.5" + "@schematics/update" "0.900.5" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.1" debug "^4.1.1" @@ -197,15 +211,15 @@ universal-analytics "^0.4.20" uuid "^3.3.2" -"@angular/common@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.0.1.tgz#78457633a447c49bcc0e0bd8049cc2adbb016484" - integrity sha512-40jbKdCb4xi6NTzLt1kE0V/X7JxCLLo8eUEr3Z34Z9Ljnd4LC+/CkuThPdQJ3HW1Z8r5SWXj+rES+sn75YNVmA== +"@angular/common@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-9.0.5.tgz#80e5ebbd5ec9b7f33bace0d6f70267b07cba9090" + integrity sha512-AwZKYK5M/3762woK+3290JnBdlBvZXqxX5vVze6wk23IiBlwIV+l79+Lyfjo/4s031kibq47taaZdC7qkkBkNA== -"@angular/compiler-cli@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.0.1.tgz#e96ab3a117ada255a9388343992dc7de6061a355" - integrity sha512-HxJAXr1TWoqVzR7pRe89UjWnu3ESJzo+gjWWtv1NtDMwUKQ2JHWmC3yp/U0URprA03Ii8lXlrZWBjps04ZIlAg== +"@angular/compiler-cli@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-9.0.5.tgz#b7b7dba46a9495e2ca7efd412f6555e2544fc59d" + integrity sha512-lFlasm8UBApTq4/MkxnYrRAMfpOvvg3YYBEMibuEGlaJjW/Xd1JcisUuFiooCxCIKF5phyORHmxjywGPhHqQgQ== dependencies: canonical-path "1.0.0" chokidar "^3.0.0" @@ -217,47 +231,48 @@ reflect-metadata "^0.1.2" semver "^6.3.0" source-map "^0.6.1" + sourcemap-codec "^1.4.8" yargs "13.1.0" -"@angular/compiler@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.1.tgz#19b6f83026a2b2771b7ef1b9be20bbe8828d8be9" - integrity sha512-ldamsPzIx+FLT/IYBqwsFL6qbP3BDgvPQa4Y3F/gFXDsoe+VTY5qwJfhr2iLbtF+fYomwOgY2kSL42BVQL873Q== - -"@angular/core@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.0.1.tgz#8908112ce6bb22aa1ae537230240ef9a324409ad" - integrity sha512-q/3VLGM98euB/ZluSuMqvWyQb563iabRcVkC/DrHqCQMadV1ZpvuOgf8Gm092d8GY/iC4CGlTsN0wiVapMxplQ== - -"@angular/forms@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.0.1.tgz#e95daa336ea93c6236fdc8863d01eaabc4070004" - integrity sha512-yzzlCslWp7IiFSYjSGNqexPmnKn9xhpT8FKzxNT0qEpQ+SieQ7apsjvMfR3TCip0Nnfus2qTh3kz1ZCaawAcjQ== - -"@angular/language-service@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-9.0.1.tgz#297f5f43ce5e843559a44ab81a89d42c0682b566" - integrity sha512-e/8CGATX7C0ElwBk6QjCfWk7A6lwikrBR1cesNu1kNwneZkiIeIel1jklbDUT0NFr4C2/FdBu2Z3GbvDeCO8Vw== - -"@angular/material@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-9.0.0.tgz#655bfd4d4047337e84480b9f92be8e81af375b92" - integrity sha512-QxN2rmR5mvg2YE1NoIGWLpbnmcJq0iFidzy6odzvN17+XkoCJBZ65IdYsHrJgfwGpoIy6bywuixrDHHcSh9I5w== - -"@angular/platform-browser-dynamic@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.0.1.tgz#43d6679863775d4f463a67b96a83c3a619854336" - integrity sha512-DslT339T+TBt4jUlXMblPR4IghXtykB+jQctm02G4AJUlvMa4b798N1oM6sD5F8NmBMa6beZ2dcRJ07f75LVBA== - -"@angular/platform-browser@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.0.1.tgz#292306095c0e4b89927ba1b94eb1714cdbdfcb65" - integrity sha512-0o2aRxbQ3xZ/ZeLXajDqhrRK6vcICzdJ7GKvPgZxdohnnJ7JN1qp8U7J4aEotPqfSAde/aD2JvoDDtKZ0XIDWg== - -"@angular/router@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.0.1.tgz#bc6acddf094361a7ef14aab0c94d7248d10f2949" - integrity sha512-pHLDooNvXEUtjYANWtJ7fMxG9l2mDJgPphOi/S6c27U5yNf0NVk+Qh3kuuNi2hQQ5RaR4jdRyCQePD2H4g2+/g== +"@angular/compiler@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.5.tgz#823dd4df25a9f1a641346712e7b7097ed1176105" + integrity sha512-TeyhRGefTOtA9N3udMrvheafoXcz/dvTTdZLcieeZQxm1SSeaQDUQ/rUH6QTOiHVNMtjOCrZ9J5rk1A4mPYuag== + +"@angular/core@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.0.5.tgz#71df41a45e60619fb7454ab9fe604d6ce7d0d8da" + integrity sha512-7VznrYjaAIzeq/zQ7v6tbeoOI7JJKgChKwG7s8jRoEpENu+w2pRlRdyQul88iJLsXgObR+/TfBNm/K+G4cqAFw== + +"@angular/forms@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-9.0.5.tgz#3bc96364754a50e03595873045b72ab886ee0748" + integrity sha512-579PXAfT92J4mghjWKiZ3Zj3xee4h3RP70YHSlsfbi94MONvryWDrnXxvUZ0zJJCVnEJQ7x+nGEp3wwWqR12Jw== + +"@angular/language-service@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-9.0.5.tgz#c663aef7f9bba0b395379e33f667bae25af4787b" + integrity sha512-9ykFNYZpWdoggFPK3LuTJobBZjoCEQP6kKt88ZZV7GTMIXoE7iY413KfhINoXdMwxIAbba0xlPMR/4p6jFAa4Q== + +"@angular/material@9.1.1": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-9.1.1.tgz#aabd148afac694dcb718ed190c0ac44042c92b56" + integrity sha512-XtfVTTzvLvw90g1sG8mV0kzkfnp2g7I/kUgwng7Zv3NG1Tzt/wEXVe6ovI45B/8qpN6i/7f2aCl7Gz4KTldAyA== + +"@angular/platform-browser-dynamic@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.0.5.tgz#df569a99d9d077733e53d3323e9f88f410f5f3df" + integrity sha512-NRfsAwbgxOvEcpqlERDAG0wap5xJa0wKwnudTCnyvf4B0D6kLkT1Idjqv22NDW5rfM2oDWaZ/qpgpDnAo6/ZBQ== + +"@angular/platform-browser@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-9.0.5.tgz#a760fa7d5921d7b58875b07dfe0a408c92abf143" + integrity sha512-24QGcQXthYXB/wT8okJjxqss/JOk4A6O1/Fmva79k0AvwtYkl2tikcyEc5T3xZtjoi8g32AN9nbZAobtkxlqTA== + +"@angular/router@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-9.0.5.tgz#97f23adc933e96ba04c0ef93b3a8f0c2e7777e77" + integrity sha512-Sz3DQUxlzAk9aZ9eVtZRh6xF5SMg/Gb3rc5I7dL1M+mycSNoFJ4HPTXleZkKM69mMkKQ5fEtza4x26MSlF+O9w== "@babel/code-frame@7.5.5", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": version "7.5.5" @@ -302,18 +317,18 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e" - integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA== +"@babel/core@7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.7.tgz#b69017d221ccdeb203145ae9da269d72cf102f3b" + integrity sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.4" + "@babel/generator" "^7.8.7" "@babel/helpers" "^7.8.4" - "@babel/parser" "^7.8.4" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/parser" "^7.8.7" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.7" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -405,6 +420,26 @@ lodash "^4.17.13" source-map "^0.5.0" +"@babel/generator@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.6.tgz#57adf96d370c9a63c241cd719f9111468578537a" + integrity sha512-4bpOR5ZBz+wWcMeVtcf7FbjcFzCp+817z2/gHNncIRcM9MmKzUhtWCYAq27RAfUrAFwb+OCG1s9WEaVxfi6cjg== + dependencies: + "@babel/types" "^7.8.6" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/generator@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.7.tgz#870b3cf7984f5297998152af625c4f3e341400f7" + integrity sha512-DQwjiKJqH4C3qGiyQCAExJHoZssn49JTMJgZ8SANGgVFdkupcUhLOdkAeoC6kmHZCPfoDG5M0b6cFlSN5wW7Ew== + dependencies: + "@babel/types" "^7.8.7" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -834,6 +869,16 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8" integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw== +"@babel/parser@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.6.tgz#ba5c9910cddb77685a008e3c587af8d27b67962c" + integrity sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g== + +"@babel/parser@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.7.tgz#7b8facf95d25fef9534aad51c4ffecde1a61e26a" + integrity sha512-9JWls8WilDXFGxs0phaXAZgpxTZhSk/yOYH2hTHC0X1yC7Z78IJfvR1vJ+rmJKq3I35td2XzXzN6ZLYlna+r/A== + "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" @@ -1787,6 +1832,15 @@ "@babel/parser" "^7.7.4" "@babel/types" "^7.7.4" +"@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" @@ -1847,6 +1901,21 @@ globals "^11.1.0" lodash "^4.17.13" +"@babel/traverse@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" + integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.8.6" + "@babel/helper-function-name" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + "@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a" @@ -1874,58 +1943,76 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babylonjs/core@4.1.0-beta.24": - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/@babylonjs/core/-/core-4.1.0-beta.24.tgz#e0e0971801de82b6473ad5354d1967fb21e1afa7" - integrity sha512-L9SMDWWQ7+y+XA1Y2rk5y79NADfHQSPAVp404WG8PL07OvGE6rryPaINb0/c/pc4BpJq9ZCO2yjCyR8fVyZfiQ== +"@babel/types@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.6.tgz#629ecc33c2557fcde7126e58053127afdb3e6d01" + integrity sha512-wqz7pgWMIrht3gquyEFPVXeXCti72Rm8ep9b5tQKz9Yg9LzJA3HxosF1SB3Kc81KD1A3XBkkVYtJvCKS2Z/QrA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@babel/types@^7.8.7": + version "7.8.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.7.tgz#1fc9729e1acbb2337d5b6977a63979b4819f5d1d" + integrity sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@babylonjs/core@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@babylonjs/core/-/core-4.1.0.tgz#63e390862debf81f8cf248496187029c42ea5eda" + integrity sha512-4pEKPEu14qRdqH5qatfmns/iHFHmujDI22SXkHIlJhTT0WgJH4I8IN1fPw9sU6jSCH2ul76Lpbi2zREvfrEDQA== dependencies: tslib "^1.10.0" -"@babylonjs/gui@4.1.0-beta.24": - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/@babylonjs/gui/-/gui-4.1.0-beta.24.tgz#ed118d8216edabe7e9d27de2df526b0129fe19a6" - integrity sha512-0p+znzVaogBqCg1pXXDXx48Xf/sisUrnn9KnrS9J01fIkP5dIQAuzBqCxl53diqK8xBfM+Sy0lLfe3uKVAIddA== +"@babylonjs/gui@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@babylonjs/gui/-/gui-4.1.0.tgz#b889251a6279fa3c05e97d3b225b7d4f2de180c5" + integrity sha512-H4+zkIMGQlqJ8r3KNlI1fY31v3AssauY7/IMXzl4GloXqmELE+A46h85q/fzY+0SPzXlD4lE0i3BqXkTIUKw+g== dependencies: - "@babylonjs/core" "4.1.0-beta.24" + "@babylonjs/core" "4.1.0" tslib "^1.10.0" -"@babylonjs/inspector@4.1.0-beta.24": - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/@babylonjs/inspector/-/inspector-4.1.0-beta.24.tgz#8cd581a1865b374d8219db31c87cb4195660d01a" - integrity sha512-P/85W40410r1UUmVWPTsOtg9UrJ1+bmd14TMoKRx5wnXEsuHmMflU9wlQbrc5xFyEoUakdy4PG36DIj7XUacLg== - dependencies: - "@babylonjs/core" "4.1.0-beta.24" - "@babylonjs/gui" "4.1.0-beta.24" - "@babylonjs/loaders" "4.1.0-beta.24" - "@babylonjs/materials" "4.1.0-beta.24" - "@babylonjs/serializers" "4.1.0-beta.24" - babylonjs-gltf2interface "4.1.0-beta.24" +"@babylonjs/inspector@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@babylonjs/inspector/-/inspector-4.1.0.tgz#05130ca1c4791baeaad1cc0e7c7676b8b07b04e2" + integrity sha512-LcNqPzRV0t7x/ubsgFzP0ByIbEcY1tmp+fEpgmuMtiD2hViU2/PQFwlTMwDVCjEN3HHa4Je72j95ItqS4cefpg== + dependencies: + "@babylonjs/core" "4.1.0" + "@babylonjs/gui" "4.1.0" + "@babylonjs/loaders" "4.1.0" + "@babylonjs/materials" "4.1.0" + "@babylonjs/serializers" "4.1.0" + babylonjs-gltf2interface "4.1.0" tslib "^1.10.0" -"@babylonjs/loaders@4.1.0-beta.24": - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/@babylonjs/loaders/-/loaders-4.1.0-beta.24.tgz#437e52f91e72d0c926beabf095a6875812b269e9" - integrity sha512-FPsxV2ENy6xJhmqh1sV2NHYiThzXrH08UXK2GfOppz4oEQeiT9na4GnlNSmAL9pSqKI7bI6GNwoxpA0kQJzYrg== +"@babylonjs/loaders@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@babylonjs/loaders/-/loaders-4.1.0.tgz#1b40f8c07b46228ae4cf6dbda2d0856293f4db80" + integrity sha512-stK/QygoNhdrJ9q8yNyZ7iE8Eu+dpwBviSoEigLX5IwHFJUmyxeI0LIZpjRAP2GRB96kqLrBsIBdWEwk076w/g== dependencies: - "@babylonjs/core" "4.1.0-beta.24" - babylonjs-gltf2interface "4.1.0-beta.24" + "@babylonjs/core" "4.1.0" + babylonjs-gltf2interface "4.1.0" tslib "^1.10.0" -"@babylonjs/materials@4.1.0-beta.24": - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/@babylonjs/materials/-/materials-4.1.0-beta.24.tgz#5c9e237432d97ecf46423d45280fc3d03283f8dc" - integrity sha512-WxbXgpompx/+1JgJbOdob1JUFu7h87/2SMMliTh7duUx4CKXMucR72ouVuQOad3Gb6TjtOlFz6OnFYJkNr0vBQ== +"@babylonjs/materials@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@babylonjs/materials/-/materials-4.1.0.tgz#238cc04fd1d70ad703e5e12a06db6df83d70a0ed" + integrity sha512-KIu3a3h9GfXIbYLhqTlB1vBMI4Wv17+FuGYZ7hxaW7QExQBYog4GaZF9I/TJEwyhXHhtV6L57LNTxh37YU3ciw== dependencies: - "@babylonjs/core" "4.1.0-beta.24" + "@babylonjs/core" "4.1.0" tslib "^1.10.0" -"@babylonjs/serializers@4.1.0-beta.24": - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/@babylonjs/serializers/-/serializers-4.1.0-beta.24.tgz#8c75851e5883b9c3b6cd0deee2c7f41d81d5c100" - integrity sha512-2eXCkDIDELXsGQuAc386VMmCxqz71CGcOTk6NbMcahk/ivoveaWaq1QqqoNUuBPjdIkrLzxJOu7+M+AU+/QvPQ== +"@babylonjs/serializers@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@babylonjs/serializers/-/serializers-4.1.0.tgz#296c5faa7ea952b17c6a09beef62ccb23ac79432" + integrity sha512-v+8IDxP5jJjMjwh/UHywMHnXzSxZ0UDhQ1TRDn3AFwqg/QLSOAEj7nl+TJwvobjllOooRclq6duKRUSIVmlgLg== dependencies: - "@babylonjs/core" "4.1.0-beta.24" - babylonjs-gltf2interface "4.1.0-beta.24" + "@babylonjs/core" "4.1.0" + babylonjs-gltf2interface "4.1.0" tslib "^1.10.0" "@cnakazawa/watch@^1.0.3": @@ -1946,13 +2033,13 @@ date-fns "^1.27.2" figures "^1.7.0" -"@cypress/webpack-preprocessor@~4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@cypress/webpack-preprocessor/-/webpack-preprocessor-4.1.0.tgz#8c4debc0b1abf045b62524d1996dd9aeaf7e86a8" - integrity sha512-LbxsdYVpHGoC2fMOdW0aQvuvVRD7aZx8p8DrP53HISpl7bD1PqLGWKzhHn7cGG24UHycBJrbaEeKEosW29W1dg== +"@cypress/webpack-preprocessor@~4.1.2": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@cypress/webpack-preprocessor/-/webpack-preprocessor-4.1.3.tgz#d5fad767a304c16ec05ca08034827c601f1c9c0c" + integrity sha512-VtTzStrKtwyftLkcgopwCHzgjefK3uHHL6FgbAQP1o5N1pa/zYUb0g7hH2skrMAlKOmLGdbySlISkUl18Y3wHg== dependencies: - bluebird "3.5.0" - debug "3.1.0" + bluebird "3.7.1" + debug "4.1.1" optionalDependencies: "@babel/core" "^7.0.1" "@babel/preset-env" "^7.0.0" @@ -2234,6 +2321,73 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" +"@nestjs/common@6.11.11": + version "6.11.11" + resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-6.11.11.tgz#701da2462a15cc94d55ec863ddd9f2fb0bbd7136" + integrity sha512-K4wuK/V2M82AsoudtY0UYV+M1nYDSSb10t8AkMwFiP+AWMuxCJNtE8qLc9jUe2aTKMbhBiQUfsbZFmg/MRinPg== + dependencies: + axios "0.19.2" + cli-color "2.0.0" + tslib "1.11.1" + uuid "7.0.1" + +"@nestjs/core@6.11.11": + version "6.11.11" + resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-6.11.11.tgz#2b97a3e9c2a853f5693ed84daf81c1ee3b2782b4" + integrity sha512-ewUy2rjiRWi6SziI5gXZnlat7PfnVklL3tusnU1qqtUm74cPY1Zre+zDCJ27P/+B7sFJHbkFfpi0qQP2pQv9jQ== + dependencies: + "@nuxtjs/opencollective" "0.2.2" + fast-safe-stringify "2.0.7" + iterare "1.2.0" + object-hash "2.0.3" + path-to-regexp "3.2.0" + tslib "1.11.1" + uuid "7.0.1" + +"@nestjs/platform-express@6.11.11": + version "6.11.11" + resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-6.11.11.tgz#d30ea1f39299e92e080553e893a0afac54f20c6e" + integrity sha512-4h3F3hDhNlO5+Ruy6eS+lSL2yIz5r4hF/BB3QkZVOuRdfji9n0gZAIR7tuSLTizqYxaHYRZ7dBv+PscQS/7ztQ== + dependencies: + body-parser "1.19.0" + cors "2.8.5" + express "4.17.1" + multer "1.4.2" + tslib "1.11.1" + +"@nestjs/platform-socket.io@6.11.11": + version "6.11.11" + resolved "https://registry.yarnpkg.com/@nestjs/platform-socket.io/-/platform-socket.io-6.11.11.tgz#e807cf0893fc4e8a383d861b54cf9d54d9a77e79" + integrity sha512-/WWMwLEoPv3aszWdVGv7ttmsK0gtQ01tvlwtFavC1SbqpNiNI0x0uJYzFD7RRwuyjo+Ab/H+//swknLEGuQbeg== + dependencies: + socket.io "2.3.0" + tslib "1.11.1" + +"@nestjs/schematics@6.9.4": + version "6.9.4" + resolved "https://registry.yarnpkg.com/@nestjs/schematics/-/schematics-6.9.4.tgz#4624c35da771fbb9a346cbd77aebd747d9348fd9" + integrity sha512-tZoLDboqXQT+DcWUFTJyDsOIg9Qt6ilXYWWbrbbEPCP2+UKjfsqZPsEnG31DOj0IbovFS5g+Mbn3IanVsEcIsQ== + dependencies: + "@angular-devkit/core" "7.3.8" + "@angular-devkit/schematics" "7.3.8" + fs-extra "8.1.0" + +"@nestjs/testing@6.11.11": + version "6.11.11" + resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-6.11.11.tgz#c9858e6516cccf923289919764ed9039376d9b3c" + integrity sha512-Mqu4IWZhnLdIFfVfueAFFCm3jPfQoWg+YmDLBsFS2kpab3az5gsRCZQv9R9CCHGa1hHKYWqM1lMcz1IQc70kww== + dependencies: + optional "0.1.4" + tslib "1.11.1" + +"@nestjs/websockets@6.11.11": + version "6.11.11" + resolved "https://registry.yarnpkg.com/@nestjs/websockets/-/websockets-6.11.11.tgz#61e886ad024b6e55d2147f20870670aea8daf5ae" + integrity sha512-maOV9KkQUiBWx7mWuLhbudM9svA3h8adRGN3z/LZ3vOZazYI97ZzrirsLw/9MeqZvaOaRnGbJpIo4p0lvtUztA== + dependencies: + iterare "1.2.0" + tslib "1.11.1" + "@ngrx/effects@8.6.0": version "8.6.0" resolved "https://registry.yarnpkg.com/@ngrx/effects/-/effects-8.6.0.tgz#a0d7339597a5128c5cf896ddcf93f73406a45860" @@ -2244,12 +2398,12 @@ resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-8.6.0.tgz#8540c5bd40b33fc2f443e7e86f47c0d801b8f413" integrity sha512-K4cvCEa+5hw9qrETQWO+Cha3YbVCAT8yaIKJr/N35KntTL9mQMjoL+51JWLZfBwPV0e19CFgJIyrBnVUTxwr2A== -"@ngtools/webpack@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.2.tgz#5f2d79f612dec21d471ca862889d3c4a80e0cb4a" - integrity sha512-RR18eMe4/k7y3KZ5Y3GTVQNOnJ8Jbe0Xs0q8IMNcGqldbUR878MmIl9PCc6J79stE/7WiNFQtq1L68RQi3i9/A== +"@ngtools/webpack@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-9.0.5.tgz#efd6d40d87c685339b402bcc68eef9b0de95d2fa" + integrity sha512-xe0rGpme04MNRK/PpPOx8cza9k8F/XuAOmxC3Tk4dIgigqIzYsP6v6N/At8vPRDrf88X4ZyR94lL5RrUYf/KNQ== dependencies: - "@angular-devkit/core" "9.0.2" + "@angular-devkit/core" "9.0.5" enhanced-resolve "4.1.1" rxjs "6.5.3" webpack-sources "1.4.3" @@ -2280,77 +2434,85 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" -"@nrwl/angular@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-9.0.0.tgz#f63b007b78863eaeb4ac2c0629aa1f85fad01e92" - integrity sha512-XPWPcdzMsJ5svugKYMvshYmJ1JkQ7yZX2BhHqXXKnEnNok7EhKKLoKfQcMVfQOE9WchZhQhWIldljT4PXZg9Gw== +"@nrwl/angular@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-9.0.4.tgz#8a85057ea448258778a30aab31612342d3dbb21a" + integrity sha512-2kDYY2yhL04VRcH2TV/sB1xurnB2Jpp8UgbHCj/6Jd+3dd1v1r/J1PZv7K90/MHEFcOeGlSAk/vaHYkfF0K3VQ== dependencies: - "@angular-devkit/schematics" "9.0.1" - "@nrwl/cypress" "9.0.0" - "@nrwl/jest" "9.0.0" - "@schematics/angular" "9.0.1" + "@angular-devkit/schematics" "~9.0.1" + "@nrwl/cypress" "9.0.4" + "@nrwl/jest" "9.0.4" + "@schematics/angular" "~9.0.1" jasmine-marbles "~0.6.0" -"@nrwl/cli@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-9.0.0.tgz#2213e6fd9df1b243e5a289d6e47c2e0e30d2bcf0" - integrity sha512-rkQwWqA85h1Y3uHR5EI5zqkQfY7eX46wFs30K4RQ+HuyrHtJj4MUxqxsB/aWZks1WxpHyDvNWSE7TdCXemfdlg== +"@nrwl/cli@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-9.0.4.tgz#662b3be48bccfd43ecf707cf7ad61307803c79fd" + integrity sha512-cOg5s4XxCNalkYqMa/Q+e5SibJP9/ykY4rSz07fmpzETJPbMyMoS/FXj4kcyXr2Ox2jovfxkzIw6bjKTRwgbLw== dependencies: - "@nrwl/tao" "9.0.0" + "@nrwl/tao" "9.0.4" chalk "2.4.2" tmp "0.0.33" yargs "^11.0.0" yargs-parser "10.0.0" -"@nrwl/cypress@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-9.0.0.tgz#7388d0247f767dc59b3c118d32c53262b27b3ae7" - integrity sha512-zU2ljr/SyVQAC2OJYoigpMDbdNBtiS0V5rNpRMxJz6qIQCDq4DJc1t04mA4ZvD9tsUFxcaFoRkTm+OpopHgeOQ== +"@nrwl/cypress@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-9.0.4.tgz#30d48dc0428576dd25197edcccc2e96978f0259b" + integrity sha512-A6I9kp+vgxWYgm4smFOtA0iX7z3z5chFiPSN/xduWKzOg4B3Sg+QGKyvI0gad8PPBSgx8NTi+qTvvHDWE7lzWQ== dependencies: - "@angular-devkit/architect" "0.900.1" - "@angular-devkit/core" "9.0.1" - "@cypress/webpack-preprocessor" "~4.1.0" + "@angular-devkit/architect" "~0.900.1" + "@angular-devkit/core" "~9.0.1" + "@cypress/webpack-preprocessor" "~4.1.2" fork-ts-checker-webpack-plugin "^3.1.1" tree-kill "1.2.2" ts-loader "^5.3.1" tsconfig-paths-webpack-plugin "3.2.0" webpack-node-externals "1.7.2" -"@nrwl/eslint-plugin-nx@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-9.0.0.tgz#2ad4a0d181b27b5370a3d151d070d83eaee93e40" - integrity sha512-fI2u0OV/mYXLLpwKJqWZba9H81zcNaLT7mA9hBI5k3Tt0+KG4CBJGvd4Sa5tbJTFK7QQfCePM0hUWEquOsIuWQ== - dependencies: - "@typescript-eslint/experimental-utils" "^2.3.2" - -"@nrwl/jest@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-9.0.0.tgz#f266dbf78446bd343c77a9850e7be1f1c01ac5b7" - integrity sha512-FV6NpPE4Ii796/OwH4CIykXh+8C8+3etEeO6E699gwO7TSx9aDp/ZBDTb9GHiwS8IjTGbu1MicvcmS/SiJbclA== - dependencies: - "@angular-devkit/architect" "0.900.1" - "@angular-devkit/core" "9.0.1" - "@angular-devkit/schematics" "9.0.1" - -"@nrwl/linter@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/linter/-/linter-9.0.0.tgz#4e0e71444e18824a8e8312893d35118f44458516" - integrity sha512-BKg/h5tFe8wAD9Y/7G+opJl3jYPJF2i1dorCswqKtlGeXgdVJuREaP+mjFA3s+LuMzrpjZsyTneIcny4IfPRxA== - dependencies: - "@angular-devkit/architect" "0.900.1" - "@angular-eslint/builder" "0.0.1-alpha.18" - -"@nrwl/node@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-9.0.0.tgz#f9b1f88c8d9e57744ab55618d641301f91a26901" - integrity sha512-iBIkzIbwHLmtcXDl5UdLPWS6NI5Wp+JT2Nf89cFnZyccL7K7GJYms+1gWQbLUiCMZbREBCVbWO0Kw5tXJ1DZuw== - dependencies: - "@angular-devkit/architect" "0.900.1" - "@angular-devkit/build-webpack" "0.900.1" - "@angular-devkit/core" "9.0.1" - "@angular-devkit/schematics" "9.0.1" - "@nrwl/jest" "9.0.0" - "@nrwl/linter" "9.0.0" +"@nrwl/eslint-plugin-nx@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-9.0.4.tgz#967a97e52dc34562d1659e4a1c80a6fd875f8e1d" + integrity sha512-OaqYdm7uHhlYBftD1WUbR15Ncjoz+Fn/Ow+kQ7ToOMxDj4Q8ViVhlYoI8q4qlh6PjGjvTfqjgDwlOD/loXPRRg== + dependencies: + "@typescript-eslint/experimental-utils" "^2.19.2" + +"@nrwl/jest@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-9.0.4.tgz#ffc6b74902b6c270021d26ecd5086de077685107" + integrity sha512-LX0ugkFTvWvcgvUTTCo8QwzfAd5fTruNsxCTSYqGbILLxFPTQYehchZokvWGE2aooGh1QficCha99ecS6VrWKQ== + dependencies: + "@angular-devkit/architect" "~0.900.1" + "@angular-devkit/core" "~9.0.1" + "@angular-devkit/schematics" "~9.0.1" + +"@nrwl/linter@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/linter/-/linter-9.0.4.tgz#15d6c4b920d3a40971fc4bef57dd27577b96ab61" + integrity sha512-LeWfVxz8MivYFji3WAOlxqNX3lc0s51FlTAwUPY0sNrH9IgzH7GMgzo2qVcfhDh/KxbZPGJYIt9NphXwx/ypEw== + dependencies: + "@angular-devkit/architect" "~0.900.1" + +"@nrwl/nest@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-9.0.4.tgz#94d3879e82f003c34962412eccb8a957028aa102" + integrity sha512-mO8w4aKHTckHxmg5U4ixkqKFbj3zp6Ebpa0tKvajxQhBTWQfk4zyR0u/uLhuNJp7gOy1zwP9O/n0EiqQ4l36uQ== + dependencies: + "@angular-devkit/schematics" "~9.0.1" + "@nrwl/jest" "9.0.4" + "@nrwl/node" "9.0.4" + +"@nrwl/node@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-9.0.4.tgz#1c416805b4c00bcf195e1563ecf4bb8bcf1b1c5e" + integrity sha512-8LncxKgG0wNdhxRwDBnX9FVASOKawx3A5DsEkGDYtokSMcUpj3bMqB6d4vEV7Q6T9CNpCD7dMg6+kIDCmslzQA== + dependencies: + "@angular-devkit/architect" "~0.900.1" + "@angular-devkit/build-webpack" "~0.900.1" + "@angular-devkit/core" "~9.0.1" + "@angular-devkit/schematics" "~9.0.1" + "@nrwl/jest" "9.0.4" + "@nrwl/linter" "9.0.4" circular-dependency-plugin "5.2.0" copy-webpack-plugin "5.1.1" fork-ts-checker-webpack-plugin "^3.1.1" @@ -2364,39 +2526,39 @@ webpack-merge "4.2.1" webpack-node-externals "1.7.2" -"@nrwl/storybook@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-9.0.0.tgz#68155c2176288e2a54a97caca67901d0355d85b1" - integrity sha512-Vh2rbos3ttTJajqU9rBOu0mA20l0/167xgghOtxd6bPwMe16KVjmKOh8eBRLLAJuLwmuVN5zfjYR4m9RUrOpZA== +"@nrwl/storybook@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-9.0.4.tgz#0d1aad5b3be48b193a148547a6995f8568adf28d" + integrity sha512-vfLkqicWNAlKC2k3IcxG6ga/JvOA7yBsaQTBAxd1OEIj9aq2BMUuynN5sLLlG4D+giYgsJ4OEPXQM/tbubKSmg== dependencies: - "@nrwl/cypress" "9.0.0" + "@nrwl/cypress" "9.0.4" core-js "^3.2.1" tree-kill "1.2.2" ts-loader "5.3.1" tsconfig-paths-webpack-plugin "3.2.0" webpack-node-externals "1.7.2" -"@nrwl/tao@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-9.0.0.tgz#d54b1ff7e0e901d211f744081e1f99ad3bf54e33" - integrity sha512-ULCzSS61ZiAyioCYovKkHcLf6EZkbJITWqblsl3iPjcmWOHS7seHs1GBdcpEP5vBItGy155eBrB/Q8To/wzbhw== +"@nrwl/tao@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-9.0.4.tgz#25873370f164333347e60f45be46c6a8dbd831ee" + integrity sha512-+9erevagAOuuyahcuh55+jfUnsuXdrJ4qzEDgTPENhppSMHVc//LuKf9eAaudaPQqMgJIyK0aQSeNzTuYrGp0g== dependencies: - "@angular-devkit/architect" "0.900.1" - "@angular-devkit/core" "9.0.1" - "@angular-devkit/schematics" "9.0.1" + "@angular-devkit/architect" "~0.900.1" + "@angular-devkit/core" "~9.0.1" + "@angular-devkit/schematics" "~9.0.1" fast-levenshtein "2.0.6" inquirer "^6.3.1" minimist "^1.2.0" strip-json-comments "2.0.1" -"@nrwl/workspace@9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-9.0.0.tgz#1bc2c13b39178b55bf4164ea6e21199d365d9ac3" - integrity sha512-iITmFNOx80kfkP/7oP5qlNEimm5pB6iPBebwT5pe00ZBCIkMkJAzF0S3Vn5kuGB2iwmIVqcjfaW+qG3r/iUTVg== +"@nrwl/workspace@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-9.0.4.tgz#1a8ac5b44c1e34cf267799dedf346307f7c9e82c" + integrity sha512-5B6MJJ18bpyQphgDoxgDmoiqtZaswaQzxKV8Qx//02Sx8z3E5WCKGTtrkyh6wLmrLkUjsCIeLgSAyTSN3F0ddQ== dependencies: - "@angular-devkit/core" "9.0.1" - "@angular-devkit/schematics" "9.0.1" - "@nrwl/cli" "9.0.0" + "@angular-devkit/core" "~9.0.1" + "@angular-devkit/schematics" "~9.0.1" + "@nrwl/cli" "9.0.4" chalk "2.4.2" cosmiconfig "4.0.0" fs-extra "6.0.0" @@ -2411,6 +2573,15 @@ yargs "^11.0.0" yargs-parser "10.0.0" +"@nuxtjs/opencollective@0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@nuxtjs/opencollective/-/opencollective-0.2.2.tgz#26a761ebf588cc92a422d7cee996a66bd6e2761e" + integrity sha512-69gFVDs7mJfNjv9Zs5DFVD+pvBW+k1TaHSOqUWqAyTTfLcKI/EMYQgvEvziRd+zAFtUOoye6MfWh0qvinGISPw== + dependencies: + chalk "^2.4.1" + consola "^2.3.0" + node-fetch "^2.3.0" + "@reach/router@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.2.1.tgz#34ae3541a5ac44fa7796e5506a5d7274a162be4e" @@ -2429,29 +2600,29 @@ dependencies: any-observable "^0.3.0" -"@schematics/angular@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.1.tgz#1b08c938da4dcee2472b4641f3cbc906d6eb88af" - integrity sha512-lQ8Qc697ef2jvEf1+tElAUsbOnbUAMo3dnOUVw9RlYO90pHeG3/OdWBMH1kjn3jbjuKuvCVZH3voJUUcLDx6eg== +"@schematics/angular@9.0.5": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.5.tgz#a40abc25e3da49dad539324e384a1b98ec6cf36b" + integrity sha512-OUCC5J5+9v2tc3O/GL+2E9LfIXeqYCo/gdOTgb+jSos0aQQ7wnXOmufuoOsgt0KrWpAt34MIBktLNUF1n+RgcQ== dependencies: - "@angular-devkit/core" "9.0.1" - "@angular-devkit/schematics" "9.0.1" + "@angular-devkit/core" "9.0.5" + "@angular-devkit/schematics" "9.0.5" -"@schematics/angular@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.2.tgz#d06950506f2aff28a24066bb3a54d0651c2450cd" - integrity sha512-H6ZyxLYoIN68bbNKnUjBCPtB0fcwnpIyTkqXQHa3B4HITcU3uee4PLAl3xCkTS2NGv8m/0eWND9zt5wryGf8PQ== +"@schematics/angular@~9.0.1": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.4.tgz#e90e15abc512c310e3865717811fc3152f3462b1" + integrity sha512-JYkzMoEITWN+c+WcAieglGM6590kbDs+80HyHFiCWDMvGeYM0JEv98wsYq5fzFfhETMKe09CkaqB80YK4m4OKg== dependencies: - "@angular-devkit/core" "9.0.2" - "@angular-devkit/schematics" "9.0.2" + "@angular-devkit/core" "9.0.4" + "@angular-devkit/schematics" "9.0.4" -"@schematics/update@0.900.2": - version "0.900.2" - resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.2.tgz#4d785deee2e9c27fdf2bf13aef97a36a4e76a057" - integrity sha512-CRDb2pax8DtSyO32b2D5uKlQZ+s5h9feD4oEMvm2zU7z/4wcoTNC0T9ols20aHYeNhKYD9FuMI3KQWlgMTPgbw== +"@schematics/update@0.900.5": + version "0.900.5" + resolved "https://registry.yarnpkg.com/@schematics/update/-/update-0.900.5.tgz#97c9a3813e708b42ec4d516378b9ff7c8d34d4b6" + integrity sha512-Nte+9DfQHQkrgqZPX1viccs6UXL+FDGHkTIB/KTisJAvC4s+o9hjKAoCldWBsPi9/p5rXPNZ+EWmXx7vSLGSNQ== dependencies: - "@angular-devkit/core" "9.0.2" - "@angular-devkit/schematics" "9.0.2" + "@angular-devkit/core" "9.0.5" + "@angular-devkit/schematics" "9.0.5" "@yarnpkg/lockfile" "1.1.0" ini "1.3.5" npm-package-arg "^7.0.0" @@ -2460,17 +2631,17 @@ semver "6.3.0" semver-intersect "1.4.0" -"@storybook/addon-knobs@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-5.3.13.tgz#fe8be71eadd118edf19656442388e2e7262d2fad" - integrity sha512-Ef3D8bbV+6fywjR4JUX699gT7ZfuNBXlXqZB1qgGde5swbuttEGty1+RRwK1fqIeBr6EbzPvhRBTVOFIQp5Ysg== - dependencies: - "@storybook/addons" "5.3.13" - "@storybook/api" "5.3.13" - "@storybook/client-api" "5.3.13" - "@storybook/components" "5.3.13" - "@storybook/core-events" "5.3.13" - "@storybook/theming" "5.3.13" +"@storybook/addon-knobs@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-5.3.14.tgz#b8b753c7e64f7087668396d66aee253a51717a2d" + integrity sha512-pBpFOdeCR8n8w6QHK1adABt6YKf+Q4itfX0+AtZRGLvbGum9O+paihvP9EVYPlKiG+0T7Zv2vFCl6q6qFjF/Mw== + dependencies: + "@storybook/addons" "5.3.14" + "@storybook/api" "5.3.14" + "@storybook/client-api" "5.3.14" + "@storybook/components" "5.3.14" + "@storybook/core-events" "5.3.14" + "@storybook/theming" "5.3.14" "@types/react-color" "^3.0.1" copy-to-clipboard "^3.0.8" core-js "^3.0.1" @@ -2484,27 +2655,27 @@ react-lifecycles-compat "^3.0.4" react-select "^3.0.8" -"@storybook/addons@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.13.tgz#8c16fbab1142e2cd4bdfb93ffcb35a883dac2866" - integrity sha512-Yjn8PXhSYw4bnB/l8ybhMw3eqpJlV3HlwMECYhRtVm+wTqal9OQlZkam5xclWm6PF/6DhyiPCt6vlXN3vfVGPA== +"@storybook/addons@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.14.tgz#ff96c2c46a617f777c3660395017d2aef5319f19" + integrity sha512-zoN1MYlArdThp93i+Ogil/pihyx8n7nkrdSO0j9HUh6jUsGeFFEluPQZdRFte9NIoY6ZWSWwuEMDgrv2Pw9r2Q== dependencies: - "@storybook/api" "5.3.13" - "@storybook/channels" "5.3.13" - "@storybook/client-logger" "5.3.13" - "@storybook/core-events" "5.3.13" + "@storybook/api" "5.3.14" + "@storybook/channels" "5.3.14" + "@storybook/client-logger" "5.3.14" + "@storybook/core-events" "5.3.14" core-js "^3.0.1" global "^4.3.2" util-deprecate "^1.0.2" -"@storybook/angular@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/angular/-/angular-5.3.13.tgz#37f71021b5fc82fa9319ae1067f1cca1df6e0974" - integrity sha512-9jGPDVsK5BneNt6MuXpxSbpq0nkGvSxLH+vqgcihCFXDV+/oEqt+j+nj+MPwu5LNlMin/asi2n46Di4x2GfVLA== +"@storybook/angular@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/angular/-/angular-5.3.14.tgz#3b06188d0869ec3f934c61ff87478cf8289ac139" + integrity sha512-8Dxbbyx5xRIQXC53fDZs0ewUupWGBX2SkuDdrAiRnVIUjAooKxCoGpROSbdZoVzqkKA0RkkPhrEumLvAiLZMtQ== dependencies: - "@storybook/addons" "5.3.13" - "@storybook/core" "5.3.13" - "@storybook/node-logger" "5.3.13" + "@storybook/addons" "5.3.14" + "@storybook/core" "5.3.14" + "@storybook/node-logger" "5.3.14" "@types/webpack-env" "^1.15.0" core-js "^3.0.1" fork-ts-checker-webpack-plugin "^3.0.1" @@ -2515,18 +2686,18 @@ ts-loader "^6.0.1" tsconfig-paths-webpack-plugin "^3.2.0" -"@storybook/api@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.13.tgz#51cbdb461ff2ee8468a3c54411f42f07aa307f5d" - integrity sha512-ZOBUOz0aRPD7w8UngcVOjwcXt417Zboi0ERW+Atn22ZUYqI3zri8M9EerLHvyKw7J42/gEIqQqg5PyfPcLJmeQ== +"@storybook/api@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.14.tgz#8c2bb226a4a5de7974ee2ccce36986b72f462f1b" + integrity sha512-ANWRMTLEoAfu0IsXqbxmbTpxS8xTByZgLj20tH96bxgH1rJo9KAZnJ8A9kGYr+zklU8QnYvVIgmV3HESXII9zg== dependencies: "@reach/router" "^1.2.1" - "@storybook/channels" "5.3.13" - "@storybook/client-logger" "5.3.13" - "@storybook/core-events" "5.3.13" + "@storybook/channels" "5.3.14" + "@storybook/client-logger" "5.3.14" + "@storybook/core-events" "5.3.14" "@storybook/csf" "0.0.1" - "@storybook/router" "5.3.13" - "@storybook/theming" "5.3.13" + "@storybook/router" "5.3.14" + "@storybook/theming" "5.3.14" "@types/reach__router" "^1.2.3" core-js "^3.0.1" fast-deep-equal "^2.0.1" @@ -2541,34 +2712,34 @@ telejson "^3.2.0" util-deprecate "^1.0.2" -"@storybook/channel-postmessage@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.13.tgz#80cf8136bf4b96b2f9b291d3cc81e5d02abecc98" - integrity sha512-FMrl49ipHPXB0XPuwXm/2GWM5b53iFFz9V4/SQC1s31kxAU99QFmWXWvRKbM29FpAVHvTdjQllIiOWgdTH8jAA== +"@storybook/channel-postmessage@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.14.tgz#768c87411d98caf09fdd92539b9edaaed26d5965" + integrity sha512-XKHxMSwW3movfTDOashuYlVCX3Hp7+X+amXc/xhDDzbiYjy3/CVm3LlkkM6v451IVEdK6pue4ewqZQWJAYAAEQ== dependencies: - "@storybook/channels" "5.3.13" - "@storybook/client-logger" "5.3.13" + "@storybook/channels" "5.3.14" + "@storybook/client-logger" "5.3.14" core-js "^3.0.1" global "^4.3.2" telejson "^3.2.0" -"@storybook/channels@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.13.tgz#2adf4595988e2586f1a360cf4760f16338ffec26" - integrity sha512-lD4HXmfoKJAnAlAYwQJ5dDXG3WnW7jpW3wJieRwvQGDFHQSXdJ3Lv5/zv2y+TM06Jx8O2esaepNw+VzjMw3/Qg== +"@storybook/channels@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.14.tgz#9969e27761a80afb495bc1475f0173f9b6ef5a76" + integrity sha512-k9QBf9Kwe+iGmdEK/kW5xprqem2SPfBVwET6LWvJkWOl9UQ9VoMuCHgV55p0tzjcugaqWWKoF9+FRMWxWRfsQg== dependencies: core-js "^3.0.1" -"@storybook/client-api@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.13.tgz#0d41ae3846a6ae2ebbbeef0ca945c3ee6448ba2e" - integrity sha512-GZCFtpU764X8TW+RYRNybIGHKJOa2fYW28I0hEPXXE0J4BeU4Z++SCeNhVBa+0tPoQ3jbsdA7M4Q5Q5UeaG2Nw== +"@storybook/client-api@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.14.tgz#5f4b199d2f2b193f9f5a856c5eb8be43a9113d12" + integrity sha512-1qx1NIwto5F9N24Fb6VzKyDzeaZHtWTZ7afPrg56e1tUu7jbog7rELdRezk8+YAujveyMDJu4MxnOSP01sv7YQ== dependencies: - "@storybook/addons" "5.3.13" - "@storybook/channel-postmessage" "5.3.13" - "@storybook/channels" "5.3.13" - "@storybook/client-logger" "5.3.13" - "@storybook/core-events" "5.3.13" + "@storybook/addons" "5.3.14" + "@storybook/channel-postmessage" "5.3.14" + "@storybook/channels" "5.3.14" + "@storybook/client-logger" "5.3.14" + "@storybook/core-events" "5.3.14" "@storybook/csf" "0.0.1" "@types/webpack-env" "^1.15.0" core-js "^3.0.1" @@ -2582,20 +2753,20 @@ ts-dedent "^1.1.0" util-deprecate "^1.0.2" -"@storybook/client-logger@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.13.tgz#1c2abf0fc53009cf159eb76e30cf32ce2b9327b1" - integrity sha512-unfhCgsGWWqNpM8t8S5coDcTgpWtOq3Kj4LEHivNjdHZFdf8WMLidW79ZTiyk/Nzx7RvZKgkvf7f6EtZniD55w== +"@storybook/client-logger@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.14.tgz#85068f1b665a52163191eb5976f1581bce6df0e4" + integrity sha512-YCHEsOvo6zPb4udlyAwqr5W0Kv9mAEQmcX73w9IDvAxbjR00T7empW7qmbjvviftKB/5MEgDdiYbj64ccs3aqg== dependencies: core-js "^3.0.1" -"@storybook/components@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.13.tgz#646f8347ffa38298e3f9c1d15866c2167f577027" - integrity sha512-AwMnLCStwqLWsBzXp7m/QXuJin//0l4FH+OXmnD/6GC8qEy4JuutEOPW35IE/Mp9KAvbapHcnPTRMmDohUsTcw== +"@storybook/components@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.14.tgz#0f2f90113674e14ee74d5d16d6b3b1220cb0fa16" + integrity sha512-AsjkIFBrrqcBDLxGdmUHiauZo5gOL65eXx8WA7/yJDF8s45VVZX5Z0buOnjFyEhGVus02gwTov8da2irjL862A== dependencies: - "@storybook/client-logger" "5.3.13" - "@storybook/theming" "5.3.13" + "@storybook/client-logger" "5.3.14" + "@storybook/theming" "5.3.14" "@types/react-syntax-highlighter" "11.0.2" "@types/react-textarea-autosize" "^4.3.3" core-js "^3.0.1" @@ -2616,33 +2787,33 @@ simplebar-react "^1.0.0-alpha.6" ts-dedent "^1.1.0" -"@storybook/core-events@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.13.tgz#df74d2ffe29a1924557dc67e46d5d399893b2b11" - integrity sha512-RAnQe/I+1Ri+aYGhaNn07467cyespNX9R9i1AzFT/baBOQF2N+998mfgRu4/i/Q9YuOXIyHhw1a7JHbE/8e1lw== +"@storybook/core-events@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.14.tgz#d476eea7032670db1a84bef7e5baadb04c2de529" + integrity sha512-VCPLKqRugsOSx/smMJiJOvRgAzTrMpsbRuFw48kBGkQMP9TEV82Qe/341dv+f4GllPyBZyANG0p0m5+w7ZCURQ== dependencies: core-js "^3.0.1" -"@storybook/core@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.3.13.tgz#a6653befc867aa46bb53b43c1f4b8c51a9aa5845" - integrity sha512-HS//95j14XOb9ChYJBDHyZKAqFD2WsUh1q7sMMynSpKgHJjyfYI12rwxH5vDIrJ7CLBQbrMWrgOITjB9/cLJKA== +"@storybook/core@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-5.3.14.tgz#510f204219695045f249733bf94018e52c7b1448" + integrity sha512-Y57cchCRw1vvZe8OhMmgAkaHciGLm2eztdfzZMUmeHH8csBt/0RO5gYzOhWDGgdC2D9HSlaysZEDJ6sH3PChlw== dependencies: "@babel/plugin-proposal-class-properties" "^7.7.0" "@babel/plugin-proposal-object-rest-spread" "^7.6.2" "@babel/plugin-syntax-dynamic-import" "^7.2.0" "@babel/plugin-transform-react-constant-elements" "^7.2.0" "@babel/preset-env" "^7.4.5" - "@storybook/addons" "5.3.13" - "@storybook/channel-postmessage" "5.3.13" - "@storybook/client-api" "5.3.13" - "@storybook/client-logger" "5.3.13" - "@storybook/core-events" "5.3.13" + "@storybook/addons" "5.3.14" + "@storybook/channel-postmessage" "5.3.14" + "@storybook/client-api" "5.3.14" + "@storybook/client-logger" "5.3.14" + "@storybook/core-events" "5.3.14" "@storybook/csf" "0.0.1" - "@storybook/node-logger" "5.3.13" - "@storybook/router" "5.3.13" - "@storybook/theming" "5.3.13" - "@storybook/ui" "5.3.13" + "@storybook/node-logger" "5.3.14" + "@storybook/router" "5.3.14" + "@storybook/theming" "5.3.14" + "@storybook/ui" "5.3.14" airbnb-js-shims "^2.2.1" ansi-to-html "^0.6.11" autoprefixer "^9.7.2" @@ -2709,10 +2880,10 @@ dependencies: lodash "^4.17.15" -"@storybook/node-logger@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.3.13.tgz#f41c611c3b200add8d85777f19970bdabaa94634" - integrity sha512-ZpuyKALHq/ZyynXnsW254JaULWZLPBFw007tkJhE5z/CLy059cIVovQhX/8Ivt3FG3qwWmcqQ0ISHFi0dJpqnA== +"@storybook/node-logger@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-5.3.14.tgz#5e4e02585b37754bbebb8810ffb17c8ce706a1f8" + integrity sha512-/phRS49/hMZ5SU4EKUxX2kFepm9iw1cJBzggOz0GA1Yj4r9g1TA1H+OD7QvZvVTC3AESf/ZUJyaqnXEh/l+hpg== dependencies: "@types/npmlog" "^4.1.2" chalk "^3.0.0" @@ -2721,10 +2892,10 @@ pretty-hrtime "^1.0.3" regenerator-runtime "^0.13.3" -"@storybook/router@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.13.tgz#1ef971488036083ee284323fe8814b8795f94626" - integrity sha512-C6PNKHxKwpNHPeQkd9ZfsIBfSBTEhWEbn9cVMPSTrUyjfaGWxbKBP8zuBIXhezIv8B2gv2bQrT62hrmsXUcCVg== +"@storybook/router@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.14.tgz#6535267624da5f54971c37e497df1c161f65be8f" + integrity sha512-O0KwQFncdBeq+O2Aq8UAFBVWjWmP5rtqoacUOFSGkXgObOnyniEraLiPH7rPtq2dAlSpgYI9+srQAZfo52Hz2A== dependencies: "@reach/router" "^1.2.1" "@storybook/csf" "0.0.1" @@ -2736,14 +2907,14 @@ qs "^6.6.0" util-deprecate "^1.0.2" -"@storybook/theming@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.13.tgz#17e8101e2d3ad3fb6245b2cb15b07e9f2a9881cd" - integrity sha512-Zb07pDt8Sv5uq+xDW3TsiTXS9IGwUNwpkR6UQgKILFJ7HX2q4Tt9r+wIi1QCwozcROx4w/bP/8MAKpEAT212lw== +"@storybook/theming@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.14.tgz#4923739ad0d7d673b7844f27da8a3c6cf118790f" + integrity sha512-raqXC3yJycEt1CrCAfnBYUA6pyJI80E9M26EeQl3UfytJOL6euprOi+D17QvxqBn7jmmf9ZDw5XRkvJhQ17Y7Q== dependencies: "@emotion/core" "^10.0.20" "@emotion/styled" "^10.0.17" - "@storybook/client-logger" "5.3.13" + "@storybook/client-logger" "5.3.14" core-js "^3.0.1" deep-object-diff "^1.1.0" emotion-theming "^10.0.19" @@ -2754,20 +2925,20 @@ resolve-from "^5.0.0" ts-dedent "^1.1.0" -"@storybook/ui@5.3.13": - version "5.3.13" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.3.13.tgz#c829bc1cbcd0995e4888056a9f43fbf8a7c22ee4" - integrity sha512-pEXWFPF097OjvbgwvMjLsjLsDViu6yBMmUcL+nd3jvtxyxkuzv5X+2J14N8Nz0veJysbp+5+5A8kKGTO+spZfA== +"@storybook/ui@5.3.14": + version "5.3.14" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-5.3.14.tgz#f3c49241d615bb20cb6facef84b4c432a85d814b" + integrity sha512-4zQOxpcvbKqRevmFw3Er6AWr2MeEMQfnuYh4Vm5G5YpiTyM6PU0VTVRzKnkEbNBcgjClD7nwXSbkUJjW6MJ8SA== dependencies: "@emotion/core" "^10.0.20" - "@storybook/addons" "5.3.13" - "@storybook/api" "5.3.13" - "@storybook/channels" "5.3.13" - "@storybook/client-logger" "5.3.13" - "@storybook/components" "5.3.13" - "@storybook/core-events" "5.3.13" - "@storybook/router" "5.3.13" - "@storybook/theming" "5.3.13" + "@storybook/addons" "5.3.14" + "@storybook/api" "5.3.14" + "@storybook/channels" "5.3.14" + "@storybook/client-logger" "5.3.14" + "@storybook/components" "5.3.14" + "@storybook/core-events" "5.3.14" + "@storybook/router" "5.3.14" + "@storybook/theming" "5.3.14" copy-to-clipboard "^3.0.8" core-js "^3.0.1" core-js-pure "^3.0.1" @@ -2923,10 +3094,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44" integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== -"@types/node@13.7.1": - version "13.7.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.1.tgz#238eb34a66431b71d2aaddeaa7db166f25971a0d" - integrity sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA== +"@types/node@13.7.7": + version "13.7.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99" + integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -2995,6 +3166,18 @@ resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg== +"@types/socket.io-client@1.4.32": + version "1.4.32" + resolved "https://registry.yarnpkg.com/@types/socket.io-client/-/socket.io-client-1.4.32.tgz#988a65a0386c274b1c22a55377fab6a30789ac14" + integrity sha512-Vs55Kq8F+OWvy1RLA31rT+cAyemzgm0EWNeax6BWF8H7QiiOYMJIdcwSDdm5LVgfEkoepsWkS+40+WNb7BUMbg== + +"@types/socket.io@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@types/socket.io/-/socket.io-2.1.4.tgz#674e7bc193c5ccdadd4433f79f3660d31759e9ac" + integrity sha512-cI98INy7tYnweTsUlp8ocveVdAxENUThO0JsLSCs51cjOP2yV5Mqo5QszMDPckyRRA+PO6+wBgKvGvHUCc23TQ== + dependencies: + "@types/node" "*" + "@types/source-list-map@*": version "0.1.2" resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" @@ -3053,62 +3236,40 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@2.19.2": - version "2.19.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.19.2.tgz#e279aaae5d5c1f2547b4cff99204e1250bc7a058" - integrity sha512-HX2qOq2GOV04HNrmKnTpSIpHjfl7iwdXe3u/Nvt+/cpmdvzYvY0NHSiTkYN257jHnq4OM/yo+OsFgati+7LqJA== +"@typescript-eslint/eslint-plugin@2.22.0": + version "2.22.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.22.0.tgz#218ce6d4aa0244c6a40baba39ca1e021b26bb017" + integrity sha512-BvxRLaTDVQ3N+Qq8BivLiE9akQLAOUfxNHIEhedOcg8B2+jY8Rc4/D+iVprvuMX1AdezFYautuGDwr9QxqSxBQ== dependencies: - "@typescript-eslint/experimental-utils" "2.19.2" + "@typescript-eslint/experimental-utils" "2.22.0" eslint-utils "^1.4.3" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.19.2": - version "2.19.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.2.tgz#4611d44cf0f0cb460c26aa7676fc0a787281e233" - integrity sha512-B88QuwT1wMJR750YvTJBNjMZwmiPpbmKYLm1yI7PCc3x0NariqPwqaPsoJRwU9DmUi0cd9dkhz1IqEnwfD+P1A== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.19.2" - eslint-scope "^5.0.0" - -"@typescript-eslint/experimental-utils@^2.3.2": - version "2.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.17.0.tgz#12ed4a5d656e02ff47a93efc7d1ce1b8f1242351" - integrity sha512-2bNf+mZ/3mj5/3CP56v+ldRK3vFy9jOvmCPs/Gr2DeSJh+asPZrhFniv4QmQsHWQFPJFWhFHgkGgJeRmK4m8iQ== +"@typescript-eslint/experimental-utils@2.22.0", "@typescript-eslint/experimental-utils@^2.19.2": + version "2.22.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.22.0.tgz#4d00c91fbaaa68e56e7869be284999a265707f85" + integrity sha512-sJt1GYBe6yC0dWOQzXlp+tiuGglNhJC9eXZeC8GBVH98Zv9jtatccuhz0OF5kC/DwChqsNfghHx7OlIDQjNYAQ== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.17.0" + "@typescript-eslint/typescript-estree" "2.22.0" eslint-scope "^5.0.0" -"@typescript-eslint/parser@2.19.2": - version "2.19.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.19.2.tgz#21f42c0694846367e7d6a907feb08ab2f89c0879" - integrity sha512-8uwnYGKqX9wWHGPGdLB9sk9+12sjcdqEEYKGgbS8A0IvYX59h01o8os5qXUHMq2na8vpDRaV0suTLM7S8wraTA== +"@typescript-eslint/parser@2.22.0": + version "2.22.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.22.0.tgz#8eeb6cb6de873f655e64153397d4790898e149d0" + integrity sha512-FaZKC1X+nvD7qMPqKFUYHz3H0TAioSVFGvG29f796Nc5tBluoqfHgLbSFKsh7mKjRoeTm8J9WX2Wo9EyZWjG7w== dependencies: "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.19.2" - "@typescript-eslint/typescript-estree" "2.19.2" + "@typescript-eslint/experimental-utils" "2.22.0" + "@typescript-eslint/typescript-estree" "2.22.0" eslint-visitor-keys "^1.1.0" -"@typescript-eslint/typescript-estree@2.17.0": - version "2.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.17.0.tgz#2ce1531ec0925ef8d22d7026235917c2638a82af" - integrity sha512-g0eVRULGnEEUakxRfJO0s0Hr1LLQqsI6OrkiCLpdHtdJJek+wyd8mb00vedqAoWldeDcOcP8plqw8/jx9Gr3Lw== - dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^6.3.0" - tsutils "^3.17.1" - -"@typescript-eslint/typescript-estree@2.19.2": - version "2.19.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.2.tgz#67485b00172f400474d243c6c0be27581a579350" - integrity sha512-Xu/qa0MDk6upQWqE4Qy2X16Xg8Vi32tQS2PR0AvnT/ZYS4YGDvtn2MStOh5y8Zy2mg4NuL06KUHlvCh95j9C6Q== +"@typescript-eslint/typescript-estree@2.22.0": + version "2.22.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.22.0.tgz#a16ed45876abf743e1f5857e2f4a1c3199fd219e" + integrity sha512-2HFZW2FQc4MhIBB8WhDm9lVFaBDy6h9jGrJ4V2Uzxe/ON29HCHBTj3GkgcsgMWfsl2U5as+pTOr30Nibaw7qRQ== dependencies: debug "^4.1.1" eslint-visitor-keys "^1.1.0" @@ -3343,6 +3504,11 @@ address@1.1.2, address@^1.0.1: resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + agent-base@4, agent-base@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" @@ -3415,6 +3581,16 @@ ajv@6.10.2, ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@6.9.1: + version "6.9.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.9.1.tgz#a4d3683d74abc5670e75f0b16520f70a20ea8dc1" + integrity sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^6.10.0: version "6.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.11.0.tgz#c3607cbc8ae392d8a5a536f25b21f8e5f3f87fe9" @@ -3464,7 +3640,7 @@ ansi-html@0.0.7: resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= -ansi-regex@^2.0.0: +ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= @@ -3550,6 +3726,11 @@ app-root-path@^2.2.1: resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" integrity sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA== +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= + aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -3676,6 +3857,11 @@ array.prototype.map@^1.0.1: es-array-method-boxes-properly "^1.0.0" is-string "^1.0.4" +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -3730,7 +3916,7 @@ astral-regex@^1.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== -async-each@^1.0.1: +async-each@^1.0.0, async-each@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== @@ -3798,6 +3984,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +axios@0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + axobject-query@2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" @@ -4103,15 +4296,20 @@ babel-preset-jest@^24.9.0: babel-plugin-transform-undefined-to-void "^6.9.4" lodash "^4.17.11" -babylonjs-gltf2interface@4.1.0-beta.24: - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/babylonjs-gltf2interface/-/babylonjs-gltf2interface-4.1.0-beta.24.tgz#218bf5623d52bc9b711ae9fe174c998d89992bf6" - integrity sha512-0V+TBq/cYAlBVekUlY5PvpdfdXLNuNSe/qLbyX3l6PbXMRLM6T27fEMUT7rMqWbyTvkkJHXdZ91Z8gav4o8NhQ== +babylonjs-gltf2interface@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/babylonjs-gltf2interface/-/babylonjs-gltf2interface-4.1.0.tgz#95ec994e352ac5cb74869e238218a1b4df18e2f4" + integrity sha512-H2obg+4t8bcmLyzGiOQqmUaTQqTu+6mJUlsMWZvmRBf0k2fQVeTdAkH7aDy6HVIz/THvpIx4ntG1Lsyquvmc5Q== -babylonjs@4.1.0-beta.24: - version "4.1.0-beta.24" - resolved "https://registry.yarnpkg.com/babylonjs/-/babylonjs-4.1.0-beta.24.tgz#325064bea7d6d54bce2cd7990b09742164dcd194" - integrity sha512-w/63FPU6HYHxIm5Ug+ZEcRHlCcfAQoKgjyLIGj4II91YNWsoyWf8X9qbPYIE9qTReJNty5pw4a3nUWzkZNYXqA== +babylonjs@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/babylonjs/-/babylonjs-4.1.0.tgz#a2d1d6765795e9d44f002831554d63d6275394bd" + integrity sha512-MnaH1BQIL+PYgqGaAvGVdP8yd7nM1j6sbQi/K/6+RlkHPxIETW2NbjqxiW7Sywgy7r3PwqWT/gxG4Bz95Z6/yA== + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= bail@^1.0.0: version "1.0.4" @@ -4123,11 +4321,21 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base64-arraybuffer@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" + integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= + base64-js@^1.0.2: version "1.3.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== +base64id@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -4166,6 +4374,13 @@ benchmark@2.1.4: lodash "^4.17.4" platform "^1.3.3" +better-assert@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522" + integrity sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI= + dependencies: + callsite "1.0.0" + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -4181,10 +4396,22 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== -bluebird@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" - integrity sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw= +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +bluebird@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de" + integrity sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg== bluebird@3.7.2, bluebird@^3.3.5: version "3.7.2" @@ -4256,7 +4483,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.1, braces@^2.3.2: +braces@^2.3.0, braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== @@ -4458,6 +4685,14 @@ builtins@^1.0.3: resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= +busboy@^0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -4573,6 +4808,11 @@ caller-path@^2.0.0: dependencies: caller-callsite "^2.0.0" +callsite@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA= + callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" @@ -4686,14 +4926,6 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4. escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@3.0.0, chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -4705,6 +4937,14 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + character-entities-html4@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.3.tgz#5ce6e01618e47048ac22f34f7f39db5c6fd679ef" @@ -4735,6 +4975,26 @@ check-more-types@2.24.0: resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= +chokidar@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + "chokidar@>=2.0.0 <4.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.2.tgz#0d1cd6d04eb2df0327446188cd13736a3367d681" @@ -4870,6 +5130,18 @@ cli-boxes@^2.2.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== +cli-color@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.0.tgz#11ecfb58a79278cf6035a60c54e338f9d837897c" + integrity sha512-a0VZ8LeraW0jTuCkuAGMNufareGHhyZU9z8OGsW0gXd1hZGi1SRuNRXdbGkraBBKnhyUhyebFWnRbp+dIn0f0A== + dependencies: + ansi-regex "^2.1.1" + d "^1.0.1" + es5-ext "^0.10.51" + es6-iterator "^2.0.3" + memoizee "^0.4.14" + timers-ext "^0.1.7" + cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" @@ -5096,11 +5368,26 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + compressible@~2.0.16: version "2.0.17" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1" @@ -5126,7 +5413,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@1.6.2, concat-stream@^1.5.0: +concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.5.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -5141,6 +5428,11 @@ connect-history-api-fallback@^1.6.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== +consola@^2.3.0: + version "2.11.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.11.3.tgz#f7315836224c143ac5094b47fd4c816c2cd1560e" + integrity sha512-aoW0YIIAmeftGR8GSpw6CGQluNdkWMWh3yEFjH/hmynTYnMtibXszii3lxCXmk8YxJtI3FAK5aTiquA5VH68Gw== + console-browserify@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" @@ -5189,6 +5481,11 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + cookie@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" @@ -5257,21 +5554,16 @@ core-js-pure@^3.0.1: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a" integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== -core-js@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.0.tgz#2b854e451de1967d1e29896025cdc13a2518d9ea" - integrity sha512-AHPTNKzyB+YwgDWoSOCaid9PUSEF6781vsfiK8qUz62zRR448/XgK2NtCbpiUGizbep8Lrpt0Du19PpGGZvw3Q== +core-js@3.6.4, core-js@^3.0.1, core-js@^3.0.4, core-js@^3.2.1: + version "3.6.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" + integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= -core-js@^3.0.1, core-js@^3.0.4, core-js@^3.2.1: - version "3.6.4" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647" - integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw== - core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -5285,6 +5577,14 @@ corejs-upgrade-webpack-plugin@^2.2.0: resolve-from "^5.0.0" webpack "^4.38.0" +cors@2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" @@ -5394,15 +5694,6 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" - integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -5656,10 +5947,10 @@ cyclist@~0.2.2: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= -cypress@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.0.1.tgz#815da77c8e2528501b9af2e8d12cfcaec8c9dde7" - integrity sha512-P+cSwc5yE+1hIkWwJzpsiSQthKmzkFeFz2ySejSrJJ6FiXoL8pp0vr1cyWp+75KT4nqL9IYt1GMrHp+mVmvocA== +cypress@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.1.0.tgz#295f115d2e8a08fff2760ab49d94d876f5877aee" + integrity sha512-FFV8pS9iuriSX4M9rna6awJUhiqozZD1D5z5BprCUJoho1ctbcgpkEUIUnqxli2OwjQqVz07egO+iqoGL+tw7g== dependencies: "@cypress/listr-verbose-renderer" "0.4.1" "@cypress/xvfb" "1.2.4" @@ -5667,13 +5958,13 @@ cypress@4.0.1: arch "2.1.1" bluebird "3.7.2" cachedir "2.3.0" - chalk "3.0.0" + chalk "2.4.2" check-more-types "2.24.0" commander "4.1.0" common-tags "1.8.0" debug "4.1.1" eventemitter2 "4.1.2" - execa "3.3.0" + execa "1.0.0" executable "4.1.1" extract-zip "1.6.7" fs-extra "8.1.0" @@ -5686,6 +5977,8 @@ cypress@4.0.1: log-symbols "3.0.0" minimist "1.2.0" moment "2.24.0" + ospath "1.2.2" + pretty-bytes "5.3.0" ramda "0.26.1" request "2.88.0" request-progress "3.0.0" @@ -5695,6 +5988,14 @@ cypress@4.0.1: url "0.11.0" yauzl "2.10.0" +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + damerau-levenshtein@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz#780cf7144eb2e8dbd1c3bb83ae31100ccc31a414" @@ -5733,14 +6034,14 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0: dependencies: ms "2.0.0" -debug@3.1.0, debug@~3.1.0: +debug@3.1.0, debug@=3.1.0, debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" -debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -5948,6 +6249,14 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + diff-sequences@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" @@ -6250,6 +6559,46 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" +engine.io-client@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.4.0.tgz#82a642b42862a9b3f7a188f41776b2deab643700" + integrity sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA== + dependencies: + component-emitter "1.2.1" + component-inherit "0.0.3" + debug "~4.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.5" + parseuri "0.0.5" + ws "~6.1.0" + xmlhttprequest-ssl "~1.5.4" + yeast "0.1.2" + +engine.io-parser@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.0.tgz#312c4894f57d52a02b420868da7b5c1c84af80ed" + integrity sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.5" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.4.0.tgz#3a962cc4535928c252759a00f98519cb46c53ff3" + integrity sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "0.3.1" + debug "~4.1.0" + engine.io-parser "~2.2.0" + ws "^7.1.2" + enhanced-resolve@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" @@ -6379,11 +6728,29 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.51, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + es5-shim@^4.5.13: version "4.5.13" resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.5.13.tgz#5d88062de049f8969f83783f4a4884395f21d28b" integrity sha512-xi6hh6gsvDE0MaW4Vp1lgNEBpVcCXRWfPXj5egDvtgLz4L9MEvNwYEMdJH+JJinWkwa8c3c3o5HduV7dB/e1Hw== +es6-iterator@^2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" @@ -6401,6 +6768,24 @@ es6-shim@^0.35.5: resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.5.tgz#46f59dc0a84a1c5029e8ff1166ca0a902077a9ab" integrity sha512-E9kK/bjtCQRpN1K28Xh4BlmP8egvZBGJJ+9GtnzOwt7mdqtrjHFuVGr7QJfdjBIKqrlU5duPf3pCBoDrkjVYFg== +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -6544,6 +6929,14 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + eventemitter2@4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-4.1.2.tgz#0e1a8477af821a6ef3995b311bf74c23a5247f15" @@ -6584,21 +6977,18 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== -execa@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-3.3.0.tgz#7e348eef129a1937f21ecbbd53390942653522c1" - integrity sha512-j5Vit5WZR/cbHlqU97+qcnw9WHRCIL4V1SVe75VcHcD1JRBdt8fv0zw89b7CQHQdUHTt2VjuhcF5ibAgVOxqpg== +execa@1.0.0, execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - p-finally "^2.0.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" execa@^0.7.0: version "0.7.0" @@ -6613,19 +7003,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execall@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/execall/-/execall-2.0.0.tgz#16a06b5fe5099df7d00be5d9c06eecded1663b45" @@ -6675,7 +7052,7 @@ expect@^24.9.0: jest-message-util "^24.9.0" jest-regex-util "^24.9.0" -express@^4.17.0, express@^4.17.1: +express@4.17.1, express@^4.17.0, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -6711,6 +7088,13 @@ express@^4.17.0, express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +ext@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" + integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== + dependencies: + type "^2.0.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -6817,6 +7201,11 @@ fast-levenshtein@2.0.6, fast-levenshtein@~2.0.4, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-safe-stringify@2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" + integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== + fastparse@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" @@ -6943,6 +7332,11 @@ file-system-cache@^1.0.5: fs-extra "^0.30.0" ramda "^0.21.0" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + filename-reserved-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4" @@ -7081,6 +7475,13 @@ focus-lock@^0.6.6: resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.6.6.tgz#98119a755a38cfdbeda0280eaa77e307eee850c7" integrity sha512-Dx69IXGCq1qsUExWuG+5wkiMqVM/zGx/reXSJSLogECwp3x6KeNQZ+NAetgxEFpnC41rD8U3+jRCW68+LNzdtw== +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + follow-redirects@^1.0.0: version "1.7.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" @@ -7232,6 +7633,14 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@^1.2.2: + version "1.2.11" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" + integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + fsevents@^1.2.7: version "1.2.9" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" @@ -7335,13 +7744,6 @@ get-stream@^4.0.0, get-stream@^4.1.0: dependencies: pump "^3.0.0" -get-stream@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" - integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== - dependencies: - pump "^3.0.0" - get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -7626,6 +8028,18 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -7956,11 +8370,6 @@ https-proxy-agent@^2.2.1: agent-base "^4.3.0" debug "^3.1.0" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -8100,6 +8509,11 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -8592,7 +9006,7 @@ is-plain-object@^3.0.0: dependencies: isobject "^4.0.0" -is-promise@^2.1.0: +is-promise@^2.1, is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= @@ -8697,11 +9111,21 @@ is-wsl@^2.1.0: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.0.tgz#94369bbeb2249ef07b831b1b08590e686330ccbb" integrity sha512-pFTjpv/x5HRj8kbZ/Msxi9VrvtOMRBqaDi3OIcbwPI3OuH+r3lLxVWukLITBaOGJIbA/w2+M1eVmVa4XNQlAmQ== +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -8805,6 +9229,11 @@ istanbul-reports@^2.2.6: dependencies: html-escaper "^2.0.0" +iterare@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/iterare/-/iterare-1.2.0.tgz#7427f5ed45986e4b73e2fea903579f1117f3dd15" + integrity sha512-RxMV9p/UzdK0Iplnd8mVgRvNdXlsTOiuDrqMRnDi3wIhbT+JP4xDquAX9ay13R3CH72NBzQ91KWe0+C168QAyQ== + iterate-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.1.tgz#d2003239b4a06c91a3f8092e379f6062b03c268c" @@ -9402,6 +9831,13 @@ junit-xml@1.2.0: dependencies: xml "^1.0.1" +kafkajs@1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/kafkajs/-/kafkajs-1.12.0.tgz#50ad336baee95f3324af8ae8df6fadc96e07c613" + integrity sha512-Izkd9iFRgeeKaHEgVpGQH08ygzCbHSxTbnu8W3G3uiNaVjGibUTmTwjv1Qf2M8NORXcPfzwVyg6bBlVj4SKr9g== + dependencies: + long "^4.0.0" + karma-source-map-support@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz#58526ceccf7e8730e56effd97a4de8d712ac0d6b" @@ -9722,6 +10158,11 @@ loglevel@^1.6.4: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.6.tgz#0ee6300cc058db6b3551fa1c4bf73b83bb771312" integrity sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ== +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + longest-streak@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.3.tgz#3de7a3f47ee18e9074ded8575b5c091f5d0a4105" @@ -9762,6 +10203,13 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-queue@0.1: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= + dependencies: + es5-ext "~0.10.2" + magic-string@0.25.4: version "0.25.4" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.4.tgz#325b8a0a79fc423db109b77fd5a19183b7ba5143" @@ -9934,6 +10382,20 @@ memoize-one@^5.0.0: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== +memoizee@^0.4.14: + version "0.4.14" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" + integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== + dependencies: + d "1" + es5-ext "^0.10.45" + es6-weak-map "^2.0.2" + event-emitter "^0.3.5" + is-promise "^2.1" + lru-queue "0.1" + next-tick "1" + timers-ext "^0.1.5" + memoizerific@^1.11.3: version "1.11.3" resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" @@ -10261,6 +10723,20 @@ ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +multer@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a" + integrity sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg== + dependencies: + append-field "^1.0.0" + busboy "^0.2.11" + concat-stream "^1.5.2" + mkdirp "^0.5.1" + object-assign "^4.1.1" + on-finished "^2.3.0" + type-is "^1.6.4" + xtend "^4.0.0" + multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" @@ -10330,6 +10806,16 @@ neo-async@^2.5.0, neo-async@^2.6.1: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +next-tick@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -10359,7 +10845,7 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.6.0: +node-fetch@^2.3.0, node-fetch@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== @@ -10604,13 +11090,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - npmlog@^4.0.2, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -10648,11 +11127,16 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-component@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/object-component/-/object-component-0.0.3.tgz#f0c69aa50efc95b866c186f400a33769cb2f1291" + integrity sha1-8MaapQ78lbhmwYb0AKM3acsvEpE= + object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -10662,6 +11146,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-hash@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" + integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + object-inspect@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" @@ -10757,7 +11246,7 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -on-finished@~2.3.0: +on-finished@^2.3.0, on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= @@ -10816,6 +11305,11 @@ opn@^5.3.0, opn@^5.5.0: dependencies: is-wsl "^1.1.0" +optional@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/optional/-/optional-0.1.4.tgz#cdb1a9bedc737d2025f690ceeb50e049444fd5b3" + integrity sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw== + optionator@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" @@ -10901,6 +11395,11 @@ osenv@^0.1.4, osenv@^0.1.5: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +ospath@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= + p-defer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" @@ -10918,11 +11417,6 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-finally@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" - integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== - p-is-promise@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" @@ -11126,6 +11620,20 @@ parse5@5.1.0, parse5@^5.0.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== +parseqs@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.5.tgz#d5208a3738e46766e291ba2ea173684921a8b89d" + integrity sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0= + dependencies: + better-assert "~1.0.0" + +parseuri@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.5.tgz#80204a50d4dbb779bfdc6ebe2778d90e4bce320a" + integrity sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo= + dependencies: + better-assert "~1.0.0" + parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -11171,11 +11679,6 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -11186,6 +11689,11 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-to-regexp@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.2.0.tgz#fa7877ecbc495c601907562222453c43cc204a5f" + integrity sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA== + path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -11812,6 +12320,11 @@ prettier@1.19.1: resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== +pretty-bytes@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" + integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== + pretty-error@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" @@ -12418,6 +12931,16 @@ read-pkg@^5.2.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readable-stream@^3.0.6, readable-stream@^3.1.1: version "3.4.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" @@ -12437,7 +12960,7 @@ readdir-scoped-modules@^1.0.0: graceful-fs "^4.1.2" once "^1.3.0" -readdirp@^2.2.1: +readdirp@^2.0.0, readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== @@ -12489,7 +13012,7 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -reflect-metadata@^0.1.2: +reflect-metadata@0.1.13, reflect-metadata@^0.1.2: version "0.1.13" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== @@ -12942,6 +13465,13 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" +rxjs@6.3.3: + version "6.3.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" + integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== + dependencies: + tslib "^1.9.0" + rxjs@6.5.3: version "6.5.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" @@ -13263,23 +13793,11 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - shell-quote@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" @@ -13413,6 +13931,61 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" +socket.io-adapter@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" + integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== + +socket.io-client@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.3.0.tgz#14d5ba2e00b9bcd145ae443ab96b3f86cbcc1bb4" + integrity sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA== + dependencies: + backo2 "1.0.2" + base64-arraybuffer "0.1.5" + component-bind "1.0.0" + component-emitter "1.2.1" + debug "~4.1.0" + engine.io-client "~3.4.0" + has-binary2 "~1.0.2" + has-cors "1.1.0" + indexof "0.0.1" + object-component "0.0.3" + parseqs "0.0.5" + parseuri "0.0.5" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-parser@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.0.tgz#2b52a96a509fdf31440ba40fed6094c7d4f1262f" + integrity sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng== + dependencies: + component-emitter "1.2.1" + debug "~3.1.0" + isarray "2.0.1" + +socket.io-parser@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.0.tgz#370bb4a151df2f77ce3345ff55a7072cc6e9565a" + integrity sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ== + dependencies: + component-emitter "1.2.1" + debug "~4.1.0" + isarray "2.0.1" + +socket.io@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.3.0.tgz#cd762ed6a4faeca59bc1f3e243c0969311eb73fb" + integrity sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg== + dependencies: + debug "~4.1.0" + engine.io "~3.4.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.3.0" + socket.io-parser "~3.4.0" + sockjs-client@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5" @@ -13540,6 +14113,11 @@ sourcemap-codec@^1.4.4: resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz#e30a74f0402bad09807640d39e971090a08ce1e9" integrity sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg== +sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + space-separated-tokens@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz#27910835ae00d0adfcdbd0ad7e611fb9544351fa" @@ -13723,6 +14301,11 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -13832,6 +14415,11 @@ string_decoder@^1.0.0, string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -13887,11 +14475,6 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -14334,6 +14917,14 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +timers-ext@^0.1.5, timers-ext@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + timsort@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" @@ -14368,6 +14959,11 @@ tmpl@1.0.x: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= + to-arraybuffer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" @@ -14599,6 +15195,11 @@ tslib@1.10.0, tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== +tslib@1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== + tslint@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.0.0.tgz#1c0148beac4779924216302f192cdaa153618310" @@ -14671,7 +15272,7 @@ type-fest@^0.8.0, type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-is@~1.6.17, type-is@~1.6.18: +type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -14679,6 +15280,16 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3" + integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow== + typed-styles@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" @@ -14870,6 +15481,11 @@ untildify@4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== +upath@^1.0.5: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + upath@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" @@ -14989,6 +15605,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +uuid@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.1.tgz#95ed6ff3d8c881cbf85f0f05cc3915ef994818ef" + integrity sha512-yqjRXZzSJm9Dbl84H2VDHpM3zMjzSJQ+hn6C4zqd5ilW+7P4ZmLEEqwho9LjP+tGuZlF4xrHQXT0h9QZUS/pWA== + uuid@^3.0.0, uuid@^3.0.1, uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -15019,7 +15640,7 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -vary@~1.1.2: +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= @@ -15363,13 +15984,6 @@ which@^1.2.9, which@^1.3.0, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -15485,11 +16099,18 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" -ws@^7.0.0: +ws@^7.0.0, ws@^7.1.2: version "7.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== +ws@~6.1.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.4.tgz#5b5c8800afab925e94ccb29d153c8d02c1776ef9" + integrity sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA== + dependencies: + async-limiter "~1.0.0" + x-is-string@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" @@ -15510,6 +16131,11 @@ xmlchars@^2.1.1: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.1.1.tgz#ef1a81c05bff629c2280007f12daca21bd6f6c93" integrity sha512-7hew1RPJ1iIuje/Y01bGD/mXokXxegAgVS+e+E0wSi2ILHQkYAH1+JXARwTjZSM4Z4Z+c73aKspEcqj+zPPL/w== +xmlhttprequest-ssl@~1.5.4: + version "1.5.5" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" + integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" @@ -15676,6 +16302,11 @@ yauzl@2.4.1: dependencies: fd-slicer "~1.0.1" +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"