From ddba67dbfa5c55f29e8485fed0b494ab49c3f6fc Mon Sep 17 00:00:00 2001 From: Philipp Otto Date: Wed, 10 Apr 2019 17:24:24 +0200 Subject: [PATCH] Tensorflow segmentation (#3461) * integrate first version of tensorflow-js segmentation model * add flood fill and whole viewport prediction * implement high-perf way of accessing arbitrary cuboid data in front-end * fix some things, wand is working again * fix everything * copy tf models via webpack * upgrade webpack * increase node memory * fix lint, tests * fix model asset path * update tensorflowjs to 1.0 * move viewport when pressing alt and moving mouse * Tensorflow segmentation statistics (#3946) * [WIP] provide sampled mean and stdev for color layer data * convert to unsigned, clean up * best resolution is actually min, not max * pretty-backend * adapt tensorflow segmentation to rectangular viewports * fix lint * added mean and stdDev fetching route and using it for the magic wand tool * applied new formular again * fixed lint and flow * predict for next 5 slices as well * allow tf inference in webworker * made magic wand tool optional * fix shard in webpack-dev-server mode * enabled magic wand tool as default * fix tests * use new segem model, restrict viewport to 100x100 voxel for perf * small perf/cleanup fixes * load model from right path * only use webworker if offscreencanvas is supported * use 3d-floodfill for magic wand * add and adapt floodfill lib, do 3d floodfill, do tile-based predict and floodfill * adapt floodfill to work slice for slice, optimize voxel labeling, remove unneccessary floodfill parts * add flow to floodfill, fix flow * add magic wand unlimited mode, will predict next x slices until aborted via toast * use global tiles instead of viewport local, makes everything easier * update the whole position, so that segments that move out of the viewport later will be correctly predicted * fix magic wand for xz and yz planes * fix mean,stddev memoization, refactor common code * small changes to toast and code * add new tensorflow model, apply PR feedback #1 * apply PR feedback #2 * update redux-saga and typedefs to 1.0, avoid spawning magic wand twice * clean up prediction data for old z slices, rename magic wand to automatic brush * refactor automatic brushing code into own module * disable magic wand by default * react to zoom changes, amend automatic brush label * apply PR feedback #3, use newest model with slightly different normalization, make floodfill_threshold configurable * disable automatic brush by default --- conf/messages | 2 + docker-compose.yml | 1 + docs/keyboard_shortcuts.md | 2 + flow-typed/npm/redux-saga_v0.16.x.js | 1638 ------------- flow-typed/npm/redux-saga_v1.x.x.js | 2178 +++++++++++++++++ frontend/javascripts/admin/admin_rest_api.js | 14 + .../admin/help/keyboardshortcut_view.js | 8 + frontend/javascripts/libs/ThreeDMap.js | 6 + frontend/javascripts/libs/floodfill.js | 88 + frontend/javascripts/libs/mjs.js | 7 + frontend/javascripts/libs/toast.js | 4 +- frontend/javascripts/oxalis/api/api_latest.js | 135 + .../volumetracing_plane_controller.js | 11 + .../controller/viewmodes/plane_controller.js | 8 +- .../model/actions/volumetracing_actions.js | 12 + .../model/sagas/automatic_brush_saga.js | 259 ++ .../oxalis/model/sagas/effect-generators.js | 2 + .../model/sagas/effect-generators.js.flow | 6 +- .../oxalis/model/sagas/save_saga.js | 7 +- .../oxalis/model/sagas/volumetracing_saga.js | 48 +- .../oxalis/workers/tensorflow.impl.js | 36 + .../oxalis/workers/tensorflow.worker.js | 27 + .../javascripts/test/helpers/sagaHelpers.js | 4 +- .../javascripts/test/sagas/save_saga.spec.js | 5 +- .../test/sagas/skeletontracing_saga.spec.js | 5 +- .../test/sagas/volumetracing_saga.spec.js | 3 + frontend/stylesheets/antd_overwrites.less | 4 + package.json | 6 +- project/Dependencies.scala | 4 +- public/tf-models/group1-shard1of1 | Bin 0 -> 173092 bytes public/tf-models/seg-model.json | 1648 +++++++++++++ .../com/scalableminds/util/tools/Math.scala | 12 + .../controllers/BinaryDataController.scala | 16 + .../datastore/services/FindDataService.scala | 118 +- ....scalableminds.webknossos.datastore.routes | 1 + webpack.config.js | 4 + yarn.lock | 529 ++-- 37 files changed, 4987 insertions(+), 1871 deletions(-) delete mode 100644 flow-typed/npm/redux-saga_v0.16.x.js create mode 100644 flow-typed/npm/redux-saga_v1.x.x.js create mode 100644 frontend/javascripts/libs/floodfill.js create mode 100644 frontend/javascripts/oxalis/model/sagas/automatic_brush_saga.js create mode 100644 frontend/javascripts/oxalis/workers/tensorflow.impl.js create mode 100644 frontend/javascripts/oxalis/workers/tensorflow.worker.js create mode 100644 public/tf-models/group1-shard1of1 create mode 100644 public/tf-models/seg-model.json diff --git a/conf/messages b/conf/messages index dbd0e788026..a8686b0b760 100644 --- a/conf/messages +++ b/conf/messages @@ -96,6 +96,8 @@ dataSet.dataStore.missing=dataStore missing in the supplied json dataSet.dataSet.missing=dataSet missing in the supplied json dataSet.downloadAlreadyRunning=Sample dataset download is already running. dataSet.alreadyPresent=Sample dataset is already present. +dataSet.noResolutions=Data layer does not contain resolutions +dataSet.sampledOnlyBlack=Sampled data positions contained only black data dataSource.notFound=Datasource not found on datastore server diff --git a/docker-compose.yml b/docker-compose.yml index 4a6139a413c..b63e5b579c1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -99,6 +99,7 @@ services: - HOME=/root - CIRCLE_TAG=${CIRCLE_TAG} - CIRCLE_BUILD_NUM=${CIRCLE_BUILD_NUM} + - NODE_OPTIONS=--max_old_space_size=2048 working_dir: /home/${USER_NAME:-sbt-user}/webknossos volumes: - ".:/home/${USER_NAME:-sbt-user}/webknossos" diff --git a/docs/keyboard_shortcuts.md b/docs/keyboard_shortcuts.md index 407447b58a3..ff3ca55d090 100644 --- a/docs/keyboard_shortcuts.md +++ b/docs/keyboard_shortcuts.md @@ -38,6 +38,7 @@ Find all available keyboard shortcuts for webKnossos listed below. | Key Binding | Operation | | ----------------------------- | ------------------------------------------- | | Left Mouse Drag or Arrow Keys | Move | +| Alt + Mouse Move | Move | | SPACE | Move Forward by a Single Slice | | Scroll Mousewheel (3D View) | Zoom In And Out | | Right Click Drag (3D View) | Rotate 3D View | @@ -78,6 +79,7 @@ Find all available keyboard shortcuts for webKnossos listed below. | CTRL + Left Mouse Drag | Add Empty Voxels To Current Cell (in Trace / Brush Mode) | | Right Mouse Drag | Remove Voxels From Current Cell | | CTRL + Right Mouse Drag | Remove Voxels From Any Cell | +| Alt + Mouse Move | Move | | C | Create New Cell | | W, 1 | Toggle Modes (Move / Trace / Brush) | | SHIFT + Mousewheel or SHIFT + I, O | Change Brush Size (Brush Mode) | diff --git a/flow-typed/npm/redux-saga_v0.16.x.js b/flow-typed/npm/redux-saga_v0.16.x.js deleted file mode 100644 index 74b9f83fd70..00000000000 --- a/flow-typed/npm/redux-saga_v0.16.x.js +++ /dev/null @@ -1,1638 +0,0 @@ -// flow-typed signature: 81155af144282e14c13e73c7ec3f203b -// flow-typed version: 0dda5b292f/redux-saga_v0.16.x/flow_>=v0.56.0 - -// @flow - -declare module "redux-saga" { - import typeof * as _effects from "redux-saga/effects"; - declare export var effects: _effects; - - declare export interface Channel { - take: (cb: (msg: mixed) => void) => void; - put: (msg: mixed) => void; - flush: (cb: (msgs: mixed) => void) => void; - close: () => void; - } - - declare export interface Task { - isRunning: () => boolean; - isCancelled: () => boolean; - result: () => T | void; - error: () => Error | void; - cancel: () => void; - done: Promise; - } - - declare export interface Buffer { - isEmpty: () => boolean; - put: (msg: mixed) => void; - take(): mixed; - } - - declare export interface SagaMonitor { - effectTriggered: (options: { - +effectId: number, - +parentEffectId: number, - +label: string, - +effect: Effect - }) => void; - effectResolved: (effectId: number, result: mixed) => void; - effectRejected: (effectId: number, error: Error) => void; - effectCancelled: (effectId: number) => void; - actionDispatched: (action: mixed) => void; - } - - declare export type Saga = Generator; - - declare export var eventChannel: ( - sub: (emit: (msg: any) => void) => () => void, - buffer?: Buffer, - matcher?: (msg: mixed) => boolean - ) => Channel; - - declare export var buffers: { - +none: () => Buffer, - +fixed: (limit?: number) => Buffer, - +dropping: (limit?: number) => Buffer, - +sliding: (limit?: number) => Buffer, - +expanding: (initialSize?: number) => Buffer - }; - - declare export var channel: (buffer?: Buffer) => Channel; - declare export var END: { +type: "@@redux-saga/CHANNEL_END" }; - declare export var CANCEL: Symbol; - declare export var delay: (timeout: number, val?: any) => Promise; - - declare type RunSagaOptions = { - +subscribe?: (emit: (input: any) => any) => () => void, - +dispatch?: (output: any) => any, - +getState?: () => any, - +sagaMonitor?: SagaMonitor, - +logger?: ( - level: "info" | "warning" | "error", - ...args: Array - ) => void, - +onError?: (error: Error) => void - }; - - declare export var runSaga: { - Saga>(options: RunSagaOptions, saga: Fn): Task, - Saga>( - options: RunSagaOptions, - saga: Fn, - t1: T1 - ): Task, - Saga>( - options: RunSagaOptions, - saga: Fn, - t1: T1, - t2: T2 - ): Task, - Saga>( - options: RunSagaOptions, - saga: Fn, - t1: T1, - t2: T2, - t3: T3 - ): Task, - Saga>( - options: RunSagaOptions, - saga: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): Task, - < - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => Saga - >( - options: RunSagaOptions, - saga: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): Task, - < - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => Saga - >( - options: RunSagaOptions, - saga: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): Task - }; - - declare interface SagaMiddleware { - // TODO: This should be aligned with the official redux typings sometime - (api: any): (next: any) => any; - run: { - Saga>(saga: Fn): Task, - Saga>(saga: Fn, t1: T1): Task, - Saga>( - saga: Fn, - t1: T1, - t2: T2 - ): Task, - Saga>( - saga: Fn, - t1: T1, - t2: T2, - t3: T3 - ): Task, - Saga>( - saga: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): Task, - < - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => Saga - >( - saga: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): Task, - < - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => Saga - >( - saga: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): Task - }; - } - - declare type createSagaMiddleware = (options?: { - +sagaMonitor?: SagaMonitor, - +logger?: ( - level: "info" | "warning" | "error", - ...args: Array - ) => void, - +onError?: (error: Error) => void - }) => SagaMiddleware; - - declare export default createSagaMiddleware - - // Effect types - declare export type PatternPart = string | (any => boolean); - declare export type Pattern = PatternPart | $ReadOnlyArray; - - declare export type TakeEffect< - P: Pattern | void, - C: Channel | void, - M: true | void - > = { - +"@@redux-saga/IO": true, - +TAKE: { - +pattern: P, - +channel: C, - +maybe: M - } - }; - - declare export type PutEffect = { - +"@@redux-saga/IO": true, - +PUT: { - +action: A, - +channel: C - } - }; - - declare export type CallEffect> = { - +"@@redux-saga/IO": true, - +CALL: { - +context: Ctx, - +fn: Fn, - +args: Args - } - }; - - declare export type ForkEffect> = { - +"@@redux-saga/IO": true, - +FORK: { - +context: Ctx, - +fn: Fn, - +args: Args - } - }; - - declare export type CpsEffect> = { - +"@@redux-saga/IO": true, - +CPS: { - +context: Ctx, - +fn: Fn, - +args: Args - } - }; - - declare export type SpawnEffect< - Ctx, - Fn: Function, - Args: $ReadOnlyArray<*> - > = { - +"@@redux-saga/IO": true, - +SPAWN: { - +context: Ctx, - +fn: Fn, - +args: Args - } - }; - - declare export type JoinEffect> = { - +"@@redux-saga/IO": true, - +JOIN: T - }; - - declare export type CancelEffect< - T: Task<*> | "@@redux-saga/SELF_CANCELLATION" - > = { - +"@@redux-saga/IO": true, - +CANCEL: T - }; - - declare export type SelectEffect> = { - +"@@redux-saga/IO": true, - +SELECT: { - +selector: Fn, - +args: Args - } - }; - - declare export type ActionChannelEffect = { - +"@@redux-saga/IO": true, - +ACTION_CHANNEL: { - +buffer: B, - +pattern: P - } - }; - - declare export type FlushEffect = { - +"@@redux-saga/IO": true, - +FLUSH: Channel - }; - - declare export type CancelledEffect = { - +"@@redux-saga/IO": true, - +CANCELLED: {} - }; - - declare export type SetContextEffect = { - +"@@redux-saga/IO": true, - +SET_CONTEXT: T - }; - - declare export type GetContextEffect = { - +"@@redux-saga/IO": true, - +GET_CONTEXT: string - }; - - declare export type RaceEffect< - R: { +[name: string]: Effect } | $ReadOnlyArray - > = { - +"@@redux-saga/IO": true, - +RACE: R - }; - - declare export type AllEffect = { - +"@@redux-saga/IO": true, - +ALL: { +[name: string]: Effect } | $ReadOnlyArray - }; - - declare export type Effect = - | TakeEffect<*, *, *> - | PutEffect<*, *> - | CallEffect<*, *, *> - | ForkEffect<*, *, *> - | CpsEffect<*, *, *> - | SpawnEffect<*, *, *> - | JoinEffect<*> - | CancelEffect<*> - | SelectEffect<*, *> - | ActionChannelEffect<*, *> - | FlushEffect - | CancelledEffect - | SetContextEffect<*> - | GetContextEffect - | RaceEffect<*> - | AllEffect; -} - -declare module "redux-saga/effects" { - import type { - ActionChannelEffect, - AllEffect, - Buffer, - CallEffect, - CancelEffect, - CancelledEffect, - Channel, - CpsEffect, - Effect, - FlushEffect, - ForkEffect, - GetContextEffect, - JoinEffect, - Pattern, - PutEffect, - RaceEffect, - Saga, - SelectEffect, - SetContextEffect, - SpawnEffect, - TakeEffect, - Task - } from "redux-saga"; - - declare export var take: { - (pattern: P): TakeEffect, - (channel: Channel): TakeEffect, - +maybe: { - (pattern: P): TakeEffect, - (channel: Channel): TakeEffect - } - }; - - declare export var put: { - (action: A): PutEffect, - (channel: Channel, action: A): PutEffect, - resolve: { - (action: A): PutEffect, - (channel: Channel, action: A): PutEffect, - } - }; - - declare export var call: { - // normal calls - R>(fn: Fn): CallEffect, - R>(fn: Fn, t1: T1): CallEffect, - R>( - fn: Fn, - t1: T1, - t2: T2 - ): CallEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): CallEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): CallEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): CallEffect, - < - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): CallEffect, - - // with context - R>(cfn: [Ctx, Fn]): CallEffect, - R>( - cfn: [Ctx, Fn], - t1: T1 - ): CallEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2 - ): CallEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3 - ): CallEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): CallEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): CallEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): CallEffect - }; - - declare export var apply: { - R>(ctx: Ctx, fn: Fn): CallEffect, - R>( - ctx: Ctx, - fn: Fn, - t1: T1 - ): CallEffect, - R>( - ctx: Ctx, - fn: Fn, - t1: T1, - t2: T2 - ): CallEffect, - R>( - ctx: Ctx, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): CallEffect, - R>( - ctx: Ctx, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): CallEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R - >( - ctx: Ctx, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): CallEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - ctx: Ctx, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): CallEffect - }; - - declare type NodeCallback = { - (err: Error): void, - (err: null | void | false, result: R): void - }; - - declare export var cps: { - // normal calls - ) => void>(fn: Fn): CpsEffect, - ) => void>( - fn: Fn, - t1: T1 - ): CpsEffect, - ) => void>( - fn: Fn, - t1: T1, - t2: T2 - ): CpsEffect, - ) => void>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): CpsEffect, - < - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, cb: NodeCallback) => void - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): CpsEffect, - < - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, cb: NodeCallback) => void - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): CpsEffect, - < - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: ( - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6, - cb: NodeCallback - ) => void - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): CpsEffect, - - // with context - ) => void>( - cfn: [Ctx, Fn] - ): CpsEffect, - ) => void>( - cfn: [Ctx, Fn], - t1: T1 - ): CpsEffect, - ) => void>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2 - ): CpsEffect, - < - Ctx, - R, - T1, - T2, - T3, - Fn: (t1: T1, t2: T2, t3: T3, cb: NodeCallback) => void - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3 - ): CpsEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, cb: NodeCallback) => void - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): CpsEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, cb: NodeCallback) => void - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): CpsEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: ( - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6, - cb: NodeCallback - ) => void - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): CpsEffect - }; - - declare export var fork: { - // normal calls - R>(fn: Fn): ForkEffect, - R>(fn: Fn, t1: T1): ForkEffect, - R>( - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect, - < - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect, - - // with context - R>(cfn: [Ctx, Fn]): ForkEffect, - R>( - cfn: [Ctx, Fn], - t1: T1 - ): ForkEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2 - ): ForkEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect - }; - - declare export var spawn: { - // normal calls - R>(fn: Fn): SpawnEffect, - R>(fn: Fn, t1: T1): SpawnEffect, - R>( - fn: Fn, - t1: T1, - t2: T2 - ): SpawnEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): SpawnEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): SpawnEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): SpawnEffect, - < - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): SpawnEffect, - - // with context - R>(cfn: [Ctx, Fn]): SpawnEffect, - R>( - cfn: [Ctx, Fn], - t1: T1 - ): SpawnEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2 - ): SpawnEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3 - ): SpawnEffect, - R>( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): SpawnEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): SpawnEffect, - < - Ctx, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - cfn: [Ctx, Fn], - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): SpawnEffect - }; - - declare export var join: { - >(task: T): JoinEffect, - (task: Task<*>, ...tasks: $ReadOnlyArray>): AllEffect - }; - - declare export var cancel: { - (): CancelEffect<"@@redux-saga/SELF_CANCELLATION">, - >(task: T): CancelEffect, - (task: Task<*>, ...tasks: $ReadOnlyArray>): AllEffect - }; - - declare export var select: { - (): SelectEffect, - R>(fn: Fn): SelectEffect, - R>( - fn: Fn, - t1: T1 - ): SelectEffect, - R>( - fn: Fn, - t1: T1, - t2: T2 - ): SelectEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): SelectEffect, - R>( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): SelectEffect, - < - S, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (state: S, t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): SelectEffect, - < - S, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (state: S, t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R - >( - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): SelectEffect - }; - - declare export var actionChannel: { - (pattern: P): ActionChannelEffect, - (pattern: P, buffer: B): ActionChannelEffect - }; - - declare export var flush: { - (channel: Channel): FlushEffect - }; - - declare export var cancelled: { - (): CancelledEffect - }; - - declare export var setContext: { - (ctx: T): SetContextEffect - }; - - declare export var getContext: { - (prop: string): GetContextEffect - }; - - declare export var race: { - >( - effects: R - ): RaceEffect - }; - - declare export var all: { - (effects: { +[name: string]: Effect }): AllEffect, - (effects: $ReadOnlyArray): AllEffect - }; - - declare export var takeEvery: { - // normal calls - Saga>( - pattern: Pattern, - fn: Fn - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1 - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect>, - - // with channel - Saga>( - channel: Channel, - fn: Fn - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1 - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect> - }; - - declare export var takeLatest: { - // normal calls - Saga>( - pattern: Pattern, - fn: Fn - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1 - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect>, - - // with channel - Saga>( - channel: Channel, - fn: Fn - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1 - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect> - }; - - declare export var takeLeading: { - // normal calls - Saga>( - pattern: Pattern, - fn: Fn - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1 - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect>, - Saga>( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, action: A) => Saga - >( - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect>, - - // with channel - Saga>( - channel: Channel, - fn: Fn - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1 - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect>, - Saga>( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect>, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, action: A) => Saga - >( - channel: Channel, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect> - }; - - declare export var throttle: { - // normal calls - Saga>( - ms: number, - pattern: Pattern, - fn: Fn - ): ForkEffect, - Saga>( - ms: number, - pattern: Pattern, - fn: Fn, - t1: T1 - ): ForkEffect, - Saga>( - ms: number, - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2 - ): ForkEffect, - Saga>( - ms: number, - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3 - ): ForkEffect, - < - A, - R, - T1, - T2, - T3, - T4, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, action: A) => Saga - >( - ms: number, - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4 - ): ForkEffect, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, action: A) => Saga - >( - ms: number, - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5 - ): ForkEffect, - < - A, - R, - T1, - T2, - T3, - T4, - T5, - T6, - Fn: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, action: A) => Saga - >( - ms: number, - pattern: Pattern, - fn: Fn, - t1: T1, - t2: T2, - t3: T3, - t4: T4, - t5: T5, - t6: T6 - ): ForkEffect - }; -} diff --git a/flow-typed/npm/redux-saga_v1.x.x.js b/flow-typed/npm/redux-saga_v1.x.x.js new file mode 100644 index 00000000000..9f31edca919 --- /dev/null +++ b/flow-typed/npm/redux-saga_v1.x.x.js @@ -0,0 +1,2178 @@ +// @flow + +declare module "redux-saga" { + import typeof * as _effects from "redux-saga/effects"; + declare export var effects: _effects; + + // These types are copied directly from the redux libdef. + // Importing them in this libdef causes a loss in type coverage. + + // * uncomment next line: + // import type { Middleware} from 'redux'; + + // * remove next types + declare type DispatchAPI = (action: A) => A; + declare type Dispatch = DispatchAPI; + + declare type MiddlewareAPI> = { + dispatch: D, + getState(): S, + }; + + declare type Middleware> = (api: MiddlewareAPI) => (next: D) => D; + + declare export var SAGA_LOCATION: "@@redux-saga/LOCATION"; + + declare export var CANCEL: "@@redux-saga/CANCEL_PROMISE"; + + declare export type TEnd = {| +type: "@@redux-saga/CHANNEL_END" |}; + + declare export var END: TEnd; + + declare export var isEnd: { + (input: TEnd): true, + (input: mixed): false, + }; + + declare export type Predicate = (arg: T) => boolean; + + declare export type MulticastChannel = $ReadOnly<{| + take(cb: (message: T | TEnd) => void, matcher?: Predicate): void, + put(message: T | TEnd): void, + close(): void, + |}>; + + declare export interface Buffer { + isEmpty(): boolean; + put(message: T): void; + take(): T | void; + flush(): Array; + } + + declare export interface Task { + isRunning: () => boolean; + isCancelled: () => boolean; + result: () => RT | void; + error: () => Error | void; + cancel: () => void; + toPromise(): Promise; + setContext(props: $Shape): void; + } + + declare export interface SagaMonitor { + effectTriggered?: (desc: { + +effectId: number, + +parentEffectId: number, + +label: string, + +root?: boolean, + +effect: Effect, + }) => void; + effectResolved?: (effectId: number, result: mixed) => void; + effectRejected?: (effectId: number, error: any) => void; + effectCancelled?: (effectId: number) => void; + + actionDispatched?: (action: A) => void; + } + + declare export type Saga = Generator; + + declare export type Unsubscribe = () => void; + + declare export type Subscribe = (cb: (input: T | TEnd) => void) => Unsubscribe; + + declare export interface TakeableChannel { + take(cb: (message: T | TEnd) => void): void; + } + + declare export interface PuttableChannel { + put(message: T | TEnd): void; + } + + declare export interface FlushableChannel { + flush(cb: (items: Array | TEnd) => void): void; + } + + declare export interface EventChannel { + take(cb: (message: T | TEnd) => void): void; + flush(cb: (items: Array | TEnd) => void): void; + close(): void; + } + + declare export var eventChannel: ( + subscribe: Subscribe, + buffer?: Buffer, + ) => EventChannel; + + declare export interface Channel { + take(cb: (message: T | TEnd) => void): void; + put(message: T | TEnd): void; + flush(cb: (items: Array | TEnd) => void): void; + close(): void; + } + + declare export function channel(buffer?: Buffer): Channel; + + declare export var buffers: $ReadOnly<{| + none: () => Buffer, + fixed: (limit?: number) => Buffer, + dropping: (limit?: number) => Buffer, + sliding: (limit?: number) => Buffer, + expanding: (initialSize?: number) => Buffer, + |}>; + + declare export function multicastChannel(): MulticastChannel; + + declare export function stdChannel(): MulticastChannel; + + declare export type Logger = (level: "info" | "warning" | "error", ...args: Array) => void; + + declare export type EffectMiddleware = (next: (effect: mixed) => void) => (effect: mixed) => void; + + declare export interface PredicateTakeableChannel { + take(cb: (message: T | TEnd) => void, matcher?: Predicate): void; + } + + declare type RunSagaOptions = {| + channel?: PredicateTakeableChannel, + dispatch?: (input: A) => mixed, + getState?: () => S, + context?: {}, + sagaMonitor?: SagaMonitor, + logger?: Logger, + effectMiddlewares?: Array, + onError?: (error: Error) => void, + |}; + + declare export var runSaga: { + Saga>(options: RunSagaOptions, saga: Fn): Task, + Saga>(options: RunSagaOptions, saga: Fn, T1): Task, + Saga>( + options: RunSagaOptions, + saga: Fn, + T1, + T2, + ): Task, + Saga>( + options: RunSagaOptions, + saga: Fn, + T1, + T2, + T3, + ): Task, + Saga>( + options: RunSagaOptions, + saga: Fn, + T1, + T2, + T3, + T4, + ): Task, + Saga>( + options: RunSagaOptions, + saga: Fn, + T1, + T2, + T3, + T4, + T5, + ): Task, + Saga>( + options: RunSagaOptions, + saga: Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): Task, + Saga>( + options: RunSagaOptions, + saga: Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): Task, + Saga>( + options: RunSagaOptions, + saga: Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): Task, + }; + + declare export type SagaMiddleware = { + (api: MiddlewareAPI): (next: D) => D, + run: { + Saga>(saga: Fn): Task, + Saga>(saga: Fn, T1): Task, + Saga>(saga: Fn, T1, T2): Task, + Saga>(saga: Fn, T1, T2, T3): Task, + Saga>(saga: Fn, T1, T2, T3, T4): Task, + Saga>( + saga: Fn, + T1, + T2, + T3, + T4, + T5, + ): Task, + Saga>( + saga: Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): Task, + Saga>( + saga: Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): Task, + Saga>( + saga: Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): Task, + }, + setContext: (props: $Shape) => void, + }; + + declare export type Emit = (input: T) => void; + + declare export type SagaMiddlewareOptions = {| + context?: C, + sagaMonitor?: SagaMonitor, + logger?: Logger, + effectMiddlewares?: Array, + emitter?: (emit: Emit) => Emit, + onError?: (error: Error) => void, + |}; + + declare function sagaMiddlewareFactory(options?: SagaMiddlewareOptions): SagaMiddleware; + + declare export default typeof sagaMiddlewareFactory; + + // Effect types + declare export type SubPattern = string | (any => boolean); + + declare export type Pattern = SubPattern | Array; + + declare export interface IEffect { + +type: T; + +payload: P; + +combinator: C; + } + + declare export type AllTakeEffect = IEffect< + "TAKE", + $ReadOnly<{| + pattern: "*", + ...$Exact, + |}>, + false, + >; + + declare export type TakeEffect< + P: { pattern: Pattern } | void, + C: { channel: TakeableChannel<*> } | void, + M: { maybe: true } | void, + > = IEffect< + "TAKE", + $ReadOnly<{| + ...$Exact

, + ...$Exact, + ...$Exact, + |}>, + false, + >; + + declare export type PutEffect< + A: {}, + C: PuttableChannel<*> | null, + R: { resolve: true } | void, + > = IEffect< + "PUT", + $ReadOnly<{| + action: A, + channel: C, + ...$Exact, + |}>, + false, + >; + + declare export type CallEffect> = IEffect< + "CALL", + $ReadOnly<{| + context: Ctx, + fn: Fn, + args: Args, + |}>, + false, + >; + + declare export type ForkEffect< + Ctx, + Fn: (...args: Array<*>) => *, + D: { detached: true } | void, + Args: $ReadOnlyArray<*>, + > = IEffect< + "FORK", + $ReadOnly<{| + context: Ctx, + fn: Fn, + args: Args, + ...$Exact, + |}>, + false, + >; + + declare export function detach( + effect: ForkEffect, + ): ForkEffect; + + declare export type CpsEffect< + Ctx, + Fn: (...args: Array<*>) => *, + Args: $ReadOnlyArray<*>, + > = IEffect< + "CPS", + $ReadOnly<{| + context: Ctx, + fn: Fn, + args: Args, + |}>, + false, + >; + + declare export type JoinEffect | Array>> = IEffect<"JOIN", T, false>; + + declare export type SELF_CANCELLATION = "@@redux-saga/SELF_CANCELLATION"; + + declare export type CancelEffect< + T: Task<*> | $ReadOnlyArray> | SELF_CANCELLATION, + > = IEffect<"CANCEL", T, false>; + + declare export type SelectEffect> = IEffect< + "SELECT", + $ReadOnly<{| + selector: Fn, + args: Args, + |}>, + false, + >; + + declare export type ActionChannelEffect | void> = IEffect< + "ACTION_CHANNEL", + $ReadOnly<{| + buffer: B, + pattern: P, + |}>, + false, + >; + + declare export type FlushEffect> = IEffect<"FLUSH", CH, false>; + + declare export type CancelledEffect = IEffect<"CANCELLED", {||}, false>; + + declare export type SetContextEffect = IEffect<"SET_CONTEXT", T, false>; + + declare export type GetContextEffect = IEffect<"GET_CONTEXT", T, false>; + + declare export type RaceEffect> = IEffect< + "RACE", + R, + true, + >; + + declare export type AllEffect = IEffect< + "ALL", + { +[name: string]: Effect } | $ReadOnlyArray, + true, + >; + + declare export type Effect = + | ActionChannelEffect<*, *, *> + | AllEffect + | CallEffect<*, *, *> + | CancelEffect<*> + | CancelledEffect + | CpsEffect<*, *, *> + | FlushEffect<*> + | ForkEffect<*, *, *, *> + | GetContextEffect<*> + | JoinEffect<*> + | PutEffect<*, *, *> + | RaceEffect<*> + | SelectEffect<*, *> + | SetContextEffect<*> + | TakeEffect<*, *, *> + | AllTakeEffect<*>; +} + +declare module "redux-saga/effects" { + import type { + ActionChannelEffect, + AllEffect, + Buffer, + CallEffect, + CancelEffect, + CancelledEffect, + Channel, + CpsEffect, + Effect, + FlushEffect, + ForkEffect, + GetContextEffect, + JoinEffect, + Pattern, + PutEffect, + RaceEffect, + Saga, + SelectEffect, + SetContextEffect, + TakeEffect, + Task, + TakeableChannel, + PuttableChannel, + FlushableChannel, + AllTakeEffect, + } from "redux-saga"; + + declare export var effectTypes: $ReadOnly<{| + TAKE: "TAKE", + PUT: "PUT", + ALL: "ALL", + RACE: "RACE", + CALL: "CALL", + CPS: "CPS", + FORK: "FORK", + JOIN: "JOIN", + CANCEL: "CANCEL", + SELECT: "SELECT", + ACTION_CHANNEL: "ACTION_CHANNEL", + CANCELLED: "CANCELLED", + FLUSH: "FLUSH", + GET_CONTEXT: "GET_CONTEXT", + SET_CONTEXT: "SET_CONTEXT", + |}>; + + declare export var put: { + (action: A): PutEffect, + >(channel: CH, action: A): PutEffect, + }; + + declare export var putResolve: { + (action: A): PutEffect, + >(channel: CH, action: A): PutEffect, + }; + + declare export var call: { + // call(fn, ...args) + R>(Fn): CallEffect, + R>(Fn, T1): CallEffect, + R>(Fn, T1, T2): CallEffect, + R>(Fn, T1, T2, T3): CallEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + ): CallEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + ): CallEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): CallEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CallEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CallEffect, + + // call([context, fn], ...args) + R>(cfn: [Ctx, Fn]): CallEffect, + R>(cfn: [Ctx, Fn], T1): CallEffect, + R>(cfn: [Ctx, Fn], T1, T2): CallEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + ): CallEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + ): CallEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + ): CallEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + ): CallEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CallEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CallEffect, + + // call([context, fnName], ...args) + R, Ctx: { [FnName]: Fn }>( + cfn: [Ctx, FnName], + ): CallEffect, + R, Ctx: { [FnName]: Fn }>( + cfn: [Ctx, FnName], + T1, + ): CallEffect, + R, Ctx: { [FnName]: Fn }>( + cfn: [Ctx, FnName], + T1, + T2, + ): CallEffect, + R, Ctx: { [FnName]: Fn }>( + cfn: [Ctx, FnName], + T1, + T2, + T3, + ): CallEffect, + R, Ctx: { [FnName]: Fn }>( + cfn: [Ctx, FnName], + T1, + T2, + T3, + T4, + ): CallEffect, + R, Ctx: { [FnName]: Fn }>( + cfn: [Ctx, FnName], + T1, + T2, + T3, + T4, + T5, + ): CallEffect, + < + R, + FnName: string, + T1, + T2, + T3, + T4, + T5, + T6, + Fn: (T1, T2, T3, T4, T5, T6) => R, + Ctx: { [FnName]: Fn }, + >( + cfn: [Ctx, FnName], + T1, + T2, + T3, + T4, + T5, + T6, + ): CallEffect, + < + R, + FnName: string, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + Fn: (T1, T2, T3, T4, T5, T6, T7) => R, + Ctx: { [FnName]: Fn }, + >( + cfn: [Ctx, FnName], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CallEffect, + < + R, + FnName: string, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8) => R, + Ctx: { [FnName]: Fn }, + >( + cfn: [Ctx, FnName], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CallEffect, + + // call({context, fn}, ...args) + R>(cfn: { context: Ctx, fn: Fn }): CallEffect, + R>(cfn: { context: Ctx, fn: Fn }, T1): CallEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + ): CallEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + ): CallEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + ): CallEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + ): CallEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + ): CallEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CallEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CallEffect, + }; + + declare export var apply: { + // apply(context, fn, args) + R>(Ctx, Fn): CallEffect, + R>(Ctx, Fn, T1): CallEffect, + R>(Ctx, Fn, T1, T2): CallEffect, + R>( + Ctx, + Fn, + T1, + T2, + T3, + ): CallEffect, + R>( + Ctx, + Fn, + T1, + T2, + T3, + T4, + ): CallEffect, + R>( + Ctx, + Fn, + T1, + T2, + T3, + T4, + T5, + ): CallEffect, + R>( + Ctx, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): CallEffect, + R>( + Ctx, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CallEffect, + R>( + Ctx, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CallEffect, + }; + + declare type NodeCallback = { + (err: Error): void, + (err: null | void | false, result: R): void, + }; + + declare export var cps: { + // cps(fn, ...args) + ) => void>(Fn): CpsEffect, + ) => void>(Fn, T1): CpsEffect, + ) => void>(Fn, T1, T2): CpsEffect, + ) => void>( + Fn, + T1, + T2, + T3, + ): CpsEffect, + ) => void>( + Fn, + T1, + T2, + T3, + T4, + ): CpsEffect, + ) => void>( + Fn, + T1, + T2, + T3, + T4, + T5, + ): CpsEffect, + ) => void>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): CpsEffect, + ) => void>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CpsEffect, + < + R, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8, NodeCallback) => void, + >( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CpsEffect, + + // cps([context, fn], ...args) + ) => void>(cfn: [Ctx, Fn]): CpsEffect, + ) => void>(cfn: [Ctx, Fn], T1): CpsEffect, + ) => void>( + cfn: [Ctx, Fn], + T1, + T2, + ): CpsEffect, + ) => void>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + ): CpsEffect, + ) => void>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + ): CpsEffect, + ) => void>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + ): CpsEffect, + ) => void>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + ): CpsEffect, + ) => void>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CpsEffect, + < + Ctx, + R, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8, NodeCallback) => void, + >( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CpsEffect, + + // cps({context, fn}, ...args) + ) => void>(cfn: { context: Ctx, fn: Fn }): CpsEffect, + ) => void>( + cfn: { context: Ctx, fn: Fn }, + T1, + ): CpsEffect, + ) => void>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + ): CpsEffect, + ) => void>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + ): CpsEffect, + ) => void>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + ): CpsEffect, + ) => void>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + ): CpsEffect, + ) => void>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + ): CpsEffect, + ) => void>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CpsEffect, + < + Ctx, + R, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8, NodeCallback) => void, + >( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CpsEffect, + }; + + declare export var fork: { + // fork(fn, ...args) + R>(Fn): ForkEffect, + R>(Fn, T1): ForkEffect, + R>(Fn, T1, T2): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + + // fork([context, fn], ...args) + R>(cfn: [Ctx, Fn]): ForkEffect, + R>(cfn: [Ctx, Fn], T1): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + + // fork({context, fn}, ...args) + R>(cfn: { context: Ctx, fn: Fn }): ForkEffect, + R>(cfn: { context: Ctx, fn: Fn }, T1): ForkEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + ): ForkEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + ): ForkEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + ): ForkEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + R>( + cfn: { context: Ctx, fn: Fn }, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + }; + + declare export var spawn: { + // spawn(fn, ...args) + R>(Fn): ForkEffect, + R>(Fn, T1): ForkEffect, + R>(Fn, T1, T2): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + + // spawn([context, fn], ...args) + R>(cfn: [Ctx, Fn]): ForkEffect, + R>(cfn: [Ctx, Fn], T1): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + R>( + cfn: [Ctx, Fn], + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + }; + + declare export var join: { + // join(task) + // join([...tasks]) + >(task: T): JoinEffect, + >>(tasks: T): JoinEffect, + }; + + declare export var cancel: { + // cancel() + // cancel(task) + // cancel([...tasks]) + (): CancelEffect<"@@redux-saga/SELF_CANCELLATION">, + >(task: T): CancelEffect, + >(tasks: Array): CancelEffect<$ReadOnlyArray>, + }; + + declare export var select: { + // select(selector, ...args) + (): SelectEffect, + R>(Fn): SelectEffect, + R>(Fn, T1): SelectEffect, + R>(Fn, T1, T2): SelectEffect, + R>(Fn, T1, T2, T3): SelectEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + ): SelectEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + ): SelectEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): SelectEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): SelectEffect, + R>( + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): SelectEffect, + }; + + declare export var actionChannel: { + // actionChannel(pattern, [buffer]) + (): ActionChannelEffect, + (pattern: P): ActionChannelEffect, + >(pattern: P, buffer: B): ActionChannelEffect, + }; + + declare export var flush: { + // flush(channel) + >(channel: CH): FlushEffect, + }; + + declare export var cancelled: { + // cancelled() + (): CancelledEffect, + }; + + declare export var setContext: { + // setContext(props) + (props: T): SetContextEffect, + }; + + declare export var getContext: { + // getContext(prop) + (prop: T): GetContextEffect, + }; + + declare export var race: { + // race(effects) + // race([...effects]) + (effects: R): RaceEffect, + >(effects: R): RaceEffect, + }; + + declare export var all: { + // all(effects) + // all([...effects]) + (effects: { +[name: string]: Effect }): AllEffect, + (effects: $ReadOnlyArray): AllEffect, + }; + + declare export var take: { + // take(pattern) + // take(channel) + (): AllTakeEffect, + >(channel: CH): TakeEffect, + (pattern: P): TakeEffect<{ pattern: P }, void, void>, + }; + + declare export var takeMaybe: { + // takeMaybe(pattern) + // takeMaybe(channel) + (): AllTakeEffect<{ maybe: true }>, + >(channel: CH): TakeEffect, + (pattern: P): TakeEffect<{ pattern: P }, void, { maybe: true }>, + }; + + declare export var takeEvery: { + // takeEvery(pattern, saga, ...args) + // takeEvery(channel, saga, ...args) + | Pattern, Fn: A => R>(P, Fn): ForkEffect, + | Pattern, T1, Fn: (T1, A) => R>( + P, + Fn, + T1, + ): ForkEffect, + | Pattern, T1, T2, Fn: (T1, T2, A) => R>( + P, + Fn, + T1, + T2, + ): ForkEffect, + | Pattern, T1, T2, T3, Fn: (T1, T2, T3, A) => R>( + P, + Fn, + T1, + T2, + T3, + ): ForkEffect, + | Pattern, T1, T2, T3, T4, Fn: (T1, T2, T3, T4, A) => R>( + P, + Fn, + T1, + T2, + T3, + T4, + ): ForkEffect, + | Pattern, T1, T2, T3, T4, T5, Fn: (T1, T2, T3, T4, T5, A) => R>( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + Fn: (T1, T2, T3, T4, T5, T6, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + Fn: (T1, T2, T3, T4, T5, T6, T7, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + }; + + declare export var takeLatest: { + // takeLatest(pattern, saga, ...args) + // takeLatest(channel, saga, ...args) + | Pattern, Fn: A => R>(P, Fn): ForkEffect, + | Pattern, T1, Fn: (T1, A) => R>( + P, + Fn, + T1, + ): ForkEffect, + | Pattern, T1, T2, Fn: (T1, T2, A) => R>( + P, + Fn, + T1, + T2, + ): ForkEffect, + | Pattern, T1, T2, T3, Fn: (T1, T2, T3, A) => R>( + P, + Fn, + T1, + T2, + T3, + ): ForkEffect, + | Pattern, T1, T2, T3, T4, Fn: (T1, T2, T3, T4, A) => R>( + P, + Fn, + T1, + T2, + T3, + T4, + ): ForkEffect, + | Pattern, T1, T2, T3, T4, T5, Fn: (T1, T2, T3, T4, T5, A) => R>( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + Fn: (T1, T2, T3, T4, T5, T6, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + Fn: (T1, T2, T3, T4, T5, T6, T7, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + }; + + declare export var takeLeading: { + // takeLeading(pattern, saga, ...args) + // takeLeading(channel, saga, ...args) + | Pattern, Fn: A => R>(P, Fn): ForkEffect, + | Pattern, T1, Fn: (T1, A) => R>( + P, + Fn, + T1, + ): ForkEffect, + | Pattern, T1, T2, Fn: (T1, T2, A) => R>( + P, + Fn, + T1, + T2, + ): ForkEffect, + | Pattern, T1, T2, T3, Fn: (T1, T2, T3, A) => R>( + P, + Fn, + T1, + T2, + T3, + ): ForkEffect, + | Pattern, T1, T2, T3, T4, Fn: (T1, T2, T3, T4, A) => R>( + P, + Fn, + T1, + T2, + T3, + T4, + ): ForkEffect, + | Pattern, T1, T2, T3, T4, T5, Fn: (T1, T2, T3, T4, T5, A) => R>( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + Fn: (T1, T2, T3, T4, T5, T6, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + Fn: (T1, T2, T3, T4, T5, T6, T7, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + < + A, + R, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8, A) => R, + >( + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + }; + + declare export var delay: { + // delay(ms, [val]) + (timeout: T1): CallEffect Promise, [T1]>, + (timeout: T1, T2): CallEffect Promise, [T1, T2]>, + }; + + declare export var throttle: { + // throttle(ms, pattern, saga, ...args) + // throttle(ms, channel, saga, ...args) + | Pattern, A, R, Fn: A => R>( + MS, + P, + Fn, + ): ForkEffect, + | Pattern, A, R, T1, Fn: (T1, A) => R>( + MS, + P, + Fn, + T1, + ): ForkEffect, + | Pattern, A, R, T1, T2, Fn: (T1, T2, A) => R>( + MS, + P, + Fn, + T1, + T2, + ): ForkEffect, + | Pattern, A, R, T1, T2, T3, Fn: (T1, T2, T3, A) => R>( + MS, + P, + Fn, + T1, + T2, + T3, + ): ForkEffect, + < + MS: number, + P: TakeableChannel<*> | Pattern, + A, + R, + T1, + T2, + T3, + T4, + Fn: (T1, T2, T3, T4, A) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + ): ForkEffect, + < + MS: number, + P: TakeableChannel<*> | Pattern, + A, + R, + T1, + T2, + T3, + T4, + T5, + Fn: (T1, T2, T3, T4, T5, A) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + < + MS: number, + P: TakeableChannel<*> | Pattern, + A, + R, + T1, + T2, + T3, + T4, + T5, + T6, + Fn: (T1, T2, T3, T4, T5, T6, A) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + < + MS: number, + P: TakeableChannel<*> | Pattern, + A, + R, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + Fn: (T1, T2, T3, T4, T5, T6, T7, A) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + < + MS: number, + P: TakeableChannel<*> | Pattern, + A, + R, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8, A) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + }; + + declare export var debounce: { + // debounce(ms, pattern, saga, ...args) + // debounce(ms, channel, saga, ...args) + | Pattern, Fn: () => R>( + MS, + P, + Fn, + ): ForkEffect, + | Pattern, T1, Fn: T1 => R>( + MS, + P, + Fn, + T1, + ): ForkEffect, + | Pattern, T1, T2, Fn: (T1, T2) => R>( + MS, + P, + Fn, + T1, + T2, + ): ForkEffect, + | Pattern, T1, T2, T3, Fn: (T1, T2, T3) => R>( + MS, + P, + Fn, + T1, + T2, + T3, + ): ForkEffect, + | Pattern, T1, T2, T3, T4, Fn: (T1, T2, T3, T4) => R>( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + ): ForkEffect, + < + R, + MS: number, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + Fn: (T1, T2, T3, T4, T5) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + ): ForkEffect, + < + R, + MS: number, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + Fn: (T1, T2, T3, T4, T5, T6) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): ForkEffect, + < + R, + MS: number, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + Fn: (T1, T2, T3, T4, T5, T6, T7) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): ForkEffect, + < + R, + MS: number, + P: TakeableChannel<*> | Pattern, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8) => R, + >( + MS, + P, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): ForkEffect, + }; + + declare export var retry: { + // retry(maxTries, delay, fn, ...args) + R>(MT, D, Fn): CallEffect, + R>( + MT, + D, + Fn, + T1, + ): CallEffect, + R>( + MT, + D, + Fn, + T1, + T2, + ): CallEffect, + R>( + MT, + D, + Fn, + T1, + T2, + T3, + ): CallEffect, + R>( + MT, + D, + Fn, + T1, + T2, + T3, + T4, + ): CallEffect, + R>( + MT, + D, + Fn, + T1, + T2, + T3, + T4, + T5, + ): CallEffect, + R>( + MT, + D, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + ): CallEffect, + R>( + MT, + D, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + ): CallEffect, + < + R, + MT: number, + D: number, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + Fn: (T1, T2, T3, T4, T5, T6, T7, T8) => R, + >( + MT, + D, + Fn, + T1, + T2, + T3, + T4, + T5, + T6, + T7, + T8, + ): CallEffect, + }; +} diff --git a/frontend/javascripts/admin/admin_rest_api.js b/frontend/javascripts/admin/admin_rest_api.js index bdf51e4755e..340fb6ff7ed 100644 --- a/frontend/javascripts/admin/admin_rest_api.js +++ b/frontend/javascripts/admin/admin_rest_api.js @@ -944,6 +944,20 @@ export async function triggerSampleDatasetDownload( ); } +export async function getMeanAndStdDevFromDataset( + datastoreUrl: string, + datasetId: APIDatasetId, + layerName: string, +): Promise<{ mean: number, stdDev: number }> { + return doWithToken(token => + Request.receiveJSON( + `${datastoreUrl}/data/datasets/${datasetId.owningOrganization}/${ + datasetId.name + }/layers/${layerName}/colorStatistics?token=${token}`, + ), + ); +} + // #### Datastores export async function getDatastores(): Promise> { const datastores = await Request.receiveJSON("/api/datastores"); diff --git a/frontend/javascripts/admin/help/keyboardshortcut_view.js b/frontend/javascripts/admin/help/keyboardshortcut_view.js index 1f2d1f1f692..e8d305fe9e5 100644 --- a/frontend/javascripts/admin/help/keyboardshortcut_view.js +++ b/frontend/javascripts/admin/help/keyboardshortcut_view.js @@ -21,6 +21,10 @@ const KeyboardShortcutView = () => { keybinding: "Left Mouse Drag or Arrow Keys", action: "Move", }, + { + keybinding: "Alt + Mouse Move", + action: "Move", + }, { keybinding: "I, O, or Alt + Mousewheel", action: "Zoom In/out", @@ -211,6 +215,10 @@ const KeyboardShortcutView = () => { keybinding: "Ctrl + Right Mouse Drag", action: "Remove Voxels From Any Cell", }, + { + keybinding: "Alt + Mouse Move", + action: "Move", + }, { keybinding: "C", action: "Create New Cell", diff --git a/frontend/javascripts/libs/ThreeDMap.js b/frontend/javascripts/libs/ThreeDMap.js index 3fe963340c0..3055e822aca 100644 --- a/frontend/javascripts/libs/ThreeDMap.js +++ b/frontend/javascripts/libs/ThreeDMap.js @@ -43,4 +43,10 @@ export default class ThreeDMap { .get(y) .set(z, value); } + + // This could be extended so the key is a Vector1 | Vector2 + // if needed in the future + delete(key: number): boolean { + return this.map.delete(key); + } } diff --git a/frontend/javascripts/libs/floodfill.js b/frontend/javascripts/libs/floodfill.js new file mode 100644 index 00000000000..e300885c0df --- /dev/null +++ b/frontend/javascripts/libs/floodfill.js @@ -0,0 +1,88 @@ +// @flow + +// Adapted from https://github.com/tuzz/n-dimensional-flood-fill +// This floodfill is highly customized to work well for the automatic brush feature. +// It's a forward-only 3D floodfill that will first fill a whole 2d slice, then call onFlood +// with the result, and then go on and fill the next 2d slice. + +type Vector3 = [number, number, number]; + +type FloodfillOptions = { + getter: (number, number, number) => Promise, + seed: Vector3, + onFlood: (Array) => Promise, +}; + +export default function(options: FloodfillOptions) { + const noop = () => {}; + + const { getter, seed } = options; + const onFlood = options.onFlood || noop; + // Disallow negative z + const permutations: Array = [[-1, 0, 0], [0, -1, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0]]; + let stack: Array = []; + let nextStack: Array = []; + let flooded = []; + const visits = {}; + + const visited = key => visits[key.toString()] === true; + + const markAsVisited = key => { + visits[key.toString()] = true; + }; + + const member = getArgs => getter(getArgs[0], getArgs[1], getArgs[2]); + + const markAsFlooded = getArgs => { + flooded.push(getArgs); + }; + + const pushAdjacent = getArgs => { + for (let i = 0; i < permutations.length; i += 1) { + const perm = permutations[i]; + const nextArgs = [getArgs[0], getArgs[1], getArgs[2]]; + + for (let j = 0; j < getArgs.length; j += 1) { + nextArgs[j] += perm[j]; + } + + if (perm[2] === 0) { + stack.push(nextArgs); + } else { + // Push permutations for the next z-slice to a separate stack + nextStack.push(nextArgs); + } + } + }; + + const flood = async getArgs => { + if (visited(getArgs)) { + return; + } + markAsVisited(getArgs); + + if (await member(getArgs)) { + markAsFlooded(getArgs); + pushAdjacent(getArgs); + } + }; + + const main = async () => { + stack.push(seed); + + while (stack.length > 0) { + // eslint-disable-next-line no-await-in-loop + await flood(stack.pop()); + + if (stack.length === 0) { + // eslint-disable-next-line no-await-in-loop + await onFlood(flooded); + stack = nextStack; + nextStack = []; + flooded = []; + } + } + }; + + return main(); +} diff --git a/frontend/javascripts/libs/mjs.js b/frontend/javascripts/libs/mjs.js index 945280ecc5a..210e3718ff1 100644 --- a/frontend/javascripts/libs/mjs.js +++ b/frontend/javascripts/libs/mjs.js @@ -221,4 +221,11 @@ V3.toArray = function(vec) { return [vec[0], vec[1], vec[2]]; }; +V2.scale2 = function scale2(a, k, r) { + if (r == null) r = new Float32Array(2); + r[0] = a[0] * k[0]; + r[1] = a[1] * k[1]; + return r; +}; + export { M4x4, V2, V3 }; diff --git a/frontend/javascripts/libs/toast.js b/frontend/javascripts/libs/toast.js index 2b2a3f608da..178af82b8eb 100644 --- a/frontend/javascripts/libs/toast.js +++ b/frontend/javascripts/libs/toast.js @@ -10,6 +10,7 @@ export type ToastConfig = { sticky?: boolean, timeout?: number, key?: string, + onClose?: () => void, }; const Toast = { @@ -54,7 +55,7 @@ const Toast = { message(type: ToastStyle, message: string | React$Element, config: ToastConfig): void { const timeout = config.timeout != null ? config.timeout : 6000; const key = config.key || (typeof message === "string" ? message : null); - const sticky = config.sticky; + const { sticky, onClose } = config; let toastMessage; if (typeof message === "string" && message.match(/]*>/)) { const src = `data:text/html;charset=utf-8,${escape(message)}`; @@ -72,6 +73,7 @@ const Toast = { message: toastMessage, style: {}, className: "", + onClose, }; if (type === "error") { diff --git a/frontend/javascripts/oxalis/api/api_latest.js b/frontend/javascripts/oxalis/api/api_latest.js index 26527d82cef..f3960a8c38e 100644 --- a/frontend/javascripts/oxalis/api/api_latest.js +++ b/frontend/javascripts/oxalis/api/api_latest.js @@ -5,17 +5,21 @@ import TWEEN from "tween.js"; import _ from "lodash"; +import { V3 } from "libs/mjs"; import { + type BoundingBoxType, type ControlMode, ControlModeEnum, OrthoViews, type Vector3, + type Vector4, type VolumeTool, VolumeToolEnum, } from "oxalis/constants"; import { InputKeyboardNoLoop } from "libs/input"; import { PullQueueConstants } from "oxalis/model/bucket_data_handling/pullqueue"; +import { type Bucket } from "oxalis/model/bucket_data_handling/bucket"; import type { Versions } from "oxalis/view/version_view"; import { callDeep } from "oxalis/view/right-menu/tree_hierarchy_view_helpers"; import { centerTDViewAction } from "oxalis/model/actions/view_mode_actions"; @@ -39,6 +43,10 @@ import { getActiveCellId, getVolumeTool } from "oxalis/model/accessors/volumetra import { getLayerBoundaries } from "oxalis/model/accessors/dataset_accessor"; import { getPosition, getRotation } from "oxalis/model/accessors/flycam_accessor"; import { overwriteAction } from "oxalis/model/helpers/overwrite_action_middleware"; +import { + bucketPositionToGlobalAddress, + globalPositionToBaseBucket, +} from "oxalis/model/helpers/position_converter"; import { rotate3DViewTo } from "oxalis/controller/camera_controller"; import { setActiveCellAction, setToolAction } from "oxalis/model/actions/volumetracing_actions"; import { @@ -76,6 +84,7 @@ import Store, { } from "oxalis/store"; import Toast, { type ToastStyle } from "libs/toast"; import UrlManager from "oxalis/controller/url_manager"; +import Request from "libs/request"; import * as Utils from "libs/utils"; import dimensions from "oxalis/model/dimensions"; import messages from "messages"; @@ -756,6 +765,8 @@ class DataApi { if (bucket.type === "null") return 0; + // todo: use new getBucket api here instead + let needsToAwaitBucket = false; if (bucket.isRequested()) { needsToAwaitBucket = true; @@ -773,6 +784,108 @@ class DataApi { return cube.getDataValue(position, null, zoomStep); } + async getLoadedBucket(layerName: string, bucketAddress: Vector4): Promise { + const cube = this.model.getCubeByLayerName(layerName); + const pullQueue = this.model.getPullQueueByLayerName(layerName); + const bucket = cube.getOrCreateBucket(bucketAddress); + + if (bucket.type === "null") return bucket; + + let needsToAwaitBucket = false; + if (bucket.isRequested()) { + needsToAwaitBucket = true; + } else if (bucket.needsRequest()) { + pullQueue.add({ bucket: bucketAddress, priority: -1 }); + pullQueue.pull(); + needsToAwaitBucket = true; + } + if (needsToAwaitBucket) { + await new Promise(resolve => { + bucket.on("bucketLoaded", resolve); + }); + } + // Bucket has been loaded by now or was loaded already + return bucket; + } + + async getDataFor2DBoundingBox(layerName: string, bbox: BoundingBoxType) { + const bucketAddresses = this.getBucketAddressesInCuboid(bbox); + const buckets = await Promise.all( + bucketAddresses.map(addr => this.getLoadedBucket(layerName, addr)), + ); + return this.cutOutCuboid(buckets, bbox); + } + + getBucketAddressesInCuboid(bbox: BoundingBoxType): Array { + const buckets = []; + const bottomRight = bbox.max; + const minBucket = globalPositionToBaseBucket(bbox.min); + const topLeft = bucketAddress => bucketPositionToGlobalAddress(bucketAddress, [[1, 1, 1]]); + const nextBucketInDim = (bucket, dim) => { + const copy = bucket.slice(); + copy[dim]++; + return ((copy: any): Vector4); + }; + + let bucket = minBucket; + while (topLeft(bucket)[0] < bottomRight[0]) { + const prevX = bucket.slice(); + while (topLeft(bucket)[1] < bottomRight[1]) { + const prevY = bucket.slice(); + while (topLeft(bucket)[2] < bottomRight[2]) { + buckets.push(bucket); + bucket = nextBucketInDim(bucket, 2); + } + bucket = nextBucketInDim(prevY, 1); + } + + bucket = nextBucketInDim(prevX, 0); + } + return buckets; + } + + cutOutCuboid(buckets: Array, bbox: BoundingBoxType): Uint8Array { + const extent = V3.sub(bbox.max, bbox.min); + const result = new Uint8Array(extent[0] * extent[1] * extent[2]); + const bucketLength = 32; + buckets.reverse(); + + for (const bucket of buckets) { + if (bucket.type === "null") { + continue; + } + const bucketTopLeft = bucketPositionToGlobalAddress(bucket.zoomedAddress, [[1, 1, 1]]); + const x = Math.max(bbox.min[0], bucketTopLeft[0]); + let y = Math.max(bbox.min[1], bucketTopLeft[1]); + let z = Math.max(bbox.min[2], bucketTopLeft[2]); + + const xMax = Math.min(bucketTopLeft[0] + bucketLength, bbox.max[0]); + const yMax = Math.min(bucketTopLeft[1] + bucketLength, bbox.max[1]); + const zMax = Math.min(bucketTopLeft[2] + bucketLength, bbox.max[2]); + + while (z < zMax) { + y = Math.max(bbox.min[1], bucketTopLeft[1]); + while (y < yMax) { + const dataOffset = + (x % bucketLength) + + (y % bucketLength) * bucketLength + + (z % bucketLength) * bucketLength * bucketLength; + const rx = x - bbox.min[0]; + const ry = y - bbox.min[1]; + const rz = z - bbox.min[2]; + + const resultOffset = rx + ry * extent[0] + rz * extent[0] * extent[1]; + const data = bucket.type !== "null" ? bucket.getData() : new Uint8Array(32 ** 3); + const length = xMax - x; + result.set(data.slice(dataOffset, dataOffset + length), resultOffset); + y += 1; + } + z += 1; + } + } + return result; + } + /** * Downloads a cuboid of raw data from a dataset (not tracing) layer. A new window is opened for the download - * if that is not the case, please check your pop-up blocker. @@ -802,6 +915,28 @@ class DataApi { }); } + getRawDataCuboid(layerName: string, topLeft: Vector3, bottomRight: Vector3): Promise { + const dataset = Store.getState().dataset; + + return doWithToken(token => { + const downloadUrl = + `${dataset.dataStore.url}/data/datasets/${dataset.owningOrganization}/${ + dataset.name + }/layers/${layerName}/data?resolution=0&` + + `token=${token}&` + + `x=${topLeft[0]}&` + + `y=${topLeft[1]}&` + + `z=${topLeft[2]}&` + + `width=${bottomRight[0] - topLeft[0]}&` + + `height=${bottomRight[1] - topLeft[1]}&` + + `depth=${bottomRight[2] - topLeft[2]}`; + + // Theoretically the window.open call could fail if the token is expired, but that would be hard to check + + return Request.receiveArraybuffer(downloadUrl); + }); + } + /** * Label voxels with the supplied value. * _Volume tracing only!_ diff --git a/frontend/javascripts/oxalis/controller/combinations/volumetracing_plane_controller.js b/frontend/javascripts/oxalis/controller/combinations/volumetracing_plane_controller.js index 26ea9fae624..fe6896c68a1 100644 --- a/frontend/javascripts/oxalis/controller/combinations/volumetracing_plane_controller.js +++ b/frontend/javascripts/oxalis/controller/combinations/volumetracing_plane_controller.js @@ -23,6 +23,7 @@ import { setContourTracingMode, cycleToolAction, copySegmentationLayerAction, + inferSegmentationInViewportAction, setActiveCellAction, } from "oxalis/model/actions/volumetracing_actions"; import { getPosition, getRequestLogZoomStep } from "oxalis/model/accessors/flycam_accessor"; @@ -36,6 +37,9 @@ import Model from "oxalis/model"; import Store from "oxalis/store"; import * as Utils from "libs/utils"; +// TODO: Build proper UI for this +window.isAutomaticBrushEnabled = false; + // eslint-disable-next-line no-unused-vars const simulateTracing = async (): Promise => { Store.dispatch(setToolAction(VolumeToolEnum.TRACE)); @@ -91,6 +95,9 @@ export function getPlaneMouseControls(_planeId: OrthoView): * { if (!event.shiftKey && (tool === VolumeToolEnum.TRACE || tool === VolumeToolEnum.BRUSH)) { if (event.ctrlKey) { + if (window.isAutomaticBrushEnabled) { + return; + } Store.dispatch(setContourTracingMode(ContourModeEnum.DRAW)); } else { Store.dispatch(setContourTracingMode(ContourModeEnum.DRAW_OVERWRITE)); @@ -161,6 +168,10 @@ export function getPlaneMouseControls(_planeId: OrthoView): * { if (cellId > 0) { Store.dispatch(setActiveCellAction(cellId)); } + } else if (event.ctrlKey) { + if (window.isAutomaticBrushEnabled) { + Store.dispatch(inferSegmentationInViewportAction(calculateGlobalPos(pos))); + } } }, diff --git a/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js b/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js index 9cd64557cb8..6bdb8ccf84e 100644 --- a/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js +++ b/frontend/javascripts/oxalis/controller/viewmodes/plane_controller.js @@ -163,8 +163,12 @@ class PlaneController extends React.PureComponent { Store.dispatch(setViewportAction(planeId)); }, pinch: delta => this.zoom(delta, true), - mouseMove: (delta: Point2, position: Point2) => { - Store.dispatch(setMousePositionAction([position.x, position.y])); + mouseMove: (delta: Point2, position: Point2, id, event) => { + if (event.altKey) { + this.movePlane([-delta.x, -delta.y, 0]); + } else { + Store.dispatch(setMousePositionAction([position.x, position.y])); + } }, }; // TODO: Find a nicer way to express this, while satisfying flow diff --git a/frontend/javascripts/oxalis/model/actions/volumetracing_actions.js b/frontend/javascripts/oxalis/model/actions/volumetracing_actions.js index 7154822fd35..02aef1960c5 100644 --- a/frontend/javascripts/oxalis/model/actions/volumetracing_actions.js +++ b/frontend/javascripts/oxalis/model/actions/volumetracing_actions.js @@ -25,6 +25,10 @@ type ResetContourAction = { type: "RESET_CONTOUR" }; type SetMousePositionAction = { type: "SET_MOUSE_POSITION", position: Vector2 }; type HideBrushAction = { type: "HIDE_BRUSH" }; type SetContourTracingMode = { type: "SET_CONTOUR_TRACING_MODE", mode: ContourMode }; +export type InferSegmentationInViewportAction = { + type: "INFER_SEGMENT_IN_VIEWPORT", + position: Vector3, +}; export type VolumeTracingAction = | InitializeVolumeTracingAction @@ -40,6 +44,7 @@ export type VolumeTracingAction = | SetMousePositionAction | HideBrushAction | CopySegmentationLayerAction + | InferSegmentationInViewportAction | SetContourTracingMode; export const VolumeTracingSaveRelevantActions = [ @@ -116,3 +121,10 @@ export const setContourTracingMode = (mode: ContourMode): SetContourTracingMode type: "SET_CONTOUR_TRACING_MODE", mode, }); + +export const inferSegmentationInViewportAction = ( + position: Vector3, +): InferSegmentationInViewportAction => ({ + type: "INFER_SEGMENT_IN_VIEWPORT", + position, +}); diff --git a/frontend/javascripts/oxalis/model/sagas/automatic_brush_saga.js b/frontend/javascripts/oxalis/model/sagas/automatic_brush_saga.js new file mode 100644 index 00000000000..91c44590bb4 --- /dev/null +++ b/frontend/javascripts/oxalis/model/sagas/automatic_brush_saga.js @@ -0,0 +1,259 @@ +// @flow +import * as tf from "@tensorflow/tfjs"; +import memoizeOne from "memoize-one"; + +import { type Saga, call, fork, select, take, _cancel } from "oxalis/model/sagas/effect-generators"; +import floodfill from "libs/floodfill"; +import { FlycamActions } from "oxalis/model/actions/flycam_actions"; +import { type InferSegmentationInViewportAction } from "oxalis/model/actions/volumetracing_actions"; +import { sleep } from "libs/utils"; +import { type Vector2, type Vector3, type OrthoView, OrthoViews } from "oxalis/constants"; +import { getMeanAndStdDevFromDataset } from "admin/admin_rest_api"; +import type { APIDataset } from "admin/api_flow_types"; +import { createWorker } from "oxalis/workers/comlink_wrapper"; +import TensorFlowWorker from "oxalis/workers/tensorflow.worker"; +import mainThreadPredict from "oxalis/workers/tensorflow.impl"; +import ThreeDMap from "libs/ThreeDMap"; +import Model from "oxalis/model"; +import Toast from "libs/toast"; +import { enforceVolumeTracing } from "oxalis/model/accessors/volumetracing_accessor"; +import Dimensions from "oxalis/model/dimensions"; +import api from "oxalis/api/internal_api"; +import { + getPosition, + getPlaneExtentInVoxelFromStore, +} from "oxalis/model/accessors/flycam_accessor"; +import { V2 } from "libs/mjs"; +import { getBaseVoxelFactors } from "oxalis/model/scaleinfo"; + +const outputExtent = 100; +const inputContextExtent = 20; +const inputExtent = outputExtent + 2 * inputContextExtent; +const NUM_PREDICT_SLICES = 3; + +// Will remove model validation, NaN checks, and other correctness checks in favor of performance +if (process.env.NODE_ENV === "production") tf.enableProdMode(); + +const workerPredict = createWorker(TensorFlowWorker); + +const configureTensorFlow = (useWebworker, useGPU) => { + window.useWebworker = useWebworker; + window.useGPU = useGPU; + console.log("useWebworker set to", useWebworker, "and useGPU set to", useGPU); +}; + +// $FlowIgnore +const isOffscreenCanvasSupported = typeof OffscreenCanvas !== "undefined"; +configureTensorFlow(isOffscreenCanvasSupported, true); +window.configureTensorFlow = configureTensorFlow; + +const meanAndStdDevFromDataset = memoizeOne( + (dataset: APIDataset, layerName: string): Promise<{ mean: number, stdDev: number }> => + getMeanAndStdDevFromDataset(dataset.dataStore.url, dataset, layerName), +); + +const getUseWebworkerAndGPU = () => { + const useWebworker = window.useWebworker != null ? window.useWebworker : false; + const useGPU = window.useGPU != null ? window.useGPU : false; + return { useWebworker, useGPU }; +}; + +const getPredictionForTile = async ( + tileX, + tileY, + tileZ, + activeViewport, + dataset, + colorLayerName, +) => { + const x = tileX * outputExtent; + const y = tileY * outputExtent; + const z = tileZ; + const min = Dimensions.transDim( + [x - inputContextExtent, y - inputContextExtent, z], + activeViewport, + ); + const max = Dimensions.transDim( + [x - inputContextExtent + inputExtent, y - inputContextExtent + inputExtent, z + 1], + activeViewport, + ); + + const cuboidData = await api.data.getDataFor2DBoundingBox(colorLayerName, { + min, + max, + }); + + const { mean, stdDev } = await meanAndStdDevFromDataset(dataset, colorLayerName); + const tensorArray = new Float32Array(new Uint8Array(cuboidData)).map( + // This is how the model was trained + el => ((el - mean) / stdDev) * (1 / 3) ** 0.5, + ); + // When interpreting the 3d data slice as a 2d slice, the x and y axis are flipped only on the YZ plane + const isXYflipped = activeViewport === OrthoViews.PLANE_YZ; + const { useWebworker, useGPU } = getUseWebworkerAndGPU(); + + return useWebworker + ? workerPredict(useGPU, tensorArray.buffer, inputExtent, isXYflipped) + : mainThreadPredict(useGPU, tf, tensorArray.buffer, inputExtent, isXYflipped); +}; + +const labelFloodedVoxels = async ( + predictions: ThreeDMap, + activeViewport: OrthoView, + activeCellId: number, + floodedVoxels: Array, +) => { + console.time("label"); + if (floodedVoxels.length > 0) { + // Clean up - If the whole z slice has been flooded, the prediction is no longer needed + const [, , tileZ] = floodedVoxels[0]; + predictions.delete(tileZ); + } + const voxelAddresses = floodedVoxels.map(addressUVW => + Dimensions.transDim(addressUVW, activeViewport), + ); + api.data.labelVoxels(voxelAddresses, activeCellId); + console.timeEnd("label"); + // Do not block the main thread and allow for some interactivity after labeling a slice + await sleep(500); +}; + +export default function* inferSegmentInViewport( + action: InferSegmentationInViewportAction, +): Saga { + const allowUpdate = yield* select(state => state.tracing.restrictions.allowUpdate); + if (!allowUpdate) return; + + const activeViewport = yield* select(state => state.viewModeData.plane.activeViewport); + if (activeViewport === "TDView") return; + + const FLOODFILL_THRESHOLD = window.floodfillThreshold || 0.6; + + let aborted = false; + const toastConfig = { + onClose: () => { + aborted = true; + }, + sticky: true, + key: "automatic-brush", + }; + const toastDescription = "Automatic brush is active. Close the toast to stop using it."; + + Toast.info(toastDescription, toastConfig); + + const colorLayers = yield* call([Model, Model.getColorLayers]); + const colorLayerName = colorLayers[0].name; + if (colorLayers.length > 1) { + Toast.warning( + `There are multiple color layers. Using ${colorLayerName} for automatic segmentation.`, + ); + } + let [halfViewportExtentX, halfViewportExtentY] = yield* call( + getHalfViewportExtents, + activeViewport, + ); + const dataset = yield* select(state => state.dataset); + const activeCellId = yield* select(state => enforceVolumeTracing(state.tracing).activeCellId); + + let [curX, curY, curZ] = Dimensions.transDim( + Dimensions.roundCoordinate(yield* select(state => getPosition(state.flycam))), + activeViewport, + ); + const clickPosition = Dimensions.transDim( + Dimensions.roundCoordinate(action.position), + activeViewport, + ); + + const predictions: ThreeDMap = new ThreeDMap(); + const { useWebworker, useGPU } = getUseWebworkerAndGPU(); + console.log("useWebworker", useWebworker); + console.log("useGPU", useGPU); + + function* currentPositionAndViewportUpdater(): Saga { + while (true) { + yield* take(FlycamActions); + [curX, curY, curZ] = Dimensions.transDim( + Dimensions.roundCoordinate(yield* select(state => getPosition(state.flycam))), + activeViewport, + ); + [halfViewportExtentX, halfViewportExtentY] = yield* call( + getHalfViewportExtents, + activeViewport, + ); + } + } + + const getter = async (x, y, z): Promise => { + if ( + x < curX - halfViewportExtentX || + y < curY - halfViewportExtentY || + z < curZ || + x >= curX + halfViewportExtentX || + y >= curY + halfViewportExtentY + ) { + return false; + } + + // If the current z-slice is too far ahead, wait + // eslint-disable-next-line no-await-in-loop + while (z >= curZ + NUM_PREDICT_SLICES && !aborted) await sleep(500); + + const tileX = Math.floor(x / outputExtent); + const tileY = Math.floor(y / outputExtent); + const tileZ = z; + + if (predictions.get([tileZ, tileY, tileX]) == null) { + // Do not make new predictions if the automatic brush has been aborted + if (aborted) return false; + console.time("predict"); + const thirdDimension = Dimensions.thirdDimensionForPlane(activeViewport); + Toast.info( + `${toastDescription}\nLabeling ${["x", "y", "z"][thirdDimension]}=${z}.`, + toastConfig, + ); + predictions.set( + [tileZ, tileY, tileX], + await getPredictionForTile(tileX, tileY, tileZ, activeViewport, dataset, colorLayerName), + ); + console.timeEnd("predict"); + } + + const relX = x % outputExtent; + const relY = y % outputExtent; + const prediction = predictions.get([tileZ, tileY, tileX]); + if (prediction != null) return prediction[relX * outputExtent + relY] > FLOODFILL_THRESHOLD; + throw new Error("This should never happen, prediction was set, but geting it failed."); + }; + + const seed = clickPosition; + const seedPrediction = yield* call(getter, ...seed); + if (seedPrediction) { + // Keep updating the current position + const updaterTask = yield* fork(currentPositionAndViewportUpdater); + + // Do not use _.partial in order to keep type information + const onFlood = voxels => labelFloodedVoxels(predictions, activeViewport, activeCellId, voxels); + // This call will block until the automatic brush is aborted or the floodfill is exhausted + yield* call(floodfill, { getter, seed, onFlood }); + + yield _cancel(updaterTask); + } else { + Toast.warning("Click position is classified as border, please click inside a segment instead."); + } + + Toast.close(toastConfig.key); +} + +export function* getHalfViewportExtents(activeViewport: OrthoView): Saga { + const zoom = yield* select(state => state.flycam.zoomStep); + const baseVoxelFactors = yield* select(state => + Dimensions.transDim(getBaseVoxelFactors(state.dataset.dataSource.scale), activeViewport), + ); + const viewportExtents = yield* select(state => + getPlaneExtentInVoxelFromStore(state, zoom, activeViewport), + ); + const scaledViewportExtents = V2.scale2(viewportExtents, baseVoxelFactors); + + const halfViewportExtents = scaledViewportExtents.map(extent => Math.round(extent / 2)); + return halfViewportExtents; +} diff --git a/frontend/javascripts/oxalis/model/sagas/effect-generators.js b/frontend/javascripts/oxalis/model/sagas/effect-generators.js index 52848364821..3c0dc13223f 100644 --- a/frontend/javascripts/oxalis/model/sagas/effect-generators.js +++ b/frontend/javascripts/oxalis/model/sagas/effect-generators.js @@ -37,6 +37,8 @@ export function* race(...args) { export const _take = IOEffects.take; export const _call = IOEffects.call; export const _takeEvery = IOEffects.takeEvery; +export const _takeLeading = IOEffects.takeLeading; export const _throttle = IOEffects.throttle; export const _cancel = IOEffects.cancel; export const _all = IOEffects.all; +export const _delay = IOEffects.delay; diff --git a/frontend/javascripts/oxalis/model/sagas/effect-generators.js.flow b/frontend/javascripts/oxalis/model/sagas/effect-generators.js.flow index 3d7bb0c6e87..7a5538dcca9 100644 --- a/frontend/javascripts/oxalis/model/sagas/effect-generators.js.flow +++ b/frontend/javascripts/oxalis/model/sagas/effect-generators.js.flow @@ -14,7 +14,9 @@ import { race as typedRace, take as typedTake, call as typedCall, + delay as typedDelay, takeEvery as typedTakeEvery, + takeLeading as typedTakeLeading, throttle as typedThrottle, cancel as typedCancel, } from 'redux-saga/effects'; @@ -143,7 +145,7 @@ declare type CallFn = declare type PutFn = { (action: T): Generator<*, void, *>; - (channel: Channel, action: T): Generator<*, void, *>; + (channel: Channel, action: T): Generator<*, void, *>; } type ExtractReturnType = ((...args: any) => R) => R; @@ -170,6 +172,8 @@ declare export var _all : typeof typedAll; declare export var _take : typeof typedTake; declare export var _call : typeof typedCall; declare export var _takeEvery : typeof typedTakeEvery; +declare export var _takeLeading : typeof typedTakeLeading; declare export var _throttle : typeof typedThrottle; declare export var _cancel : typeof typedCancel; +declare export var _delay : typeof typedDelay; export type Saga = _Saga; diff --git a/frontend/javascripts/oxalis/model/sagas/save_saga.js b/frontend/javascripts/oxalis/model/sagas/save_saga.js index 45af9aa9e8d..89c888cc7bd 100644 --- a/frontend/javascripts/oxalis/model/sagas/save_saga.js +++ b/frontend/javascripts/oxalis/model/sagas/save_saga.js @@ -3,7 +3,7 @@ * @flow */ -import { type Saga, delay } from "redux-saga"; +import { type Saga } from "redux-saga"; import Maybe from "data.maybe"; import { FlycamActions } from "oxalis/model/actions/flycam_actions"; @@ -19,6 +19,7 @@ import { type UpdateAction } from "oxalis/model/sagas/update_actions"; import { VolumeTracingSaveRelevantActions } from "oxalis/model/actions/volumetracing_actions"; import { _all, + _delay, take, _take, _call, @@ -114,7 +115,7 @@ export function* pushTracingTypeAsync(tracingType: "skeleton" | "volume"): Saga< yield* take("PUSH_SAVE_QUEUE_TRANSACTION"); } yield* race({ - timeout: _call(delay, PUSH_THROTTLE_TIME), + timeout: _delay(PUSH_THROTTLE_TIME), forcePush: _take("SAVE_NOW"), }); yield* put(setSaveBusyAction(true, tracingType)); @@ -201,7 +202,7 @@ export function* sendRequestToServer(tracingType: "skeleton" | "volume"): Saga { yield* take("WK_READY"); yield _takeEvery("COPY_SEGMENTATION_LAYER", copySegmentationLayer); + yield _takeLeading("INFER_SEGMENT_IN_VIEWPORT", inferSegmentInViewport); yield* fork(warnOfTooLowOpacity); } @@ -131,24 +130,11 @@ export function* editVolumeLayerAsync(): Generator { function* getBoundingsFromPosition(currentViewport: OrthoView): Saga { const position = Dimensions.roundCoordinate(yield* select(state => getPosition(state.flycam))); - const zoom = yield* select(state => state.flycam.zoomStep); - const baseVoxelFactors = yield* select(state => - getBaseVoxelFactors(state.dataset.dataSource.scale), - ); - const halfViewportExtentXY = yield* select(state => { - const extents = getViewportExtents(state)[currentViewport]; - return map2(el => (el / 2) * zoom, extents); - }); - const halfViewportExtentUVW = Dimensions.transDim([...halfViewportExtentXY, 0], currentViewport); - - const halfViewportBounds = V3.ceil([ - halfViewportExtentUVW[0] * baseVoxelFactors[0], - halfViewportExtentUVW[1] * baseVoxelFactors[1], - halfViewportExtentUVW[2] * baseVoxelFactors[2], - ]); + const halfViewportExtents = yield* call(getHalfViewportExtents, currentViewport); + const halfViewportExtentsUVW = Dimensions.transDim([...halfViewportExtents, 0], currentViewport); return { - min: V3.sub(position, halfViewportBounds), - max: V3.add(position, halfViewportBounds), + min: V3.sub(position, halfViewportExtentsUVW), + max: V3.add(position, halfViewportExtentsUVW), }; } @@ -195,12 +181,10 @@ function* copySegmentationLayer(action: CopySegmentationLayerAction): Saga const segmentationLayer = yield* call([Model, Model.getSegmentationLayer]); const position = Dimensions.roundCoordinate(yield* select(state => getPosition(state.flycam))); - const zoom = yield* select(state => state.flycam.zoomStep); - const baseVoxelFactors = yield* select(state => - Dimensions.transDim(getBaseVoxelFactors(state.dataset.dataSource.scale), activeViewport), + const [halfViewportExtentX, halfViewportExtentY] = yield* call( + getHalfViewportExtents, + activeViewport, ); - const halfViewportWidth = Math.round((Constants.VIEWPORT_WIDTH / 2) * zoom); - const [scaledOffsetX, scaledOffsetY] = baseVoxelFactors.map(f => halfViewportWidth * f); const activeCellId = yield* select(state => enforceVolumeTracing(state.tracing).activeCellId); @@ -225,8 +209,8 @@ function* copySegmentationLayer(action: CopySegmentationLayerAction): Saga const [tx, ty, tz] = Dimensions.transDim(position, activeViewport); const z = tz; - for (let x = tx - scaledOffsetX; x < tx + scaledOffsetX; x++) { - for (let y = ty - scaledOffsetY; y < ty + scaledOffsetY; y++) { + for (let x = tx - halfViewportExtentX; x < tx + halfViewportExtentX; x++) { + for (let y = ty - halfViewportExtentY; y < ty + halfViewportExtentY; y++) { copyVoxelLabel( Dimensions.transDim([x, y, tz + direction * directionInverter], activeViewport), Dimensions.transDim([x, y, z], activeViewport), diff --git a/frontend/javascripts/oxalis/workers/tensorflow.impl.js b/frontend/javascripts/oxalis/workers/tensorflow.impl.js new file mode 100644 index 00000000000..3d4746e0d6c --- /dev/null +++ b/frontend/javascripts/oxalis/workers/tensorflow.impl.js @@ -0,0 +1,36 @@ +// @flow +let segmentationModel = null; + +export default async function predict( + useGPU: boolean, + tf: Object, + buffer: ArrayBuffer, + inputExtent: number, + isXYflipped: boolean, +) { + if (useGPU) { + tf.setBackend("webgl"); + } else { + tf.setBackend("cpu"); + } + + const tensorArray = new Float32Array(buffer); + if (segmentationModel == null) { + segmentationModel = await tf.loadLayersModel("/assets/bundle/tf-models/seg-model.json", { + strict: true, + }); + } + + let tensor = tf.tensor4d(tensorArray, [1, inputExtent, inputExtent, 1]); + // The tensorflow model expects a flipped x/y-axis + if (!isXYflipped) { + tensor = tf.transpose(tensor, [0, 2, 1, 3]); + } + + const model = segmentationModel; + const inferredTensor = model.predict(tensor); + const data = await inferredTensor.data(); + tensor.dispose(); + inferredTensor.dispose(); + return data; +} diff --git a/frontend/javascripts/oxalis/workers/tensorflow.worker.js b/frontend/javascripts/oxalis/workers/tensorflow.worker.js new file mode 100644 index 00000000000..1b690b49bf7 --- /dev/null +++ b/frontend/javascripts/oxalis/workers/tensorflow.worker.js @@ -0,0 +1,27 @@ +// @flow +import { expose } from "./comlink_wrapper"; +import predict from "./tensorflow.impl.js"; + +// Taken from https://github.com/tensorflow/tfjs/issues/102#issuecomment-465952614 +// $FlowIgnore +if (typeof OffscreenCanvas !== "undefined") { + self.document = { + createElement: () => new OffscreenCanvas(640, 480), + }; + self.window = self; + self.screen = { + width: 640, + height: 480, + }; + self.HTMLVideoElement = function() {}; + self.HTMLImageElement = function() {}; + self.HTMLCanvasElement = function() {}; +} + +const tf = require("@tensorflow/tfjs"); + +function predictWrapper(useGPU, buffer: ArrayBuffer, inputExtent: number, isXYflipped: boolean) { + return predict(useGPU, tf, buffer, inputExtent, isXYflipped); +} + +export default expose(predictWrapper); diff --git a/frontend/javascripts/test/helpers/sagaHelpers.js b/frontend/javascripts/test/helpers/sagaHelpers.js index 0c17e00b30f..ad30077197e 100644 --- a/frontend/javascripts/test/helpers/sagaHelpers.js +++ b/frontend/javascripts/test/helpers/sagaHelpers.js @@ -6,6 +6,6 @@ export function expectValueDeepEqual(t, block, expected) { export function execCall(t, block) { t.false(block.done); - t.truthy(block.value.CALL); - return block.value.CALL.fn.apply(block.value.CALL.context, block.value.CALL.args); + t.is(block.value.type, "CALL"); + return block.value.payload.fn.apply(block.value.payload.context, block.value.payload.args); } diff --git a/frontend/javascripts/test/sagas/save_saga.spec.js b/frontend/javascripts/test/sagas/save_saga.spec.js index 43ddd074331..4c1bbb96ded 100644 --- a/frontend/javascripts/test/sagas/save_saga.spec.js +++ b/frontend/javascripts/test/sagas/save_saga.spec.js @@ -22,6 +22,9 @@ mockRequire("libs/date", DateMock); mockRequire("oxalis/model/sagas/root_saga", function*() { yield; }); +mockRequire("@tensorflow/tfjs", {}); +mockRequire("oxalis/workers/tensorflow.impl", {}); +mockRequire("oxalis/workers/tensorflow.worker", {}); const UpdateActions = mockRequire.reRequire("oxalis/model/sagas/update_actions"); const SaveActions = mockRequire.reRequire("oxalis/model/actions/save_actions"); @@ -187,7 +190,7 @@ test("SaveSaga should escalate on permanent client error update actions", t => { saga.throw({ status: 409 }); const alertEffect = saga.next().value; - t.is(alertEffect.CALL.fn, alert); + t.is(alertEffect.payload.fn, alert); t.true(saga.next().done); }); diff --git a/frontend/javascripts/test/sagas/skeletontracing_saga.spec.js b/frontend/javascripts/test/sagas/skeletontracing_saga.spec.js index 7cc5a13f749..ada9b3fb306 100644 --- a/frontend/javascripts/test/sagas/skeletontracing_saga.spec.js +++ b/frontend/javascripts/test/sagas/skeletontracing_saga.spec.js @@ -25,6 +25,9 @@ mockRequire("libs/date", DateMock); mockRequire("oxalis/model/sagas/root_saga", function*() { yield; }); +mockRequire("@tensorflow/tfjs", {}); +mockRequire("oxalis/workers/tensorflow.impl", {}); +mockRequire("oxalis/workers/tensorflow.worker", {}); const { diffSkeletonTracing } = mockRequire.reRequire("oxalis/model/sagas/skeletontracing_saga"); const { saveTracingTypeAsync } = mockRequire.reRequire("oxalis/model/sagas/save_saga"); @@ -124,7 +127,7 @@ test("SkeletonTracingSaga should create a tree if there is none (saga test)", t saga.next(); saga.next({ tracing: { trees: {} } }); saga.next(initialState.flycam); - t.is(saga.next(true).value.PUT.action.type, "CREATE_TREE"); + t.is(saga.next(true).value.payload.action.type, "CREATE_TREE"); }); test("SkeletonTracingSaga shouldn't do anything if unchanged (saga test)", t => { diff --git a/frontend/javascripts/test/sagas/volumetracing_saga.spec.js b/frontend/javascripts/test/sagas/volumetracing_saga.spec.js index 6fbc5b19995..ae93d138d92 100644 --- a/frontend/javascripts/test/sagas/volumetracing_saga.spec.js +++ b/frontend/javascripts/test/sagas/volumetracing_saga.spec.js @@ -27,6 +27,9 @@ mockRequire("app", { currentUser: { firstName: "SCM", lastName: "Boy" } }); mockRequire("oxalis/model/sagas/root_saga", function*() { yield; }); +mockRequire("@tensorflow/tfjs", {}); +mockRequire("oxalis/workers/tensorflow.impl", {}); +mockRequire("oxalis/workers/tensorflow.worker", {}); const { saveTracingTypeAsync } = require("oxalis/model/sagas/save_saga"); const { editVolumeLayerAsync, finishLayer } = require("oxalis/model/sagas/volumetracing_saga"); diff --git a/frontend/stylesheets/antd_overwrites.less b/frontend/stylesheets/antd_overwrites.less index 233120af617..5714d1b1c9a 100644 --- a/frontend/stylesheets/antd_overwrites.less +++ b/frontend/stylesheets/antd_overwrites.less @@ -74,6 +74,10 @@ } } +.ant-notification-notice-message { + white-space: pre-wrap; +} + .ant-table-small > .ant-table-content > .ant-table-body > table > .ant-table-tbody > tr > td { padding: 1px 8px; } diff --git a/package.json b/package.json index cf116e991e9..e6eb7d5c165 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "terser-webpack-plugin": "^1.1.0", "tmp": "0.0.33", "url-loader": "^1.0.1", - "webpack": "^4.20.2", + "webpack": "^4.27.0", "webpack-cli": "^3.1.0", "webpack-dev-server": "^3.2.1" }, @@ -128,6 +128,7 @@ "dependencies": { "@scalableminds/prop-types": "^15.6.1", "@scalableminds/saxophone": "^0.5.0", + "@tensorflow/tfjs": "^1.0.0", "Enumjs": "scalableminds/Enumjs", "airbrake-js": "^1.4.0", "antd": "3.5.4", @@ -137,6 +138,7 @@ "classnames": "^2.2.5", "clipboard-js": "^0.2.0", "comlinkjs": "^3.0.3", + "copy-webpack-plugin": "^4.6.0", "cross-fetch": "^3.0.1", "data.maybe": "^1.2.2", "deep-for-each": "^2.0.3", @@ -174,7 +176,7 @@ "react-sortable-tree": "^2.1.1", "react-virtualized": "^9.20.1", "redux": "^3.6.0", - "redux-saga": "^0.16.0", + "redux-saga": "^1.0.0", "three": "^0.87.0", "tween.js": "^16.3.1", "url-join": "^4.0.0", diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d408de353b5..b02a9c52df1 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -43,6 +43,7 @@ object Dependencies { val xmlWriter = "org.glassfish.jaxb" % "txw2" % "2.2.11" val woodstoxXml = "org.codehaus.woodstox" % "wstx-asl" % "3.2.3" val redis = "net.debasishg" %% "redisclient" % "3.9" + val spire = "org.typelevel" %% "spire" % "0.14.1" val sql = Seq( "com.typesafe.slick" %% "slick" % "3.2.3", @@ -78,7 +79,8 @@ object Dependencies { playIterateesStreams, filters, ws, - guice + guice, + spire ) val webknossosTracingstoreDependencies = Seq( diff --git a/public/tf-models/group1-shard1of1 b/public/tf-models/group1-shard1of1 new file mode 100644 index 0000000000000000000000000000000000000000..6dde0e624bfdfc9b186a39248bcd21df18db3b4c GIT binary patch literal 173092 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 z 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 math.pow(a - avg, 2)).sum / xs.size + } + + def stdDev[T: Numeric](xs: Iterable[T]): Double = math.sqrt(variance(xs)) + } diff --git a/webknossos-datastore/app/com/scalableminds/webknossos/datastore/controllers/BinaryDataController.scala b/webknossos-datastore/app/com/scalableminds/webknossos/datastore/controllers/BinaryDataController.scala index 723bbcf9a0e..c78a587d22b 100644 --- a/webknossos-datastore/app/com/scalableminds/webknossos/datastore/controllers/BinaryDataController.scala +++ b/webknossos-datastore/app/com/scalableminds/webknossos/datastore/controllers/BinaryDataController.scala @@ -370,6 +370,22 @@ class BinaryDataController @Inject()( private def formatNeighborList(neighbors: List[Int]): String = "[" + neighbors.mkString(", ") + "]" + def colorStatistics(organizationName: String, dataSetName: String, dataLayerName: String) = Action.async { + implicit request => + accessTokenService + .validateAccess(UserAccessRequest.readDataSources(DataSourceId(dataSetName, organizationName))) { + AllowRemoteOrigin { + for { + (dataSource, dataLayer) <- getDataSourceAndDataLayer(organizationName, dataSetName, dataLayerName) + meanAndStdDev <- findDataService.meanAndStdDev(dataSource, dataLayer) + } yield + Ok( + Json.obj("mean" -> meanAndStdDev._1, "stdDev" -> meanAndStdDev._2) + ) + } + } + } + def findData(organizationName: String, dataSetName: String, dataLayerName: String) = Action.async { implicit request => accessTokenService diff --git a/webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/FindDataService.scala b/webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/FindDataService.scala index b55a60e6efd..f30855dcfe6 100644 --- a/webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/FindDataService.scala +++ b/webknossos-datastore/app/com/scalableminds/webknossos/datastore/services/FindDataService.scala @@ -7,8 +7,9 @@ import com.scalableminds.util.tools.{Fox, FoxImplicits} import com.scalableminds.webknossos.datastore.models.{DataRequest, VoxelPosition} import com.scalableminds.webknossos.datastore.models.datasource.{DataLayer, DataSource, ElementClass} import com.scalableminds.webknossos.datastore.models.requests.DataServiceDataRequest +import com.scalableminds.util.tools.Math import net.liftweb.common.Full -import play.api.i18n.MessagesProvider +import play.api.i18n.{Messages, MessagesProvider} import scala.concurrent.ExecutionContext import scala.reflect.ClassTag @@ -18,40 +19,41 @@ class FindDataService @Inject()(dataServicesHolder: BinaryDataServiceHolder)(imp val binaryDataService: BinaryDataService = dataServicesHolder.binaryDataService var i = 0 - def findPositionWithData(dataSource: DataSource, dataLayer: DataLayer)(implicit m: MessagesProvider) = + def findPositionWithData(dataSource: DataSource, dataLayer: DataLayer)( + implicit m: MessagesProvider): Fox[Option[(Point3D, Point3D)]] = for { positionAndResolutionOpt <- checkAllPositionsForData(dataSource, dataLayer) } yield positionAndResolutionOpt - private def checkAllPositionsForData(dataSource: DataSource, dataLayer: DataLayer) = { + private def convertData(data: Array[Byte], + elementClass: ElementClass.Value): Array[_ >: Byte with Short with Int with Long] = + elementClass match { + case ElementClass.uint8 => + convertDataImpl[Byte, ByteBuffer](data, DataTypeFunctors[Byte, ByteBuffer](identity, _.get(_), _.toByte)) + case ElementClass.uint16 => + convertDataImpl[Short, ShortBuffer](data, + DataTypeFunctors[Short, ShortBuffer](_.asShortBuffer, _.get(_), _.toShort)) + case ElementClass.uint32 => + convertDataImpl[Int, IntBuffer](data, DataTypeFunctors[Int, IntBuffer](_.asIntBuffer, _.get(_), _.toInt)) + case ElementClass.uint64 => + convertDataImpl[Long, LongBuffer](data, DataTypeFunctors[Long, LongBuffer](_.asLongBuffer, _.get(_), identity)) + } - def convertData(data: Array[Byte]) = - dataLayer.elementClass match { - case ElementClass.uint8 => - convertDataImpl[Byte, ByteBuffer](data, DataTypeFunctors[Byte, ByteBuffer](identity, _.get(_), _.toByte)) - case ElementClass.uint16 => - convertDataImpl[Short, ShortBuffer]( - data, - DataTypeFunctors[Short, ShortBuffer](_.asShortBuffer, _.get(_), _.toShort)) - case ElementClass.uint32 => - convertDataImpl[Int, IntBuffer](data, DataTypeFunctors[Int, IntBuffer](_.asIntBuffer, _.get(_), _.toInt)) - case ElementClass.uint64 => - convertDataImpl[Long, LongBuffer](data, - DataTypeFunctors[Long, LongBuffer](_.asLongBuffer, _.get(_), identity)) - } + private def convertDataImpl[T: ClassTag, B <: Buffer](data: Array[Byte], + dataTypeFunctor: DataTypeFunctors[T, B]): Array[T] = { + val srcBuffer = dataTypeFunctor.getTypedBufferFn(ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN)) + srcBuffer.rewind() + val dstArray = Array.ofDim[T](srcBuffer.remaining()) + dataTypeFunctor.copyDataFn(srcBuffer, dstArray) + dstArray + } - def convertDataImpl[T: ClassTag, B <: Buffer](data: Array[Byte], - dataTypeFunctor: DataTypeFunctors[T, B]): Array[T] = { - val srcBuffer = dataTypeFunctor.getTypedBufferFn(ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN)) - srcBuffer.rewind() - val dstArray = Array.ofDim[T](srcBuffer.remaining()) - dataTypeFunctor.copyDataFn(srcBuffer, dstArray) - dstArray - } + private def checkAllPositionsForData(dataSource: DataSource, + dataLayer: DataLayer): Fox[Option[(Point3D, Point3D)]] = { def getExactDataOffset(data: Array[Byte]): Point3D = { val cubeLength = DataLayer.bucketLength / dataLayer.bytesPerElement - val convertedData = convertData(data) + val convertedData = convertData(data, dataLayer.elementClass) for { z <- 0 until cubeLength y <- 0 until cubeLength @@ -103,7 +105,7 @@ class FindDataService @Inject()(dataServicesHolder: BinaryDataServiceHolder)(imp resolutionIter(createPositions(dataLayer).distinct, dataLayer.resolutions.sortBy(_.maxDim)) } - private def createPositions(dataLayer: DataLayer) = { + private def createPositions(dataLayer: DataLayer, iterationCount: Int = 4) = { def positionCreationIter(remainingRuns: List[Int], currentPositions: List[Point3D]): List[Point3D] = { @@ -140,6 +142,66 @@ class FindDataService @Inject()(dataServicesHolder: BinaryDataServiceHolder)(imp } } - positionCreationIter((1 to 4).toList, List[Point3D]()) + positionCreationIter((1 to iterationCount).toList, List[Point3D]()) + } + + def meanAndStdDev(dataSource: DataSource, dataLayer: DataLayer)( + implicit m: MessagesProvider): Fox[(Double, Double)] = { + + def getDataFor(position: Point3D, resolution: Point3D): Fox[Array[Byte]] = { + val request = DataRequest( + new VoxelPosition(position.x, position.y, position.z, resolution), + DataLayer.bucketLength, + DataLayer.bucketLength, + DataLayer.bucketLength + ) + binaryDataService.handleDataRequest( + DataServiceDataRequest(dataSource, dataLayer, None, request.cuboid(dataLayer), request.settings)) + } + + def concatenateBuckets(buckets: Seq[Array[Byte]]): Array[Byte] = + buckets.foldLeft(Array[Byte]()) { (acc, i) => + { + acc ++ i + } + } + + def convertNonZeroDataToDouble(data: Array[Byte], elementClass: ElementClass.Value): Array[Double] = + elementClass match { + case ElementClass.uint8 => + convertDataImpl[Byte, ByteBuffer](data, DataTypeFunctors[Byte, ByteBuffer](identity, _.get(_), _.toByte)) + .filter(_ != 0) + .map(spire.math.UByte(_).toDouble) + case ElementClass.uint16 => + convertDataImpl[Short, ShortBuffer](data, + DataTypeFunctors[Short, ShortBuffer]( + _.asShortBuffer, + _.get(_), + _.toShort)).filter(_ != 0).map(spire.math.UShort(_).toDouble) + case ElementClass.uint32 => + convertDataImpl[Int, IntBuffer](data, DataTypeFunctors[Int, IntBuffer](_.asIntBuffer, _.get(_), _.toInt)) + .filter(_ != 0) + .map(spire.math.UInt(_).toDouble) + case ElementClass.uint64 => + convertDataImpl[Long, LongBuffer](data, + DataTypeFunctors[Long, LongBuffer](_.asLongBuffer, _.get(_), identity)) + .filter(_ != 0) + .map(spire.math.ULong(_).toDouble) + } + + def meanAndStdDevForPositions(positions: List[Point3D], resolution: Point3D)( + implicit m: MessagesProvider): Fox[(Double, Double)] = + for { + dataBucketWise: Seq[Array[Byte]] <- Fox.serialCombined(positions)(pos => getDataFor(pos, resolution)) + dataConcatenated = concatenateBuckets(dataBucketWise) + dataAsDoubles = convertNonZeroDataToDouble(dataConcatenated, dataLayer.elementClass) + _ <- Fox.bool2Fox(dataAsDoubles.nonEmpty) ?~> "dataSet.sampledOnlyBlack" + } yield (Math.mean(dataAsDoubles), Math.stdDev(dataAsDoubles)) + + for { + _ <- bool2Fox(dataLayer.resolutions.nonEmpty) ?~> "dataSet.noResolutions" + meanAndStdDev <- meanAndStdDevForPositions(createPositions(dataLayer, 2).distinct, + dataLayer.resolutions.minBy(_.maxDim)) + } yield meanAndStdDev } } diff --git a/webknossos-datastore/conf/com.scalableminds.webknossos.datastore.routes b/webknossos-datastore/conf/com.scalableminds.webknossos.datastore.routes index abf1883ca26..655bda4794b 100644 --- a/webknossos-datastore/conf/com.scalableminds.webknossos.datastore.routes +++ b/webknossos-datastore/conf/com.scalableminds.webknossos.datastore.routes @@ -14,6 +14,7 @@ GET /datasets/:organizationName/:dataSetName/layers/:dataLayerName/image GET /datasets/:organizationName/:dataSetName/layers/:dataLayerName/thumbnail.json @com.scalableminds.webknossos.datastore.controllers.BinaryDataController.requestImageThumbnailJson(organizationName: String, dataSetName: String, dataLayerName: String, width: Int, height: Int, centerX: Option[Int], centerY: Option[Int], centerZ: Option[Int], zoom: Option[Double]) GET /datasets/:organizationName/:dataSetName/layers/:dataLayerName/thumbnail.jpg @com.scalableminds.webknossos.datastore.controllers.BinaryDataController.requestImageThumbnailJpeg(organizationName: String, dataSetName: String, dataLayerName: String, width: Int, height: Int, centerX: Option[Int], centerY: Option[Int], centerZ: Option[Int], zoom: Option[Double]) GET /datasets/:organizationName/:dataSetName/layers/:dataLayerName/findData @com.scalableminds.webknossos.datastore.controllers.BinaryDataController.findData(organizationName: String, dataSetName: String, dataLayerName: String) +GET /datasets/:organizationName/:dataSetName/layers/:dataLayerName/colorStatistics @com.scalableminds.webknossos.datastore.controllers.BinaryDataController.colorStatistics(organizationName: String, dataSetName: String, dataLayerName: String) # Knossos compatibale routes GET /datasets/:organizationName/:dataSetName/layers/:dataLayerName/mag:resolution/x:x/y:y/z:z/bucket.raw @com.scalableminds.webknossos.datastore.controllers.BinaryDataController.requestViaKnossos(organizationName: String, dataSetName: String, dataLayerName: String, resolution: Int, x: Int, y: Int, z: Int, cubeSize: Int) diff --git a/webpack.config.js b/webpack.config.js index b60372b8511..4c136de08b7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,6 +7,7 @@ module.exports = function(env = {}) { const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // const HardSourceWebpackPlugin = require("hard-source-webpack-plugin"); + const CopyWebpackPlugin = require("copy-webpack-plugin"); var srcPath = path.resolve(__dirname, "frontend/javascripts/"); var nodePath = path.join(__dirname, "node_modules/"); @@ -32,6 +33,9 @@ module.exports = function(env = {}) { $: "jquery", jQuery: "jquery", }), + new CopyWebpackPlugin([{ from: "./public/tf-models/**", to: "tf-models", flatten: true }], { + dot: true, + }), ]; if (env.production) { diff --git a/yarn.lock b/yarn.lock index 27cbbf38b20..8584cbc95e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1046,6 +1046,50 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= +"@redux-saga/core@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@redux-saga/core/-/core-1.0.2.tgz#4336a5bb4253e5ca69681c25a863fbbc03ea6d88" + integrity sha512-AsJYcpuYfM1cmxJvfhXs9HAFSZVEG17TMsLPlXH7+Hq5a5ZP4GqcbtijEmS2AC7NR5lLJHy8csxpqz22PeW5dw== + dependencies: + "@babel/runtime" "^7.0.0" + "@redux-saga/deferred" "^1.0.1" + "@redux-saga/delay-p" "^1.0.1" + "@redux-saga/is" "^1.0.2" + "@redux-saga/symbols" "^1.0.1" + "@redux-saga/types" "^1.0.2" + redux ">=0.10 <5" + typescript-tuple "^2.1.0" + +"@redux-saga/deferred@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@redux-saga/deferred/-/deferred-1.0.1.tgz#c895445e486bded90acf0b873b4e978fbfe458c2" + integrity sha512-+gW5xQ93QXOOmRLAmX8x2Hx1HpbTG6CM6+HcdTSbJovh4uMWaGyeDECnqXSt8QqA/ja3s2nqYXLqXFKepIQ1hw== + +"@redux-saga/delay-p@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@redux-saga/delay-p/-/delay-p-1.0.1.tgz#d69fc6103c7509ae80faa144ea17bbc69e51e029" + integrity sha512-0SnNDyDLUyB4NThtptAwiprNOnbCNhoed/Rp5JwS7SB+a/AdWynVgg/E6BmjsggLFNr07KW0bzn05tsPRBuU7Q== + dependencies: + "@redux-saga/symbols" "^1.0.1" + +"@redux-saga/is@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@redux-saga/is/-/is-1.0.2.tgz#7f4be014c97061898d7efb11d6c9de31e943ed38" + integrity sha512-WnaUOwYvPK2waWjzebT4uhL8zY76XNkzzpJ2EQJe8bN1tByvAjvT7MuJZTSshOhdHL5PsRO0MsH224XIXBJidQ== + dependencies: + "@redux-saga/symbols" "^1.0.1" + "@redux-saga/types" "^1.0.2" + +"@redux-saga/symbols@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@redux-saga/symbols/-/symbols-1.0.1.tgz#46512ae1275f88df061c42168d0f600ddb170c1e" + integrity sha512-akKkzcVnb1RzJaZV2LQFbi51abvdICMuAKwwLoCjjxLbLAGIw9EJxk5ucNnWSSCEsoEQMeol5tkAcK+Xzuv1Bg== + +"@redux-saga/types@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.0.2.tgz#1d94f02800b094753f9271c206a26c2a06ca14ee" + integrity sha512-8/qcMh15507AnXJ3lBeuhsdFwnWQqnp68EpUuHlYPixJ5vjVmls7/Jq48cnUlrZI8Jd9U1jkhfCl0gaT5KMgVw== + "@rpl/badge-up@2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@rpl/badge-up/-/badge-up-2.2.0.tgz#79a5ccf72bdb1777390bb7e4caa08dc42d57dd9a" @@ -1078,11 +1122,57 @@ dependencies: stream "^0.0.2" +"@tensorflow/tfjs-converter@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-converter/-/tfjs-converter-1.0.2.tgz#eb38a06ddb0788bac2ba3b0a7d448bcb65e43eed" + integrity sha512-kOq4sou7q488Jafg7fYLbFyt4a/WrRFlDq0m9xG4iLBMQPyXDHCR/B30gPW7GnnX9nCjyRP3AnL0BTltpLk7Qg== + +"@tensorflow/tfjs-core@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-core/-/tfjs-core-1.0.2.tgz#98be72677eccf367b71115067d9c498517da0f89" + integrity sha512-SJ7HdFfQ9jcDgyj4mMqU5kvfy5yy3X7cuixHrN7cAmlnCcaIVx732HIBHo+krepLMhlCPaMbR3xN2YJmmF5L8A== + dependencies: + "@types/seedrandom" "2.4.27" + "@types/webgl-ext" "0.0.30" + "@types/webgl2" "0.0.4" + seedrandom "2.4.3" + +"@tensorflow/tfjs-data@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-data/-/tfjs-data-1.0.2.tgz#de42ac493f11a5b2ade27d08f459cacd61b358f4" + integrity sha512-qNykMp9S7XX2PDrUBbYwXJTCBZvXtSSLfg0/saABwSJgtBNEL64+oWzaNY/Fd88TtzwQFiv+MzjUFsxzJRx8lQ== + dependencies: + "@types/node-fetch" "^2.1.2" + node-fetch "~2.1.2" + seedrandom "~2.4.3" + +"@tensorflow/tfjs-layers@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-layers/-/tfjs-layers-1.0.2.tgz#58c604005ff5fd1429e7ad3de36b145e874662ea" + integrity sha512-tJVshA36msG7w6NmxapN1D3TDd8VaMHvnjYtfiEFS/5ZfJt6jfUthSGr1GYAZtnyPYi6/jB905cGPRLuMluhsg== + +"@tensorflow/tfjs@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tensorflow/tfjs/-/tfjs-1.0.2.tgz#d605b72bb819fe703e9e26bce02ef379a73ef802" + integrity sha512-GJEu7cUoQvBu7oInSdDwJvSizfFv3X5831/98m4Lsh9DofdpWzXuOO7PrQ/ZaU52dAcfcWwvmc+8L2SgZs5LYA== + dependencies: + "@tensorflow/tfjs-converter" "1.0.2" + "@tensorflow/tfjs-core" "1.0.2" + "@tensorflow/tfjs-data" "1.0.2" + "@tensorflow/tfjs-layers" "1.0.2" + "@types/long@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== +"@types/node-fetch@^2.1.2": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.1.7.tgz#0231559340f6e3f3a0608692077d744c87b5b367" + integrity sha512-TZozHCDVrs0Aj1B9ZR5F4Q9MknDNcVd+hO5lxXOCzz07ELBey6s1gMUSZHUYHlPfRFKJFXiTnNuD7ePiI6S4/g== + dependencies: + "@types/node" "*" + "@types/node@*": version "11.10.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-11.10.4.tgz#3f5fc4f0f322805f009e00ab35a2ff3d6b778e42" @@ -1098,161 +1188,173 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18" integrity sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA== -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== +"@types/seedrandom@2.4.27": + version "2.4.27" + resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-2.4.27.tgz#9db563937dd86915f69092bc43259d2f48578e41" + integrity sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE= + +"@types/webgl-ext@0.0.30": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/webgl-ext/-/webgl-ext-0.0.30.tgz#0ce498c16a41a23d15289e0b844d945b25f0fb9d" + integrity sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg== + +"@types/webgl2@0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@types/webgl2/-/webgl2-0.0.4.tgz#c3b0f9d6b465c66138e84e64cb3bdf8373c2c279" + integrity sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw== + +"@webassemblyjs/ast@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" + integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== +"@webassemblyjs/floating-point-hex-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" + integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== +"@webassemblyjs/helper-api-error@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" + integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== +"@webassemblyjs/helper-buffer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" + integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== +"@webassemblyjs/helper-code-frame@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" + integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== dependencies: - "@webassemblyjs/wast-printer" "1.8.5" + "@webassemblyjs/wast-printer" "1.7.11" -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== +"@webassemblyjs/helper-fsm@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181" + integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A== -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== - dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" +"@webassemblyjs/helper-module-context@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209" + integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg== -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== +"@webassemblyjs/helper-wasm-bytecode@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06" + integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ== -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== +"@webassemblyjs/helper-wasm-section@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a" + integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ieee754@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b" + integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" + integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== dependencies: - "@xtuc/long" "4.2.2" + "@xtuc/long" "4.2.1" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== +"@webassemblyjs/utf8@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" + integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" - -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== +"@webassemblyjs/wasm-edit@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" + integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/helper-wasm-section" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-opt" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/wasm-gen@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" + integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== +"@webassemblyjs/wasm-opt@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7" + integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== +"@webassemblyjs/wasm-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a" + integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== +"@webassemblyjs/wast-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c" + integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" - "@xtuc/long" "4.2.2" + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/floating-point-hex-parser" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-code-frame" "1.7.11" + "@webassemblyjs/helper-fsm" "1.7.11" + "@xtuc/long" "4.2.1" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" + integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" - "@xtuc/long" "4.2.2" + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + "@xtuc/long" "4.2.1" "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" + integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== Enumjs@scalableminds/Enumjs: version "1.0.2" @@ -1289,10 +1391,12 @@ accepts@~1.3.4, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" -acorn-dynamic-import@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" - integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== + dependencies: + acorn "^5.0.0" acorn-globals@^4.1.0: version "4.3.0" @@ -1312,12 +1416,12 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== -acorn@^5.2.1, acorn@^5.5.3: +acorn@^5.0.0, acorn@^5.2.1, acorn@^5.5.3, acorn@^5.6.2: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.1, acorn@^6.0.5, acorn@^6.0.7: +acorn@^6.0.1, acorn@^6.0.7: version "6.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== @@ -2056,6 +2160,11 @@ bluebird@^3.5.0, bluebird@^3.5.3: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== +bluebird@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA== + bmp-js@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.1.tgz#5ad0147099d13a9f38aa7b99af1d6e78666ed37f" @@ -2315,6 +2424,25 @@ bytes@3.0.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= +cacache@^10.0.4: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + integrity sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA== + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + cacache@^11.0.2: version "11.3.2" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" @@ -2976,6 +3104,20 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +copy-webpack-plugin@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz#e7f40dd8a68477d405dd1b7a854aae324b158bae" + integrity sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA== + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + globby "^7.1.1" + is-glob "^4.0.0" + loader-utils "^1.1.0" + minimatch "^3.0.4" + p-limit "^1.0.0" + serialize-javascript "^1.4.0" + core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" @@ -7076,6 +7218,14 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" + integrity sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -7098,11 +7248,6 @@ make-dir@^2.0.0: pify "^4.0.1" semver "^5.6.0" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -7457,6 +7602,22 @@ minizlib@^1.1.1: dependencies: minipass "^2.2.1" +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + integrity sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mississippi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" @@ -7689,6 +7850,11 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" +node-fetch@~2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= + node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" @@ -8220,7 +8386,7 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.0.0.tgz#7554e3d572109a87e1f3f53f6a7d85d1b194f4c5" integrity sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg== -p-limit@^1.1.0: +p-limit@^1.0.0, p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== @@ -9887,10 +10053,20 @@ redux-mock-store@^1.2.2: dependencies: lodash.isplainobject "^4.0.6" -redux-saga@^0.16.0: - version "0.16.2" - resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-0.16.2.tgz#993662e86bc945d8509ac2b8daba3a8c615cc971" - integrity sha512-iIjKnRThI5sKPEASpUvySemjzwqwI13e3qP7oLub+FycCRDysLSAOwt958niZW6LhxfmS6Qm1BzbU70w/Koc4w== +redux-saga@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/redux-saga/-/redux-saga-1.0.2.tgz#0599703f975438f1b2f9d2b9a965ec58f0fdfcd7" + integrity sha512-dHV256by3eF2AnBPx1l3HqazQFkErZ82HDXgh4jSRpT72OrX31wyg8DA1q8+0HvENRfJAyhT/4qT5yH/vVqFfw== + dependencies: + "@redux-saga/core" "^1.0.2" + +"redux@>=0.10 <5", redux@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5" + integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg== + dependencies: + loose-envify "^1.4.0" + symbol-observable "^1.2.0" redux@^3.6.0: version "3.7.2" @@ -9902,14 +10078,6 @@ redux@^3.6.0: loose-envify "^1.1.0" symbol-observable "^1.0.3" -redux@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5" - integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg== - dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" - regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" @@ -10445,7 +10613,7 @@ scheduler@^0.13.3: loose-envify "^1.1.0" object-assign "^4.1.1" -schema-utils@^0.4.0, schema-utils@^0.4.5: +schema-utils@^0.4.0, schema-utils@^0.4.4, schema-utils@^0.4.5: version "0.4.7" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== @@ -10462,6 +10630,16 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" +seedrandom@2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.3.tgz#2438504dad33917314bff18ac4d794f16d6aaecc" + integrity sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw= + +seedrandom@~2.4.3: + version "2.4.4" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.4.tgz#b25ea98632c73e45f58b77cfaa931678df01f9ba" + integrity sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA== + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -10913,6 +11091,13 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + integrity sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ== + dependencies: + safe-buffer "^5.1.1" + ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" @@ -11631,6 +11816,25 @@ typedarray@^0.0.6, typedarray@~0.0.5: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript-compare@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/typescript-compare/-/typescript-compare-0.0.2.tgz#7ee40a400a406c2ea0a7e551efd3309021d5f425" + integrity sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA== + dependencies: + typescript-logic "^0.0.0" + +typescript-logic@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/typescript-logic/-/typescript-logic-0.0.0.tgz#66ebd82a2548f2b444a43667bec120b496890196" + integrity sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q== + +typescript-tuple@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/typescript-tuple/-/typescript-tuple-2.2.1.tgz#7d9813fb4b355f69ac55032e0363e8bb0f04dad2" + integrity sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q== + dependencies: + typescript-compare "^0.0.2" + ua-parser-js@^0.7.18: version "0.7.19" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.19.tgz#94151be4c0a7fb1d001af7022fdaca4642659e4b" @@ -11722,6 +11926,13 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + integrity sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM= + dependencies: + unique-slug "^2.0.0" + unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -12256,17 +12467,17 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.3.0: source-list-map "^2.0.0" source-map "~0.6.1" -webpack@^4.20.2: - version "4.29.6" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.29.6.tgz#66bf0ec8beee4d469f8b598d3988ff9d8d90e955" - integrity sha512-MwBwpiE1BQpMDkbnUUaW6K8RFZjljJHArC6tWQJoFm0oQtfoSebtg4Y7/QHnJ/SddtjYLHaKGX64CFjG5rehJw== - dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - acorn "^6.0.5" - acorn-dynamic-import "^4.0.0" +webpack@^4.27.0: + version "4.27.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.27.0.tgz#1db66f03f0239bf797827f0580f53a41abd4067c" + integrity sha512-y77EQNIlsB9fUGgpLv/ZzmH+Yd9DgyIF9omX9RFavR5ZFM6HxFm6sqkbBXYxpjbKej9K6hD+Y8qEVg2rWdI2gg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/wasm-edit" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" ajv "^6.1.0" ajv-keywords "^3.1.0" chrome-trace-event "^1.0.0" @@ -12280,7 +12491,7 @@ webpack@^4.20.2: mkdirp "~0.5.0" neo-async "^2.5.0" node-libs-browser "^2.0.0" - schema-utils "^1.0.0" + schema-utils "^0.4.4" tapable "^1.1.0" terser-webpack-plugin "^1.1.0" watchpack "^1.5.0"