diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 75ecc24..0000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -doc/* -/**/*.d.ts \ No newline at end of file diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index c9d16f9..70dddc3 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -1,36 +1,29 @@ -# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - +# Lint, type-check, test, and build across supported Node.js versions name: Node.js CI on: push: - branches: [ master ] + branches: [main] pull_request: - branches: [ master ] + branches: [main] jobs: build: - - runs-on: ${{ matrix.platform }} + runs-on: ubuntu-latest strategy: matrix: - node-version: [10.x, 12.x, 14.x] - platform: [ubuntu-latest] + node-version: [22.x, 24.x, 26.x] steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node-version }} - - run: sudo apt-get update - - run: sudo apt-get install -y libgbm-dev - - run: npm ci - - run: npm run build - - run: npm test - env: - CI: true - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + - uses: actions/checkout@v7 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v7 + with: + node-version: ${{ matrix.node-version }} + cache: npm + - run: npm ci + - run: npm run lint + - run: npm run typecheck + - run: npm test + - run: npm run build diff --git a/.github/workflows/docgen.yml b/.github/workflows/docgen.yml deleted file mode 100644 index cbe3dbf..0000000 --- a/.github/workflows/docgen.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Build and Deploy Docs -on: [push] -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout 🛎️ - uses: actions/checkout@v2 - with: - persist-credentials: false - - - name: Install and Build 🔧 - run: | - npm install - npm run generate-docs - ln -s ./doc/react-sigplot/latest - - name: Set doc version - id: vars - run: echo ::set-output name=doc_version::$(grep '"version"' package.json | cut -d '"' -f 4) - - name: Deploy 🚀 - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./doc/react-sigplot/${{ steps.vars.outputs.doc_version }} \ No newline at end of file diff --git a/.github/workflows/npm_publish.yml b/.github/workflows/npm_publish.yml index fae9abf..f91a3a5 100644 --- a/.github/workflows/npm_publish.yml +++ b/.github/workflows/npm_publish.yml @@ -1,6 +1,4 @@ -# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created -# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages - +# Test, build, and publish the package to npm when a release is created name: Node.js Package on: @@ -8,25 +6,18 @@ on: types: [created] jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 - with: - node-version: 12 - - run: npm ci - - run: npm test publish-npm: - needs: build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v7 + - uses: actions/setup-node@v7 with: - node-version: 12 + node-version: 24 registry-url: https://registry.npmjs.org/ + cache: npm - run: npm ci + - run: npm test + # `prepack` builds dist/ before the tarball is created - run: npm publish env: - NODE_AUTH_TOKEN: ${{secrets.npm_token}} \ No newline at end of file + NODE_AUTH_TOKEN: ${{secrets.npm_token}} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f969f73..e1c51c7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,38 +1,15 @@ -image: node:10.1.0 +image: node:24 stages: - - build - test before_script: -- npm install + - npm ci -build_node6144: - image: node:6.14.4 - stage: build - script: npm run build - -build_node8120: - image: node:8.12.0 - stage: build - script: npm run build - -build_node10110: - image: node:10.11.0 - stage: build - script: npm run build - -test_node6144: - image: node:6.14.4 - stage: test - script: npm test - -test_node8120: - image: node:8.12.0 - stage: test - script: npm test - -test_node10110: - image: node:10.11.0 +test: stage: test - script: npm test + script: + - npm run lint + - npm run typecheck + - npm test + - npm run build diff --git a/.jsdoc.json b/.jsdoc.json deleted file mode 100644 index 40d4c43..0000000 --- a/.jsdoc.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "tags": { - "allowUnknownTags": true, - "dictionaries": ["jsdoc"] - }, - "source": { - "include": ["src", "package.json", "README.md"], - "includePattern": ".js$", - "excludePattern": "(node_modules/|doc)" - }, - "plugins": ["plugins/markdown"], - "opts": { - "destination": "./doc", - "encoding": "utf8", - "private": true, - "recurse": true, - "template": "./node_modules/minami" - } -} diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 2e2b202..0000000 --- a/.npmignore +++ /dev/null @@ -1,44 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directory -node_modules - -# Optional npm cache directory -.npm - -# Optional REPL history -.node_repl_history - -# No need to publish src -/src/ - -# Unnecessary documentation for npm -/docs/ -/CHANGELOG.md -/CONTRIBUTING.md - -# Unnecessary config -/webpack.js diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 93533a4..0000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: node_js -node_js: - - "6.14.4" - - "8.12.0" - - "10.11.0" - -cache: - directories: - - "node_modules" - -services: - - docker - -before_install: - - sudo apt-get install libgif-dev - - rm -rf dist/* - - npm install -q - -script: - - npm run build - - npm run test - -after_success: - - pip install --user codecov - - codecov --file coverage/lcov.info --disable search - -notifications: - email: - on_success: never diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c4f5dcf --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,124 @@ +# AGENTS.md + +Guidance for AI coding agents working in this repository. For the public API +and user-facing docs, see [README.md](README.md). + +## Project + +react-sigplot is a React 19 wrapper for [sigplot](https://github.com/LGSInnovations/sigplot) +3.x, written in TypeScript and built with Vite. `` creates a sigplot +`Plot` and provides it through React context. Layer and plugin components +render no DOM (`return null`); they drive the plot imperatively from effects. + +## Commands + +```bash +npm ci # Install (CI uses npm ci; keep package-lock.json in sync) +npm run lint # Biome lint + format check +npm run format # Biome format --write +npm run typecheck # tsc --noEmit over src, __tests__, example, and configs +npm test # Vitest, once +npx vitest run __tests__/ArrayLayer.test.tsx # One file +npm run build # ESM + CJS bundles and .d.ts into dist/ +npm run dev # Vite dev server for example/ (index.html) +``` + +Before finishing a change, run what CI runs: `lint`, `typecheck`, `test`, and +`build`. CI tests on Node 22, 24, and 26. + +## Layout + +- `src/index.ts` — Public entry point. Anything exported here is public API. +- `src/SigPlot.tsx` — Creates the `Plot`, applies size and option changes, and + tears it down on unmount. +- `src/SigPlotContext.ts` — `SigPlotContext` and `usePlot()`. +- `src/useLayer.ts` — Shared layer lifecycle: `create`, incremental `update`, + and `recreateOn` for props that replace the layer. +- `src/*Layer.tsx`, `src/Plugin.tsx`, `src/BoxesPlugin.tsx` — Components. +- `src/events.ts` — `usePlotListener` and the public `usePlotEvent` hook. +- `src/plot.ts` — Typed facade over sigplot's `Plot` and the subset of its API + we use. +- `src/options.ts` — `PlotOptions`, `DataHeader`, and `LayerOptions` types. +- `src/utils.ts` — `copyOf` (deep copy for sigplot) and `propChanged`. +- `src/types/sigplot.d.ts` — Ambient module so `import sigplot` resolves; + sigplot ships no types. +- `__tests__/` — Vitest tests; `helpers.tsx` has shared fixtures and + `dat/` has sample data files. +- `example/` — Demo app served by `npm run dev`. +- `dist/` — Build output. Git-ignored; never commit it. + +## Code conventions + +- Formatting and linting are Biome (`biome.json`): 2-space indent, single + quotes, 80-column lines. Don't add ESLint or Prettier. +- Relative imports inside `src/` use a `.js` extension + (`import { usePlot } from './SigPlotContext.js'`) so the NodeNext + declaration build resolves. Tests import from `'../src'` without one. +- Use `import type` / `type` modifiers for type-only imports + (`verbatimModuleSyntax` is on). +- Components are function components exported as `default` from their own + file and re-exported by name, with their `*Props` type, from `src/index.ts`. +- `ref` is a regular prop (React 19); expose instances with + `useImperativeHandle`. Don't use `forwardRef`. +- Every `biome-ignore` needs a reason, e.g. why an effect intentionally omits + dependencies. +- Public props and types get TSDoc comments; editors surface them. + +## sigplot gotchas + +These are why the code looks the way it does. Keep them in mind when adding or +changing a component. + +- **Import:** sigplot is CommonJS. Import its default export and read members + off it (`sigplot.Plot`), as `src/plot.ts` does. Named imports fail under + Node's ESM loader. +- **sigplot mutates its inputs.** Pass every options, header, or layer + options object through `copyOf()` before handing it to sigplot. +- **Change detection:** use `propChanged()`. Plain objects (options) are + compared by value, so inline `options={{ ... }}` isn't re-applied every + render. Data arrays, callbacks, and headers are compared by reference. +- **Layer IDs are UUID strings.** `reload` and `push` throw if given a + number. +- **Teardown:** sigplot has no `destroy()`. `SigPlot` calls + `disable_listeners()`, clears the element, and calls + `releaseDetachedContext()`. Don't `setState(null)` in unmount cleanups; + React keeps the queued update, and the `Plot`, alive. +- **Creation-only vs. change-only settings:** some `PlotOptions` are read + only by the constructor and others only by `change_settings`. Mark new + options accordingly in `src/options.ts`. +- **PipeLayer** sends the header with every `push`; sigplot only autoscales + on header-bearing pushes. +- Prefer one `reload`/`push` with the header over a separate `headermod`. + +## Testing + +- Vitest with jsdom. `vitest.setup.ts` loads `vitest-canvas-mock` and patches + `measureText`; without that patch sigplot's font sizing loops forever. +- Render layers with `renderWithPlot(createPlot(), )` from + `__tests__/helpers.tsx`, or inside a real ``. +- Assert on sigplot's internal state (`plot._Gx.lyr`, `plot._Gx.plugins`) and + spy on `Plot.prototype` methods with `vi.spyOn`. Call + `vi.restoreAllMocks()` in `afterEach`. +- Simulate sigplot events with `emit(plot, type, fields)`. +- `__tests__/types.test.tsx` holds compile-time checks (`@ts-expect-error`, + `expectTypeOf`). Only `npm run typecheck` enforces them. +- `__tests__/rerender.test.tsx` checks that re-rendering with equal props + makes no sigplot calls. Keep it passing when adding a component or prop. +- Add tests for mount, update, and unmount (layers and plugins removed) for + any new component. + +## Docs and packaging + +- When public API or behavior changes, update the props tables and examples in + `README.md`, and the "Migrating from 0.x" section for breaking changes. +- The package ships ESM and CJS with separate type declarations + (`dist/index.d.ts` and `dist/cjs/index.d.ts`). The `exports` map blocks deep + imports, so new public API must be exported from `src/index.ts`. +- `react` and `react-dom` are peer dependencies; `sigplot` is a dependency. + Both are external to the bundle (`vite.config.ts`). +- Publishing runs on GitHub release; `prepack` builds `dist/`. + +## Commits + +Use an imperative subject line. In the body, explain why the change is needed +and include measurements for performance or memory changes. diff --git a/README.md b/README.md index 649c4e9..966dddf 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,24 @@ react-sigplot =============== -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Build Status](https://travis-ci.org/LGSInnovations/react-sigplot.svg?branch=master)](https://travis-ci.org/LGSInnovations/react-sigplot) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](.github/CONTRIBUTING.md#pull-requests) [![npm version](https://badge.fury.io/js/react-sigplot.svg)](https://badge.fury.io/js/react-sigplot) [![codecov](https://codecov.io/gh/LGSInnovations/react-sigplot/branch/master/graph/badge.svg)](https://codecov.io/gh/LGSInnovations/react-sigplot) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](.github/CONTRIBUTING.md#pull-requests) [![npm version](https://badge.fury.io/js/react-sigplot.svg)](https://badge.fury.io/js/react-sigplot) -SigPlot wrapper component for ReactJS. +SigPlot wrapper component for React 19. Install: `npm install --save react-sigplot` ## What is it? -Provides a component that wraps the SigPlot library. +Provides React components that wrap the [SigPlot](https://github.com/LGSInnovations/sigplot) library. Layer components don't render DOM nodes — they perform imperative canvas operations on the parent `` plot instance via React Context. + +## Requirements + +- React 19+ +- sigplot ^3.1.7 (installed automatically) ## Properties +Options props (`options`, `layerOptions`, `overrides`) are compared by value, so inline objects like `options={{ autol: 1 }}` are only re-applied when their contents change. `data` is compared by reference: pass a new array to update the plot, and keep the same array to leave it alone. + ### \ |Property|Type|Default|Explanation| @@ -19,14 +26,16 @@ Provides a component that wraps the SigPlot library. |`height`|`number`|300|Height of the `div` wrapping SigPlot| |`width`|`number`|300|Width of the `div` wrapping SigPlot| |`display`|`string`|inline-block|CSS display type for `div` wrapping SigPlot| -|`styles`|`object`|`undefined`|any other CSS Styles as JS object| -|`options`|`object`|`{all: true, expand: true, autol: 100, autohide_panbars: true}`|SigPlot `Plot` options| +|`styles`|`CSSProperties`|`undefined`|any other CSS Styles as JS object| +|`options`|`PlotOptions`|`{all: true, expand: true, autol: 100, autohide_panbars: true}`|SigPlot `Plot` options (see [Options](#options))| +|`onMtag`|`(event: MtagEvent) => void`|`undefined`|Called on a click, or a ctrl/⌘-drag (which also reports the box size in `w`/`h`)| +|`ref`|`Ref`|`undefined`|Receives the underlying sigplot `Plot` instance| ### \ |Property|Type|Default|Explanation| |---|---|---|---| -|`data`|`array(number)`|`undefined`|Array of values to plot| +|`data`|`number[] \| TypedArray \| ArrayBuffer \| number[][]`|`undefined`|Values to plot; an array of rows plots a 2-D raster| |`options`|`object`|`undefined`|SigPlot data header| |`layerOptions`|`object`|`undefined`|SigPlot `Layer` options| @@ -34,67 +43,248 @@ Provides a component that wraps the SigPlot library. |Property|Type|Default|Explanation| |---|---|---|---| -|`data`|`array(number)`|`undefined`|Array of values to plot| -|`options`|`object`|`undefined`|SigPlot `Layer` options| +|`data`|`number[] \| TypedArray \| ArrayBuffer`|`undefined`|Next chunk of data; each new reference is pushed once| +|`options`|`object`|`undefined`|SigPlot data header| +|`layerOptions`|`object`|`undefined`|SigPlot `Layer` options| ### \ |Property|Type|Default|Explanation| |---|---|---|---| -|`href`|`string`|`''`|URL or path to a bluefile or MATLAB file| -|`onload`|`function`|`null`|Function that will get executed when file is loaded| +|`href`|`string`|required|URL or path to a bluefile or MATLAB file; changing it replaces the layer| +|`onload`|`(hcb, layerId) => void`|`null`|Called once the file is loaded| |`options`|`object`|`undefined`|SigPlot `Layer` options| +### \ + +|Property|Type|Default|Explanation| +|---|---|---|---| +|`data`|`object`|required|Bluefile header control block (HCB); a new header replaces the layer| +|`options`|`object`|`undefined`|SigPlot data header, applied when it changes| +|`layerOptions`|`object`|`undefined`|SigPlot `Layer` options| + ### \ + |Property|Type|Default|Explanation| |---|---|---|---| -|`wsurl`|`string`|`''`|URL to the websocket server| -|`overrides`|`object`|`undefined`|SigPlot `Layer` overrides| +|`wsurl`|`string`|required|URL to the websocket server; changing it reconnects| +|`overrides`|`object`|`undefined`|SigPlot data header overrides, read when the connection opens| |`options`|`object`|`undefined`|SigPlot `Layer` options| -### \ +### \ + |Property|Type|Default|Explanation| |---|---|---|---| -|`wsurl`|`string`|`''`|URL to the websocket server| -|`overrides`|`object`|`undefined`|SigPlot `Layer` overrides| -|`options`|`object`|`undefined`|SigPlot `Layer` options| -|`fps`|`number`|`undefined`|Frames per second for WPIPE| +|`plugin`|`PlotPlugin`|required|A sigplot plugin instance| +|`zorder`|`number`|topmost|Render order among plugins (must be > 0)| + +### \ + +Draws boxes on the plot with sigplot's boxes plugin. + +|Property|Type|Default|Explanation| +|---|---|---|---| +|`options`|`BoxesPluginOptions`|`undefined`|Plugin-wide defaults (`enableSelect`, `enableMove`, `enableResize`, `fill`, `strokeStyle`, …); changes apply to existing boxes| +|`addOnMtag`|`boolean`|`false`|Add a box when the user ctrl/⌘-drags a region| +|`onAdd`|`(box: Box) => void`|`undefined`|Called when a box is added| +|`onRemove`|`(box: Box) => void`|`undefined`|Called when a box is removed| +|`onMove`|`(box: Box) => void`|`undefined`|Called after the user moves or resizes a box| +|`onSelect`|`(boxes: Box[]) => void`|`undefined`|Called with the boxes under a click| +|`zorder`|`number`|topmost|Render order among plugins; changing it recreates the plugin and clears its boxes| +|`ref`|`Ref`|`undefined`|Receives the plugin, for `addBox`, `removeBox`, `clearBoxes`, and `getBoxes`| + +Callbacks receive copies of the boxes, so they're safe to keep in React state. + +### Hooks and types + +- **`usePlot()`** — Returns the parent `Plot` instance from context. Use this in custom layer or plugin components. +- **`usePlotEvent(type, handler)`** — Listens for a sigplot event (`'mtag'`, `'zoom'`, `'boxadd'`, …) on the parent plot. The handler can change on every render without re-subscribing. +- **`SigPlotContext`** — The React context providing the `Plot` instance. +- Types: `Plot`, `PlotLayer`, `PlotPlugin`, `LayerId`, `PlotData`, `PlotOptions`, `DataHeader`, `LayerOptions`, `BlueHeader`, `HrefOnload`, `Box`, `BoxesPluginOptions`, `BoxesPluginInstance`, `MtagEvent`, `PlotEventMap`, and each component's `*Props`. + +### Options + +`PlotOptions`, `DataHeader`, and `LayerOptions` list the settings sigplot 3.x reads, with editor autocomplete and docs. Settings that aren't listed are still accepted. + +sigplot reads some plot settings only when the plot is created and others only when `options` changes. Each is marked in its doc comment. For example, hide the grid with `nogrid` at creation, or toggle it later with `grid`. ## Usage ### Basic -```js -/** Default plot an array three different ways - * 1. As a standard array - * 2. As a pipe - * 3. As a file/url - */ -
- - - - - - - - - -
+```tsx +import { useState } from 'react'; +import { ArrayLayer, HrefLayer, PipeLayer, SigPlot } from 'react-sigplot'; + +const PLOT_OPTIONS = { autol: 1 }; +const PIPE_HEADER = { type: 2000, subsize: 1000 }; + +function App() { + const [data, setData] = useState([]); + + return ( +
+ + + + + + + + + +
+ ); +} ``` -## Example Preview +### Accessing the Plot + +```tsx +import { useRef } from 'react'; +import { type Plot, SigPlot } from 'react-sigplot'; + +function App() { + const plotRef = useRef(null); + return ; +} +``` -If you run +### Drawing boxes +```tsx +import { useRef, useState } from 'react'; +import { + type Box, + BoxesPlugin, + type BoxesPluginInstance, + SigPlot, +} from 'react-sigplot'; + +const BOX_OPTIONS = { enableSelect: true, enableMove: true, enableResize: true }; + +function App() { + const boxes = useRef(null); + const [added, setAdded] = useState([]); + + return ( + <> + + setAdded((prev) => [...prev, box])} + /> + + + +

{added.length} boxes added

+ + ); +} +``` + +### Custom layer with usePlot + +Layer IDs are UUID strings, so removing one layer never affects another. + +```tsx +import { useEffect, useRef } from 'react'; +import { type LayerId, usePlot } from 'react-sigplot'; + +function MyLayer({ data }: { data: number[] }) { + const plot = usePlot(); + const layer = useRef(null); + const applied = useRef(data); + + // Create the layer once per plot, from the most recently applied data + useEffect(() => { + const id = plot.overlay_array(applied.current); + layer.current = id; + return () => { + plot.remove_layer(id); + layer.current = null; + }; + }, [plot]); + + // Apply later data changes to the existing layer + useEffect(() => { + if (layer.current && data !== applied.current) { + applied.current = data; + plot.reload(layer.current, data); + } + }, [plot, data]); + + return null; +} +``` + +## Development + +```bash +npm install +npm run dev # Start Vite dev server with example app +npm test # Run tests +npm run lint # Lint and format check (Biome) +npm run typecheck # Type check src, tests, and example +npm run build # Build library (ESM + CommonJS + type declarations) ``` -$ npm run build -$ python -m SimpleHTTPServer 8888 + +## Migrating from 0.x + +### Layer base class removed + +The `Layer` abstract class has been removed. In 0.x, you could extend `Layer` to create custom layers: + +```jsx +// 0.x — no longer supported +import { Layer } from 'react-sigplot'; + +class MyLayer extends Layer { + componentDidMount() { + this.layer = this.plot.overlay_array(this.props.data); + } +} ``` -and in a browser, navigate to http://0.0.0.0:8888, you -should see the following +In 1.x, write a function component that uses the `usePlot()` hook (see [Custom layer with usePlot](#custom-layer-with-useplot)). + +### Children no longer receive a `plot` prop + +0.x cloned every child of `` with an injected `plot` prop. 1.x provides the plot through context instead, so components that read `props.plot` should call `usePlot()`. + +### Plugin is now a component + +The `Plugin` abstract class has been replaced by a `` component. Pass a sigplot plugin instance instead of subclassing. + +### Accessing the Plot + +In 0.x a ref to `` exposed the class instance, so the plot was at `ref.current.plot`. In 1.x the ref receives the `Plot` directly: `ref.current`. + +### sigplot 3.x + +react-sigplot now depends on sigplot `^3.1.7`. The old `^2.0.0-rc20` range actually resolved to `2.0.0-rc9`, because npm sorts prerelease tags as strings (`rc9` > `rc20`). + +- The `overlay_*` methods return string layer UUIDs instead of numeric indexes, and `reload`/`push` throw if given a number. +- A file that fails to load is logged instead of shown in an `alert()`. + +### Other changes + +- **React 19+ required** — legacy context (`contextTypes`) is no longer supported by React, and `prop-types` is no longer a peer dependency. +- **Required props** — `href` (`HrefLayer`), `wsurl` (`WebsocketLayer`), and `data` (`BlueLayer`) no longer default to empty values. +- **Layer updates**: + - `BlueLayer` replaces its layer when given a new header instead of calling `reload`. + - `WebsocketLayer` reconnects only when `wsurl` changes. + - A data change sends the header with the same `reload`/`push` call instead of a separate `headermod`. + - Options objects are compared by value. A new object with the same contents is no longer re-applied, and sigplot receives a copy, so your objects aren't modified. +- **Packaging** — ESM (`dist/react-sigplot.js`) and CommonJS (`dist/react-sigplot.cjs`) builds with type declarations. The UMD build and `window` global are gone (React 19 ships no UMD build), and the `exports` map blocks deep imports such as `react-sigplot/src/...` and `react-sigplot/dist/react-sigplot.js`. +- **`WPipeLayer` removed** — it was never exported from the package entry point. + +## Example Preview ![React Sigplot](https://raw.githubusercontent.com/spectriclabs/react-sigplot/master/docs/example.gif) diff --git a/__tests__/ArrayLayer.test.js b/__tests__/ArrayLayer.test.js deleted file mode 100644 index 422b462..0000000 --- a/__tests__/ArrayLayer.test.js +++ /dev/null @@ -1,180 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import sinon from 'sinon'; -import { configure, mount } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import { Plot } from 'sigplot'; -import { ArrayLayer } from '../src/index'; - -configure({ adapter: new Adapter() }); - -window.alert = (msg) => { - console.log(msg); -}; - -describe('', () => { - beforeEach(() => { - sinon.spy(Plot.prototype, 'overlay_array'); - sinon.spy(Plot.prototype, 'reload'); - sinon.spy(Plot.prototype, 'headermod'); - }); - - afterEach(() => { - Plot.prototype.overlay_array.restore(); - Plot.prototype.reload.restore(); - Plot.prototype.headermod.restore(); - }); - - it('reloads plot on data prop change', () => { - const options = {}; - const element = document.createElement('div'); - const context = { plot: new Plot(element, options) }; - - const random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(i * 10); - } - const oneDimensionalData = random; - - const component = mount(, { - context, - }); - - expect(component.props().data).to.equal(oneDimensionalData); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.have.lengthOf( - oneDimensionalData.length - ); - expect(component.instance().plot._Gx.lyr[0].ypoint).to.eql( - new Float64Array(oneDimensionalData) - ); - - const random2 = []; - for (let i = 0; i <= 1000; i += 1) { - random2.push(i * 10); - } - const oneDimensionalData2 = random2; - - component.setProps({ data: random2 }); - expect(component.props().data).to.equal(oneDimensionalData2); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.have.lengthOf( - oneDimensionalData2.length - ); - expect(component.instance().plot._Gx.lyr[0].ypoint).to.eql( - new Float64Array(oneDimensionalData2) - ); - }); - - it("doesn't do anything when props change but remain the same", () => { - const options = { framesize: 1000 }; - const element = document.createElement('div'); - const context = { plot: new Plot(element, options) }; - - const random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(i * 10); - } - const oneDimensionalData = random; - - const component = mount( - , - { context } - ); - - expect(component.props().data).to.equal(oneDimensionalData); - expect(component.props().layerOptions).to.equal(options); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].size).to.equal(1000); - - component.setProps({ layerOptions: options }); - expect(component.props().layerOptions).to.equal(options); - expect(component.instance().plot._Gx.lyr[0].size).to.equal(1000); - }); - - it('changes layer settings on layerOptions prop change', () => { - const options = { framesize: 1000 }; - const element = document.createElement('div'); - const context = { plot: new Plot(element, options) }; - - const random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(i * 10); - } - const oneDimensionalData = random; - - const component = mount( - , - { context } - ); - - expect(component.props().data).to.equal(oneDimensionalData); - expect(component.props().layerOptions).to.equal(options); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].size).to.equal(1000); - - const newOptions = { framesize: 50 }; - - component.setProps({ layerOptions: newOptions }); - expect(component.props().layerOptions).to.equal(newOptions); - expect(component.instance().plot._Gx.lyr[0].size).to.equal(50); - }); - - it('headermods plot on options prop change', () => { - const options = {}; - const element = document.createElement('div'); - const context = { plot: new Plot(element, options) }; - - const random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(i * 10); - } - const oneDimensionalData = random; - - const component = mount( - , - { context } - ); - - expect(component.props().data).to.equal(oneDimensionalData); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.have.lengthOf( - oneDimensionalData.length - ); - expect(component.instance().plot._Gx.lyr[0].ypoint).to.eql( - new Float64Array(oneDimensionalData) - ); - expect(Plot.prototype.overlay_array).to.have.property('callCount', 1); - expect(Plot.prototype.reload).to.have.property('callCount', 0); - expect(Plot.prototype.headermod).to.have.property('callCount', 0); - - const newOptions = { subsize: 100 }; - - component.setProps({ options: newOptions }); - expect(component.props().options.subsize).to.equal(100); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(100); - expect(Plot.prototype.overlay_array).to.have.property('callCount', 1); - expect(Plot.prototype.reload).to.have.property('callCount', 0); - expect(Plot.prototype.headermod).to.have.property('callCount', 1); - }); -}); diff --git a/__tests__/ArrayLayer.test.tsx b/__tests__/ArrayLayer.test.tsx new file mode 100644 index 0000000..1c86b3a --- /dev/null +++ b/__tests__/ArrayLayer.test.tsx @@ -0,0 +1,161 @@ +import { act } from '@testing-library/react'; +import { useState } from 'react'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { ArrayLayer } from '../src'; +import { Plot } from '../src/plot'; +import { createPlot, range, renderWithPlot } from './helpers'; + +describe('', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('overlays data on mount and removes the layer on unmount', () => { + const plot = createPlot(); + const data = range(1001); + const { unmount } = renderWithPlot(plot, ); + expect(plot._Gx.lyr).toHaveLength(1); + expect(plot._Gx.lyr[0].ypoint).toEqual(new Float64Array(data)); + unmount(); + expect(plot._Gx.lyr).toHaveLength(0); + }); + + it('accepts typed arrays', () => { + const plot = createPlot(); + const { rerender } = renderWithPlot( + plot, + , + ); + expect(plot._Gx.lyr[0].ypoint).toEqual(new Float64Array([1, 2, 3])); + rerender(); + expect(plot._Gx.lyr[0].ypoint).toEqual(new Float64Array([4, 5, 6, 7])); + }); + + it('reloads new data without re-sending an unchanged header', () => { + const plot = createPlot(); + const reload = vi.spyOn(Plot.prototype, 'reload'); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const options = { type: 1000 }; + const { rerender } = renderWithPlot( + plot, + , + ); + const next = range(10, 2); + rerender(); + expect(reload).toHaveBeenCalledTimes(1); + expect(reload.mock.calls[0][2]).toBeUndefined(); + expect(headermod).not.toHaveBeenCalled(); + expect(plot._Gx.lyr[0].ypoint).toEqual(new Float64Array(next)); + }); + + it('applies data and header together with a single reload', () => { + const plot = createPlot(); + const reload = vi.spyOn(Plot.prototype, 'reload'); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(reload).toHaveBeenCalledTimes(1); + expect(reload.mock.calls[0][2]).toEqual({ xdelta: 2 }); + expect(headermod).not.toHaveBeenCalled(); + expect(plot._Gx.lyr[0].hcb.xdelta).toBe(2); + }); + + it('headermods when only options change', () => { + const plot = createPlot(); + const reload = vi.spyOn(Plot.prototype, 'reload'); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const data = range(1001); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(headermod).toHaveBeenCalledTimes(1); + expect(reload).not.toHaveBeenCalled(); + expect(plot._Gx.lyr[0].hcb.subsize).toBe(100); + }); + + it('changes layer settings when layerOptions change', () => { + const plot = createPlot(); + const data = range(1001); + const { rerender } = renderWithPlot( + plot, + , + ); + const size = plot._Gx.lyr[0].size; + rerender(); + expect(plot._Gx.lyr[0].size).toBe(50); + expect(size).not.toBe(50); + }); + + it('does nothing when props are unchanged', () => { + const plot = createPlot(); + const data = range(10); + const layerOptions = { framesize: 10 }; + const { rerender } = renderWithPlot( + plot, + , + ); + const reload = vi.spyOn(Plot.prototype, 'reload'); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const getLayer = vi.spyOn(Plot.prototype, 'get_layer'); + rerender(); + expect(reload).not.toHaveBeenCalled(); + expect(headermod).not.toHaveBeenCalled(); + expect(getLayer).not.toHaveBeenCalled(); + }); + + it('does not let sigplot mutate the options passed in', () => { + const plot = createPlot(); + // sigplot deletes `name` from the layer options it's given + const layerOptions = { name: 'signal' }; + renderWithPlot( + plot, + , + ); + expect(layerOptions).toEqual({ name: 'signal' }); + expect(plot._Gx.lyr[0].name).toBe('signal'); + }); + + it('passes user_data through by reference', () => { + const plot = createPlot(); + const userData = { id: 7 }; + renderWithPlot( + plot, + , + ); + expect(plot._Gx.lyr[0].user_data).toBe(userData); + }); + + it('keeps tracking its own layer after a sibling is removed', () => { + const plot = createPlot(); + let showFirst: (show: boolean) => void = () => {}; + let setSecond: (data: number[]) => void = () => {}; + function Layers() { + const [show, setShow] = useState(true); + const [second, setData] = useState([10, 20, 30]); + showFirst = setShow; + setSecond = setData; + return ( + <> + {show && } + + + ); + } + const { unmount } = renderWithPlot(plot, ); + expect(plot._Gx.lyr).toHaveLength(2); + + act(() => showFirst(false)); + expect(plot._Gx.lyr).toHaveLength(1); + + act(() => setSecond([7, 8, 9])); + expect(plot._Gx.lyr[0].ypoint).toEqual(new Float64Array([7, 8, 9])); + + unmount(); + expect(plot._Gx.lyr).toHaveLength(0); + }); +}); diff --git a/__tests__/BlueLayer.test.tsx b/__tests__/BlueLayer.test.tsx new file mode 100644 index 0000000..e1dd616 --- /dev/null +++ b/__tests__/BlueLayer.test.tsx @@ -0,0 +1,77 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { BlueLayer } from '../src'; +import { Plot } from '../src/plot'; +import { blueHeader, createPlot, renderWithPlot } from './helpers'; + +describe('', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('overlays the header on mount and removes it on unmount', () => { + const plot = createPlot(); + const hcb = blueHeader([1, 2, 3]); + const { unmount } = renderWithPlot(plot, ); + expect(plot._Gx.lyr).toHaveLength(1); + expect(plot._Gx.lyr[0].ypoint).toEqual(new Float64Array([1, 2, 3])); + unmount(); + expect(plot._Gx.lyr).toHaveLength(0); + }); + + it('replaces the layer when given a new header', () => { + const plot = createPlot(); + const overlay = vi.spyOn(Plot.prototype, 'overlay_bluefile'); + const reload = vi.spyOn(Plot.prototype, 'reload'); + const layerOptions = { name: 'blue' }; + const { rerender } = renderWithPlot( + plot, + , + ); + rerender( + , + ); + + expect(overlay).toHaveBeenCalledTimes(2); + // sigplot deletes `name` from the options it's given; ours stay intact + expect(layerOptions).toEqual({ name: 'blue' }); + expect(plot._Gx.lyr[0].name).toBe('blue'); + expect(reload).not.toHaveBeenCalled(); + expect(plot._Gx.lyr).toHaveLength(1); + expect(plot._Gx.lyr[0].ypoint).toEqual(new Float64Array([4, 5])); + }); + + it('headermods when options change', () => { + const plot = createPlot(); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const hcb = blueHeader([1, 2, 3]); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(headermod).toHaveBeenCalledTimes(1); + expect(plot._Gx.lyr[0].hcb.xdelta).toBe(2); + }); + + it('changes layer settings when layerOptions change', () => { + const plot = createPlot(); + const hcb = blueHeader([1, 2, 3, 4]); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(plot._Gx.lyr[0].size).toBe(2); + }); + + it('does nothing when props are unchanged', () => { + const plot = createPlot(); + const hcb = blueHeader([1, 2, 3]); + const { rerender } = renderWithPlot(plot, ); + const overlay = vi.spyOn(Plot.prototype, 'overlay_bluefile'); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + rerender(); + expect(overlay).not.toHaveBeenCalled(); + expect(headermod).not.toHaveBeenCalled(); + }); +}); diff --git a/__tests__/BoxesPlugin.test.tsx b/__tests__/BoxesPlugin.test.tsx new file mode 100644 index 0000000..2644d77 --- /dev/null +++ b/__tests__/BoxesPlugin.test.tsx @@ -0,0 +1,122 @@ +import { createRef } from 'react'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { BoxesPlugin, type BoxesPluginInstance } from '../src'; +import { createPlot, emit, renderWithPlot } from './helpers'; + +const box = { x: 0, y: 1, w: 10, h: 0.5 }; + +function setup(ui = ) { + const plot = createPlot(); + const result = renderWithPlot(plot, ui); + const plugin = () => plot._Gx.plugins[0]?.impl as BoxesPluginInstance; + return { plot, plugin, ...result }; +} + +describe('', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('adds the plugin with its options and zorder, and removes it on unmount', () => { + const { plot, plugin, unmount } = setup( + , + ); + expect(plot._Gx.plugins).toHaveLength(1); + expect(plot._Gx.plugins[0].zorder).toBe(4); + expect(plugin().options).toMatchObject({ + enableSelect: true, + lineWidth: 3, + enableMove: false, + }); + unmount(); + expect(plot._Gx.plugins).toHaveLength(0); + }); + + it('exposes the plugin instance through ref', () => { + const ref = createRef(); + const { plugin, unmount } = setup(); + expect(ref.current).toBe(plugin()); + const id = ref.current?.addBox(box); + expect(plugin().getBoxes()).toMatchObject([{ ...box, id }]); + unmount(); + expect(ref.current).toBeNull(); + }); + + it('applies option changes to the existing plugin and resets removed ones', () => { + const { plot, plugin, rerender } = setup( + , + ); + const instance = plugin(); + instance.addBox(box); + instance.getBoxes()[0].selected = true; + + rerender(); + + expect(plot._Gx.plugins[0].impl).toBe(instance); + expect(instance.getBoxes()).toHaveLength(1); + expect(instance.options).toMatchObject({ + lineWidth: 2, + fill: false, + enableSelect: false, + }); + expect(instance.getBoxes()[0].selected).toBeUndefined(); + }); + + it('reports added and removed boxes as copies', () => { + const onAdd = vi.fn(); + const onRemove = vi.fn(); + const { plugin } = setup(); + const id = plugin().addBox(box); + const live = plugin().getBoxes()[0]; + expect(onAdd).toHaveBeenCalledWith({ ...live }); + expect(onAdd.mock.calls[0][0]).not.toBe(live); + + plugin().removeBox(id); + expect(onRemove).toHaveBeenCalledWith(expect.objectContaining({ id })); + }); + + it('reports moves and selections from its own plugin only', () => { + const onMove = vi.fn(); + const onSelect = vi.fn(); + const { plot, plugin } = setup( + , + ); + plugin().addBox(box); + const live = plugin().getBoxes()[0]; + + emit(plot, 'boxmove', { source: {}, box: live, action: 'mouseup' }); + emit(plot, 'boxselect', { source: {}, boxes: [live], action: 'mouseup' }); + expect(onMove).not.toHaveBeenCalled(); + expect(onSelect).not.toHaveBeenCalled(); + + emit(plot, 'boxmove', { source: plugin(), box: live, action: 'mouseup' }); + emit(plot, 'boxselect', { + source: plugin(), + boxes: [live], + action: 'mouseup', + }); + expect(onMove).toHaveBeenCalledWith({ ...live }); + expect(onMove.mock.calls[0][0]).not.toBe(live); + expect(onSelect).toHaveBeenCalledWith([{ ...live }]); + }); + + it('adds a box for ctrl-drag mtags when addOnMtag is set, ignoring clicks', () => { + const { plot, plugin, rerender } = setup(); + emit(plot, 'mtag', { ...box, xpos: 0, ypos: 0 }); + expect(plugin().getBoxes()).toHaveLength(0); + + rerender(); + emit(plot, 'mtag', { x: 1, y: 2, xpos: 0, ypos: 0 }); + emit(plot, 'mtag', { ...box, xpos: 0, ypos: 0 }); + expect(plugin().getBoxes()).toMatchObject([box]); + }); + + it('does not duplicate listeners across re-renders', () => { + const onAdd = vi.fn(); + const { plugin, rerender } = setup(); + rerender(); + rerender( onAdd(b)} />); + plugin().addBox(box); + expect(onAdd).toHaveBeenCalledTimes(1); + }); +}); diff --git a/__tests__/HrefLayer.test.js b/__tests__/HrefLayer.test.js deleted file mode 100644 index 7c007e2..0000000 --- a/__tests__/HrefLayer.test.js +++ /dev/null @@ -1,105 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import sinon from 'sinon'; -import { configure, mount } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import { Plot } from 'sigplot'; -import { HrefLayer } from '../src/index'; - -configure({ adapter: new Adapter() }); - -window.alert = (msg) => { - console.log(msg); -}; - -describe('', () => { - beforeEach(() => { - sinon.spy(Plot.prototype, 'deoverlay'); - sinon.spy(Plot.prototype, 'overlay_href'); - sinon.spy(Plot.prototype, 'change_settings'); - }); - - afterEach(() => { - Plot.prototype.deoverlay.restore(); - Plot.prototype.overlay_href.restore(); - Plot.prototype.change_settings.restore(); - }); - - it('reloads plot on href prop change', () => { - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - const hrefOne = ''; - const component = mount(, { context }); - - expect(component.props().href).to.equal(hrefOne); - expect(component.instance().plot).to.not.be.undefined; - expect(Plot.prototype.deoverlay).to.have.property('callCount', 0); - expect(Plot.prototype.overlay_href).to.have.property('callCount', 1); - expect(Plot.prototype.overlay_href.getCall(0).args).to.have.length(3); - expect(Plot.prototype.overlay_href.getCall(0).args[0]).to.equal(hrefOne); - - const hrefTwo = 'dat/penny.prm'; - component.setProps({ href: hrefTwo }); - expect(component.props().href).to.equal(hrefTwo); - expect(component.instance().plot).to.not.be.undefined; - expect(Plot.prototype.deoverlay).to.have.property('callCount', 1); - expect(Plot.prototype.deoverlay.getCall(0).args).to.not.be.empty; - expect(Plot.prototype.overlay_href).to.have.property('callCount', 2); - expect(Plot.prototype.overlay_href.getCall(1).args).to.have.length(3); - expect(Plot.prototype.overlay_href.getCall(1).args[0]).to.equal(hrefTwo); - }); - - it("doesn't do anything when props change, but stay the same", () => { - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - const hrefOne = 'dat/penny.prm'; - const options = {}; - const component = mount(, { - context, - }); - expect(Plot.prototype.deoverlay).to.have.property('callCount', 0); - expect(Plot.prototype.overlay_href).to.have.property('callCount', 1); - expect(Plot.prototype.change_settings).to.have.property('callCount', 1); - - component.setProps({ href: hrefOne, options: options }); - expect(Plot.prototype.deoverlay).to.have.property('callCount', 0); - expect(Plot.prototype.overlay_href).to.have.property('callCount', 1); - expect(Plot.prototype.change_settings).to.have.property('callCount', 1); - }); - - it('changes settings on options prop change', () => { - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - const hrefOne = 'dat/penny.prm'; - - sinon.spy(Plot.prototype, 'overlay_bluefile'); - - const component = mount(, { context }); - - expect(component.props().href).to.equal(hrefOne); - expect(component.instance().plot).to.not.be.undefined; - expect(Plot.prototype.overlay_bluefile).to.have.property('callCount', 1); - expect(component.instance().layer).to.equal(0); - expect(Plot.prototype.deoverlay).to.have.property('callCount', 0); - expect(Plot.prototype.overlay_href).to.have.property('callCount', 1); - expect(Plot.prototype.overlay_href.getCall(0).args).to.have.length(3); - expect(Plot.prototype.overlay_href.getCall(0).args[0]).to.equal(hrefOne); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].drawmode).to.be.undefined; - - const options = { - drawmode: 'righttoleft', - }; - component.setProps({ options: options }); - expect(component.props().href).to.equal(hrefOne); - expect(component.instance().plot).to.not.be.undefined; - expect(Plot.prototype.deoverlay).to.have.property('callCount', 0); - expect(Plot.prototype.overlay_href).to.have.property('callCount', 1); - expect(Plot.prototype.overlay_href.getCall(0).args).to.have.length(3); - expect(Plot.prototype.overlay_href.getCall(0).args[0]).to.equal(hrefOne); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].drawmode).to.equal( - options.drawmode - ); - }); -}); diff --git a/__tests__/HrefLayer.test.tsx b/__tests__/HrefLayer.test.tsx new file mode 100644 index 0000000..5d1462d --- /dev/null +++ b/__tests__/HrefLayer.test.tsx @@ -0,0 +1,96 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { ArrayLayer, HrefLayer, type PlotLayer } from '../src'; +import { Plot } from '../src/plot'; +import { createPlot, renderWithPlot } from './helpers'; + +describe('', () => { + let nextId = 0; + + beforeEach(() => { + nextId = 0; + // Avoid real network requests; sigplot returns the layer UUID synchronously + vi.spyOn(Plot.prototype, 'overlay_href').mockImplementation( + () => `href-${nextId++}`, + ); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('overlays the href with onload and options', () => { + const plot = createPlot(); + const onload = vi.fn(); + const options = { name: 'penny' }; + renderWithPlot( + plot, + , + ); + expect(plot.overlay_href).toHaveBeenCalledWith( + 'dat/penny.prm', + onload, + options, + ); + }); + + it('replaces only its own layer when href changes', () => { + const plot = createPlot(); + const removeLayer = vi.spyOn(Plot.prototype, 'remove_layer'); + const deoverlay = vi.spyOn(Plot.prototype, 'deoverlay'); + const tree = (href: string) => ( + <> + + + + ); + const { rerender } = renderWithPlot(plot, tree('a.tmp')); + rerender(tree('b.tmp')); + + expect(removeLayer).toHaveBeenCalledTimes(1); + expect(removeLayer).toHaveBeenCalledWith('href-0'); + expect(deoverlay).not.toHaveBeenCalled(); + expect(plot.overlay_href).toHaveBeenLastCalledWith( + 'b.tmp', + null, + undefined, + ); + expect(plot._Gx.lyr).toHaveLength(1); + }); + + it('does nothing when props are unchanged', () => { + const plot = createPlot(); + const removeLayer = vi.spyOn(Plot.prototype, 'remove_layer'); + const options = {}; + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(plot.overlay_href).toHaveBeenCalledTimes(1); + expect(removeLayer).not.toHaveBeenCalled(); + }); + + it('changes layer settings when options change', () => { + const plot = createPlot(); + const layer = { change_settings: vi.fn() } as PlotLayer; + const getLayer = vi + .spyOn(Plot.prototype, 'get_layer') + .mockReturnValue(layer); + const { rerender } = renderWithPlot(plot, ); + rerender(); + expect(getLayer).toHaveBeenCalledWith('href-0'); + expect(layer.change_settings).toHaveBeenCalledWith({ + drawmode: 'righttoleft', + }); + expect(plot.overlay_href).toHaveBeenCalledTimes(1); + }); + + it('removes every layer it created on unmount', () => { + vi.mocked(Plot.prototype.overlay_href).mockReturnValue(['a', 'b']); + const plot = createPlot(); + const removeLayer = vi.spyOn(Plot.prototype, 'remove_layer'); + const { unmount } = renderWithPlot(plot, ); + unmount(); + expect(removeLayer.mock.calls).toEqual([['a'], ['b']]); + }); +}); diff --git a/__tests__/PipeLayer.test.js b/__tests__/PipeLayer.test.js deleted file mode 100644 index 4bc9284..0000000 --- a/__tests__/PipeLayer.test.js +++ /dev/null @@ -1,172 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import sinon from 'sinon'; -import { configure, mount } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import { Plot } from 'sigplot'; -import { PipeLayer } from '../src/index'; - -configure({ adapter: new Adapter() }); - -window.alert = (msg) => { - console.log(msg); -}; - -describe('', () => { - beforeEach(() => { - sinon.spy(Plot.prototype, 'push'); - sinon.spy(Plot.prototype, 'headermod'); - sinon.spy(Plot.prototype, 'change_settings'); - }); - - afterEach(() => { - Plot.prototype.push.restore(); - Plot.prototype.headermod.restore(); - Plot.prototype.change_settings.restore(); - }); - - it('modifies the header on options prop change', () => { - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - - const options = { framesize: 1000, type: 2000, subsize: 1000 }; - const component = mount(, { - context, - }); - expect(component.props().options).to.equal(options); - expect(Plot.prototype.push).to.have.property('callCount', 0); - expect(Plot.prototype.headermod).to.have.property('callCount', 0); - expect(Plot.prototype.change_settings).to.have.property('callCount', 1); - - const newOptions = { - framesize: 2000, - }; - component.setProps({ options: newOptions }); - expect(component.props().options).to.equal(newOptions); - expect(Plot.prototype.push).to.have.property('callCount', 1); - expect(Plot.prototype.headermod).to.have.property('callCount', 1); - expect(Plot.prototype.change_settings).to.have.property('callCount', 2); - }); - - it('modifies settings on layerOptions prop change', () => { - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - - const layerOptions = { drawmode: 'scrolling' }; - const options = { framesize: 1000, type: 2000, subsize: 1000 }; - const component = mount( - , - { context } - ); - expect(component.props().layerOptions).to.equal(layerOptions); - expect(Plot.prototype.push).to.have.property('callCount', 0); - expect(Plot.prototype.headermod).to.have.property('callCount', 0); - expect(Plot.prototype.change_settings).to.have.property('callCount', 1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].drawmode).to.equal( - layerOptions.drawmode - ); - - const newLayerOptions = { drawmode: 'righttoleft' }; - component.setProps({ layerOptions: newLayerOptions }); - expect(component.props().layerOptions).to.equal(newLayerOptions); - expect(Plot.prototype.push).to.have.property('callCount', 0); - expect(Plot.prototype.headermod).to.have.property('callCount', 0); - expect(Plot.prototype.change_settings).to.have.property('callCount', 1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].drawmode).to.equal( - newLayerOptions.drawmode - ); - }); - - it('pushes new data to plot on data prop change', () => { - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - - const twoDimensionalData = []; - - const options = { framesize: 1000, type: 2000, subsize: 1000 }; - const component = mount( - , - { context } - ); - - expect(component.props().data).to.equal(twoDimensionalData); - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - const tmp = new Float64Array(1000); - for (let i = 0; i < 1000; i++) { - expect(component.instance().plot._Gx.lyr[0].hcb.dview[i]).to.equal( - tmp[i] - ); - } - - let random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(i * 10); - } - component.setProps({ data: random }); - expect(component.props().data).to.equal(random); - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - const tmp2 = new Float64Array(random); - for (let i = 0; i < 1000; i++) { - expect(component.instance().plot._Gx.lyr[0].hcb.dview[i]).to.equal( - tmp2[i] - ); - } - }); - - it("doesn't replot the same data on data prop change", () => { - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - - let random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(i * 10); - } - - const options = { framesize: 1000, type: 2000, subsize: 1000 }; - const component = mount(, { - context, - }); - - expect(component.props().data).to.equal(random); - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - expect(Plot.prototype.push).to.have.property('callCount', 1); - for (let i = 0; i < 1000; i++) { - expect(component.instance().plot._Gx.lyr[0].hcb.dview[i]).to.equal( - random[i] - ); - } - - component.setProps({ data: random }); - expect(component.props().data).to.equal(random); - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - - expect(Plot.prototype.push).to.have.property('callCount', 1); - for (let i = 0; i < 1000; i++) { - expect(component.instance().plot._Gx.lyr[0].hcb.dview[i]).to.equal( - random[i] - ); - } - }); -}); diff --git a/__tests__/PipeLayer.test.tsx b/__tests__/PipeLayer.test.tsx new file mode 100644 index 0000000..b33d2da --- /dev/null +++ b/__tests__/PipeLayer.test.tsx @@ -0,0 +1,130 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { ArrayLayer, PipeLayer } from '../src'; +import { Plot } from '../src/plot'; +import { createPlot, range, renderWithPlot } from './helpers'; + +const header = { type: 2000, subsize: 1000 }; + +describe('', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('overlays a pipe with the header and removes it on unmount', () => { + const plot = createPlot(); + const { unmount } = renderWithPlot(plot, ); + expect(plot._Gx.lyr).toHaveLength(1); + expect(plot._Gx.lyr[0].hcb).toMatchObject(header); + unmount(); + expect(plot._Gx.lyr).toHaveLength(0); + }); + + it('does not let sigplot mutate the options passed in', () => { + const plot = createPlot(); + // sigplot sets `pipe` on the header; frozen, that write is silently lost + const options = Object.freeze({ type: 2000, subsize: 1000 }); + const layerOptions = Object.freeze({ name: 'stream' }); + renderWithPlot( + plot, + , + ); + expect(plot._Gx.lyr[0].hcb.pipe).toBe(true); + }); + + it.each([ + ['number[]', [1, 2, 3]], + ['Float32Array', new Float32Array([1, 2, 3])], + ['ArrayBuffer', new Float64Array([1, 2, 3]).buffer], + ])('pushes initial %s data on mount', (_, data) => { + const plot = createPlot(); + const push = vi.spyOn(Plot.prototype, 'push'); + renderWithPlot( + plot, + , + ); + expect(push).toHaveBeenCalledTimes(1); + expect(push.mock.calls[0][1]).toBe(data); + }); + + it('does not push empty initial data', () => { + const plot = createPlot(); + const push = vi.spyOn(Plot.prototype, 'push'); + renderWithPlot(plot, ); + expect(push).not.toHaveBeenCalled(); + }); + + // sigplot only re-autoscales a 1-D pipe on pushes that carry a header, so + // omitting an unchanged header would freeze the Y axis (0.x sent it too) + it('pushes each new data reference once, with the header', () => { + const plot = createPlot(); + const push = vi.spyOn(Plot.prototype, 'push'); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const { rerender } = renderWithPlot(plot, ); + + const data = range(1000); + rerender(); + rerender(); + + expect(push).toHaveBeenCalledTimes(1); + expect(push.mock.calls[0][2]).toBe(header); + expect(headermod).not.toHaveBeenCalled(); + }); + + it('sends a changed header with the data push instead of a separate headermod', () => { + const plot = createPlot(); + const push = vi.spyOn(Plot.prototype, 'push'); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const { rerender } = renderWithPlot(plot, ); + const next = { ...header, xdelta: 2 }; + rerender(); + expect(push).toHaveBeenCalledTimes(1); + expect(push.mock.calls[0][2]).toBe(next); + expect(headermod).not.toHaveBeenCalled(); + }); + + it('headermods when only options change', () => { + const plot = createPlot(); + const headermod = vi.spyOn(Plot.prototype, 'headermod'); + const data = range(1000); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(headermod).toHaveBeenCalledTimes(1); + }); + + it('changes layer settings when layerOptions change', () => { + const plot = createPlot(); + const { rerender } = renderWithPlot( + plot, + , + ); + expect(plot._Gx.lyr[0].drawmode).toBe('scrolling'); + rerender( + , + ); + expect(plot._Gx.lyr[0].drawmode).toBe('righttoleft'); + }); + + it('streams with inline options when it is not the first layer', () => { + const plot = createPlot(); + const tree = (data: number[]) => ( + <> + + + + ); + const { rerender } = renderWithPlot(plot, tree([1, 2])); + expect(() => rerender(tree([3, 4]))).not.toThrow(); + expect(plot._Gx.lyr).toHaveLength(2); + }); +}); diff --git a/__tests__/Plugin.test.tsx b/__tests__/Plugin.test.tsx new file mode 100644 index 0000000..509b057 --- /dev/null +++ b/__tests__/Plugin.test.tsx @@ -0,0 +1,63 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { Plugin } from '../src'; +import { Plot } from '../src/plot'; +import { createPlot, renderWithPlot } from './helpers'; + +function mockPlugin() { + return { init: vi.fn(), dispose: vi.fn(), refresh: vi.fn() }; +} + +describe('', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('adds the plugin with its zorder', () => { + const plot = createPlot(); + const plugin = mockPlugin(); + renderWithPlot(plot, ); + expect(plugin.init.mock.calls[0][0]).toBe(plot); + expect(plot._Gx.plugins).toHaveLength(1); + expect(plot._Gx.plugins[0]).toMatchObject({ impl: plugin, zorder: 5 }); + }); + + it('defaults zorder to sigplot’s default (topmost)', () => { + const plot = createPlot(); + renderWithPlot(plot, ); + expect(plot._Gx.plugins[0].zorder).toBe(Number.MAX_VALUE); + }); + + it('is not re-added on re-render with the same props', () => { + const plot = createPlot(); + const plugin = mockPlugin(); + const add = vi.spyOn(Plot.prototype, 'add_plugin'); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(add).toHaveBeenCalledTimes(1); + expect(plugin.dispose).not.toHaveBeenCalled(); + }); + + it('re-adds the plugin when zorder changes', () => { + const plot = createPlot(); + const plugin = mockPlugin(); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(plot._Gx.plugins).toHaveLength(1); + expect(plot._Gx.plugins[0].zorder).toBe(2); + }); + + it('removes the plugin on unmount', () => { + const plot = createPlot(); + const plugin = mockPlugin(); + const { unmount } = renderWithPlot(plot, ); + unmount(); + expect(plugin.dispose).toHaveBeenCalledTimes(1); + expect(plot._Gx.plugins).toHaveLength(0); + }); +}); diff --git a/__tests__/SigPlot.test.js b/__tests__/SigPlot.test.js deleted file mode 100644 index 17fcb5f..0000000 --- a/__tests__/SigPlot.test.js +++ /dev/null @@ -1,707 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import sinon from 'sinon'; -import { configure, mount } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import { Plot } from 'sigplot'; -import { SigPlot, ArrayLayer, PipeLayer, HrefLayer } from '../src/index'; - -configure({ adapter: new Adapter() }); - -window.alert = (msg) => { - console.log(msg); -}; - -describe('', () => { - it('calls componentDidMount', () => { - sinon.spy(SigPlot.prototype, 'componentDidMount'); - mount(); - expect(SigPlot.prototype.componentDidMount).to.have.property( - 'callCount', - 1 - ); - }); - - it('fails correctly if plot is undefined', () => { - const oldComponentDidMount = SigPlot.prototype.componentDidMount; - SigPlot.prototype.componentDidMount = () => null; - const component = mount(); - expect(component.instance().children).to.be.undefined; - SigPlot.prototype.componentDidMount = oldComponentDidMount; - }); - - it('handles undefined children', () => { - // eslint-disable-next-line react/no-children-prop - const component = mount(); - expect(component.instance().children).to.be.undefined; - }); - - it('renders with no child layer', () => { - const component = mount(); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.undefined; - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.be.an('array').that.is.empty; - }); - - it('renders with no child layer with custom height and width', () => { - const component = mount(); - expect(component.props().width).to.equal(800); - expect(component.props().height).to.equal(500); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.undefined; - expect(component.find('div').prop('style').width).to.equal(800); - expect(component.find('div').prop('style').height).to.equal(500); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.be.an('array').that.is.empty; - }); - - it('handles changing custom height and width', () => { - const component = mount(); - - sinon.spy(Plot.prototype, 'checkresize'); - - expect(component.props().width).to.equal(800); - expect(component.props().height).to.equal(500); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.undefined; - expect(component.find('div').prop('style').width).to.equal(800); - expect(component.find('div').prop('style').height).to.equal(500); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.be.an('array').that.is.empty; - expect(Plot.prototype.checkresize).to.have.property('callCount', 0); - - component.setProps({ height: 200 }); - expect(component.props().width).to.equal(800); - expect(component.props().height).to.equal(200); - expect(component.find('div').prop('style').width).to.equal(800); - expect(component.find('div').prop('style').height).to.equal(200); - expect(Plot.prototype.checkresize).to.have.property('callCount', 1); - - component.setProps({ width: 100 }); - expect(component.props().width).to.equal(100); - expect(component.props().height).to.equal(200); - expect(component.find('div').prop('style').width).to.equal(100); - expect(component.find('div').prop('style').height).to.equal(200); - expect(Plot.prototype.checkresize).to.have.property('callCount', 2); - }); - - it('handles changing plot options', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const component = mount(); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.undefined; - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.be.an('array').that.is.empty; - - const newOptions = { - all: false, - autol: 200, - }; - - component.setProps({ options: newOptions }); - expect(component.props().options.all).to.equal(false); - expect(component.props().options.autol).to.equal(200); - expect(component.props().children).to.be.undefined; - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(200); - expect(component.instance().plot._Gx.lyr).to.be.an('array').that.is.empty; - }); - - it('renders with no child layer with custom options and custom height and width', () => { - const options = { - all: false, - expand: false, - autol: 1, - autohide_panbars: false, - }; - const component = mount( - - ); - expect(component.props().width).to.equal(800); - expect(component.props().height).to.equal(500); - expect(component.props().options.all).to.equal(false); - expect(component.props().options.expand).to.equal(false); - expect(component.props().options.autol).to.equal(1); - expect(component.props().options.autohide_panbars).to.equal(false); - expect(component.props().children).to.be.undefined; - expect(component.find('div').prop('style').width).to.equal(800); - expect(component.find('div').prop('style').height).to.equal(500); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(1); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(false); - expect(component.instance().plot._Gx.lyr).to.be.an('array').that.is.empty; - }); - - it('renders with 1D ArrayLayer with no data', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const oneDimensionalData = []; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.not.be.undefined; - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.data).to.equal(oneDimensionalData); - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.be.null; - }); - - it('renders with 2 1D ArrayLayers with no data', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const oneDimensionalData1 = []; - const oneDimensionalData2 = []; - const component = mount( - - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('array'); - expect(component.props().children).to.have.lengthOf(2); - expect(component.props().children[0].props.data).to.equal( - oneDimensionalData1 - ); - expect(component.props().children[1].props.data).to.equal( - oneDimensionalData2 - ); - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(2); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.be.null; - expect(component.instance().plot._Gx.lyr[1].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[1].ypoint).to.be.null; - }); - - it('renders with 1D ArrayLayer with data', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - let random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(i * 10); - } - const oneDimensionalData = random; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.data).to.equal(oneDimensionalData); - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.have.lengthOf( - oneDimensionalData.length - ); - expect(component.instance().plot._Gx.lyr[0].ypoint).to.eql( - new Float64Array(oneDimensionalData) - ); - }); - - it('renders with 1D ArrayLayer with data then re-renders', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const random1 = []; - for (let i = 0; i <= 1000; i += 1) { - random1.push(i * 10); - } - const oneDimensionalData1 = random1; - - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.data).to.equal(oneDimensionalData1); - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.have.lengthOf( - oneDimensionalData1.length - ); - expect(component.instance().plot._Gx.lyr[0].ypoint).to.eql( - new Float64Array(oneDimensionalData1) - ); - }); - - it('renders with 2 1D ArrayLayers with data', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - - const random1 = []; - for (let i = 0; i <= 1000; i += 1) { - random1.push(10 * i); - } - - const random2 = []; - for (let i = 0; i <= 1000; i += 1) { - random2.push(10 * i); - } - - const oneDimensionalData1 = random1; - const oneDimensionalData2 = random2; - const component = mount( - - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('array'); - expect(component.props().children).to.have.lengthOf(2); - expect(component.props().children[0].props.data).to.equal( - oneDimensionalData1 - ); - expect(component.props().children[1].props.data).to.equal( - oneDimensionalData2 - ); - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(2); - expect(component.instance().plot._Gx.lyr[0].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[0].ypoint).to.have.lengthOf( - oneDimensionalData1.length - ); - expect(component.instance().plot._Gx.lyr[0].ypoint).to.eql( - new Float64Array(oneDimensionalData1) - ); - expect(component.instance().plot._Gx.lyr[1].options).to.be.an('object').that - .is.empty; - expect(component.instance().plot._Gx.lyr[1].ypoint).to.have.lengthOf( - oneDimensionalData2.length - ); - expect(component.instance().plot._Gx.lyr[1].ypoint).to.eql( - new Float64Array(oneDimensionalData2) - ); - }); - - it('renders with 2D ArrayLayer with no data', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const layerOptions = { type: 2000, subsize: 1000 }; - const twoDimensionalData = []; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.data).to.equal(twoDimensionalData); - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].buf).to.be.empty; - }); - - it('renders with 2D ArrayLayer with data', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const layerOptions = { type: 2000, subsize: 1000 }; - let random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(10 * i); - } - const twoDimensionalData = random; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.data).to.equal(twoDimensionalData); - expect(component.find('div').prop('style').width).to.equal(300); - expect(component.find('div').prop('style').height).to.equal(300); - expect(component.find('div').prop('style').display).to.equal( - 'inline-block' - ); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - }); - - it('throws with 1D PipeLayer with no data and no size defined', () => { - const originalError = console.error; - console.error = jest.fn(); - expect(() => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - mount( - - - - ); - }).to.throw( - /1D layer could not determine appropriate size for pipe, use framesize option/ - ); - console.error = originalError; - }); - - it('renders with 2D PipeLayer with no data', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const twoDimensionalData = []; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.data).to.equal(twoDimensionalData); - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - expect(component.instance().plot._Gx.lyr[0].zbuf).to.eql( - new Float64Array(1000) - ); - }); - - it('renders with 2D PipeLayer with data passed in but not displayed', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - let random = []; - for (let i = 0; i <= 1000; i += 1) { - random.push(10 * i); - } - const twoDimensionalData = random; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.data).to.equal(twoDimensionalData); - expect(component.instance().plot._Gx.all).to.equal(true); - expect(component.instance().plot._Gx.expand).to.equal(true); - expect(component.instance().plot._Gx.autol).to.equal(100); - expect(component.instance().plot._Gx.autohide_panbars).to.equal(true); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].hcb.subsize).to.equal(1000); - expect(component.instance().plot._Gx.lyr[0].hcb.type).to.equal(2000); - expect(component.instance().plot._Gx.lyr[0].zbuf).to.eql( - new Float64Array(1000) - ); - }); - - it('renders with HrefLayer with no file', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const file = ''; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.href).to.equal(file); - }); - - it('renders with HrefLayer with valid href', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const file = 'dat/penny.prm'; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.href).to.equal(file); - }); - - it('renders with HrefLayer with invalid href', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const file = 'dat/invalid.prm'; - const component = mount( - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('object'); - expect(component.props().children.props.href).to.equal(file); - }); - - it('renders with HrefLayer with 2 valid hrefs', () => { - const options = { - all: true, - expand: true, - autol: 100, - autohide_panbars: true, - }; - const file1 = 'dat/penny.prm'; - const file2 = 'dat/sin.tmp'; - const component = mount( - - - - - ); - expect(component.props().width).to.equal(300); - expect(component.props().height).to.equal(300); - expect(component.props().options.all).to.equal(true); - expect(component.props().options.expand).to.equal(true); - expect(component.props().options.autol).to.equal(100); - expect(component.props().options.autohide_panbars).to.equal(true); - expect(component.props().children).to.be.an('array'); - expect(component.props().children).to.have.lengthOf(2); - expect(component.props().children[0].props.href).to.equal(file1); - expect(component.props().children[1].props.href).to.equal(file2); - }); -}); diff --git a/__tests__/SigPlot.test.tsx b/__tests__/SigPlot.test.tsx new file mode 100644 index 0000000..ae5d4cd --- /dev/null +++ b/__tests__/SigPlot.test.tsx @@ -0,0 +1,228 @@ +import { render } from '@testing-library/react'; +import { createRef, StrictMode, useLayoutEffect } from 'react'; +import sigplot from 'sigplot'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { ArrayLayer, HrefLayer, PipeLayer, SigPlot, usePlot } from '../src'; +import { Plot } from '../src/plot'; +import { range } from './helpers'; + +let capturedPlot: Plot | null = null; +function PlotCapture() { + capturedPlot = usePlot(); + return null; +} + +const DEFAULTS = { + all: true, + expand: true, + autol: 100, + autohide_panbars: true, +}; + +describe('', () => { + afterEach(() => { + capturedPlot = null; + vi.restoreAllMocks(); + }); + + it('renders a default-sized plot with default options', () => { + const { container } = render( + + + , + ); + const div = container.firstElementChild as HTMLDivElement; + expect(div.style.width).toBe('300px'); + expect(div.style.height).toBe('300px'); + expect(div.style.display).toBe('inline-block'); + expect(capturedPlot).toBeInstanceOf(Plot); + expect(capturedPlot?._Gx).toMatchObject(DEFAULTS); + expect(capturedPlot?._Gx.lyr).toHaveLength(0); + }); + + it('passes custom size and options to the plot', () => { + const options = { + all: false, + expand: false, + autol: 1, + autohide_panbars: false, + }; + const { container } = render( + + + , + ); + const div = container.firstElementChild as HTMLDivElement; + expect(div.style.width).toBe('800px'); + expect(div.style.height).toBe('500px'); + expect(capturedPlot?._Gx).toMatchObject(options); + }); + + it('does not re-apply size or options after constructing the plot', () => { + const checkresize = vi.spyOn(Plot.prototype, 'checkresize'); + const changeSettings = vi.spyOn(Plot.prototype, 'change_settings'); + new Plot(document.createElement('div'), DEFAULTS); + const baseline = [ + checkresize.mock.calls.length, + changeSettings.mock.calls.length, + ]; + checkresize.mockClear(); + changeSettings.mockClear(); + + render(); + expect([ + checkresize.mock.calls.length, + changeSettings.mock.calls.length, + ]).toEqual(baseline); + }); + + it('calls checkresize once per size change', () => { + const { container, rerender } = render( + , + ); + const div = container.firstElementChild as HTMLDivElement; + const checkresize = vi.spyOn(Plot.prototype, 'checkresize'); + + rerender(); + expect(div.style.height).toBe('200px'); + expect(checkresize).toHaveBeenCalledTimes(1); + + rerender(); + expect(div.style.width).toBe('100px'); + expect(checkresize).toHaveBeenCalledTimes(2); + + rerender(); + expect(checkresize).toHaveBeenCalledTimes(2); + }); + + it('resizes the canvas before the browser paints', () => { + const checkresize = vi.spyOn(Plot.prototype, 'checkresize'); + let callsAtLayout = -1; + // Layout effects run in tree order before paint; a passive resize would + // not have happened yet when this sibling's layout effect runs + function AfterSigPlot() { + useLayoutEffect(() => { + callsAtLayout = checkresize.mock.calls.length; + }); + return null; + } + const tree = (height: number) => ( + <> + + + + ); + const { rerender } = render(tree(300)); + checkresize.mockClear(); + rerender(tree(200)); + expect(callsAtLayout).toBe(1); + }); + + it('applies changed plot options', () => { + const { rerender } = render( + + + , + ); + rerender( + + + , + ); + expect(capturedPlot?._Gx.all).toBe(false); + expect(capturedPlot?._Gx.autol).toBe(200); + }); + + it('renders child layers', () => { + vi.spyOn(Plot.prototype, 'overlay_href').mockReturnValue('href-layer'); + const data = range(1001); + render( + + + + + + + , + ); + const lyr = capturedPlot?._Gx.lyr ?? []; + expect(lyr).toHaveLength(3); + expect(lyr[0].ypoint).toEqual(new Float64Array(data)); + expect(lyr[1].ypoint).toBeNull(); + expect(lyr[2].hcb).toMatchObject({ type: 2000, subsize: 1000 }); + expect(Plot.prototype.overlay_href).toHaveBeenCalledWith( + 'dat/penny.prm', + null, + undefined, + ); + }); + + it('detaches plot listeners and canvases on unmount', () => { + const added = vi.spyOn(window, 'addEventListener'); + const removed = vi.spyOn(window, 'removeEventListener'); + const { container, unmount } = render(); + const div = container.firstElementChild as HTMLDivElement; + expect(div.querySelector('canvas')).not.toBeNull(); + const listeners = added.mock.calls.map(([type, fn]) => [type, fn]); + expect(listeners.length).toBeGreaterThan(0); + + unmount(); + + const removedListeners = removed.mock.calls.map(([type, fn]) => [type, fn]); + for (const listener of listeners) { + expect(removedListeners).toContainEqual(listener); + } + expect(div.childNodes).toHaveLength(0); + }); + + it('does not let sigplot mutate the options passed in', () => { + // sigplot normalizes constructor options in place and fills in color + // defaults on change_settings + const options = { autol: 100 }; + const changed = { autol: 50, colors: { bg: '#000' } }; + const { rerender } = render(); + rerender(); + expect(options).toEqual({ autol: 100 }); + expect(changed).toEqual({ autol: 50, colors: { bg: '#000' } }); + }); + + it("releases sigplot's cached canvas context on unmount", () => { + const mx = sigplot.mx as { _ctx?: CanvasRenderingContext2D }; + const { unmount } = render(); + expect(mx._ctx).toBeDefined(); + unmount(); + expect(mx._ctx).toBeUndefined(); + }); + + it('works under StrictMode', () => { + const plain = render(); + const canvases = plain.container.querySelectorAll('canvas').length; + plain.unmount(); + + const { container } = render( + + + + + + , + ); + expect(container.querySelectorAll('canvas')).toHaveLength(canvases); + expect(capturedPlot?._Gx.lyr).toHaveLength(1); + }); + + it('exposes the Plot through ref', () => { + const ref = createRef(); + const { unmount } = render(); + expect(ref.current).toBeInstanceOf(Plot); + unmount(); + expect(ref.current).toBeNull(); + }); + + it('usePlot throws outside ', () => { + vi.spyOn(console, 'error').mockImplementation(() => {}); + expect(() => render()).toThrow( + 'usePlot must be used within a component', + ); + }); +}); diff --git a/__tests__/WebsocketLayer.test.js b/__tests__/WebsocketLayer.test.js deleted file mode 100644 index 86af254..0000000 --- a/__tests__/WebsocketLayer.test.js +++ /dev/null @@ -1,140 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import sinon from 'sinon'; -import { configure, mount } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import { Plot } from 'sigplot'; -import { WebsocketLayer } from '../src/index.js'; - -configure({ adapter: new Adapter() }); - -window.alert = (msg) => { - console.log(msg); -}; - -describe('', () => { - beforeEach(() => { - sinon.spy(Plot.prototype, 'deoverlay'); - sinon.spy(Plot.prototype, 'overlay_websocket'); - sinon.spy(Plot.prototype, 'change_settings'); - }); - - afterEach(() => { - Plot.prototype.deoverlay.restore(); - Plot.prototype.overlay_websocket.restore(); - Plot.prototype.change_settings.restore(); - }); - - it("doesn't reload plot on same wsurl change", () => { - const options = { framesize: 1000 }; - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - - const websocketURL = 'ws://0.0.0.0'; - const component = mount( - , - { context } - ); - - expect(component.props().wsurl).to.equal(websocketURL); - expect(component.props().options).to.equal(options); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - - component.setProps({ wsurl: websocketURL }); - expect(component.props().wsurl).to.equal(websocketURL); - }); - - it('reloads plot on wsurl prop change', () => { - const options = { framesize: 1000 }; - const element = global.document.createElement('div'); - const context = { plot: new Plot(element, {}) }; - - const websocketURL = 'ws://0.0.0.0'; - const component = mount( - , - { context } - ); - - expect(component.props().wsurl).to.equal(websocketURL); - expect(component.props().options).to.equal(options); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - - component.setProps({ wsurl: websocketURL }); - expect(component.props().wsurl).to.equal(websocketURL); - - const websocketURL2 = 'ws://0.0.0.0/foo'; - - component.setProps({ wsurl: websocketURL2 }); - expect(component.props().wsurl).to.equal(websocketURL2); - expect(component.props().options).to.equal(options); - expect(component.instance().plot).to.not.be.undefined; - expect(component.instance().plot._Gx.all).to.equal(false); - expect(component.instance().plot._Gx.expand).to.equal(false); - expect(component.instance().plot._Gx.autol).to.equal(-1); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - }); - - it('throws an error on empty URL', () => { - const originalError = console.error; - console.error = jest.fn(); - expect(() => { - const element = global.document.createElement('div'); - const options = {}; - const context = { plot: new Plot(element, options) }; - - const websocketURL = ''; - mount(, { - context, - }); - }).to.throw(/The URL '' is invalid./); - console.error = originalError; - }); - - it('changes settings on options prop change', () => { - const element = global.document.createElement('div'); - const options = { drawmode: 'scrolling', framesize: 1000 }; - const context = { plot: new Plot(element, {}) }; - - const websocketURL = 'ws://0.0.0.0'; - const component = mount( - , - { context } - ); - - expect(component.props().wsurl).to.equal(websocketURL); - expect(component.props().options).to.equal(options); - expect(component.instance().plot).to.not.be.undefined; - expect(Plot.prototype.deoverlay).to.have.property('callCount', 0); - expect(Plot.prototype.overlay_websocket).to.have.property('callCount', 1); - expect(Plot.prototype.overlay_websocket.getCall(0).args).to.have.length(3); - expect(Plot.prototype.overlay_websocket.getCall(0).args[0]).to.equal( - websocketURL - ); - expect(component.instance().plot._Gx.lyr).to.have.lengthOf(1); - expect(component.instance().plot._Gx.lyr[0].drawmode).to.equal( - options.drawmode - ); - - const newOptions = { drawmode: 'righttoleft' }; - component.setProps({ options: newOptions }); - expect(component.props().wsurl).to.equal(websocketURL); - expect(component.props().options).to.equal(newOptions); - expect(component.instance().plot).to.not.be.undefined; - expect(Plot.prototype.overlay_websocket).to.have.property('callCount', 1); - expect(Plot.prototype.overlay_websocket.getCall(0).args).to.have.length(3); - expect(Plot.prototype.overlay_websocket.getCall(0).args[0]).to.equal( - websocketURL - ); - expect(component.instance().plot._Gx.lyr[0].drawmode).to.equal( - newOptions.drawmode - ); - }); -}); diff --git a/__tests__/WebsocketLayer.test.tsx b/__tests__/WebsocketLayer.test.tsx new file mode 100644 index 0000000..63f19e9 --- /dev/null +++ b/__tests__/WebsocketLayer.test.tsx @@ -0,0 +1,110 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { WebsocketLayer } from '../src'; +import { createPlot, renderWithPlot } from './helpers'; + +class FakeWebSocket extends EventTarget { + static instances: FakeWebSocket[] = []; + binaryType = 'blob'; + close = vi.fn(); + constructor( + public url: string, + public protocol?: string, + ) { + super(); + FakeWebSocket.instances.push(this); + } +} + +const options = { framesize: 1000 }; + +describe('', () => { + beforeEach(() => { + FakeWebSocket.instances = []; + vi.stubGlobal('WebSocket', FakeWebSocket); + }); + + afterEach(() => { + vi.unstubAllGlobals(); + vi.restoreAllMocks(); + }); + + it('connects on mount and disconnects on unmount', () => { + const plot = createPlot(); + const { unmount } = renderWithPlot( + plot, + , + ); + expect(FakeWebSocket.instances.map((ws) => ws.url)).toEqual([ + 'ws://host/a', + ]); + expect(plot._Gx.lyr).toHaveLength(1); + + unmount(); + expect(FakeWebSocket.instances[0].close).toHaveBeenCalled(); + expect(plot._Gx.lyr).toHaveLength(0); + }); + + it('does not reconnect on re-render, even with inline overrides', () => { + const plot = createPlot(); + const tree = () => ( + + ); + const { rerender } = renderWithPlot(plot, tree()); + rerender(tree()); + rerender(tree()); + expect(FakeWebSocket.instances).toHaveLength(1); + }); + + it('reconnects when wsurl changes', () => { + const plot = createPlot(); + const { rerender } = renderWithPlot( + plot, + , + ); + rerender(); + expect(FakeWebSocket.instances.map((ws) => ws.url)).toEqual([ + 'ws://host/a', + 'ws://host/b', + ]); + expect(FakeWebSocket.instances[0].close).toHaveBeenCalled(); + expect(plot._Gx.lyr).toHaveLength(1); + }); + + it('changes layer settings when options change', () => { + const plot = createPlot(); + const { rerender } = renderWithPlot( + plot, + , + ); + expect(plot._Gx.lyr[0].drawmode).toBe('scrolling'); + rerender( + , + ); + expect(plot._Gx.lyr[0].drawmode).toBe('righttoleft'); + expect(FakeWebSocket.instances).toHaveLength(1); + }); + + it('does not mutate the caller’s overrides', () => { + const plot = createPlot(); + const overrides = Object.freeze({ type: 1000 }); + renderWithPlot( + plot, + , + ); + expect(overrides).toEqual({ type: 1000 }); + }); +}); diff --git a/__tests__/events.test.tsx b/__tests__/events.test.tsx new file mode 100644 index 0000000..ccfc9a4 --- /dev/null +++ b/__tests__/events.test.tsx @@ -0,0 +1,90 @@ +import { act, render } from '@testing-library/react'; +import { useState } from 'react'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { type MtagEvent, SigPlot, usePlot, usePlotEvent } from '../src'; +import type { Plot } from '../src/plot'; +import { createPlot, emit, renderWithPlot } from './helpers'; + +describe('usePlotEvent', () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('calls the handler for matching events only', () => { + const plot = createPlot(); + const handler = vi.fn(); + function Listener() { + usePlotEvent('zoom', handler); + return null; + } + renderWithPlot(plot, ); + emit(plot, 'unzoom'); + const event = emit(plot, 'zoom', { level: 1 }); + expect(handler).toHaveBeenCalledTimes(1); + expect(handler).toHaveBeenCalledWith(event); + }); + + it('uses the latest handler without re-subscribing', () => { + const plot = createPlot(); + const add = vi.spyOn(plot, 'addListener'); + const first = vi.fn(); + const second = vi.fn(); + function Listener({ handler }: { handler: () => void }) { + usePlotEvent('zoom', () => handler()); + return null; + } + const { rerender } = renderWithPlot(plot, ); + rerender(); + emit(plot, 'zoom'); + expect(add).toHaveBeenCalledTimes(1); + expect(first).not.toHaveBeenCalled(); + expect(second).toHaveBeenCalledTimes(1); + }); + + it('unsubscribes when the handler is removed or the component unmounts', () => { + const plot = createPlot(); + const handler = vi.fn(); + let setEnabled: (enabled: boolean) => void = () => {}; + function Listener() { + const [enabled, set] = useState(true); + setEnabled = set; + usePlotEvent('zoom', enabled ? handler : null); + return null; + } + const { unmount } = renderWithPlot(plot, ); + act(() => setEnabled(false)); + emit(plot, 'zoom'); + act(() => setEnabled(true)); + emit(plot, 'zoom'); + unmount(); + emit(plot, 'zoom'); + expect(handler).toHaveBeenCalledTimes(1); + }); +}); + +describe('', () => { + it('receives mtag events from the plot', () => { + let plot: Plot | null = null; + function Capture() { + plot = usePlot(); + return null; + } + const onMtag = vi.fn((event: MtagEvent) => event.preventDefault()); + render( + + + , + ); + const event = emit(plot as unknown as Plot, 'mtag', { + x: 1, + y: 2, + xpos: 10, + ypos: 20, + w: 3, + h: 4, + }); + expect(onMtag).toHaveBeenCalledWith(event); + expect(onMtag.mock.calls[0][0]).toMatchObject({ x: 1, y: 2, w: 3, h: 4 }); + expect(event.defaultPrevented).toBe(true); + }); +}); diff --git a/__tests__/helpers.tsx b/__tests__/helpers.tsx new file mode 100644 index 0000000..ededc7b --- /dev/null +++ b/__tests__/helpers.tsx @@ -0,0 +1,43 @@ +import { render } from '@testing-library/react'; +import type { ReactNode } from 'react'; +import sigplot from 'sigplot'; +import type { BlueHeader } from '../src'; +import { Plot } from '../src/plot'; +import { SigPlotContext } from '../src/SigPlotContext'; + +export function createPlot(): Plot { + return new Plot(document.createElement('div'), {}); +} + +/** Renders `ui` inside a context that provides `plot`. */ +export function renderWithPlot(plot: Plot, ui: ReactNode) { + const wrap = (node: ReactNode) => ( + {node} + ); + const result = render(wrap(ui)); + return { + ...result, + rerender: (node: ReactNode) => result.rerender(wrap(node)), + }; +} + +export function range(length: number, scale = 10): number[] { + return Array.from({ length }, (_, i) => i * scale); +} + +const m = sigplot.m as { + initialize(data: ArrayLike, overrides?: object): BlueHeader; +}; + +export function blueHeader(data: ArrayLike): BlueHeader { + return m.initialize(data, {}); +} + +/** Dispatches a sigplot-style event (a plain `Event` with extra fields). */ +export function emit(plot: Plot, type: string, fields: object = {}): Event { + const event = Object.assign(new Event(type, { cancelable: true }), fields); + ( + plot as unknown as { _Mx: { wid_canvas: HTMLCanvasElement } } + )._Mx.wid_canvas.dispatchEvent(event); + return event; +} diff --git a/__tests__/rerender.test.tsx b/__tests__/rerender.test.tsx new file mode 100644 index 0000000..e5d70b9 --- /dev/null +++ b/__tests__/rerender.test.tsx @@ -0,0 +1,88 @@ +import { render } from '@testing-library/react'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { + ArrayLayer, + BlueLayer, + BoxesPlugin, + HrefLayer, + PipeLayer, + SigPlot, + WebsocketLayer, +} from '../src'; +import { BoxesPluginClass, Plot } from '../src/plot'; +import { blueHeader } from './helpers'; + +const METHODS = [ + 'change_settings', + 'checkresize', + 'headermod', + 'push', + 'reload', + 'refresh', + 'get_layer', + 'remove_layer', + 'overlay_array', + 'overlay_pipe', + 'overlay_bluefile', + 'overlay_href', + 'overlay_websocket', + 'add_plugin', + 'remove_plugin', +] as const; + +class FakeWebSocket extends EventTarget { + binaryType = 'blob'; + close() {} +} + +describe('re-rendering with equal inline options', () => { + beforeEach(() => { + vi.stubGlobal('WebSocket', FakeWebSocket); + vi.spyOn(Plot.prototype, 'overlay_href').mockReturnValue('href'); + }); + + afterEach(() => { + vi.unstubAllGlobals(); + vi.restoreAllMocks(); + }); + + it('does not call into sigplot', () => { + const data = [1, 2, 3, 4]; + const hcb = blueHeader([1, 2, 3]); + // Every options object is recreated on each render, as inline props are + const tree = () => ( + + + + + + + + + ); + const { rerender } = render(tree()); + const spies = METHODS.map((name) => vi.spyOn(Plot.prototype, name)); + for (const spy of spies) spy.mockClear(); + const plugin = vi.spyOn(BoxesPluginClass.prototype, 'enableSelect'); + + rerender(tree()); + rerender(tree()); + + for (const spy of spies) { + expect(spy, spy.getMockName()).not.toHaveBeenCalled(); + } + expect(plugin).not.toHaveBeenCalled(); + }); +}); diff --git a/__tests__/types.test.tsx b/__tests__/types.test.tsx new file mode 100644 index 0000000..a7c0128 --- /dev/null +++ b/__tests__/types.test.tsx @@ -0,0 +1,45 @@ +// Checked by `npm run typecheck`: each @ts-expect-error must stay an error. +import { expectTypeOf, it } from 'vitest'; +import type { + DataHeader, + LayerOptions, + MtagEvent, + PlotEventHandler, + PlotOptions, +} from '../src'; +import { ArrayLayer, SigPlot } from '../src'; + +it('types known options and allows unlisted ones', () => { + const plot: PlotOptions = { + autol: 100, + cmode: 'MA', + rubberbox_action: 'select', + xlab: 'Hz', + xlabel: (units) => `units ${units}`, + some_future_option: true, + }; + // @ts-expect-error rubberbox_action is 'zoom' | 'select' | null + const badAction: PlotOptions = { rubberbox_action: 'box' }; + // @ts-expect-error autox is 0 | 1 | 2 | 3 + const badAutox: PlotOptions = { autox: 4 }; + + const header: DataHeader = { type: 2000, subsize: 1024, format: 'CF' }; + // @ts-expect-error subsize is a number + const badHeader: DataHeader = { subsize: '1024' }; + + const layer: LayerOptions = { name: 'signal', drawmode: 'falling' }; + // @ts-expect-error drawmode is a fixed set of modes + const badLayer: LayerOptions = { drawmode: 'sideways' }; + + expectTypeOf>() + .parameter(0) + .toEqualTypeOf(); + expectTypeOf>().parameter(0).toEqualTypeOf(); + + void [plot, badAction, badAutox, header, badHeader, layer, badLayer]; + void ( + e.w}> + + + ); +}); diff --git a/__tests__/utils.test.ts b/__tests__/utils.test.ts new file mode 100644 index 0000000..143cb79 --- /dev/null +++ b/__tests__/utils.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from 'vitest'; +import { propChanged } from '../src/utils'; + +describe('propChanged', () => { + it('compares plain objects by value, including nested ones', () => { + expect( + propChanged({ a: 1, b: { c: [1, 2] } }, { a: 1, b: { c: [1, 2] } }), + ).toBe(false); + expect(propChanged({ a: 1 }, { a: 2 })).toBe(true); + expect(propChanged({ a: 1 }, { a: 1, b: 2 })).toBe(true); + expect(propChanged({ a: undefined }, { b: undefined })).toBe(true); + expect(propChanged({ n: Number.NaN }, { n: Number.NaN })).toBe(false); + }); + + it('compares everything else by reference', () => { + const fn = () => 0; + expect(propChanged([1, 2], [1, 2])).toBe(true); + expect(propChanged(new Float32Array([1]), new Float32Array([1]))).toBe( + true, + ); + expect(propChanged({ f: fn }, { f: fn })).toBe(false); + expect(propChanged({ f: fn }, { f: () => 0 })).toBe(true); + expect(propChanged(new Map(), new Map())).toBe(true); + expect(propChanged('a', 'a')).toBe(false); + expect(propChanged(undefined, {})).toBe(true); + }); +}); diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index df08db5..0000000 --- a/babel.config.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = { - presets: ['@babel/preset-env', '@babel/preset-react'], -}; diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..f374b09 --- /dev/null +++ b/biome.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.4.8/schema.json", + "assist": { + "enabled": true + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 80 + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "correctness": { + "noUnusedImports": "warn" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single" + } + }, + "files": { + "includes": ["**", "!dist", "!coverage", "!doc", "!docs", "!node_modules"] + } +} diff --git a/dist/demo.html b/dist/demo.html deleted file mode 100644 index 60a273c..0000000 --- a/dist/demo.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - -
- - - diff --git a/dist/example.js b/dist/example.js deleted file mode 100644 index 0903cd9..0000000 --- a/dist/example.js +++ /dev/null @@ -1,268 +0,0 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["react-sigplot"]=t():e["react-sigplot"]=t()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=30)}([function(e,t,n){"use strict";(function(e){n.d(t,"e",(function(){return r})),n.d(t,"p",(function(){return i})),n.d(t,"a",(function(){return o})),n.d(t,"c",(function(){return a})),n.d(t,"d",(function(){return l})),n.d(t,"o",(function(){return s})),n.d(t,"q",(function(){return u})),n.d(t,"t",(function(){return c})),n.d(t,"i",(function(){return d})),n.d(t,"r",(function(){return f})),n.d(t,"s",(function(){return h})),n.d(t,"k",(function(){return p})),n.d(t,"m",(function(){return m})),n.d(t,"j",(function(){return x})),n.d(t,"l",(function(){return y})),n.d(t,"g",(function(){return v})),n.d(t,"f",(function(){return g})),n.d(t,"h",(function(){return b})),n.d(t,"n",(function(){return _})),n.d(t,"b",(function(){return w}));var r="1.12.0",i="object"==typeof self&&self.self===self&&self||"object"==typeof e&&e.global===e&&e||Function("return this")()||{},o=Array.prototype,a=Object.prototype,l="undefined"!=typeof Symbol?Symbol.prototype:null,s=o.push,u=o.slice,c=a.toString,d=a.hasOwnProperty,f="undefined"!=typeof ArrayBuffer,h="undefined"!=typeof DataView,p=Array.isArray,m=Object.keys,x=Object.create,y=f&&ArrayBuffer.isView,v=isNaN,g=isFinite,b=!{toString:null}.propertyIsEnumerable("toString"),_=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],w=Math.pow(2,53)-1}).call(this,n(8))},function(e,t,n){e.exports=n(13)()},function(e,t,n){"use strict";e.exports=n(12)},function(e,t,n){ -/** - * @license - * File: sigplot.js - * Copyright (c) 2012-2017, LGS Innovations Inc., All rights reserved. - * - * This file is part of SigPlot. - * - * Licensed to the LGS Innovations (LGS) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. LGS licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -!function(){var t=n(23),r=n(15),i=n(6),o=n(9),a=o.bluefile,l=o.matfile,s=n(5),u=n(7),c=n(21),d=n(22);function f(e,t){if(!(this instanceof f))return new f.Plot(e,t)}f.bluefile=a,f.matfile=l,f.m=s,f.mx=u,f.Layer1D=c,f.Layer2D=d,f.version="version-PLACEHOLDER";var h={lines:13,length:7,width:4,radius:10,corners:1,rotate:0,color:"#FFF",speed:1,trail:60,shadow:!1,hwaccel:!1,className:"spinner",zIndex:2e9,top:"auto",left:"auto"};f.browserIsCompatible=function(){var e=!!document.createElement("canvas").getContext,t="ArrayBuffer"in window;return e&&t};var p=function(e,t){if(!f.browserIsCompatible())throw"Browser is not compatible";this._Mx=u.open(e);var n,r=this._Mx;return this._Gx=new y,this._Gx.parent=e,this.mouseOnCanvas=!1,t||(t={}),function(e,t){var n=e._Mx,r=e._Gx;t.xlab||(t.xlab=0);t.ylab||(t.ylab=0);t.useDomMenu&&(n.useDomMenu=!0);t.xlab=s.unit_lookup(t.xlab),t.ylab=s.unit_lookup(t.ylab),r.xmin=void 0===t.xmin?0:t.xmin,r.xmax=void 0===t.xmax?0:t.xmax;var i,o=void 0!==t.xmin,a=void 0!==t.xmax;if("number"==typeof t.cmode)switch(t.cmode){case 1:i="MA";break;case 2:i="PH";break;case 3:i="RE";break;case 4:i="IM";break;case 5:i="IR";break;case 6:i="LO";break;case 7:i="L2";break;default:throw new RangeError("Invalid cmode value")}else i=void 0===t.cmode?"":t.cmode.toUpperCase();void 0===t.line||t.line;r.ylab=t.ylab,r.ylabel=t.ylabel,r.ymin=void 0===t.ymin?0:t.ymin,r.ymax=void 0===t.ymax?0:t.ymax;var l=void 0!==t.ymin,c=void 0!==t.ymax;r.zmin=t.zmin,r.zmax=t.zmax;var d=void 0!==t.zmin,f=void 0!==t.zmax;void 0!==t.colors&&u.setbgfg(n,t.colors.bg,t.colors.fg,n.xi);t.xi&&u.invertbgfg(n);r.forcelab=void 0===t.forcelab||t.forcelab,r.all=void 0!==t.all&&t.all,r.expand=void 0!==t.expand&&t.expand,r.xlab=t.xlab,r.xlabel=t.xlabel,r.segment=void 0!==t.segment&&t.segment,r.plab=24;var h=void 0===t.phunits?"D":t.phunits;"R"===h[0]?r.plab=23:"C"===h[0]&&(r.plab=25);r.xdiv=void 0===t.xdiv?5:t.xdiv,r.ydiv=void 0===t.ydiv?5:t.ydiv,r.xcompression=t.xcmp||0,r.rasterDownscale=t.downscale||0,r.rasterSmoothing=t.smoothing||!1,n.origin=1,t.yinv&&(n.origin=4);r.pmt=void 0===t.pmt?1:t.pmt,r.bufmax=void 0===t.bufmax?32768:t.bufmax,r.sections=void 0===t.nsec?0:t.nsec,r.anno_type=void 0===t.anno_type?0:t.anno_type,r.xfmt=void 0===t.xfmt?"":t.xfmt,r.yfmt=void 0===t.yfmt?"":t.yfmt,r.index=void 0!==t.index&&t.index;var p=r.index||"IN"===i.slice(0,2);p&&(o&&1===r.xmin&&(o=!1),a&&1===r.xmin&&(a=!1));r.xdata=!1,r.note=t.note||"",r.hold=0,r.always_show_marker=t.always_show_marker||!1,s.vstype("D"),t.inputs||M(e,!1);var m=i;r.lyr.length>0&&r.lyr[0].cx?r.cmode=1:r.cmode=3;"MA"!==m&&"INMA"!==m&&"ABMA"!==m&&"__MA"!==m&&"MAGNITUDE"!==m||(r.cmode=1);"PH"!==m&&"INPH"!==m&&"ABPH"!==m&&"__PH"!==m&&"PHASE"!==m||(r.cmode=2);"RE"!==m&&"INRE"!==m&&"ABRE"!==m&&"__RE"!==m&&"REAL"!==m||(r.cmode=3);"IM"!==m&&"INIM"!==m&&"ABIM"!==m&&"__IM"!==m&&"IMAGINARY"!==m||(r.cmode=4);"LO"!==m&&"D1"!==m&&"INLO"!==m&&"IND1"!==m&&"ABIM"!==m&&"ABD1"!==m&&"__LO"!==m&&"__D1"!==m&&"10*LOG10"!==m||(r.cmode=6);"L2"!==m&&"D2"!==m&&"INL2"!==m&&"IND2"!==m&&"ABLO"!==m&&"ABD2"!==m&&"__L2"!==m&&"__D2"!==m&&"20*LOG10"!==m||(r.cmode=7);"RI"!==m&&"IR"!==m&&"INRI"!==m&&"INIR"!==m&&"ABRI"!==m&&"ABIR"!==m&&"__RI"!==m&&"__IR"!==m&&"IMAG/REAL"!==m&&"REAL/IMAG"!==m||(r.index?alert("Imag/Real mode not permitted in INDEX mode"):r.cmode=5);if(r.basemode=r.cmode,e.change_settings({cmode:r.cmode}),r.dbmin=1e-20,r.cmode>=6){var x=10;7===r.cmode&&(x=20),"L"===m[0]||"1"===m[0]||"2"===m[0]?(r.lyr.length>0&&r.lyr[0].cx?(r.ymin=Math.max(r.ymin,1e-10),r.ymax=Math.max(r.ymax,1e-10)):(r.ymin=Math.max(r.ymin,1e-20),r.ymax=Math.max(r.ymax,1e-20)),r.ymin=s.log10(r.ymin)*x,r.ymax=s.log10(r.ymax)*x):r.lyr.length>0&&r.lyr[0].cx?(r.ymin=Math.max(-18*x,r.ymin),r.ymax=Math.max(-18*x,r.ymax),r.dbmin=1e-37):Math.min(r.ymin,r.ymax)<-20*x&&(r.ymin=Math.max(-37*x,r.ymin),r.ymax=Math.max(-37*x,r.ymax),r.dbmin=Math.pow(10,Math.min(r.ymin,r.ymax)/x))}n.level=0,p&&!r.index&&(o&&(r.xmin=r.xstart+r.xdelta*(r.xmin-1)),o&&(r.xmax=r.xstart+r.xdelta*(r.xmax-1)));switch(r.xmult=t.xmult,r.ymult=t.xmult,t.autox){case"none":t.autox=-1;break;case"min":t.autox=1;break;case"max":t.autox=2;break;case"full":t.autox=3}r.autox=void 0===t.autox?-1:t.autox,r.autox<0&&(r.autox=0,o||(r.autox+=1),a||(r.autox+=2));switch(t.autoy){case"none":t.autoy=-1;break;case"min":t.autoy=1;break;case"max":t.autoy=2;break;case"full":t.autoy=3}r.autoy=void 0===t.autoy?-1:t.autoy,r.autoy<0&&(r.autoy=0,l||(r.autoy+=1),c||(r.autoy+=2));switch(t.autoz){case"none":t.autoz=-1;break;case"min":t.autoz=1;break;case"max":t.autoz=2;break;case"full":t.autoz=3}r.autoz=void 0===t.autoz?-1:t.autoz,r.autoz<0&&(r.autoz=0,d||(r.autoz+=1),f||(r.autoz+=2));r.autol=void 0===t.autol?-1:t.autol,o||(r.xmin=void 0);a||(r.xmax=void 0);U(e,{get_data:!0},r.xmin,r.xmax,r.xlab,r.ylab),o||(r.xmin=n.stk[0].xmin);a||(r.xmax=n.stk[0].xmax);l||(r.ymin=n.stk[0].ymin);c||(r.ymax=n.stk[0].ymax);r.xmin>r.xmax&&(n.stk[0].xmin=r.xmax,r.xmax=r.xmin,r.xmin=n.stk[0].xmin);r.ymin>r.ymax&&(n.stk[0].ymin=r.ymax,r.ymax=r.ymin,r.ymin=n.stk[0].ymin);n.stk[0].xmin=r.xmin,n.stk[0].xmax=r.xmax,n.stk[0].ymin=r.ymin,n.stk[0].ymax=r.ymax,r.panxmin=Math.min(r.panxmin,r.xmin),r.panxmax=Math.max(r.panxmax,r.xmax),r.panymin=Math.min(r.panymin,r.ymin),r.panymax=Math.max(r.panymax,r.ymax),r.panxpad=t.panxpad,r.panypad=t.panypad;var y=r.panxmax-r.panxmin,g=r.panymax-r.panymin;r.panxmin-=s.pad(y,r.panxpad),r.panxmax+=s.pad(y,r.panxpad),r.panymin-=s.pad(g,r.panypad),r.panymax+=s.pad(g,r.panypad),r.xmin=n.stk[0].xmin,r.ymin=n.stk[0].ymin,t.font_family&&(n.font_family=t.font_family);t.font_width&&(n.font_width=t.font_width);t.font_scaled&&(n.font_scaled=!0);var b=n.font_width;n.font_scaled&&(b=Math.min(n.font_width,n.width/64));u.set_font(n,b),r.ncolors=void 0===t.ncolors?500:t.ncolors,r.cmap=null,void 0!==t.cmap?r.cmap=t.cmap:r.cmap=void 0===t.xc?-1:t.xc;v(e,r.cmap),"leftmouse"===t.xcnt?r.cntrls=1:"continuous"===t.xcnt?r.cntrls=2:r.cntrls=void 0===t.xcnt?1:t.xcnt;r.default_rubberbox_mode=void 0===t.rubberbox_mode?"box":t.rubberbox_mode,r.default_rubberbox_action=void 0===t.rubberbox_action?"zoom":t.rubberbox_action,r.default_rightclick_rubberbox_mode=void 0===t.rightclick_rubberbox_mode?"box":t.rightclick_rubberbox_mode,r.default_rightclick_rubberbox_action=void 0===t.rightclick_rubberbox_action?null:t.rightclick_rubberbox_action,r.cross=void 0!==t.cross&&t.cross,r.grid=void 0===t.nogrid||!t.nogrid,r.fillStyle=t.fillStyle,r.gridBackground=t.gridBackground,r.gridStyle=t.gridStyle,r.wheelZoom=t.wheelZoom,r.wheelZoomPercent=t.wheelZoomPercent,r.legend=void 0!==t.legend&&t.legend,r.no_legend_button=void 0!==t.no_legend_button&&t.no_legend_button,r.legendBtnLocation=null,r.pan=void 0===t.nopan||!t.nopan,r.nomenu=void 0!==t.nomenu&&t.nomenu,r.modmode=0,r.modlayer=-1,r.modsource=0,r.modified=t.mod&&r.lyr.length>0,r.nmark=0,r.iabsc=0,r.index&&(r.iabsc=1);r.specs=!t.nospecs,r.scroll_time_interval=void 0===t.scroll_time_interval?r.scroll_time_interval:t.scroll_time_interval,r.autohide_readout=t.autohide_readout,r.autohide_panbars=t.autohide_panbars,r.x_scrollbar_location=t.x_scrollbar_location,r.specs?(r.show_x_axis=!t.noxaxis,r.show_y_axis=!t.noyaxis,r.show_readout=!t.noreadout,r.show_x_axis||r.show_y_axis||r.show_readout?r.specs=!0:r.specs=!1):(r.show_x_axis=!1,r.show_y_axis=!1,r.show_readout=!1);r.hide_note=t.hide_note||!1,r.xmrk=0,r.ymrk=0,t.nodragdrop||(u.addEventListener(n,"dragover",(function(e){e.preventDefault()}),!1),u.addEventListener(n,"drop",function(e){return function(t){var n=t.dataTransfer.files;n.length>0&&(t.preventDefault(),e.load_files(n))}}(e),!1));r.initialized=!0}(this,t),this.mimicListeners={other:null,listeners:{zoom:null,unzoom:null,xpan:null,ypan:null}},this._refresh(),this.onmousemove=(n=this,function(e){var t,r=n._Mx,i=n._Gx,o=e.target.getBoundingClientRect(),a=void 0===e.offsetX?e.pageX-o.left-window.scrollX:e.offsetX,l=void 0===e.offsetX?e.pageY-o.top-window.scrollY:e.offsetY,s=F(n,a,l);i.retx=s.x,i.rety=s.y,r.widget||(B(n),(t=document.createEvent("Event")).initEvent("mmove",!0,!0),t.originalEvent=e,t.xpos=a,t.ypos=l,t.x=i.retx,t.y=i.rety,u.dispatchEvent(r,t)&&(i.cross&&(r.warpbox?(void 0!==i.cross_xpos&&u.rubberline(r,i.cross_xpos,r.t,i.cross_xpos,r.b),void 0!==i.cross_ypos&&u.rubberline(r,r.l,i.cross_ypos,r.r,i.cross_ypos),i.cross_xpos=void 0,i.cross_ypos=void 0):n.mouseOnCanvas&&(O(n),i.p_cuts&&1===i.lyr.length&&2===i.lyr[0].hcb.class&&(i.y_cut_press_on||i.x_cut_press_on||L(n)))),2===i.cntrls&&((t=document.createEvent("Event")).initEvent("mtag",!0,!0),t.originalEvent=e,t.x=i.retx,t.y=i.rety,t.xpos=a,t.ypos=l,u.dispatchEvent(r,t))))}),this.throttledOnMouseMove=s.throttle(this._Gx.scroll_time_interval,this.onmousemove),u.addEventListener(r,"mousemove",this.throttledOnMouseMove,!1),this.onmouseout=function(e){return function(t){var n=e._Gx,r=e._Mx;e.mouseOnCanvas&&(e.mouseOnCanvas=!1,n.autohide_readout&&B(e),n.autohide_panbars&&R(e),r.prompt&&r.prompt.input.enableBlur())}}(this),u.addEventListener(r,"mouseout",this.onmouseout,!1),this.onmouseover=function(e){return function(t){var n=e._Gx,r=e._Mx;e.mouseOnCanvas=!0,n.autohide_panbars&&R(e),r.prompt&&r.prompt.input.disableBlur()}}(this),u.addEventListener(r,"mouseover",this.onmouseover,!1),this.onmousedown=function(e){return function(t){t.preventDefault();var n=e._Mx,r=e._Gx;n.widget&&"ONESHOT"===n.widget.type&&(n.widget=null,e.refresh()),u.ifevent(n,t);var i=document.createEvent("Event");if(i.initEvent("mdown",!0,!0),i.originalEvent=t,i.xpos=n.xpos,i.ypos=n.ypos,i.x=r.retx,i.y=r.rety,i.which=t.which,!u.dispatchEvent(n,i))return!1;var o,a,l,c,d,f,h=W(e);if(h.inPanRegion){if(t.preventDefault()," "!==h.command){var p=null,m=null;if("XPAN"===h.command?p=n.scrollbar_x:"YPAN"===h.command&&(p=n.scrollbar_y),2===t.which)m={x:n.xpos,y:n.ypos},void 0!==p&&j(m,p)&&function(e,t){var n=e._Mx;u.removeEventListener(n,"mousedown",e.onmousedown,!1),u.menu(n,{title:"SCROLLBAR",refresh:function(){e.refresh()},finalize:function(){u.addEventListener(n,"mousedown",e.onmousedown,!1),e.refresh()},items:[{text:"Expand Range",handler:function(){Y(e,u.SB_EXPAND,t)}},{text:"Shrink Range",handler:function(){Y(e,u.SB_SHRINK,t)}},{text:"Expand Full",handler:function(){Y(e,u.SB_FULL,t)}}]})}(e,h.command);else if(" "!==h.command&&!j(m={x:n.xpos,y:n.ypos},p)&&1===t.which){D(e,h.command,0,t);var x=function(){j({x:n.xpos,y:n.ypos},p)?r.stillPanning&&(window.clearInterval(r.stillPanning),r.repeatPanning=void 0):D(e,h.command,0,t)};r.stillPanning=window.setTimeout((function(){r.repeatPanning=window.setInterval(x,50)}),250)}}}else if(1===t.which||3===t.which){var y=!1;if(r.legendBtnLocation&&(o=n.xpos,a=n.ypos,l=r.legendBtnLocation.x,c=r.legendBtnLocation.y,d=r.legendBtnLocation.width,f=r.legendBtnLocation.height,y=o>=l&&o<=l+d&&a>=c&&a<=c+f),r.legend)for(var v=S(e),g=v.height/r.lyr.length,b=0;b=n.xpos&&v.y<=n.ypos&&v.y+g>=n.ypos)return n.mouseUpLatch=!0,w(e,b),!1;v.y+=g}if(r.lg_colorbar&&2===r.lyr[0].hcb.class&&(1===t.which||3===t.which)){var M=n.xpos,E=n.ypos,T=r.cbb_top_x1,C=r.cbb_top_y1;if(H(M,E,T,C,T+r.cbb_width,C,T+.5*r.cbb_width,C-r.cbb_height)){var A=r.cmap;e.get_layer(0).img=void 0;var P=s.Mc.colormap[A];for(b=0;b=r.xmin&&y<=r.xmax&&(n.stk[i].xmin=x,n.stk[i].xmax=y),v>=r.ymin&&g<=r.ymax&&(n.stk[i].ymin=v,n.stk[i].ymax=g),r.cmode===r.basemode&&1===n.level&&(r.xmin=Math.min(r.xmin,x),r.xmax=Math.max(r.xmax,y),r.ymin=Math.min(r.ymin,v),r.ymax=Math.max(r.ymax,g)),e.refresh()}else if(2===t.targetTouches.length){var b=s.touch_distance(t.targetTouches[0],t.targetTouches[1]),_=.05*(1-n.touch_distance/b),w=n.stk[i].xmax-n.stk[i].xmin,k=n.stk[i].ymax-n.stk[i].ymin;x=n.stk[i].xmin+_*w,y=n.stk[i].xmax-_*w,v=n.stk[i].ymin+_*k,g=n.stk[i].ymax-_*k;n.stk[i].xmin=Math.max(r.xmin,x),n.stk[i].xmax=Math.min(r.xmax,y),n.stk[i].ymin=Math.max(r.ymin,v),n.stk[i].ymax=Math.min(r.ymax,g),e.refresh()}}}(this),this.throttledOnTouchMove=s.throttle(this._Gx.scroll_time_interval,this.ontouchmove),u.addEventListener(r,"touchmove",this.throttledOnTouchMove,!1),this.ontouchend=function(e){return function(t){var n=e._Gx,r=e._Mx;t.preventDefault(),console.log("on touch end ",t.targetTouches.length),n.panning=void 0,e._Mx.scrollbar_x.action=0,e._Mx.scrollbar_y.action=0,r.touch_distance=void 0,u.widget_callback(r,t),r.touchClear=window.setTimeout((function(){r.touches=void 0,r.touchClear=void 0}),100)}}(this),u.addEventListener(r,"touchend",this.ontouchend,!1),this.docMouseUp=function(e){return function(t){var n=e._Gx;return 1===t.which&&(n.panning=void 0,e._Mx.scrollbar_x.action=0,e._Mx.scrollbar_y.action=0),n.stillPanning&&(window.clearTimeout(n.stillPanning),n.stillPanning=void 0),n.repeatPanning&&(window.clearInterval(n.repeatPanning),n.repeatPanning=void 0),!1}}(this),document.addEventListener("mouseup",this.docMouseUp,!1),this.mouseup=function(e){return function(t){t.preventDefault();var n=e._Gx,r=e._Mx;if(u.ifevent(e._Mx,t),(a=document.createEvent("Event")).initEvent("mup",!0,!0),a.originalEvent=t,a.xpos=r.xpos,a.ypos=r.ypos,a.x=n.retx,a.y=n.rety,a.which=t.which,u.dispatchEvent(r,a)){if(r.warpbox||r.widget||r.prompt)return;if(1===t.which){var i=function(e){var t=!1,n=e._Mx,r=n.xpos,i=n.ypos,o=n.text_h,a=n.text_w,l=" ";r=n.t?(l="YCENTER",t=!0):i>n.b+s.trunc(.5*a)&&i<=n.b+s.trunc(s.trunc(3*o)/2)&&r>=n.l&&r<=n.r&&(l="XCENTER",t=!0);return{inCenterRegion:t,command:l}}(e);if(i.inCenterRegion)" "!==i.command&&D(e,i.command,0,t);else if(1===n.cntrls){n.xmrk=n.retx,n.ymrk=n.rety;var o=document.createEvent("Event");o.initEvent("mtag",!0,!0),o.originalEvent=t,o.x=n.xmrk,o.y=n.ymrk,o.xpos=t.x||t.clientX,o.ypos=t.y||t.clientY,o.w=void 0,o.h=void 0,o.shift=t.shiftKey,u.dispatchEvent(r,o),e.redraw()}}else if(2===t.which){var a;if(n.nomenu)if((a=document.createEvent("Event")).initEvent("showmenu",!0,!0),a.originalEvent=t,a.x=t.x||t.clientX,a.y=t.y||t.clientY,u.dispatchEvent(r,a)){t.stopPropagation&&t.stopPropagation(),t.cancelBubble=!0,u.removeEventListener(r,"mousedown",e.onmousedown,!1);var l=function(){try{var t=document.createEvent("Event");t.initEvent("hidemenu",!0,!0),u.dispatchEvent(r,t)&&u.addEventListener(r,"mousedown",e.onmousedown,!1)}finally{document.removeEventListener("mouseup",l,!1)}};document.addEventListener("mouseup",l,!1)}}else 3===t.which&&(t.preventDefault(),e.unzoom(1),e.refresh())}}}(this),u.addEventListener(r,"mouseup",this.mouseup,!1),this.mouseclick=function(e){return function(t){t.preventDefault();var n=e._Gx,r=e._Mx;u.ifevent(e._Mx,t);var i=document.createEvent("Event");return i.initEvent("mclick",!0,!0),i.originalEvent=t,i.xpos=r.xpos,i.ypos=r.ypos,i.x=n.retx,i.y=n.rety,i.which=t.which,u.dispatchEvent(r,i),!1}}(this),u.addEventListener(r,"click",this.mouseclick,!1),this.mousedblclick=function(e){return function(t){t.preventDefault();var n=e._Gx,r=e._Mx;u.ifevent(e._Mx,t);var i=document.createEvent("Event");return i.initEvent("mdblclick",!0,!0),i.originalEvent=t,i.xpos=r.xpos,i.ypos=r.ypos,i.x=n.retx,i.y=n.rety,i.which=t.which,u.dispatchEvent(r,i),!1}}(this),u.addEventListener(r,"dblclick",this.mousedblclick,!1),this.dragMouseDownHandler=function(e){return function(t){var n=e._Mx,r=e._Gx,i=W(e);if(i.inPanRegion&&(t.preventDefault()," "!==i.command)){var o;"XPAN"===i.command?o=n.scrollbar_x:"YPAN"===i.command&&(o=n.scrollbar_y);var a={x:n.xpos,y:n.ypos};void 0!==o&&j(a,o)&&1===t.which&&(r.panning={axis:i.command,xpos:t.screenX,ypos:t.screenY,xmin:n.stk[n.level].xmin,xmax:n.stk[n.level].xmax,ymin:n.stk[n.level].ymin,ymax:n.stk[n.level].ymax})}}}(this),window.addEventListener("mousedown",this.dragMouseDownHandler,!1),this.dragMouseMoveHandler=function(e){return function(t){var n=e._Gx;if(void 0!==n.panning)try{!function(e,t,n){var r,i,o,a=e._Mx,l=e._Gx;if("XPAN"===t)o=e._Mx.scrollbar_x;else{if("YPAN"!==t)throw"Unable to drag scrollbar - scrollAction is not 'XPAN' or 'YPAN'!!";o=e._Mx.scrollbar_y}o.flag=-12;var s=a.level;"XPAN"===t?(r=a.stk[s].xmin,i=a.stk[s].xmax):"YPAN"===t?(r=a.stk[s].ymin,i=a.stk[s].ymax):(r=void 0,i=void 0);var c={min:r,max:i};(function(e,t,n,r,i,o){if(n.action=u.SB_DRAG,"YPAN"===r){var a=e.scrollbar_y.trange/e.scrollbar_y.h;4===n.origin&&(a*=-1);var l=(o.screenY-t.panning.ypos)*a;t.panning.ymin-lt.panymax?(i.min=t.panymax-(i.max-i.min),i.max=t.panymax):(i.min=t.panning.ymin-l,i.max=t.panning.ymax-l)}else if("XPAN"===r){a=e.scrollbar_x.trange/e.scrollbar_x.w;3===n.origin&&(a*=-1);l=(o.screenX-t.panning.xpos)*a;t.panning.xmin+lt.panxmax?(i.min=t.panxmax-(i.max-i.min),i.max=t.panxmax):(i.min=t.panning.xmin+l,i.max=t.panning.xmax+l)}})(a,l,o,t,c,n),r=c.min,i=c.max,o.smin=r,o.srange=i-r,u.redrawScrollbar(o,a,void 0),X(e,o.smin,o.smin+o.srange,t.slice(0,1)),e.inPan=!0;var d=document.createEvent("Event");"XPAN"===t?d.initEvent("xpan",!0,!0):"YPAN"===t&&d.initEvent("ypan",!0,!0);d.level=a.level,d.xmin=a.stk[a.level].xmin,d.ymin=a.stk[a.level].ymin,d.xmax=a.stk[a.level].xmax,d.ymax=a.stk[a.level].ymax,u.dispatchEvent(a,d),e.inPan=!1,o.action=0,e.refresh()}(e,n.panning.axis,t)}catch(e){console.log("Error: "+e)}}}(this),this.throttledDragOnMouseMove=s.throttle(this._Gx.scroll_time_interval,this.dragMouseMoveHandler),window.addEventListener("mousemove",this.throttledDragOnMouseMove,!1),this.dragMouseUpHandler=function(e){return function(t){var n=e._Gx;1===t.which&&(n.panning=void 0)}}(this),window.addEventListener("mouseup",this.dragMouseUpHandler,!1),this.onresize=function(e){return function(t){u.checkresize(e._Mx)&&e.refresh()}}(this),this.wheelHandler=function(e){var t=e._Mx,n=e._Gx,r=s.throttle(100,(function(r){var i;"XPAN"===r.command?i=t.scrollbar_x:"YPAN"===r.command&&(i=t.scrollbar_y),n.wheelscroll_mode_natural?i.action=event.deltaY<0?u.SB_WHEELDOWN:u.SB_WHEELUP:i.action=event.deltaY<0?u.SB_WHEELUP:u.SB_WHEELDOWN,i.step=.1*i.srange,i.page=9*i.step,u.scroll(t,i,u.XW_COMMAND,void 0,i),X(e,i.smin,i.smin+i.srange,r.command.slice(0,1))})),i=s.throttle(100,(function(){var t=n.wheelZoomPercent||.2;n.wheelscroll_mode_natural?event.deltaY>0&&(t*=-1):event.deltaY<0&&(t*=-1),"x"===n.wheelZoom?e.percent_zoom(t,1,!0):"y"===n.wheelZoom?e.percent_zoom(1,t,!0):e.percent_zoom(t,t,!0)}));return function(o){u.ifevent(t,o);var a=W(e);e.mouseOnCanvas&&(o.preventDefault(),a.inPanRegion?r(a):n.wheelZoom&&i())}}(this),window.addWheelListener(window,this.wheelHandler,!1),window.addEventListener("resize",this.onresize,!1),t.nokeypress||(this.onkeypress=function(e){return function(t){var n=e._Mx,r=e._Gx;if(e.mouseOnCanvas){if(n.widget&&"MENU"===n.widget.type)return;if(n.widget&&"ONESHOT"===n.widget.type)return n.widget=null,void e.refresh();var o=i.getKeyCode(t);if((a=document.createEvent("Event")).initEvent("plotkeypress",!0,!0),a.originalEvent=t,a.keyCode=o,a.shiftKey=t.shiftKey,a.ctrlKey=t.ctrlKey,a.altKey=t.altKey,a.metaKey=t.metaKey,!u.dispatchEvent(n,a))return;if(97===o)r.iabsc=(r.iabsc+1)%4,B(e);else if(108===o)e.change_settings({legend:!r.legend});else if(103===o)e.change_settings({grid:!r.grid});else if(98===o||2===o)n.warpbox&&("box"===n.warpbox.mode?n.warpbox.mode="horizontal":"horizontal"===n.warpbox.mode?n.warpbox.mode="vertical":n.warpbox.mode="box",u.redraw_warpbox(n));else if(99===o)e.change_settings({xcnt:-1*r.cntrls});else if(114===o)e.change_settings({show_readout:!r.show_readout});else if(115===o)e.change_settings({specs:!r.specs});else if(112===o)e.change_settings({p_cuts:!r.p_cuts});else if(120===o)r.x_cut_press_on?e.xCut():"pop-up"===r.xyKeys||1===r.lyr[0].hcb.class&&"automatic"===r.xyKeys?r.x_pop_now?r.x_pop_now=!1:(g(e),r.x_pop_now=!0):"disable"!==r.xyKeys&&2===r.lyr[0].hcb.class&&(r.y_cut_press_on||e.xCut(F(e,0,n.ypos).y));else if(121===o)r.y_cut_press_on?e.yCut():"pop-up"===r.xyKeys||1===r.lyr[0].hcb.class&&"automatic"===r.xyKeys?r.y_pop_now?r.y_pop_now=!1:(b(e),r.y_pop_now=!0):"disable"!==r.xyKeys&&2===r.lyr[0].hcb.class&&(r.x_cut_press_on||e.yCut(F(e,n.xpos,0).x));else if(122===o)!function(e){var t=e._Gx,n=e._Mx;if(t.zmin&&t.zmax){var r="";if(1===t.lyr.length)r="Z = "+t.lyr[0].get_z(t.retx,t.rety).toString();else r="TODO";u.message(n,r)}}(e);else if(116===o)!function(e){var t=e._Gx,n=e._Mx;if(t.lyr.length>0){var r=t.lyr[0].hcb;r&&(1!==r.class||1!==r.xunits&&4!==r.xunits?2!==r.class||1!==r.yunits&&4!==r.yunits?u.message(n,"Time = UNK"):u.message(n,"Time = "+s.sec2tod(r.timecode+t.rety),!0):u.message(n,"Time = "+s.sec2tod(r.timecode+t.retx),!0))}}(e);else if(109===o){var a;if(!r.nomenu)(a=document.createEvent("Event")).initEvent("showmenu",!0,!0),a.originalEvent=t,a.x=n.x,a.y=n.y,u.dispatchEvent(n,a)&&_(e)}else 63===o?u.message(n,"To zoom, press and drag the left mouse (LM) over the region of interest and release. To unzoom, press right mouse (RM). Press the middle mouse (MM) button or press the 'M' key to open the main menu.View the function of all keypresses by selecting 'Keypress Info' from the main menu."):102===o?(u.fullscreen(n),e.refresh()):9===o&&t.ctrlKey?e.change_settings({invert:null}):107===o&&(r.show_marker=!r.show_marker,e.redraw())}}}(this),i.setKeypressHandler(this.onkeypress)),this};p.prototype={add_plugin:function(e,t){if(void 0===t&&(t=Number.MAX_VALUE),t<=0)throw"Invalid plugin zorder";var n=document.createElement("canvas");n.width=this._Mx.canvas.width,n.height=this._Mx.canvas.height,e.init(this,n),this._Gx.plugins.push({impl:e,zorder:t,canvas:n}),this._Gx.plugins.sort((function(e,t){return e.zorder-t.zorder})),this.refresh()},remove_plugin:function(e){for(var t=this._Gx.plugins.length;t--;)this._Gx.plugins[t].impl===e&&(e.dispose&&e.dispose(),this._Gx.plugins[t].canvas.parentNode&&this._Gx.plugins[t].canvas.parentNode.removeElement(this._Gx.plugins[t].canvas),this._Gx.plugins.splice(t,1));this._Gx.plugins.sort((function(e,t){return e.zorder-t.zorder})),this.refresh()},addListener:function(e,t){var n=this._Mx;u.addEventListener(n,e,t,!1)},removeListener:function(e,t){var n=this._Mx;u.removeEventListener(n,e,t,!1)},change_settings:function(e){for(var t,n=this._Gx,r=this._Mx,i=0;i0||"enable"===e.xcnt&&n.cntrls<0?n.cntrls=-1*n.cntrls:n.cntrls=e.xcnt),void 0!==e.legend&&(null===e.legend?n.legend=!n.legend:n.legend=e.legend),void 0!==e.pan&&(null===e.pan?n.pan=!n.pan:n.pan=e.pan),void 0!==e.cross&&(null===e.cross?n.cross=!n.cross:n.cross=e.cross,n.cross?(n.cross_xpos=void 0,n.cross_ypos=void 0,!r.warpbox&&this.mouseOnCanvas&&O(this)):(void 0!==n.cross_xpos&&u.rubberline(r,n.cross_xpos,r.t,n.cross_xpos,r.b),void 0!==n.cross_ypos&&u.rubberline(r,r.l,n.cross_ypos,r.r,n.cross_ypos),n.cross_xpos=void 0,n.cross_ypos=void 0));var o=void 0===e.cmode?"":e.cmode;t="string"==typeof o?(o+="").toUpperCase():o,void 0!==e.cmode&&("MA"!==t&&"INMA"!==t&&"ABMA"!==t&&"__MA"!==t&&"MAGNITUDE"!==t&&1!==t||(t=1),"PH"!==t&&"INPH"!==t&&"ABPH"!==t&&"__PH"!==t&&"PHASE"!==t&&2!==t||(t=2),"RE"!==t&&"INRE"!==t&&"ABRE"!==t&&"__RE"!==t&&"REAL"!==t&&3!==t||(t=3),"IM"!==t&&"INIM"!==t&&"ABIM"!==t&&"__IM"!==t&&"IMAGINARY"!==t&&4!==t||(t=4),"LO"!==t&&"D1"!==t&&"INLO"!==t&&"IND1"!==t&&"ABIM"!==t&&"ABD1"!==t&&"__LO"!==t&&"__D1"!==t&&"10*LOG10"!==t&&6!==t||(t=6),"L2"!==t&&"D2"!==t&&"INL2"!==t&&"IND2"!==t&&"ABLO"!==t&&"ABD2"!==t&&"__L2"!==t&&"__D2"!==t&&"20*LOG10"!==t&&7!==t||(t=7),"RI"!==t&&"IR"!==t&&"INRI"!==t&&"INIR"!==t&&"ABRI"!==t&&"ABIR"!==t&&"__RI"!==t&&"__IR"!==t&&"IMAG/REAL"!==t&&"REAL/IMAG"!==t&&5!==t||(n.index?alert("Imag/Real mode not permitted in INDEX mode"):t=5),I(this,t)),void 0!==e.phunits&&function(e,t){var n=e._Gx,r=e._Mx,i=n.plab;"R"===t?i=23:"D"===t&&(i=24);"C"===t&&(i=25);if(i!==n.plab){var o=[Math.PI,180,.5],a=o[i-23]/o[n.plab-23];if(n.plab=i,2===n.cmode){for(var l=0;l<=r.level;l++)r.stk[l].ymin=r.stk[l].ymin*a,r.stk[l].ymax=r.stk[l].ymax*a,r.stk[l].yscl=r.stk[l].yscl*a;n.panymin=n.panymin*a,n.panymax=n.panymax*a,e.refresh()}}}(this,e.phunits),void 0!==e.rubberbox_action&&(n.default_rubberbox_action=e.rubberbox_action),void 0!==e.rubberbox_mode&&(n.default_rubberbox_mode=e.rubberbox_mode),void 0!==e.rightclick_rubberbox_action&&(n.default_rightclick_rubberbox_action=e.rightclick_rubberbox_action),void 0!==e.rightclick_rubberbox_mode&&(n.default_rightclick_rubberbox_mode=e.rightclick_rubberbox_mode),void 0!==e.wheelscroll_mode_natural&&(n.wheelscroll_mode_natural=e.wheelscroll_mode_natural),void 0!==e.colors&&(e.colors.fg||(e.colors.fg=r.fg),e.colors.bg||(e.colors.bg=r.bg),u.setbgfg(r,e.colors.bg,e.colors.fg,r.xi)),void 0!==e.cmap&&(null===e.cmap?2===n.cmode?n.cmap=2:n.cmap=1:n.cmap=e.cmap,v(this,n.cmap)),void 0!==e.yinv&&(e.yinv?r.origin=4:r.origin=1),void 0!==e.rasterSmoothing&&(null===e.rasterSmoothing?n.rasterSmoothing=!n.rasterSmoothing:n.rasterSmoothing=e.rasterSmoothing),void 0!==e.fillStyle&&(n.fillStyle=e.fillStyle),void 0!==e.invert&&(null===e.invert?u.invertbgfg(r):!0===e.invert?u.setbgfg(this,"white","black"):u.setbgfg(this,"black","white")),void 0!==e.nomenu&&(null===e.nomenu?n.nomenu=!n.nomenu:n.nomenu=e.nomenu),void 0!==e.ymax&&(null===e.ymax?(n.autoy=2|n.autoy,n.panymax=void 0,U(this,{}),n.ymax=n.panymax):(n.autoy=13&n.autoy,n.ymax=e.ymax,X(this,r.stk[0].ymin,e.ymax,"Y"),this.redraw())),void 0!==e.ymin&&(null===e.ymin?(n.autoy=1|n.autoy,n.panymin=void 0,U(this,{}),n.ymin=n.panymin):(n.autoy=14&n.autoy,n.ymin=e.ymin,X(this,e.ymin,r.stk[0].ymax,"Y"),this.redraw())),void 0!==e.autoy&&(n.autoy=e.autoy,0!=(1&n.autoy)&&(n.ymin=void 0),0!=(2&n.autoy)&&(n.ymax=void 0)),void 0!==e.xmin&&(X(this,e.xmin,r.stk[0].xmax,"X"),n.autox=2&n.autox,this.redraw()),void 0!==e.xmax&&(X(this,r.stk[0].xmin,e.xmax,"X"),n.autox=1&n.autox,this.redraw()),void 0!==e.zmin&&(n.zmin=e.zmin,n.autoz=2&n.autoz),void 0!==e.zmax&&(n.zmax=e.zmax,n.autoz=1&n.autoz),void 0!==e.autoz&&(n.autoz=e.autoz,0!=(1&n.autoz)&&(n.zmin=void 0),0!=(2&n.autoz)&&(n.zmax=void 0)),void 0!==e.note&&(n.note=e.note),void 0!==e.lg_colorbar&&(n.lg_colorbar=!n.lg_colorbar),void 0!==e.p_cuts&&(null===e.p_cuts?n.p_cuts=!n.p_cuts:n.p_cuts=e.p_cuts),void 0!==e.xcut_now&&(n.xcut_now=!n.xcut_now),void 0!==e.ycut_now&&(n.ycut_now=!n.ycut_now),this.refresh(),void 0!==e.pan&&B(this)},reread:function(){for(var e=this._Gx,n=[],r=0;r=a.lyr.length){if("number"==typeof e)throw"reload requires use the layer uuid returned by overlay and no longer supports layer indexes"}else if(void 0!==a.lyr[l].reload){var s=a.lyr[l].reload(n,r);0===o.level&&U(this,{get_data:!1},s.xmin,s.xmax),i?this._refresh():this.refresh()}},rescale:function(){0===this._Mx.level&&U(this,{get_data:!1},void 0,void 0),this.refresh()},headermod:function(e,t){this.change_settings(t),this.push(e,[],t)},push:function(e,n,r,i,o){var a=this._Mx,l=this._Gx,s=-1;if(t.has(l.HCB_UUID,e)&&(s=this.get_lyrn(e)),s<0||s>=l.lyr.length){if("number"==typeof e)throw"push requires use the layer uuid returned by overlay and no longer supports layer indexes"}else if(void 0!==l.lyr[s].push&&!1!==l.lyr[s].display){var u=r;if(r){u=JSON.parse(JSON.stringify(r));0===n.length&&(u.xmin=a.stk[0].xmin,u.xmax=a.stk[0].xmax,u.ymin=a.stk[0].ymin,u.ymax=a.stk[0].ymax)}var c=l.lyr[s].push(n,u,i);0===a.level&&c&&U(this,{get_data:!1}),o?this._refresh():this.refresh()}},overlay_array:function(e,t,n){s.log.debug("Overlay array");var r=s.initialize(e,t);return this.overlay_bluefile(r,n)},overlay_pipe:function(e,t){s.log.debug("Overlay pipe"),e||(e={}),e.pipe=!0;var n=s.initialize(null,e);return this.overlay_bluefile(n,t)},overlay_websocket:function(e,t,n){s.log.debug("Overlay websocket: "+e);var r=new WebSocket(e,"plot-data");r.binaryType="arraybuffer";var i=this;t||(t={}),t.pipe=!0;var o=s.initialize(null,t);o.ws=r;var a=this.overlay_bluefile(o,n);return r.onopen=function(e){},r.onmessage=function(e){if(e.data instanceof ArrayBuffer){var t=o.createArray(e.data);i.push(a,t)}else if("string"==typeof e.data){i._Gx.lyr[a].hcb||s.log.warning("Couldn't find header for layer "+a);var n=JSON.parse(e.data);i.push(a,[],n)}},a},overlay_wpipe:function(e,t,n,r){let i=this,o={hcb:null,layer_n:null,plotLayerOptions:null,ws:null};return o.ws=new WebSocket(e,"pipe-data"),o.ws.binaryType="arraybuffer",s.log.debug("Overlay websocket: "+e),o.ws.onopen=function(e){o.ws.send(JSON.stringify({event:"open",payload:{set_buffer:{fps:r}}}))},o.ws.onmessage=(o.ws,function(e){if("string"==typeof e.data){var r=JSON.parse(e.data);if("version"===r.event)s.log.debug("server: "+r.payload.server+"\nxm-ver: "+r.payload["xm-ver"]);else if("header"===r.event)o.hcb=r.payload,o.hcb.ws=o.ws,o.hcb.ystart=0,o.hcb.class=Math.floor(o.hcb.type/1e3);else if("out_buffer"===r.event){null!==o.layer_n&&(i.remove_layer(o.layer_n),o.layer_n=null);var a={framesize:r.payload.framesize,cmode:r.payload.mode,xcmp:r.payload.xcmp,ycmp:r.payload.ycmp,fps:r.payload.fps};o.plotLayerOptions=null!=n?Object.assign(a,n):a,null!=t&&(o.hcb=Object.assign(o.hcb,t)),o.hcb.pipe=!0;try{o.hcb=s.initialize(null,o.hcb),o.layer_n=i.overlay_bluefile(o.hcb,o.plotLayerOptions)}catch(e){o.ws.close()}}else if("error"===r.event)s.log.error(r);else{if("eof"===r.event)return void o.ws.close();"abscissa_update"===r.event?o.plotLayerOptions.layerType===c?o.hcb.xstart+=r.payload.skip_count*o.hcb.xdelta:o.plotLayerOptions.layerType===d&&(o.hcb.ystart+=r.payload.skip_count*o.hcb.ydelta):(s.log.error('Received unexpected pipe-data event "'+r.event+'"'),o.ws.close())}}else if(o.plotLayerOptions.layerType===c){var l=o.hcb.createArray(e.data);i.push(o.layer_n,l)}else if(o.plotLayerOptions.layerType===d)for(var u=e.data.byteLength/o.hcb.bpe,f=0;f{null===t&&(n+=1)}),(0===n||e)&&(this._Gx.spinner&&this._Gx.spinner.stop(),this._Gx.spinner=void 0)},reg_hcb:function(e){var t=i.uuidv4();return this._Gx.HCB_UUID[t]=e,t},get_lyrn:function(e){return t.indexOf(this._Gx.HCB,e)},get_lyr_uuid:function(e){return this._Gx.HCB[e]},get_hcb_by_uuid:function(e){return this._Gx.HCB[e]},get_hcb_by_lyrn:function(e){return this.get_hcb_by_uuid(this.get_lyr_uuid(e))},add_layer:function(e){var t=this._Gx,n=this._Mx,r=document.createEvent("Event");return r.initEvent("lyradd",!0,!0),r.name=e.name,r.layer=e,!!u.dispatchEvent(n,r)&&(t.lyr.push(e),e.index=t.lyr.length-1,!0)},get_layer:function(e){var n=this._Gx;return t.has(n.HCB_UUID,e)&&(e=this.get_lyrn(e)),e>=0&&e0)if(void 0===e)for(var r=n.HCB.length-1;r>=0;r--)this.remove_layer(this.get_lyr_uuid(r));else if(e<0){if((r=n.HCB.length+e)<0)return;this.remove_layer(this.get_lyr_uuid(r))}else e=0&&o=0)for(a=n.lyr.length-1;a>=0;a--)n.lyr[a].hcb===r&&z(this,a);T(this),this.refresh();var l=document.createEvent("Event");l.initEvent("file_deoverlayed",!0,!0),""!==i&&(l.fileName=i),u.dispatchEvent(this._Mx,l)},pixel_zoom:function(e,t,n,r,i){var o=F(this,e,t),a=F(this,n,r);this.zoom(o,a,i)},percent_zoom:function(e,t,n){var r=this._Mx,i=this._Gx,o=0;Math.abs(e)<1&&(o=(o=Math.abs(r.stk[r.level].xmax-r.stk[r.level].xmin))*e/2);var a=0;Math.abs(t)<1&&(a=(a=Math.abs(r.stk[r.level].ymax-r.stk[r.level].ymin))*t/2);var l={x:Math.max(r.stk[r.level].xmin+o,i.panxmin),y:Math.max(r.stk[r.level].ymin+a,i.panymin)},s={x:Math.min(r.stk[r.level].xmax-o,i.panxmax),y:Math.min(r.stk[r.level].ymax-a,i.panymax)};this.zoom(l,s,n)},zoom:function(e,t,n){var r=this._Mx,i=this._Gx;if(!(r.level>=9)){if(void 0===e.x&&(e.x=r.stk[r.level].xmin),void 0===e.y&&(e.y=r.stk[r.level].ymin),void 0===t.x&&(t.x=r.stk[r.level].xmax),void 0===t.y&&(t.y=r.stk[r.level].ymax),t.x0&&0!==t.level;)t.stk.pop(),t.level=t.stk.length-1,e-=1;0===t.level&&this.rescale(),n.inContinuousZoom=!1,this.inZoom=!0;var r=document.createEvent("Event");r.initEvent("unzoom",!0,!0),r.level=t.level,r.xmin=t.stk[t.level].xmin,r.ymin=t.stk[t.level].ymin,r.xmax=t.stk[t.level].xmax,r.ymax=t.stk[t.level].ymax,u.dispatchEvent(t,r),this.inZoom=!1,this.refresh()}},mimic:function(e,t){var n=this;if(!t)throw"mimic must be called with at least one event mask";if(this.unmimic(e),t.zoom){var r=function(e){n.inZoom||n.zoom({x:e.xmin,y:e.ymin},{x:e.xmax,y:e.ymax},e.inContinuousZoom)};e.addListener("zoom",r),this.mimicListeners.listeners.zoom=r}else if(t.xzoom){r=function(e){n.inZoom||n.zoom({x:e.xmin,y:void 0},{x:e.xmax,y:void 0},e.inContinuousZoom)};e.addListener("zoom",r),this.mimicListeners.listeners.zoom=r}else if(t.yzoom){r=function(e){n.inZoom||n.zoom({x:void 0,y:e.ymin},{x:void 0,y:e.ymax},e.inContinuousZoom)};e.addListener("zoom",r),this.mimicListeners.listeners.zoom=r}if(t.unzoom){r=function(e){n.inZoom||e.level0)){var e=this;u.render(this._Mx,(function(){e._refresh()}))}},refresh_after:function(e){this._Gx.refresh_after_ctr+=1;try{e(this)}finally{this._Gx.refresh_after_ctr=Math.max(this._Gx.refresh_after_ctr-1,0),0===this._Gx.refresh_after_ctr&&this.refresh()}},enable_listeners:function(){var e=this._Mx;u.addEventListener(e,"mousedown",this.onmousedown,!1),u.addEventListener(e,"mousemove",this.throttledOnMouseMove,!1),window.addEventListener("mouseup",e.onmouseup,!1),window.addEventListener("keydown",e.onkeydown,!1),window.addEventListener("keyup",e.onkeyup,!1),window.addEventListener("resize",this.onresize,!1),document.addEventListener("mouseup",this.docMouseUp,!1),u.addEventListener(e,"mouseup",this.mouseup,!1),window.addEventListener("mousedown",this.dragMouseDownHandler,!1),window.addEventListener("mousemove",this.throttledDragOnMouseMove,!1),window.addEventListener("mouseup",this.dragMouseUpHandler,!1),window.addEventListener("wheel",this.wheelHandler,!1),window.addEventListener("mousewheel",this.wheelHandler,!1),window.addEventListener("DOMMouseScroll",this.wheelHandler,!1),window.addEventListener("keypress",this.onkeypress,!1)},disable_listeners:function(){var e=this._Mx;u.removeEventListener(e,"mousedown",this.onmousedown,!1),u.removeEventListener(e,"mousemove",this.throttledOnMouseMove,!1),u.removeEventListener(e,"mouseup",this.mouseup,!1),window.removeEventListener("mouseup",e.onmouseup,!1),window.removeEventListener("keydown",e.onkeydown,!1),window.removeEventListener("keyup",e.onkeyup,!1),window.removeEventListener("resize",this.onresize,!1),document.removeEventListener("mouseup",this.docMouseUp,!1),window.removeEventListener("mousedown",this.dragMouseDownHandler,!1),window.removeEventListener("mousemove",this.throttledDragOnMouseMove,!1),window.removeEventListener("mouseup",this.dragMouseUpHandler,!1),window.removeEventListener("wheel",this.wheelHandler,!1),window.removeEventListener("mousewheel",this.wheelHandler,!1),window.removeEventListener("DOMMouseScroll",this.wheelHandler,!1),window.removeEventListener("keypress",this.onkeypress,!1)},checkresize:function(){u.checkresize(this._Mx)&&this.refresh()},addColorMaps:function(e){e.forEach((function(e){e.hasOwnProperty("name")&&s.Mc.colormap.push(e)}))},xCut:function(e){var t=this._Gx,n=this._Mx;if(void 0!==e){if(t.cut_stash={},t.cut_stash.ylabel=t.ylabel,t.cut_stash.xlabel=t.xlabel,t.cut_stash.level=n.level,t.cut_stash.stk=JSON.parse(JSON.stringify(n.stk)),t.cut_stash.panymin=t.panymin,t.cut_stash.panymax=t.panymax,t.cut_stash.panxmin=t.panxmin,t.cut_stash.panxmax=t.panxmax,!t.p_cuts){t.x_cut_data=[];var r=t.lyr[0].xframe,i=Math.round((e-t.lyr[0].ystart)/t.lyr[0].ydelta);if(i<0||i>t.lyr[0].lps)return;var o=i*r,a=o+r;t.x_cut_data=t.lyr[0].buf.slice(o,a)}t.old_drawmode=t.lyr[0].drawmode,t.old_autol=t.autol,this.change_settings({drawmode:"undefined",autol:-1});var l=t.lyr.length>0&&t.lyr[0].cx;1===t.cmode?t.ylabel=s.UNITS[28][0]:2===t.cmode?t.ylabel=t.plab:3===t.cmode&&l?t.ylabel=s.UNITS[21][0]:4===t.cmode||5===t.cmode?t.ylabel=s.UNITS[22][0]:6===t.cmode?t.ylabel=s.UNITS[26][0]:7===t.cmode?t.ylabel=s.UNITS[27][0]:t.ylabel="Intensity","None"!==s.UNITS[t.xlab][0]&&"Unknown"!==s.UNITS[t.xlab][0]?t.xlabel=s.UNITS[t.xlab][0]:t.xlabel="Frequency",t.xlabel+=" CURRENTLY IN X_CUT MODE",n.origin=1,t.xcut_layer=this.overlay_array(t.x_cut_data,{xstart:t.lyr[0].xstart,xdelta:t.lyr[0].xdelta},{name:"x_cut_data",line:3}),t.xcut_layer=t.lyr.length-1;for(var u=0;u0&&t.lyr[0].cx;1===t.cmode?t.ylabel=s.UNITS[28][0]:2===t.cmode?t.ylabel=t.plab:3===t.cmode&&a?t.ylabel=s.UNITS[21][0]:4===t.cmode||5===t.cmode?t.ylabel=s.UNITS[22][0]:6===t.cmode?t.ylabel=s.UNITS[26][0]:7===t.cmode?t.ylabel=s.UNITS[27][0]:t.ylabel="Intensity","None"!==s.UNITS[t.ylab][0]&&"Unknown"!==s.UNITS[t.ylab][0]?t.xlabel=s.UNITS[t.ylab][0]:t.xlabel="Time",t.xlabel+=" CURRENTLY IN Y_CUT MODE",n.origin=1,t.ycut_layer=this.overlay_array(t.y_cut_data,{xstart:t.lyr[0].ystart,xdelta:t.lyr[0].ydelta},{name:"y_cut_data",line:3}),t.ycut_layer=t.lyr.length-1;for(var l=0;l=31536e3||Math.abs(e.stk[0].ymax)>=31536e3)&&(e.l=11*e.text_w)}else e.l=1;!0===t.pan?e.r=e.width-(t.pthk+2*e.text_w):e.r=e.width-5,t.show_readout?(e.t=2*e.text_h,t.show_x_axis?e.b=e.height-4*e.text_h:e.b=e.height-3*e.text_h):"bottom"===t.x_scrollbar_location?(e.t=2*e.text_h,t.pan?t.show_x_axis?e.b=e.height-3*e.text_h:e.b=e.height-2*e.text_h:t.show_x_axis?e.b=e.height-2*e.text_h:e.b=e.height-5):(t.pan?e.t=t.pthk+2*e.text_w:e.t=1,t.show_x_axis?e.b=e.height-3*e.text_h/2:e.b=e.height-2),t.show_readout?t.pl=50*e.text_w:"bottom"===t.x_scrollbar_location?t.pl=e.l:t.pl=35*e.text_w,t.pr=Math.max(t.pl+9*e.text_w,e.r),t.show_readout||"bottom"===t.x_scrollbar_location?t.show_x_axis?t.pt=e.b+e.text_h+(e.height-e.b-e.text_h-t.pthk)/2:t.pt=e.b+(e.height-e.b-t.pthk)/2:t.pt=(e.t-t.pthk)/2,t.lbtn=e.text_h+e.text_w+2}else t.pan?(e.t=t.pthk+2*e.text_w,e.r=e.width-(t.pthk+e.text_w)):(e.t=1,e.r=e.width-2),e.b=e.height-2,e.l=1,t.pl=e.l,t.pr=e.r,t.pt=(e.t-t.pthk)/2,t.lbtn=0;if(t.pyl=e.r+(e.width-e.r-t.pthk)/2+1,t.lg_colorbar&&2===t.lyr[0].hcb.class){var i=e.r;e.r=i-100}if(t.p_cuts&&1===t.lyr.length&&2===t.lyr[0].hcb.class){t.cross=!0;i=e.r;e.r=i-100;var o=e.b;e.b=o-100}t.xcut_now&&(e.canvas.width=t.x_box_w-1,e.canvas.height=t.x_box_h,e.r=t.x_box_w-1,e.l=0,e.b=t.x_box_h,e.t=0),t.ycut_now&&(e.canvas.width=t.y_box_h-1,e.canvas.height=t.y_box_w,e.r=t.y_box_h-1,e.l=0,e.b=t.y_box_w,e.t=0);var a=e.level;e.stk[a].x1=e.l,e.stk[a].y1=e.t,e.stk[a].x2=e.r,e.stk[a].y2=e.b,e.stk[a].xscl=(e.stk[a].xmax-e.stk[a].xmin)/(e.r-e.l),e.stk[a].yscl=(e.stk[a].ymax-e.stk[a].ymin)/(e.b-e.t);var l=F(this,e.xpos,e.ypos);t.retx=l.x,t.rety=l.y,0!==t.panning&&0===t.panning||(t.plotData.valid=!1,u.clear_window(e));var f=t.xlab,h=t.ylab;if(void 0===f&&(f=30),t.index&&(f=0),void 0===h){var p=t.lyr.length>0&&t.lyr[0].cx;1===t.cmode?h=28:2===t.cmode?h=t.plab:3===t.cmode&&p?h=21:4===t.cmode?h=22:5===t.cmode?(h=22,f=21):h=6===t.cmode?26:7===t.cmode?27:0}if(t.specs){if(0===t.sections){var m={grid:t.grid};2===t.panning&&(m.noxtlab=!0),t.show_x_axis||(m.noxtics=!0,m.noxtlab=!0,m.noxplab=!0),t.show_y_axis||(m.noytics=!0,m.noytlab=!0,m.noyplab=!0),!t.specs||t.show_readout||t.pan||(m.noyplab=!0,m.noxplab=!0),t.gridBackground&&(m.fillStyle=t.gridBackground),t.gridStyle&&(m.gridStyle=t.gridStyle),t.xmult&&(m.xmult=t.xmult),t.ymult&&(m.ymult=t.ymult),4===f&&(m.xtimecode=!0),4===h&&(m.ytimecode=!0),void 0!==t.xlabel&&(m.xlabel=t.xlabel),void 0!==t.ylabel&&(m.ylabel=t.ylabel),u.drawaxis(t,e,t.xdiv,t.ydiv,f,h,m)}var x=t.lbtn-2;t.show_readout?(t.no_legend_button||(t.legend?(t.legendBtnLocation={x:e.width-t.lbtn,y:2,width:x,height:x},u.shadowbox(e,e.width-t.lbtn,2,x,x,1,-2,"L")):(t.legendBtnLocation={x:e.width-t.lbtn,y:2,width:x,height:x},u.shadowbox(e,e.width-t.lbtn,2,x,x,1,2,"L"))),B(this)):t.legendBtnLocation=null}else if(t.grid&&t.sections>=0){m={grid:!0,noaxisbox:!0,noxtics:!0,noxtlab:!0,noxplab:!0,noytics:!0,noytlab:!0,noyplab:!0};u.drawaxis(t,e,t.xdiv,t.ydiv,f,h,m)}!function(e){for(var t=e._Gx.lyr,n=0;n0){if(t>=4&&r.show_readout&&!r.hide_note){var i=r.note.length;u.text(n,n.width-r.lbtn-(i+1)*n.text_w,n.text_h,r.note)}t>=4&&R(e),t>=1&&r.legend&&function(e){var t,n,r,i,o=e._Mx,a=e._Gx,l=o.canvas.getContext("2d"),f=0,h=0,p=0,m=0,x=0;t=o.text_w,i=23*t,(a.lyr.length+1)*o.text_h,n=o.r-i,r=o.t;var y=S(e),v=0,g=0;for(f=0;fv&&(v=b)}v>98&&(g=v-98,y.width+=g,y.x-=g);for(l.strokeStyle=o.fg,l.fillStyle=o.bg,l.fillRect(y.x,y.y,y.width,y.height),l.strokeRect(y.x,y.y,y.width,y.height),f=0;f0&&((m=s.sign(Math.min(t,Math.abs(a.lyr[f].thick)),a.lyr[f].thick))<0||m===u.L_dashed?u.draw_line(o,x,h-g,p-3,h+2*t-g,p-3,Math.abs(m),{mode:"dashed",on:4,off:4}):u.draw_line(o,x,h-g,p-3,h+2*t-g,p-3,Math.abs(m))),a.lyr[f].symbol>0&&(m=a.lyr[f].radius<0?-s.trunc(.6*t):Math.min(a.lyr[f].radius,s.trunc(.6*t)),u.draw_symbol(o,x,h+t-g,p-3,a.lyr[f].symbol,m))):a.lyr[f]instanceof d&&u.legend_colorbar(o,n+2*t-g,p-o.text_h/2,4*t,o.text_h/2)),h+=3*t,p+=.3*o.text_h,u.text(o,h-g,p,a.lyr[f].name)}(e)}}(this,4),E(this),t.cross_xpos=void 0,t.cross_ypos=void 0,!e.warpbox&&this.mouseOnCanvas&&(O(this),t.y_cut_press_on||t.x_cut_press_on||1!==t.lyr.length||2!==t.lyr[0].hcb.class||L(this)),(t.always_show_marker||t.show_marker)&&N(this)}}};var m=["Ma","Ph","Re","Im","IR","Lo","L2"],x=["(absc)","(indx)","(1/ab)","(dydx)"];function y(){this.initialized=!1,this.xptr=void 0,this.yptr=void 0,this.retx=0,this.rety=0,this.xmrk=0,this.ymrk=0,this.aretx=0,this.arety=0,this.xstart=0,this.xdelta=0,this.panxmin=0,this.panxmax=0,this.panymin=0,this.panymax=0,this.xmin=0,this.xmax=0,this.xmult=void 0,this.ymin=0,this.ymax=0,this.ymult=void 0,this.zmin=void 0,this.zmax=void 0,this.zoff=0,this.dbmin=0,this.pxscl=0,this.pyscl=0,this.pmt=0,this.note="",this.format="",this.pl=0,this.pr=0,this.pt=0,this.pb=0,this.px1=0,this.px2=0,this.py1=0,this.py2=0,this.pyl=0,this.pthk=0,this.modlayer=0,this.modsource=0,this.modified=!1,this.modmode=0,this.xdiv=0,this.ydiv=0,this.all=!1,this.expand=!1,this.cross=!1,this.grid=!0,this.gridBackground=void 0,this.index=!1,this.pan=!0,this.specs=!0,this.legend=!0,this.xdata=!1,this.show_x_axis=!0,this.show_y_axis=!0,this.show_readout=!0,this.hide_note=!1,this.autohide_readout=!1,this.autohide_panbars=!1,this.panning=void 0,this.panmode=0,this.hold=!1,this.sections=0,this.iysec=0,this.nsec=0,this.isec=0,this.xlab=void 0,this.xlabel=void 0,this.ylab=void 0,this.ylabel=void 0,this.xcompression=0,this.default_rubberbox_action="zoom",this.default_rubberbox_mode="box",this.wheelscroll_mode_natural=!0,this.scroll_time_interval=10,this.repeatPanning=void 0,this.stillPanning=void 0,this.autol=-1,this.lineSmoothing=!1,this.rasterSmoothing=!1,this.wheelZoom=!1,this.wheelZoomPercent=.2,this.inContinuousZoom=!1,this.lyr=[],this.HCB=[],this.HCB_UUID={},this.HCB_RDR={},this.plugins=[],this.plotData=document.createElement("canvas"),this.plotData.valid=!1,this.lg_colorbar=!1,this.cbb_top_x1=0,this.cbb_top_y1=0,this.cbb_bot_x1=0,this.cbb_bot_y1=0,this.cbb_width=0,this.cbb_height=0,this.p_cuts=!1,this.x_box_x=0,this.x_box_y=0,this.x_box_h=0,this.x_box_w=0,this.y_box_x=0,this.y_box_y=0,this.y_box_h=0,this.y_box_w=0,this.p_cuts_xpos=void 0,this.p_cuts_ypos=void 0,this.x_cut_data=[],this.y_cut_data=[],this.xcut=void 0,this.xcut_layer=void 0,this.x_cut_press_on=!1,this.xcut_now=!1,this.ycut=void 0,this.ycut_layer=void 0,this.y_cut_press_on=!1,this.ycut_now=!1,this.ylabel_stash=void 0,this.cut_stash=void 0,this.element1=void 0,this.element2=void 0,this.xyKeys="automatic",this.x_pop_now=!1,this.y_pop_now=!1,this.old_drawmode=void 0,this.old_autol=void 0,this.refresh_after_ctr=0}function v(e,t){var n=e._Gx,r=e._Mx;if(Array.isArray(t)){var i={name:"Custom",colors:t};"Custom"===s.Mc.colormap[s.Mc.colormap.length-1].name?s.Mc.colormap[s.Mc.colormap.length-1].colors=t:s.Mc.colormap.push(i),n.cmap=s.Mc.colormap.length-1}else if("string"==typeof t){n.cmap=-1;for(var o=0;os.Mc.colormap.length)&&(2===n.cmode?n.cmap=2:n.cmap=1),u.colormap(r,s.Mc.colormap[n.cmap].colors,n.ncolors)}function g(e){var t=e._Gx,n=e._Mx,r=t.aretx.toString();1===t.iabsc?u.message(n,"INDEX = "+r):2===t.iabsc?u.message(n,"1/X = "+r):u.message(n,"X = "+r)}function b(e){var t=e._Gx,n=e._Mx,r=t.arety.toString();2===t.iabsc?u.message(n,"1/Y = "+r):u.message(n,"Y = "+r)}function _(e){var t=e._Gx,n=e._Mx;u.removeEventListener(n,"mousedown",e.onmousedown,!1);for(var r={text:"Cntrls...",menu:{title:"CONTROLS OPTIONS",items:[{text:"Continuous (Disabled)",checked:-2===t.cntrls,handler:function(){e.change_settings({xcnt:-2})}},{text:"LM Click (Disabled)",checked:-1===t.cntrls,handler:function(){e.change_settings({xcnt:-1})}},{text:"Off",checked:0===t.cntrls,handler:function(){e.change_settings({xcnt:0})}},{text:"LM Click",checked:1===t.cntrls,handler:function(){e.change_settings({xcnt:1})}},{text:"Continuous",checked:2===t.cntrls,handler:function(){e.change_settings({xcnt:2})}}]}},i={text:"CX Mode...",menu:{title:"COMPLEX MODE",items:[{text:"Magnitude",checked:1===t.cmode,handler:function(){e.change_settings({cmode:1})}},{text:"Phase",checked:2===t.cmode,handler:function(){e.change_settings({cmode:2})}},{text:"Real",checked:3===t.cmode,handler:function(){e.change_settings({cmode:3})}},{text:"Imaginary",checked:4===t.cmode,handler:function(){e.change_settings({cmode:4})}},{text:"IR: Imag/Real",checked:5===t.cmode,handler:function(){e.change_settings({cmode:5})}},{text:"10*Log10",checked:6===t.cmode,handler:function(){e.change_settings({cmode:6})}},{text:"20*Log10",checked:7===t.cmode,handler:function(){e.change_settings({cmode:7})}}]}},o={text:"Scaling...",menu:{title:"SCALING",items:[{text:"Y Axis",style:"separator"},{text:"Parameters...",checked:0===t.autoy,handler:function(){t.autoy=0;G(e,"Y Axis Min:",u.floatValidator,(function(t){parseFloat(t)!==n.stk[n.level].ymin?(""===t&&(t=0),X(e,parseFloat(t),n.stk[n.level].ymax,"Y")):e.refresh()}),n.stk[n.level].ymin,void 0,void 0,(function(){G(e,"Y Axis Max:",u.floatValidator,(function(t){parseFloat(t)!==n.stk[n.level].ymax?(""===t&&(t=0),X(e,n.stk[n.level].ymin,parseFloat(t),"Y")):e.refresh()}),n.stk[n.level].ymax,void 0,void 0,void 0)}))}},{text:"Min Auto",checked:1===t.autoy,handler:function(){t.autoy=1}},{text:"Max Auto",checked:2===t.autoy,handler:function(){t.autoy=2}},{text:"Full Auto",checked:3===t.autoy,handler:function(){t.autoy=3}},{text:"X Axis",style:"separator"},{text:"Parameters...",checked:0===t.autox,handler:function(){t.autox=0;G(e,"X Axis Min:",u.floatValidator,(function(t){parseFloat(t)!==n.stk[n.level].xmin?(""===t&&(t=0),X(e,parseFloat(t),n.stk[n.level].xmax,"X")):e.refresh()}),n.stk[n.level].xmin,void 0,void 0,(function(){G(e,"X Axis Max:",u.floatValidator,(function(t){parseFloat(t)!==n.stk[n.level].xmax?(""===t&&(t=0),X(e,n.stk[n.level].xmin,parseFloat(t),"X")):e.refresh()}),n.stk[n.level].xmax,void 0,void 0,void 0)}))}},{text:"Min Auto",checked:1===t.autox,handler:function(){t.autox=1}},{text:"Max Auto",checked:2===t.autox,handler:function(){t.autox=2}},{text:"Full Auto",checked:3===t.autox,handler:function(){t.autox=3}},{text:"Z Axis",style:"separator"},{text:"Parameters...",checked:0===t.autoz,handler:function(){t.autoz=0;G(e,"Z Axis Min:",u.floatValidator,(function(n){var r=parseFloat(n);r!==t.zmin&&(""===n&&(r=0),e.change_settings({zmin:r}))}),t.zmin,void 0,void 0,(function(){G(e,"Z Axis Max:",u.floatValidator,(function(n){var r=parseFloat(n);r!==t.zmax&&(""===n&&(r=0),e.change_settings({zmax:r}))}),t.zmax,void 0,void 0,void 0)}))}},{text:"Min Auto",checked:1===t.autoz,handler:function(){e.change_settings({autoz:1})}},{text:"Max Auto",checked:2===t.autoz,handler:function(){e.change_settings({autoz:2})}},{text:"Full Auto",checked:3===t.autoz,handler:function(){e.change_settings({autoz:3})}}]}},a={text:"Grid",handler:function(){e.change_settings({grid:!t.grid})}},l={text:"Settings...",menu:{title:"SETTINGS",items:[{text:"ALL Mode",checked:t.all,style:"checkbox",handler:function(){e.change_settings({all:!t.all})}},{text:"Controls...",menu:{title:"CONTROLS OPTIONS",items:[{text:"Continuous (Disabled)",checked:-2===t.cntrls,handler:function(){e.change_settings({xcnt:-2})}},{text:"LM Click (Disabled)",checked:-1===t.cntrls,handler:function(){e.change_settings({xcnt:-1})}},{text:"Off",checked:0===t.cntrls,handler:function(){e.change_settings({xcnt:0})}},{text:"LM Click",checked:1===t.cntrls,handler:function(){e.change_settings({xcnt:1})}},{text:"Continuous",checked:2===t.cntrls,handler:function(){e.change_settings({xcnt:2})}}]}},{text:"Mouse...",menu:{title:"MOUSE OPTIONS",items:[{text:"LM Drag (Zoom)",checked:"zoom"===t.default_rubberbox_action,handler:function(){t.default_rubberbox_action="zoom"}},{text:"LM Drag (Select)",checked:"select"===t.default_rubberbox_action,handler:function(){t.default_rubberbox_action="select"}},{text:"LM Drag (Disabled)",checked:null===t.default_rubberbox_action,handler:function(){t.default_rubberbox_action=null}},{text:"RM Drag (Zoom)",checked:"zoom"===t.default_rightclick_rubberbox_action,handler:function(){t.default_rightclick_rubberbox_action="zoom"}},{text:"RM Drag (Select)",checked:"select"===t.default_rightclick_rubberbox_action,handler:function(){t.default_rightclick_rubberbox_action="select"}},{text:"RM Drag (Disabled)",checked:null===t.default_rightclick_rubberbox_action,handler:function(){t.default_rightclick_rubberbox_action=null}},{text:"Mode...",menu:{title:"MOUSE Mode",items:[{text:"Box",checked:"box"===t.default_rubberbox_mode,handler:function(){t.default_rubberbox_mode="box"}},{text:"Horizontal",checked:"horizontal"===t.default_rubberbox_mode,handler:function(){t.default_rubberbox_mode="horizontal"}},{text:"Vertical",checked:"vertical"===t.default_rubberbox_mode,handler:function(){t.default_rubberbox_mode="vertical"}}]}},{text:"CROSShairs...",menu:{title:"Crosshairs Mode",items:[{text:"Off",checked:!t.cross,handler:function(){t.cross=!1}},{text:"On",checked:!0===t.cross,handler:function(){t.cross=!0}},{text:"Horizontal",checked:"horizontal"===t.cross,handler:function(){t.cross="horizontal"}},{text:"Vertical",checked:"vertical"===t.cross,handler:function(){t.cross="vertical"}}]}},{text:"Mousewheel Natural Mode",checked:t.wheelscroll_mode_natural,style:"checkbox",handler:function(){e.change_settings({wheelscroll_mode_natural:!t.wheelscroll_mode_natural})}}]}},{text:"CROSShairs",checked:t.cross,style:"checkbox",handler:function(){e.change_settings({cross:!t.cross})}},{text:"GRID",checked:t.grid,style:"checkbox",handler:function(){e.change_settings({grid:!t.grid})}},{text:"INDEX Mode",checked:t.index,style:"checkbox",handler:function(){e.change_settings({index:!t.index})}},{text:"LEGEND",checked:t.legend,style:"checkbox",handler:function(){e.change_settings({legend:!t.legend})}},{text:"PAN Scrollbars",checked:t.pan,style:"checkbox",handler:function(){e.change_settings({pan:!t.pan})}},{text:"PHase UNITS...",menu:{title:"PHASE UNITS",items:[{text:"Radians",checked:23===t.plab,handler:function(){e.change_settings({phunits:"R"})}},{text:"Degrees",checked:24===t.plab,handler:function(){e.change_settings({phunits:"D"})}},{text:"Cycles",checked:25===t.plab,handler:function(){e.change_settings({phunits:"C"})}}]}},{text:"SPECS",checked:t.specs,style:"checkbox",handler:function(){e.change_settings({specs:!t.specs})}},{text:"P-Cuts",checked:t.p_cuts,style:"checkbox",handler:function(){e.change_settings({p_cuts:!t.p_cuts})}},{text:"Large Colorbar",checked:t.lg_colorbar,style:"checkbox",handler:function(){e.change_settings({lg_colorbar:!t.lg_colorbar})}},{text:"XDIVisions...",handler:function(){G(e,"X Divisions:",(function(e){var t=u.intValidator(e),r=s.trunc(n.width/2);return t.valid&&e>r?{valid:!1,reason:"Exceeds maximum number of divisions ("+r+")."}:t}),(function(n){parseFloat(n)!==t.xdiv&&(""===n&&(n=1),t.xdiv=parseFloat(n)),e.refresh()}),t.xdiv,void 0,void 0,void 0)}},{text:"XLABel...",handler:function(){G(e,"X Units:",(function(e){return console.log("The value is "+e),u.intValidator(e)}),(function(n){parseFloat(n)!==t.xlab&&(n<0&&(n=0),t.xlab=parseFloat(n)),e.refresh()}),t.xlab,void 0,void 0,void 0)}},{text:"YDIVisions...",handler:function(){G(e,"Y Divisions:",(function(e){var t=u.intValidator(e),r=s.trunc(n.height/2);return t.valid&&e>r?{valid:!1,reason:"Exceeds maximum number of divisions ("+r+")."}:t}),(function(n){parseFloat(n)!==t.ydiv&&(""===n&&(n=1),t.ydiv=parseFloat(n)),e.refresh()}),t.ydiv,void 0,void 0,void 0)}},{text:"YINVersion",checked:4===n.origin,style:"checkbox",handler:function(){e.change_settings({yinv:4!==n.origin})}},{text:"YLABel...",handler:function(){G(e,"Y Units:",(function(e){return u.intValidator(e)}),(function(n){parseFloat(n)!==t.ylab&&(n<0&&(n=0),t.ylab=parseFloat(n)),e.refresh()}),t.ylab,void 0,void 0,void 0)}},{text:"X-axis",checked:t.show_x_axis,style:"checkbox",handler:function(){e.change_settings({show_x_axis:!t.show_x_axis})}},{text:"Y-axis",checked:t.show_y_axis,style:"checkbox",handler:function(){e.change_settings({show_y_axis:!t.show_y_axis})}},{text:"Readout",checked:t.show_readout,style:"checkbox",handler:function(){e.change_settings({show_readout:!t.show_readout})}},{text:"Invert Colors",checked:n.xi,style:"checkbox",handler:function(){u.invertbgfg(n)}}]}},c={text:"Colormap...",menu:{title:"COLORMAP",items:[]}},d=function(t){e.change_settings({cmap:this.cmap})},f=0;f0?(i=2,o=r):(i=1,o=0),void 0!==n)e._Gx.lyr[n].line=0,e._Gx.lyr[n].radius=o,e._Gx.lyr[n].symbol=i;else for(a=0;a0?i=r:(1,i=0),void 0!==n)e._Gx.lyr[n].line=0,e._Gx.lyr[n].radius=i;else for(var o=0;o (index) -> (1/absc) -> (time).\nB - Toggle LM Drag Mode:\n (box) -> (horizontal) -> (vertical).\nC - Toggle controls.\nK - Show Marker.\nL - Toggle legend.\nM - Pops up main menu\nR - Toggle display specs (x/y readout)\nS - Toggle display specs and axes.\nT - Popup box with timecode value at mouse.\nX - In 1D mode, popup box with X value at mouse.\n - In 2D mode, toggle x-cut display.\nY - In 1D mode, popup box with Y value at mouse.\n - In 2D mode, toggle y-cut display.\nP - In 2D mode, displays p-cuts along side and bottom.\nF - Toggle fullscreen.\nCntrl+I - Invert colors.")}},{text:"Save as...",menu:{title:"SAVE AS",items:[{text:"PNG",handler:function(){var t=e._Mx.active_canvas.toDataURL("image/png"),n=document.createElement("a");n.href=t,n.download="SigPlot."+(new Date).getTime()+".png",n.display="none",document.body.appendChild(n),n.click(),document.body.removeChild(n)}},{text:"JPG",handler:function(){var t=e._Mx.active_canvas.toDataURL("image/jpg"),n=document.createElement("a");n.href=t,n.download="SigPlot."+(new Date).getTime()+".jpg",n.display="none",document.body.appendChild(n),n.click(),document.body.removeChild(n)}},{text:"SVG",handler:function(){var t=e._Mx.active_canvas.toDataURL("image/svg"),n=document.createElement("a");n.href=t,n.download="SigPlot."+(new Date).getTime()+".svg",n.display="none",document.body.appendChild(n),n.click(),document.body.removeChild(n)}}]}},{text:"Exit",handler:function(){var e=document.createEvent("Event");e.initEvent("sigplotexit",!0,!0),u.dispatchEvent(n,e)}}]};u.menu(n,m)}function w(e,t){var n=e._Gx,r=e._Mx;u.removeEventListener(r,"mousedown",e.onmousedown,!1);var i={text:"Dashed...",handler:function(){var r=1;if(void 0!==t)r=Math.abs(e._Gx.lyr[t].thick);else{if(0===n.lyr.length)return;r=Math.abs(e._Gx.lyr[0].thick);for(var i=0;i2:("vertical"===s||h>2)&&p>2),m){if(void 0===l||"zoom"===l)e.pixel_zoom(r,i,o,a),e.refresh();else if("select"===l){var x=document.createEvent("Event");x.initEvent("mtag",!0,!0),x.originalEvent=n;var y=F(e,d,f),v=F(e,d+h,f+p);x.x=y.x,x.y=y.y,x.xpos=d,x.ypos=f,x.w=Math.abs(v.x-y.x),x.h=Math.abs(v.y-y.y),x.wpxl=h,x.hpxl=p,x.shift=n.shiftKey,u.dispatchEvent(c,x)}}else e.mouseup(n)}}function M(e,t){var n=e._Gx,r=e._Mx,i=e.get_hcb_by_lyrn(0);t?(i?(n.xstart=i.xstart,n.xdelta=i.xdelta):(n.xstart=0,n.xdelta=1),r.origin=1):(n.xstart=0,n.xdelta=1,n.autol=-1,r.origin=1)}function E(e){for(var t,n=e._Gx,r=e._Mx.canvas.getContext("2d"),i=0;i0&&(r.panxmin=1,r.panxmax=-1,r.panymin=1,r.panymax=-1)}}function L(e){var t=e._Gx,n=e._Mx;if(2===t.lyr[0].hcb.class){var r=n.b-n.t,i=n.r-n.l,o=t.lyr[0].yframe,a=t.lyr[0].xframe;if(t.p_cuts)if(t.lyr[0].hcb.pipe){if(n.xpos>=n.l&&n.xpos<=n.r){l=0;for(o=t.lyr[0].lps,t.y_cut_data=[],l=Math.floor(a*(n.xpos-n.l)/i);l=n.t&&n.ypos<=n.b){s=0,u=0;t.x_cut_data=[],u=(s=Math.floor(o*(n.ypos-n.t)/r)*a)+a,t.x_cut_data=t.lyr[0].zbuf.slice(s,u),C(e)}}else{if(n.xpos>=n.l&&n.xpos<=n.r&&t.p_cuts_xpos!==n.xpos){var l=0;for(t.y_cut_data=[],l=Math.floor(a*(n.xpos-n.l)/i);l=n.t&&n.ypos<=n.b&&t.p_cuts_ypos!==n.ypos){var s=0,u=0,l=0;u=(s=Math.floor(o*(n.ypos-n.t)/r)*a)+a,t.x_cut_data=t.lyr[0].zbuf.slice(s,u),C(e),t.p_cuts_ypos=n.ypos}}}}function O(e){var t=e._Gx,n=e._Mx;t.cross&&("vertical"!==t.cross&&!0!==t.cross||n.xpos>=n.l&&n.xpos<=n.r&&t.cross_xpos!==n.xpos&&(void 0!==t.cross_xpos&&u.rubberline(n,t.cross_xpos,n.t,t.cross_xpos,n.b),u.rubberline(n,n.xpos,n.t,n.xpos,n.b),t.cross_xpos=n.xpos),"horizontal"!==t.cross&&!0!==t.cross||n.ypos>=n.t&&n.ypos<=n.b&&t.cross_ypos!==n.ypos&&(void 0!==t.cross_ypos&&u.rubberline(n,n.l,t.cross_ypos,n.r,t.cross_ypos),u.rubberline(n,n.l,n.ypos,n.r,n.ypos),t.cross_ypos=n.ypos))}function N(e){var t=e._Gx,n=e._Mx;if(null!==t.xmrk&&null!==t.ymrk){var r=u.real_to_pixel(n,t.xmrk,t.ymrk);if(t.lyr.length>0&&1===t.lyr[0].hcb.class){if(r.clipped)return}else if(t.lyr.length>0&&2===t.lyr[0].hcb.class&&(r.clipped_x||!r.clipped_y))return;var i=n.active_canvas.getContext("2d");i.beginPath(),i.strokeStyle=n.xwfg,i.fillStyle=n.xwfg,i.arc(r.x,r.y,2,0,360),i.stroke(),i.textBaseline="alphabetic",i.textAlign="left",i.fillStyle=n.fg,i.font=n.font.font;var o="x:"+u.format_g(t.xmrk,6,3,!0);i.fillText(o,r.x+5,r.y-5),o="y:"+u.format_g(t.ymrk,6,3,!0),i.fillText(o,r.x+5,r.y-5+n.text_h)}}function I(e,n){var r=e._Mx,i=e._Gx;i.xdata=!1;for(var o=0;o0){var a=i.cmode;i.cmode=n;var l=i.autox,s=i.autoy;if(i.autox=3,i.autoy=3,5===n||5===a)i.panxmin=1,i.panxmax=-1,i.panymin=1,i.panymax=-1,r.level=0,n===i.basemode?(r.stk[0].xmin=i.xmin,r.stk[0].xmax=i.xmax,r.stk[0].ymin=i.ymin,r.stk[0].ymax=i.ymax):5===n||5===i.basemode?U(e,{get_data:!0}):(r.stk[0].xmin=i.xmin,r.stk[0].xmax=i.xmax,U(e,{get_data:!0},i.xmin,i.xmax));else{0===t.size(i.HCB_UUID)&&n===i.basemode?(i.panymin=1,i.panymax=-1,r.stk[0].ymin=i.ymin,r.stk[0].ymax=i.ymax):U(e,{},r.stk[r.level].xmin,r.stk[r.level].xmax);for(o=1;o<=r.level;o++)r.stk[o].ymin=r.stk[0].ymin,r.stk[o].ymax=r.stk[0].ymax}i.autox=l,i.autoy=s,e.refresh()}}function R(e){var t,n=e._Mx,r=e._Gx;if(r.pan&&!n.widget){t=n.level;var i={ps:n.stk[t].ymin,pe:n.stk[t].ymax},o=i.ps!==r.panymin||i.pe!==r.panymax;if(o=o&&n.level>0,!r.autohide_panbars||o&&e.mouseOnCanvas||r.panning){u.scrollbar(n,0,r.pyl,r.pyl+r.pthk,n.t,n.b,i,r.panymin,r.panymax,void 0,n.scrollbar_y);n.stk[t].ymin=i.ps,n.stk[t].ymax=i.pe}else{(l=n.canvas.getContext("2d")).fillStyle=n.bg,l.fillRect(r.pyl,n.t,r.pyl+r.pthk,n.b-n.t)}if(r.pl0),!r.autohide_panbars||a&&e.mouseOnCanvas||r.panning){u.scrollbar(n,0,r.pl,r.pr,r.pt,r.pt+r.pthk,i,r.panxmin,r.panxmax,void 0,n.scrollbar_x);n.stk[t].xmin=i.ps,n.stk[t].xmax=i.pe}else{var l;(l=n.canvas.getContext("2d")).fillStyle=n.bg,l.fillRect(r.pl,r.pt-1,r.pr-r.pl,r.pthk+4)}}}}function D(e,t,n,r){var i,o,a,l,s,c,d,f,h=e._Mx,p=e._Gx,m=new u.SCROLLBAR,x=new u.SCROLLBAR,y=!1;if(i=h.level,p.panmode>0?(m.flag=11,x.flag=11):(m.flag=-12,x.flag=-12),0===n&&(m.action=0,x.action=0),!0,"Y"===t.substring(0,1)){if(s=h.stk[i].ymin,d=(c=h.stk[i].ymax)-s,"YPAN"===t){f=h.scrollbar_y;var v={ps:s,pe:c};u.scrollbar(h,x,p.pyl,p.pyl+p.pthk,h.t,h.b,v,p.panymin,p.panymax,r,f),s=v.ps,c=v.pe,0!==x.action&&u.scroll(h,x,u.XW_UPDATE,void 0,f),!1}else"YCENTER"===t&&(c=(s-=d*(h.ypos-(h.t+h.b)/2)/(h.b-h.t))+d,!1);if(s!==h.stk[i].ymin||c!==h.stk[i].ymax)h.stk[i].ymin=s,h.stk[i].ymax=c,p.cmode===p.basemode&&1===h.level&&(p.ymin=Math.min(p.ymin,s),p.ymax=Math.max(p.ymax,c)),e.inPan=!0,(g=document.createEvent("Event")).initEvent("ypan",!0,!0),g.level=h.level,g.xmin=h.stk[h.level].xmin,g.ymin=h.stk[h.level].ymin,g.xmax=h.stk[h.level].xmax,g.ymax=h.stk[h.level].ymax,u.dispatchEvent(h,g),e.inPan=!1,e.refresh(),y=!0}else{if(o=h.stk[i].xmin,l=(a=h.stk[i].xmax)-o,"XPAN"===t){f=h.scrollbar_x;v={ps:o,pe:a};u.scrollbar(h,m,p.pl,p.pr,p.pt,p.pt+p.pthk,v,p.panxmin,p.panxmax,r,f),o=v.ps,a=v.pe,0!==m.action&&u.scroll(h,m,u.XW_UPDATE,void 0,f),!1}else"XCENTER"===t&&((o+=l*(h.xpos-(h.l+h.r)/2)/(h.r-h.l))!==h.stk[i].xmin&&(a=o+l),!1);var g;if(h.stk[i].xmin!==o||h.stk[i].xmax!==a)h.stk[i].xmin=o,h.stk[i].xmax=a,p.xdata||1!==h.level||(p.xmin=h.stk[1].xmin,p.xmax=h.stk[1].xmax),e.inPan=!0,(g=document.createEvent("Event")).initEvent("xpan",!0,!0),g.level=h.level,g.xmin=h.stk[h.level].xmin,g.ymin=h.stk[h.level].ymin,g.xmax=h.stk[h.level].xmax,g.ymax=h.stk[h.level].ymax,u.dispatchEvent(h,g),e.inPan=!1,e.refresh(),y=!0}return y}function G(e,t,n,r,i,o,a,l){var s=e._Mx;if(s.prompt)throw"Prompt already exists! Can only have one prompt at a time!";u.disableListeners(s),e.disable_listeners();try{u.prompt(s,t,n,function(e,t){return function(n){t(n),u.enableListeners(s),e.enable_listeners(),e.refresh(),void 0!==l&&l()}}(e,r),(function(){e.refresh()}),i,o,a,5e3)}catch(e){console.log("ERROR: Failed to set up prompt due to: "+e)}}function B(e){var t=e._Mx,n=e._Gx,r=t.canvas.getContext("2d");if(0!==n.sections||(n.isec=0),t.warpbox){var i=F(e,t.warpbox.xo,t.warpbox.yo),o=F(e,t.warpbox.xl,t.warpbox.yl);n.aretx=i.x,n.arety=i.y,n.dretx=o.x-i.x,n.drety=o.y-i.y}else n.aretx=n.retx,n.arety=n.rety,n.dretx=n.retx-n.xmrk,n.drety=n.rety-n.ymrk;if(5===n.cmode&&1===n.iabsc&&(n.iabsc=2),1===n.iabsc?(n.aretx=Math.round((n.aretx-n.xstart)/n.xdelta),n.index||(n.aretx+=1),n.dretx=Math.round(n.dretx/n.xdelta)):2===n.iabsc&&(0!==n.aretx&&(n.aretx=1/n.aretx),0!==n.arety&&(n.arety=1/n.arety),0!==n.dretx&&(n.dretx=1/n.dretx),0!==n.drety&&(n.drety=1/n.drety)),n.show_readout&&!t.widget){r.fillStyle=t.bg;var a=Math.floor(t.height-2.5*t.text_h);r.fillRect(t.text_w,a-1,49*t.text_w,a+1.5*t.text_h),a=Math.floor(t.height-.5*t.text_h);var l=Math.max(n.pr+t.text_w,t.width-2*t.text_w);if(r.fillStyle=t.bg,r.fillRect(l,a-t.text_h,t.text_w,t.text_h),!n.autohide_readout||e.mouseOnCanvas||n.panning){var c,f,h,p;0===n.iabsc&&4===n.ylab?(f=(s.sec2tspec(n.arety)+" ").substring(0,16),p=(s.sec2tspec(n.drety,"delta")+" ").substring(0,16)):(f=u.format_g(n.arety,16,9,!0),p=u.format_g(n.drety,16,9)),0===n.iabsc&&4===n.xlab?(c=(s.sec2tspec(n.aretx)+" ").substring(0,16),h=(s.sec2tspec(n.dretx,"delta")+" ").substring(0,16)):(c=u.format_g(n.aretx,16,9,!0),h=u.format_g(n.dretx,16,9));var y="y: "+f+" dy: "+p+" L="+t.level+" "+m[n.cmode-1],v="x: "+c+" dx: "+h+" "+x[n.iabsc];if(3===n.iabsc&&(y=0===n.dretx?y.substr(0,20)+"sl: Inf "+y.substr(40,y.length):y.substr(0,20)+"sl: "+u.format_g(n.drety/n.dretx,16,9)+y.substr(40,y.length)),a=Math.floor(t.height-1.5*t.text_h),u.text(t,t.text_w,a,y),a=Math.floor(t.height-.5*t.text_h),u.text(t,t.text_w,a,v),u.LEGACY_RENDER&&l0?u.text(t,l,a,"C"):u.text(t,l,a," ")),n.lyr.some((function(e){return e instanceof d}))){var g=0,b=0,_=0,w=0;if(n.lg_colorbar){var k=t.b-t.t;g=t.r+35,b=t.t+1/8*k,_=5*t.text_w,w=3/4*k,(r=t.active_canvas.getContext("2d")).strokeStyle="rgba(124, 123, 121, 0.8)",r.fillStyle=" rgba(124, 123, 121, 0.8)";var M=w,E=_-2,S=E/2,T=g+(_-E)/2,P=b-10;r.beginPath(),r.moveTo(T,P),r.lineTo(T+E,P),r.lineTo(T+.5*E,P-S),r.lineTo(T,P),r.stroke(),r.fill();var z=P+M+20;r.beginPath(),r.moveTo(T,z),r.lineTo(T+E,z),r.lineTo(T+.5*E,z+S),r.lineTo(T,z),r.stroke(),r.fill(),n.cbb_top_x1=T,n.cbb_top_y1=P,n.cbb_bot_x1=T,n.cbb_bot_y1=z,n.cbb_width=E,n.cbb_height=S}else g=49*t.text_w-3,b=t.height-2.5*t.text_h,_=t.text_w,w=2*t.text_h;u.colorbar(t,g,b,_,w)}n.p_cuts&&1===n.lyr.length&&2===n.lyr[0].hcb.class&&(A(e),C(e))}}}function U(e,t,n,r,i,o){var a=e._Mx,l=e._Gx,u=!0===t.get_data;l.panxmin=1,l.panxmax=-1,l.panymin=1,l.panymax=-1;var c=n,d=r,f=void 0===c,h=void 0===d;if(0===l.lyr.length)l.panxmin=-1,l.panxmax=1,l.panymin=-1,l.panymax=1;else{void 0===i&&(l.xlab=l.lyr[0].xlab),void 0===o&&(l.ylab=l.lyr[0].ylab);for(var p=0;p0||l.autoy>0)for(;c=0?c+=l.lyr[p].size*l.lyr[p].xdelta:d+=l.lyr[p].size*l.lyr[p].xdelta:c=d}else l.lyr[p].prep(1,-1)}var x=l.panxmax-l.panxmin;if(x<0&&(l.panxmax=l.panxmin,l.panxmin=l.panxmax+x,x=-x),x<=1e-20&&(l.panxmin=l.panxmin-1,l.panxmax=l.panxmax+1),x=l.panxmax-l.panxmin,l.panxmin-=s.pad(x,l.panxpad),l.panxmax+=s.pad(x,l.panxpad),0!=(1&l.autox)&&f&&(a.stk[0].xmin=l.panxmin),0!=(2&l.autox)&&h&&(a.stk[0].xmax=l.panxmax,!l.all&&!l.xdata))for(p=0;p0&&(a.stk[0].xmax=d-y*Math.abs(l.lyr[p].xdelta))}0!=(1&l.autoy)&&(a.stk[0].ymin=l.panymin),0!=(2&l.autoy)&&(a.stk[0].ymax=l.panymax);var v=l.panymax-l.panymin;l.panymin-=s.pad(v,l.panypad),l.panymax+=s.pad(v,l.panypad)}function F(e,t,n){var r=e._Gx,i=e._Mx,o=u.pixel_to_real(i,t,n);return r.index&&(o.x=o.x*r.xdelta),o}function H(e,t,n,r,i,o,a,l){var s=[a-n,l-r],u=[i-n,o-r],c=[e-n,t-r],d=s[0]*s[0]+s[1]*s[1],f=s[0]*u[0]+s[1]*u[1],h=s[0]*c[0]+s[1]*c[1],p=u[0]*u[0]+u[1]*u[1],m=u[0]*c[0]+u[1]*c[1],x=1/(d*p-f*f),y=(p*h-f*m)*x,v=(d*m-f*h)*x;return y>=0&&v>=0&&y+v<1}function W(e,t){var n=!1,r=e._Gx,i=e._Mx,o=0,a=0;if(void 0===t){if(o=i.xpos,a=i.ypos,!e.mouseOnCanvas)return!1}else o=t.x,a=t.y;var l=" ";if(!r.pan)return!1;var u=o>i.r,c=a<=r.pt+r.pthk+2,d=a>r.pt-2,f=a>=i.t&&a<=i.b,h=o>=r.pl&&o<=r.pr,p=r.show_readout||"bottom"===r.x_scrollbar_location;u&&f?(l="YPAN",r.lg_colorbar&&2===r.lyr[0].hcb.class?n=!!(o>i.r+100):(i.xpos=r.pyl+s.trunc(r.pthk/2),n=!0)):(p&&h&&d||!p&&h&&c)&&(l="XPAN",i.ypos=r.pt+s.trunc(r.pthk/2),n=!0);return{inPanRegion:n,command:l}}function j(e,t){var n,r,i;1&t.origin?(i=e.x-t.x,2&t.origin&&(i=t.w-i)):(i=e.y-t.y,t.origin<=2&&(i=t.h-i));var o=u.scroll_real2pix(t);return n=o.s1,r=o.sw,i>=n&&i<=n+r}function Y(e,t,n){var r,i=e._Mx;"XPAN"===n?r=i.scrollbar_x:"YPAN"===n&&(r=i.scrollbar_y),r.action=t,r.step=.1*r.srange,r.page=9*r.step,r.scale=2,u.scroll(i,r,u.XW_COMMAND,void 0,r),X(e,r.smin,r.smin+r.srange,n.slice(0,1)),e.inPan=!0;var o=document.createEvent("Event");"XPAN"===n?o.initEvent("xpan",!0,!0):"YPAN"===n&&o.initEvent("ypan",!0,!0),o.level=i.level,o.xmin=i.stk[i.level].xmin,o.ymin=i.stk[i.level].ymin,o.xmax=i.stk[i.level].xmax,o.ymax=i.stk[i.level].ymax,u.dispatchEvent(i,o),e.inPan=!1}function X(e,t,n,r){var i=e._Mx,o=e._Gx,a=i.level;if("X"===r){var l=t,s=n;i.stk[a].xmin===l&&i.stk[a].xmax===s||(i.stk[a].xmin=l,i.stk[a].xmax=s,o.xdata||1!==i.level||(o.xmin=i.stk[1].xmin,o.xmax=i.stk[1].xmax),e.refresh())}else if("Y"===r){var u=t,c=n;u===i.stk[a].ymin&&c===i.stk[a].ymax||(i.stk[a].ymin=u,i.stk[a].ymax=c,o.cmode===o.basemode&&1===i.level&&(o.ymin=Math.min(o.ymin,u),o.ymax=Math.max(o.ymax,c)),e.refresh())}}f.Plot=p,e.exports=f}()},function(e,t,n){"use strict";n.r(t),n.d(t,"SigPlot",(function(){return c})),n.d(t,"ArrayLayer",(function(){return p})),n.d(t,"PipeLayer",(function(){return m})),n.d(t,"HrefLayer",(function(){return v})),n.d(t,"BlueLayer",(function(){return g})),n.d(t,"WebsocketLayer",(function(){return w})),n.d(t,"Layer",(function(){return h})),n.d(t,"Plugin",(function(){return E}));var r=n(2),i=n.n(r),o=n(1),a=n.n(o),l=n(3);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class u extends r.Component{constructor(e){super(e),this.state={}}getChildContext(){return{plot:this.plot}}componentDidMount(){const{options:e}=this.props;this.plot=new l.Plot(this.element,e),this.setState({plot:this.plot})}UNSAFE_componentWillReceiveProps(e){const{height:t,width:n,options:r}=this.props,{height:i,width:o,options:a}=e;i===t&&o===n||this.plot.checkresize(),a!==r&&this.plot.change_settings(a)}render(){const{height:e,width:t,display:n,styles:r,children:o}=this.props,{plot:a}=this,l=a?i.a.Children.map(o,e=>e?i.a.cloneElement(e,{plot:a}):null):null;return i.a.createElement("div",{style:{height:e,width:t,display:n,...r},ref:e=>this.element=e},l)}}s(u,"propTypes",{children:a.a.node,height:a.a.number,width:a.a.number,display:a.a.string,styles:a.a.object,options:a.a.object}),s(u,"childContextTypes",{plot:a.a.instanceOf(l.Plot)}),s(u,"defaultProps",{height:300,width:300,display:"inline-block",options:{all:!0,expand:!0,autol:100,autohide_panbars:!0}});var c=u;function d(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class f extends r.Component{componentWillUnmount(){this.plot.remove_layer(this.layer)}get plot(){const{plot:e}=this.context;return e}render(){return!1}}d(f,"propTypes",{data:a.a.arrayOf(a.a.number),options:a.a.object,layerOptions:a.a.object}),d(f,"contextTypes",{plot:a.a.instanceOf(l.Plot)});var h=f;var p=class extends h{componentDidMount(){const{data:e,options:t,layerOptions:n}=this.props;this.layer=this.plot.overlay_array(e,t,n)}UNSAFE_componentWillReceiveProps(e){const{data:t,options:n,layerOptions:r}=this.props,{data:i,options:o,layerOptions:a}=e;return i!==t?this.plot.reload(this.layer,i,o):o!==n?this.plot.headermod(this.layer,o):a!==r&&this.plot.get_layer(this.layer).change_settings(a),!1}};var m=class extends h{componentDidMount(){const{options:e,data:t,layerOptions:n}=this.props;this.layer=this.plot.overlay_pipe(e,n),void 0!==t&&t.length>0&&this.plot.push(this.layer,t)}UNSAFE_componentWillReceiveProps(e){const{data:t,options:n,layerOptions:r}=this.props,{data:i,options:o,layerOptions:a}=e;return i&&i!==t?this.plot.push(this.layer,i,o):o!==n?this.plot.headermod(this.layer,o):a!==r&&this.plot.get_layer(this.layer).change_settings(a),!1}};function x(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class y extends h{componentDidMount(){const{href:e,onload:t,options:n}=this.props;this.layer=this.plot.overlay_href(e,t,n)}UNSAFE_componentWillReceiveProps(e){const{href:t,options:n}=this.props,{href:r,onload:i,options:o}=e;return r!==t?(this.plot.deoverlay(this.layer),this.layer=this.plot.overlay_href(r,i,o)):void 0!==this.layer&&o!==n&&this.plot.get_layer(this.layer).change_settings(o),!1}}x(y,"propTypes",{href:a.a.string,onload:a.a.func,options:a.a.object}),x(y,"defaultProps",{href:"",onload:null});var v=y;var g=class extends h{componentDidMount(){const{data:e,layerOptions:t}=this.props;this.layer=this.plot.overlay_bluefile(e,t)}UNSAFE_componentWillReceiveProps(e){const{data:t,options:n,layerOptions:r}=this.props,{data:i,options:o,layerOptions:a}=e;return i!==t?this.plot.reload(this.layer,i,o):o!==n?this.plot.headermod(this.layer,o):a!==r&&this.plot.get_layer(this.layer).change_settings(a),!1}};function b(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class _ extends h{componentDidMount(){const{wsurl:e,overrides:t,options:n}=this.props;this.layer=this.plot.overlay_websocket(e,t,n)}UNSAFE_componentWillReceiveProps(e){const{wsurl:t,options:n}=this.props,{wsurl:r,overrides:i,options:o}=e;return r!==t?(this.plot.deoverlay(this.layer),this.layer=this.plot.overlay_websocket(r,i,o)):void 0!==this.layer&&o!==n&&this.plot.get_layer(this.layer).change_settings(o),!1}}b(_,"propTypes",{wsurl:a.a.string,overrides:a.a.object,options:a.a.object}),b(_,"defaultProps",{wsurl:""});var w=_;function k(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}class M extends r.Component{componentWillUnmount(){this.plot.remove_plugin(this.plugin)}get plot(){const{plot:e}=this.context;return e}render(){return!1}}k(M,"propTypes",{pluginOptions:a.a.object}),k(M,"contextTypes",{plot:a.a.instanceOf(l.Plot)});var E=M},function(e,t,n){ -/** - * @license - * File: m.js - * Copyright (c) 2012-2017, LGS Innovations Inc., All rights reserved. - * - * This file is part of SigPlot. - * - * Licensed to the LGS Innovations (LGS) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. LGS licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -!function(){"use strict";var t=n(9).bluefile,r=n(17);function i(){}i.log=r;!!navigator.userAgent.match(/(iPad|iPhone|iPod)/i)||"undefined"==typeof Float64Array||Float64Array.emulated||!Float64Array.BYTES_PER_ELEMENT?i.PointArray=Float32Array:i.PointArray=Float64Array;var o={0:["None","U",!0,!0],1:["Time","sec",!0,!0],2:["Delay","sec",!0,!1],3:["Frequency","Hz",!0,!0],4:["Time code format","",!0,!1],5:["Distance","m",!0,!0],6:["Speed","m/s",!0,!0],7:["Acceleration","m/sec^2",!0,!0],8:["Jerk","m/sec^3",!0,!0],9:["Doppler","Hz",!0,!1],10:["Doppler rate","Hz/sec",!0,!0],11:["Energy","J",!0,!0],12:["Power","W",!0,!0],13:["Mass","g",!0,!0],14:["Volume","l",!0,!0],15:["Angular power density","W/ster",!0,!0],16:["Integrated power density","W/rad",!0,!0],17:["Spatial power density","W/m^2",!0,!0],18:["Integrated power density","W/m",!1,!0],19:["Spectral power density","W/MHz",!0,!0],20:["Amplitude","U",!0,!1],21:["Real","U",!0,!1],22:["Imaginary","U",!0,!1],23:["Phase","rad",!0,!0],24:["Phase","deg",!1,!0],25:["Phase","cycles",!1,!0],26:["10*Log","U",!0,!1],27:["20*Log","U",!0,!1],28:["Magnitude","U",!0,!1],29:["Unknown","U",!0,!1],30:["Unknown","U",!1,!1],31:["General dimensionless","",!0,!0],32:["Counts","",!0,!1],33:["Angle","rad",!0,!1],34:["Angle","deg",!1,!1],35:["Relative power","dB",!0,!0],36:["Relative power","dBm",!1,!0],37:["Relative power","dBW",!1,!0],38:["Solid angle","ster",!0,!0],40:["Distance","ft",!1,!0],41:["Distance","nmi",!1,!0],42:["Speed","ft/sec",!1,!0],43:["Speed","nmi/sec",!1,!0],44:["Speed","knots=nmi/hr",!1,!0],45:["Acceleration","ft/sec^2",!1,!0],46:["Acceleration","nmi/sec^2",!1,!0],47:["Acceleration","knots/sec",!1,!0],48:["Acceleration","G",!1,!0],49:["Jerk","G/sec",!1,!0],50:["Rotation","rps",!0,!1],51:["Rotation","rpm",!1,!1],52:["Angular velocity","rad/sec",!0,!0],53:["Angular velocity","deg/sec",!1,!0],54:["Angular acceleration","rad/sec^2",!0,!0],55:["Angular acceleration","deg/sec^2",!1,!0],60:["Latitude","deg",!0,!1],61:["Longitude","deg",!0,!1],62:["Altitude","ft",!0,!1],63:["Altitude","m",!1,!1]};i.UNITS=o,i.Mc={colormap:[{name:"Greyscale",colors:[{pos:0,red:0,green:0,blue:0},{pos:60,red:50,green:50,blue:50},{pos:100,red:100,green:100,blue:100},{pos:100,red:0,green:0,blue:0},{pos:100,red:0,green:0,blue:0},{pos:100,red:0,green:0,blue:0},{pos:100,red:0,green:0,blue:0}]},{name:"Ramp Colormap",colors:[{pos:0,red:0,green:0,blue:15},{pos:10,red:0,green:0,blue:50},{pos:31,red:0,green:65,blue:75},{pos:50,red:0,green:85,blue:0},{pos:70,red:75,green:80,blue:0},{pos:83,red:100,green:60,blue:0},{pos:100,red:100,green:0,blue:0}]},{name:"Color Wheel",colors:[{pos:0,red:100,green:100,blue:0},{pos:20,red:0,green:80,blue:40},{pos:30,red:0,green:100,blue:100},{pos:50,red:10,green:10,blue:0},{pos:65,red:100,green:0,blue:0},{pos:88,red:100,green:40,blue:0},{pos:100,red:100,green:100,blue:0}]},{name:"Spectrum",colors:[{pos:0,red:0,green:75,blue:0},{pos:22,red:0,green:90,blue:90},{pos:37,red:0,green:0,blue:85},{pos:49,red:90,green:0,blue:85},{pos:68,red:90,green:0,blue:0},{pos:80,red:90,green:90,blue:0},{pos:100,red:95,green:95,blue:95}]},{name:"calewhite",colors:[{pos:0,red:100,green:100,blue:100},{pos:16.666,red:0,green:0,blue:100},{pos:33.333,red:0,green:100,blue:100},{pos:50,red:0,green:100,blue:0},{pos:66.666,red:100,green:100,blue:0},{pos:83.333,red:100,green:0,blue:0},{pos:100,red:100,green:0,blue:100}]},{name:"HotDesat",colors:[{pos:0,red:27.84,green:27.84,blue:85.88},{pos:14.2857,red:0,green:0,blue:35.69},{pos:28.571,red:0,green:100,blue:100},{pos:42.857,red:0,green:49.8,blue:0},{pos:57.14286,red:100,green:100,blue:0},{pos:71.42857,red:100,green:37.65,blue:0},{pos:85.7143,red:41.96,green:0,blue:0},{pos:100,red:87.84,green:29.8,blue:29.8}]},{name:"Sunset",colors:[{pos:0,red:10,green:0,blue:23},{pos:18,red:34,green:0,blue:60},{pos:36,red:58,green:20,blue:47},{pos:55,red:74,green:20,blue:28},{pos:72,red:90,green:43,blue:0},{pos:87,red:100,green:72,blue:0},{pos:100,red:100,green:100,blue:76}]},{name:"Hot",colors:["#000000","#7f0000","#b30000","#d7301f","#ef6548","#fc8d59","#fdbb84","#fdd49e","#fee8c8","#fff7ec","#ffffff"]},{name:"Cold",colors:["#000000","#023858","#045a8d","#0570b0","#3690c0","#74a9cf","#a6bddb","#d0d1e6","#ece7f2","#fff7fb","#ffffff"]},{name:"Purple",colors:["#230022","#4d004b","#810f7c","#88419d","#8c6bb1","#8c96c6","#9ebcda","#bfd3e6","#e0ecf4","#f7fcfd"]},{name:"BuGn",colors:["#f7fcfd","#e5f5f9","#ccece6","#99d8c9","#66c2a4","#41ae76","#238b45","#006d2c","#00441b"]},{name:"YlOrBr",colors:["#ffffe5","#fff7bc","#fee391","#fec44f","#fe9929","#ec7014","#cc4c02","#993404","#662506"]},{name:"YlGnBu",colors:["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"]},{name:"YlOrRd",colors:["#000000","#662506","#993404","#cc4c02","#ec7014","#fe9929","#fec44f","#fee391","#fff7bc","#ffffe5","#ffffff"]},{name:"GreyNRed",colors:["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff","#e0e0e0","#bababa","#878787","#4d4d4d","#1a1a1a"].reverse()}]},i.PIPESIZE=1048576,i.unit_lookup=function(e){for(var t=0;t<64;t++){var n,r=(n=void 0===o[t]?o[0]:o[t])[0],i=n[1],a=n[0]+" "+n[1],l=n[0]+"_"+n[1];if(e===r){if(n[2])return t}else if(e===i){if(n[3])return t}else if(e===a||e===l)return t}return e},i.initialize=function(e,n){var r=new t.BlueHeader(null);for(var o in r.version="BLUE",r.size=0,r.type=1e3,r.format="SF",r.timecode=0,r.xstart=0,r.xdelta=1,r.xunits=0,r.subsize=1,r.ystart=0,r.ydelta=1,r.yunits=0,r.enabled_streaming_pcut=!1,n||(n={}),n)r[o]=n[o];if(r.xunits=i.unit_lookup(r.xunits),r.yunits=i.unit_lookup(r.yunits),r.subsize>1?r.type=2e3:Array.isArray(e)&&(Array.isArray(e[0])||ArrayBuffer.isView(e[0]))&&(r.type=2e3,r.subsize=e[0].length,r.size=e.length),r.class=r.type/1e3,2===r.class&&void 0===r.subsize)throw"subsize must be provided with type 2000 files";if(n.pipe){r.pipe=!0,r.in_byte=0,r.out_byte=0;var a=n.pipesize||i.PIPESIZE;r.buf=new ArrayBuffer(a),r.setData(r.buf),r.data_free=r.dview.length}else r.setData(e);return r},i.force1000=function(e){2===e.class&&(e.size&&!e.pipe?e.size=e.subsize*e.size:e.size=0,e.bpe=e.bpe/e.subsize,e.ape=1)},i.grab=function(e,t,n,r){if(!e.dview)return 0;"C"===e.format[0]&&(n*=2),r=e.ape*r;var i=Math.min(t.length,e.dview.length-n);if(void 0===t.set)for(var o=0;oe.dview.length){var o=e.dview.length-r,a=t.length-o;t.subarray?(e.dview.set(t.subarray(0,o),r),e.dview.set(t.subarray(o,t.length),0)):(e.dview.set(t.slice(0,o),r),e.dview.set(t.slice(o,t.length),0)),e.in_byte=a*e.dview.BYTES_PER_ELEMENT}else e.dview.set(t,r),e.in_byte=i*e.dview.BYTES_PER_ELEMENT%e.buf.byteLength;if(e.data_free-=t.length,e.onwritelisteners)for(var l=0;lt.length-r)throw"m.grabx : nget larger then available buffer space"}else n=Math.min(t.length-r,i);if(n<0)throw"m.grabx : nget cannot be negative";if(n>i)return 0;var o=e.out_byte/e.dview.BYTES_PER_ELEMENT,a=o+n;if(a>=e.dview.length){var l=e.dview.length-o;a-=e.dview.length,t.set(e.dview.subarray(o,e.dview.length),r),t.set(e.dview.subarray(0,a),r+l)}else t.set(e.dview.subarray(o,a),r);return e.out_byte=a*e.dview.BYTES_PER_ELEMENT%e.buf.byteLength,e.data_free+=n,n},i.addPipeWriteListener=function(e,t){e.onwritelisteners||(e.onwritelisteners=[]),-1===e.onwritelisteners.indexOf(t)&&e.onwritelisteners.push(t)},i.units_name=function(e){var t=o[e];return t[0]+" ("+t[1]+")"},i.trim_name=function(e){var t=e.indexOf("]");-1===t&&(t=e.indexOf("/")),-1===t&&(t=e.indexOf(":"));var n=e.substr(t+1,e.length).indexOf(".");return n<0&&(n=e.length-t),e.substr(t+1,t+n+1)},i.label=function(e,t){var n=["Unknown","U"];"string"==typeof e?n=[e,null]:Array.isArray(e)?n=e:void 0===(n=o[e])&&(n=["Unknown","U"]);var r=i.mult_prefix(t);return n[1]?n[0]+" ("+r+n[1]+")":n[0]},i.bound=function(e,t,n){return en?n:e},i.touch_distance=function(e,t){var n=e.pageX-t.pageX,r=e.pageY-t.pageY;return Math.sqrt(n*n+r*r)},i.mult_prefix=function(e){var t="?";return 1==e?t="":10==e?t="da":.1==e?t="d":100==e?t="h":.01==e?t="c":1e3==e?t="K":.001==e?t="m":1e6==e?t="M":1e-6==e?t="u":1e9==e?t="G":1e-9==e?t="n":1e12==e?t="T":1e-12==e&&(t="p"),t};var a={MV:"F",MS:"F",nbpt:4,view:void 0};function l(e){return(e<10?"0":"")+e}i.vstype=function(e){a.MS=e,a.MV=e,"D"===a.MV?a.nbpt=8:"L"===a.MV||"F"===a.MV?a.nbpt=4:"I"===a.MV?a.nbpt=2:"B"===a.MV?a.nbpt=1:alert("Unsupported vector type")},i.log10=function(e,t){return void 0===t&&(t=1e-20),Math.log(Math.max(e,t))/Math.log(10)},i.vlog10=function(e,t,n){void 0===t&&(t=1e-20),void 0===n&&(n=e);for(var r=0;r=e.length);o++)r[o]=e[i-1]*e[i-1]+e[i]*e[i],r[o]=Math.log(Math.abs(Math.max(r[o],t)))/Math.log(10),r[o]=r[o]*n},i.vsmul=function(e,t,n,r){void 0===n&&(n=e),void 0===r&&(r=n.length),r=Math.min(n.length,r),r=Math.min(e.length,r);for(var i=0;in&&(n=e[a],i=a),e[a]=e.length)break;if(l>=n.length)break;n[l]=e[a]}},i.vfill=function(e,t,n){void 0===n&&(n=e.length),n=Math.min(e.length,n);for(var r=0;r=e.length)break;t[r]=Math.sqrt(e[i-1]*e[i-1]+e[i]*e[i])}},i.cvmag2=function(e,t,n){void 0===n&&(n=t.length),n=Math.min(t.length,n);for(var r=0,i=0;i=e.length);i++)t[i]=e[r-1]*e[r-1]+e[r]*e[r]},i.cvpha=function(e,t,n){void 0===n&&(n=t.length),n=Math.min(t.length,n);for(var r=0,i=0,o=0,a=0;a=e.length);a++)i=e[r-1],o=e[r],0===i&&0===o&&(i=1),t[a]=Math.atan2(o,i)},i.cvphad=function(e,t,n){void 0===n&&(n=t.length),n=Math.min(t.length,n);for(var r=0,i=0,o=0,a=0;a=e.length);a++)i=e[r-1],o=e[r],0===i&&0===o&&(i=1),t[a]=Math.atan2(o,i)*(180/Math.PI)},i.trunc=function(e){return e-e%1},i.sign=function(e,t){return t>=0?Math.abs(e):-Math.abs(e)},i.sec2tod=function(e,t){var n="",r=Date.UTC(1950,0,1),i=(new Date(r),new Date),o=new Date(i.getFullYear(),i.getMonth(),i.getDate(),0,0,0,0);if(e>=0)if(e<86400){var a=o.getTime()+1e3*e;n=l((i=new Date(a)).getHours())+":"+l(i.getMinutes())+":"+l(i.getSeconds())}else if(86400===e)n="24:00:00";else if(e<31536e3){f=[(f=e/86400)>0?Math.floor(f):Math.ceil(f)];var s=Math.floor(e%86400),u=Math.floor(s/3600),c=Math.floor(s/60%60);s%=60,n=f.toString()+"::"+l(u)+":"+l(c)+":"+l(s)}else{var d=Math.floor(1e3*e)+r;n=(i=new Date(d)).getUTCFullYear()+":"+l(i.getUTCMonth()+1)+":"+l(i.getUTCDate())+"::"+l(i.getUTCHours())+":"+l(i.getUTCMinutes())+":"+l(i.getUTCSeconds())}else if(e>-31536e3){var f;f=(f=e/86400)<=0?Math.ceil(f):Math.floor(f);s=Math.floor(Math.abs(e)%86400),u=Math.floor(s/3600),c=Math.floor(s/60%60);s%=60,n=(f=0===f?"-0":f.toString())+"::"+l(u)+":"+l(c)+":"+l(s)}else{d=Math.floor(1e3*e)+r;n=(i=new Date(d)).getUTCFullYear()+":"+l(i.getUTCMonth()+1)+":"+l(i.getUTCDate())+"::"+l(i.getUTCHours())+":"+l(i.getUTCMinutes())+":"+l(i.getUTCSeconds())}if(n+=0===e%1?".000000":"."+Math.abs(e%1).toPrecision(6).slice(2,8),t){var h=n.indexOf("."),p=-1;-1!==h&&(p=n.substr(h,n.length).indexOf("0")),-1!==p&&(n=n.substr(0,h+p))}return n};i.sec2tspec=function(e,t,n){return t=t||"",e>=0&&e<=86400?i.sec2tod(e,n):(e%=86400,"delta"!==t&&e<=0?i.sec2tod(e+86400,n):"delta"===t&&e<=0?"-"+i.sec2tod(-1*e,n):i.sec2tod(e,n))},i.sec2tod_j1970=function(e){var t,n="";if(e>=0&&e<86400)n=l((t=new Date(1e3*e)).getHours())+":"+l(t.getMinutes())+":"+l(t.getSeconds());else if(e<0&&e>-31536e3){var r=e/86400*-1;t=new Date(1e3*e),n=r.toString()+"::"+l(t.getHours())+":"+l(t.getMinutes())+":"+l(t.getSeconds())}else n=(t=new Date(1e3*(e-631152e3))).getFullYear()+":"+l(t.getMonth())+":"+l(t.getDate())+"::"+l(t.getHours())+":"+l(t.getMinutes())+":"+l(t.getSeconds());return e%1!=0&&(n+="."+(e%1).toPrecision(6).slice(2,8)),n},i.j1970toj1950=function(e){return void 0!==e.getTime?e.getTime()/1e3+631152e3:e+631152e3},i.j1950toj1970=function(e){return e-631152e3},i.throttle=function(e,t){var n=(new Date).getTime();return function(){var r=(new Date).getTime();r-n>=e&&(n=r,t.apply(null,arguments))}},i.pad=function(e,t){return t?("string"==typeof t&&(t=t.endsWith("%")?e*(parseFloat(t)/100):parseFloat(t)),t):0},e.exports=i}()},function(e,t,n){(function(t,n){ -/** - * @license - * File: common.js - * Copyright (c) 2012-2017, LGS Innovations Inc., All rights reserved. - * - * This file is part of SigPlot. - * - * Licensed to the LGS Innovations (LGS) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. LGS licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */var r;e.exports={},window.ArrayBuffer&&(ArrayBuffer.prototype.slice||(ArrayBuffer.prototype.slice=function(e,t){var n=new Uint8Array(this);void 0===t&&(t=n.length);for(var r=new ArrayBuffer(t-e),i=new Uint8Array(r),o=0;othis.length)&&(t=this.length),this.substring(t-e.length,t)===e}),Uint8Array.prototype.slice||Object.defineProperty(Uint8Array.prototype,"slice",{value:Array.prototype.slice}),Int8Array.prototype.slice||Object.defineProperty(Int8Array.prototype,"slice",{value:Array.prototype.slice}),Int16Array.prototype.slice||Object.defineProperty(Int16Array.prototype,"slice",{value:Array.prototype.slice}),Int32Array.prototype.slice||Object.defineProperty(Int32Array.prototype,"slice",{value:Array.prototype.slice}),Float32Array.prototype.slice||Object.defineProperty(Float32Array.prototype,"slice",{value:Array.prototype.slice}),Float64Array.prototype.slice||Object.defineProperty(Float64Array.prototype,"slice",{value:Array.prototype.slice}),Array.isArray||(Array.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)}),window.Float64Array||(window.Float64Array=window.Float64Array||function(e,t,n){if(!(e instanceof ArrayBuffer))throw"Invalid type";var r=new DataView(e),i=[],o=(e.byteLength-t)/8;i.length=void 0===n?o:Math.min(n,o);for(var a=0;a=t&&(r=!0),e<=n&&(i=!0),!0===r&&!0===i}function d(e,t,n,r,i,o){return(n-e)*(o-t)-(i-e)*(r-t)}function f(e,t,n,r,i,o,a){return i<=n?a>n&&d(t,n,r,i,o,a)>0&&(e+=1):a<=n&&d(t,n,r,i,o,a)<0&&(e-=1),e}l.DomMenu=n(20),l.XW_INIT=-3,l.XW_DRAW=1,l.XW_EVENT=2,l.XW_UPDATE=3,l.XW_COMMAND=5,l.SB_EXPAND=1,l.SB_SHRINK=2,l.SB_FULL=3,l.SB_STEPINC=4,l.SB_STEPDEC=5,l.SB_PAGEINC=6,l.SB_PAGEDEC=7,l.SB_DRAG=8,l.SB_WHEELUP=9,l.SB_WHEELDOWN=10,l.L_ArrowLeft=1001,l.L_ArrowRight=1002,l.L_ArrowUp=1003,l.L_ArrowDown=1004,l.L_dashed=801,l.GBorder=3,l.L_RModeOff=900,l.L_RModeOn=901,l.L_PixelSymbol=1,l.L_CircleSymbol=2,l.L_SquareSymbol=3,l.L_PlusSymbol=4,l.L_XSymbol=5,l.L_TriangleSymbol=6,l.L_ITriangleSymbol=7,l.L_HLineSymbol=8,l.L_VLineSymbol=9,l.LEGACY_RENDER=!1,l.STKSTRUCT=function(){this.xmin=0,this.xmax=0,this.ymin=0,this.ymax=0,this.xscl=0,this.yscl=0,this.x1=0,this.y1=0,this.x2=0,this.y2=0},l.SCROLLBAR=function(){this.flag=null,this.action=null,this.smin=null,this.srange=null,this.tmin=null,this.trange=null,this.step=null,this.page=null,this.scale=null,this.dragoutline=null,this.initial_pause=null,this.repeat_pause=null,this.x=null,this.y=null,this.w=null,this.h=null,this.s1=null,this.sw=null,this.swmin=null,this.soff=null,this.a1=null,this.a2=null,this.arrow=null,this.mxevent=null,this.origin=null,this.repeat_count=null},l.open=function(e){var t=new u(e);return t.wid_canvas.oncontextmenu=function(e){return e.preventDefault(),!1},this._ctx=t.active_canvas.getContext("2d"),t.onmousemove=function(e){return function(t){var n=t.target.getBoundingClientRect();e.x=t.x||t.clientX,e.y=t.y||t.clientY,e.xpos=void 0===t.offsetX?t.pageX-n.left-window.scrollX:t.offsetX,e.ypos=void 0===t.offsetX?t.pageY-n.top-window.scrollY:t.offsetY,e.warpbox&&((t.ctrlKey||t.metaKey)&&void 0!==e.warpbox.alt_style?e.warpbox.style=e.warpbox.alt_style:e.warpbox.style=e.warpbox.def_style,l.redraw_warpbox(e)),l.widget_callback(e,t)}}(t),t.onmouseup=function(e){return function(t){if(e.warpbox){l.onWidgetLayer(e,(function(){l.erase_window(e)}));var n=e.warpbox;if(e.warpbox=void 0,(1===t.which||3===t.which)&&n.func){var r=n.xo,i=n.yo,o=n.xl,a=n.yl;"vertical"===n.mode?(r=e.l,o=e.r):"horizontal"===n.mode&&(i=e.t,a=e.b),n.func(t,r,i,o,a,n.style.return_value,n.mode)}}l.widget_callback(e,t)}}(t),t.onmousedown=function(e){return function(t){return t.preventDefault(),l.widget_callback(e,t),!1}}(t),t.onkeydown=function(e){return function(t){if(e.warpbox){var n=i.getKeyCode(t);17!==n&&224!==n&&91!==n&&93!==n||e.warpbox.style===e.warpbox.alt_style||(e.warpbox.style=e.warpbox.alt_style,l.redraw_warpbox(e))}l.widget_callback(e,t)}}(t),t.onkeyup=function(e){return function(t){if(e.warpbox){var n=i.getKeyCode(t);17!==n&&224!==n&&91!==n&&93!==n||e.warpbox.style===e.warpbox.def_style||(e.warpbox.style=e.warpbox.def_style,l.redraw_warpbox(e))}}}(t),t.ontouchend=function(e){return function(t){e.onmouseup({which:1})}}(t),t.ontouchmove=function(e){return function(t){var n=e.canvas,r=0,i=0;if(void 0!==n.offsetParent)do{r+=n.offsetLeft,i+=n.offsetTop}while(n=n.offsetParent);e.xpos=t.targetTouches[0].pageX-r,e.ypos=t.targetTouches[0].pageY-i,l.redraw_warpbox(e)}}(t),l.enableListeners(t),t},l.enableListeners=function(e){l.addEventListener(e,"mousemove",e.onmousemove,!1),window.addEventListener("mouseup",e.onmouseup,!1),l.addEventListener(e,"mousedown",e.onmousedown,!1),window.addEventListener("keydown",e.onkeydown,!1),window.addEventListener("keyup",e.onkeyup,!1)},l.disableListeners=function(e){l.removeEventListener(e,"mousemove",e.onmousemove,!1),window.removeEventListener("mouseup",e.onmouseup,!1),l.removeEventListener(e,"mousedown",e.onmousedown,!1),window.removeEventListener("keydown",e.onkeydown,!1),window.removeEventListener("keyup",e.onkeyup,!1)},l.addEventListener=function(e,t,n,r){return e.wid_canvas.addEventListener(t,n,r)},l.removeEventListener=function(e,t,n,r){return e.wid_canvas.removeEventListener(t,n,r)},l.dispatchEvent=function(e,t){return e.wid_canvas.dispatchEvent(t)},l.onWidgetLayer=function(e,t){l.onCanvas(e,e.wid_canvas,t)},l.onCanvas=function(e,t,n){var r=e.active_canvas;e.active_canvas=t;try{if(n)return n()}finally{e.active_canvas=r}},l.withWidgetLayer=function(e,t){return function(){l.onWidgetLayer(e,t)}},l.render=function(e,t){if(t){var n=e.active_canvas;!1===e._syncRender?n._animationFrameHandle||(n._animationFrameHandle=requestAnimFrame((function(){n._animationFrameHandle=void 0,t()}))):t()}},l.fullscreen=function(e,t){void 0===t&&(t=!e.fullscreen),t?(e.fullscreen={position:e.root.style.position,height:e.root.style.height,width:e.root.style.width,left:e.root.style.left,top:e.root.style.top,zIndex:e.root.style.zIndex},e.root.style.position="fixed",e.root.style.height="100%",e.root.style.width="100%",e.root.style.left="0px",e.root.style.top="0px",e.root.style.zIndex=16777271):(e.root.style.position=e.fullscreen.position,e.root.style.height=e.fullscreen.height,e.root.style.width=e.fullscreen.width,e.root.style.left=e.fullscreen.left,e.root.style.top=e.fullscreen.top,e.root.style.zIndex=e.fullscreen.zIndex,e.fullscreen=void 0),l.checkresize(e)},l.checkresize=function(e){var t=e.canvas;return(t.height!==e.root.clientHeight||t.width!==e.root.clientWidth)&&(e.height=e.root.clientHeight,e.width=e.root.clientWidth,e.canvas.height=e.height,e.canvas.width=e.width,e.wid_canvas.height=e.height,e.wid_canvas.width=e.width,!0)},l.invertbgfg=function(e){l.setbgfg(e,e.fg,e.bg,!e.xi)},l.mixcolor=function(e,n,r){var i=t(e).toRgb(),o=t(n).toRgb(),a=1-r;return o.r=i.r*a+o.r*r,o.g=i.g*a+o.g*r,o.b=i.b*a+o.b*r,t(o).toHexString(!0)},l.linear_gradient=function(e,t,n,r,i,o){for(var a=e.active_canvas.getContext("2d"),l=1/o.length,s=a.createLinearGradient(t,n,r,i),u=0;u127.5?(e.xwfg="black",e.xwbg="rgb(60%,60%,55%)",e.xwts="rgb(80%,80%,75%)",e.xwbs="rgb(40%,40%,35%)",e.xwms=l.mixcolor(e.xwts,e.xwbs,.5),e.xwlo="rgb(70%,70%,65%)",e.hi=e.xwts):(e.xwfg="white",e.xwbg="rgb(35%,35%,30%)",e.xwts="rgb(60%,60%,55%)",e.xwbs="rgb(25%,25%,20%)",e.xwms=l.mixcolor(e.xwts,e.xwbs,.5),e.xwlo="rgb(15%,15%,10%)",e.hi=e.xwbs)}},l.settheme=function(e,t){e.bg=t.bg,e.fg=t.fg,e.xi=t.xi,e.xwfg=t.xwfg,e.xwbg=t.xwbg,e.xwts=t.xwts,e.xwbs=t.xwbs,e.xwlo=t.xwlo,e.hi=t.hi},l.close=function(e){var t=e.wid_canvas;t.removeEventListener("mousemove",e.onmousemove,!1),t.removeEventListener("mouseup",e.onmouseup,!1),e.parent&&e.parent.parentNode&&e.parent.parentNode.removeChild(e.parent)},l.scrollbar=function(e,t,n,r,i,o,a,s,u,c,d){var f,h,p,m,x,y,v=0,g=new l.SCROLLBAR;switch(f=void 0!==t.flag?t.flag:t,h=Math.abs(f),p=o-i>r-n?e.origin<3?2:4:2&e.origin?3:1,h<10&&(t=g),(h<10||0===t.action)&&(l.scroll(e,t,l.XW_INIT,void 0,d),t.flag=f,t.initial_pause=-1,l.scroll_loc(t,n,i,r-n+1,o-i+1,p,d)),t.srange=a.pe-a.ps,h){case 0:m=x=y=1;break;case 1:case 11:m=x=.9*t.srange,y=2;break;case 2:case 12:x=9*(m=.1*t.srange),y=2;break;case 3:case 13:m=1,x=t.srange-1,y=1;break;default:return 0}return l.scroll_vals(t,a.ps,t.srange,s,u-s,m,x,y,d),0===f?l.scroll(e,t,l.XW_DRAW,void 0,void 0):l.scroll(e,t,l.XW_EVENT,c,d)&&(a.ps!==t.smin&&(a.ps=t.smin,v+=1),a.pe!==t.smin+t.srange&&(a.pe=t.smin+t.srange,v+=2)),v},l.scroll=function(e,t,n,r,i){var o,a,s,u;if(void 0===t)return!1;switch(n){case l.XW_INIT:l.scroll_loc(t,0,0,e.width,20,1,i),l.scroll_vals(t,0,10,0,100,1,10,1,i),t.flag=0,t.action=0,t.initial_pause=.25,t.repeat_pause=.05,t.mxevent=!0,t.repeat_count=0;break;case l.XW_EVENT:if(o=0,t.mxevent)o=e.button_release?-e.button_release:e.button_press;else if("mousedown"===r.type||"mouseup"===r.type){switch(r.which){case 1:o=1;break;case 2:o=2;break;case 3:o=3;break;case 4:o=4;break;case 5:o=5}"mouseup"===r.type&&(o=-o)}else"mousewheel"!==r.type&&"DOM-MouseScroll"!==r.type||(r.wheelDelta&&r.wheelDelta>0?o=4:r.wheelDelta&&r.wheelDelta<0&&(o=5));if(0===t.action){if(4!==o&&5!==o||(e.xpos=t.x),1!==o&&2!==o&&4!==o&&5!==o||e.xpost.x+t.w||e.ypos>t.y+t.h)return!1}else if(o<0)return t.action=t.repeat_count=0,!0;if(1&t.origin?(u=e.xpos-t.x,2&t.origin&&(u=t.w-u)):(u=e.ypos-t.y,t.origin<=2&&(u=t.h-u)),0===t.action){t.repeat_count=0;var c=l.scroll_real2pix(t);if(t.s1=i.s1=c.s1,t.sw=i.sw=c.sw,t.soff=i.soff=u-t.s1,0===t.trange)t.smin=i.smin=t.tmin,t.srange=i.srange=0;else switch(o){case 1:u>t.a1&&u0?l.SB_PAGEINC:l.SB_PAGEDEC:t.action=t.soff>0?l.SB_STEPINC:l.SB_STEPDEC;break;case 4:t.action=l.SB_WHEELUP;break;case 5:t.action=l.SB_WHEELDOWN}}else switch(t.action){case l.SB_WHEELUP:case l.SB_WHEELDOWN:case l.SB_EXPAND:case l.SB_SHRINK:case l.SB_FULL:t.action=t.repeat_count=0}case l.XW_COMMAND:switch(a=t.smin,s=t.srange,t.action){case l.SB_STEPINC:a+=t.step;break;case l.SB_STEPDEC:a-=t.step;break;case l.SB_PAGEINC:a+=t.page;break;case l.SB_PAGEDEC:a-=t.page;break;case l.SB_FULL:a=t.tmin,s=t.trange;break;case l.SB_EXPAND:s*=t.scale,a<=0&&a+t.srange>=0?a*=t.scale:a-=(s-t.srange)/2;break;case l.SB_SHRINK:s/=t.scale,a<0&&a+t.srange>=0?a+=s/t.scale:0===a&&a+t.srange>=0?a=s/t.scale:a+=(t.srange-s)/2;break;case l.SB_WHEELUP:a-=t.page;break;case l.SB_WHEELDOWN:a+=t.page}t.trange>0?(a=Math.max(t.tmin,Math.min(a,t.tmin+t.trange-s)),s=Math.min(s,t.trange)):(a=Math.min(t.tmin,Math.max(a,t.tmin+t.trange-s)),s=Math.max(s,t.trange)),t.smin===a&&t.srange===s?t.action!==l.SB_DRAG&&(t.action=t.repeat_count=0):(t.smin=i.smin=a,t.srange=i.srange=s,t.repeat_count++),n===l.XW_COMMAND&&(l.scroll(e,t,l.XW_UPDATE,void 0),t.action=0);break;case l.XW_DRAW:case l.XW_UPDATE:l.redrawScrollbar(t,e,n)}return!0},l.scroll_loc=function(e,t,n,r,i,o,s){void 0!==e&&(e.x=s.x=t,e.y=s.y=n,e.w=s.w=r,e.h=s.h=i,e.origin=s.origin=Math.max(1,Math.min(4,o)),1&e.origin?(e.a2=s.a2=e.w,e.arrow=s.arrow=Math.min(a.trunc((e.w-a.trunc(2*l.GBorder))/3),e.h+l.GBorder)):(e.a2=s.a2=e.h,e.arrow=s.arrow=Math.min(a.trunc((e.h-a.trunc(2*l.GBorder))/3),e.w+l.GBorder)),e.a1=s.a1=e.arrow+l.GBorder,e.a2-=e.arrow+l.GBorder,s.a2-=e.arrow+l.GBorder,e.swmin=s.swmin=Math.min(10,e.a2-e.a1),e.s1=s.s1=0,e.sw=s.sw=0,e.action=s.action=0)},l.scroll_vals=function(e,t,n,r,i,o,a,l,s){void 0!==e&&(e.smin=s.smin=t,e.srange=s.srange=n,e.tmin=s.tmin=r,e.trange=s.trange=i,e.step=s.step=o,e.page=s.page=a,e.scale=s.scale=Math.max(l,1))},l.draw_symbol=function(e,t,n,r,i,o,s){for(var u,c=e.active_canvas.getContext("2d"),d=0,f=0,h=0,p=[],m=0;m<4;m++)p[m]={x:0,y:0};var x="";if(u=o<0,f=2*(d=Math.abs(o)),c.fillStyle=t,c.strokeStyle=t,"function"==typeof i)i(c,s,n,r);else switch(i){case l.L_CircleSymbol:c.beginPath(),u?(c.arc(n,r,d,0,360),c.fill()):(c.arc(n,r,d,0,360),c.stroke());break;case l.L_SquareSymbol:u?function(e,t,n,r,i,o,a,l){l&&(e.lineWidth=l);a&&(e.strokeStyle=a);o&&(e.fillStyle=o);e.fillRect(t,n,r,i)}(c,n-d,r-d,f,f):function(e,t,n,r,i,o,a){a&&(e.lineWidth=a);o&&(e.strokeStyle=o);e.strokeRect(t,n,r,i)}(c,n-d,r-d,f,f);break;case l.L_PixelSymbol:f=1,c.beginPath(),c.arc(n,r,1,0,2*Math.PI,!0),c.fill();break;case l.L_ITriangleSymbol:d=-d;case l.L_TriangleSymbol:f=a.trunc(1.5*d),h=a.trunc(.8*d),p[1].x=-h,p[1].y=f,p[2].x=2*h,p[2].y=0,p[3].x=-h,p[3].y=-f;var y=[];for(m=0;m<4;m++)y[m]={x:0,y:0};u?(y[0].x=n,y[0].y=r-d,y[1].x=y[0].x+p[1].x,y[1].y=y[0].y+p[1].y,y[2].x=y[1].x+p[2].x,y[2].y=y[1].y+p[2].y,y[3].x=y[2].x+p[3].x,y[3].y=y[2].y+p[3].y,g(c,y)):(y[0].x=n,y[0].y=r-d,y[1].x=y[0].x+p[1].x,y[1].y=y[0].y+p[1].y,y[2].x=y[1].x+p[2].x,y[2].y=y[1].y+p[2].y,y[3].x=y[2].x+p[3].x,y[3].y=y[2].y+p[3].y,function(e,t,n,r){b(e,t,r),n&&(e.strokeStyle=n);e.stroke(),e.closePath()}(c,y));break;case l.L_PlusSymbol:v(c,n,r+d,n,r-d),v(c,n+d,r,n-d,r);break;case l.L_HLineSymbol:v(c,n+d,r,n-d,r);break;case l.L_VLineSymbol:v(c,n,r+d,n,r-d);break;case l.L_XSymbol:v(c,n-d,r-d,n+d,r+d),v(c,n+d,r-d,n-d,r+d);break;default:x=i,d=a.trunc(e.text_w/2),u&&c.fillText(x.substring(0,2),n-d,r+d)}},l.draw_symbols=function(e,t,n,r,i,o,a,s){for(var u=0;u=S&&I<=C&&R>=T&&R<=A)&&(z[0]=Math.round((I-b)*_)+v,L[0]=Math.round((R-w)*k)+g,l.draw_symbol(e,t,z[0],L[0],d,h,o+N))}if(!0===p.vertsym)for(N=s-1;N=S&&I<=C){var D=Math.round((I-b)*_)+v;l.draw_line(e,t,D,0,D,e.height),R>=T&&R<=A&&(z[0]=D,L[0]=Math.round((R-w)*k)+g,l.draw_symbol(e,t,z[0],L[0],d,h,o+N))}}if(!0===p.horzsym)for(N=s-1;N=T&&R<=A){D=Math.round((R-w)*k)+g;l.draw_line(e,t,0,D,e.width,D),I>=S&&I<=C&&(z[0]=Math.round((I-b)*_)+v,L[0]=D,l.draw_symbol(e,t,z[0],L[0],d,h,o+N))}}else if(0!==u){var G;if(p&&p.highlight){G=[];for(var B=0;B=C||p.highlight[B].xend<=S)){var U=Math.max(p.highlight[B].xstart,S),F=Math.min(p.highlight[B].xend,C);if(U=0;j--)H<=G[j].start&&W>=G[j].end?G.splice(j,1):(H>=G[j].start&&W<=G[j].end?(G.push({start:W,end:G[j].end,color:G[j].color}),G[j].end=H):H<=G[j].start&&W>=G[j].start?G[j].start=W:H<=G[j].end&&W>=G[j].end&&(G[j].end=H),G[j].end<=G[j].start&&G.splice(j,1));G.push({start:H,end:W,color:p.highlight[B].color})}}G.push({start:v,color:t}),G.sort((function(e,t){return e.start-t.start}))}else G=t;var Y,X=0,V=(e.stk[e.level].xmax+e.stk[e.level].xmin)/2,q=(e.stk[e.level].ymax+e.stk[e.level].ymin)/2;I=n[0],R=r[0];X=f(X,V,q,e.stk[e.level].xmin,e.stk[e.level].ymin,I,R),(Y=I>=S&&I<=C&&R>=T&&R<=A)?(z[O]=Math.round((I-b)*_)+v,L[O]=Math.round((R-w)*k)+g,O+=1,0!==d&&l.draw_symbols(e,t,z,L,1,d,h,o)):O=0;var K=0,$=!1;for(N=s;N<=s*(i-1);N+=s){var Q=I,Z=R;if(X=f(X,V,q,Q,Z,I=n[N],R=r[N]),$=I>=S&&I<=C&&R>=T&&R<=A,Y&&$)z[O]=Math.round((I-b)*_)+v,L[O]=Math.round((R-w)*k)+g,O+=1;else if(Y=$,E=Z-R,0!==(M=Q-I)||0!==E){var J={tL:1,tE:0};y(M,S-I,J)&&y(-M,I-C,J)&&y(E,T-R,J)&&y(-E,R-A,J)&&(J.tL<1&&(z[O]=Math.round((I-b+J.tL*M)*_)+v,L[O]=Math.round((R-w+J.tL*E)*k)+g,O+=1),J.tE>0?(z[O]=Math.round((I-b+J.tE*M)*_)+v,L[O]=Math.round((R-w+J.tE*E)*k)+g,O+=1,l.draw_lines(e,G,z.subarray(K,O),L.subarray(K,O),O-K,u,m),0!==d&&O-K>2&&l.draw_symbols(e,t,z.subarray(K+1,O-1),L.subarray(K+1,O-1),O-K-2,d,h,o+N-(O-K-2)),K=O):(z[O]=Math.round((I-b)*_)+v,L[O]=Math.round((R-w)*k)+g,O+=1))}}if(X=f(X,V,q,I,R,e.stk[e.level].xmax,e.stk[e.level].ymin),X=f(X,V,q,e.stk[e.level].xmax,e.stk[e.level].ymin,e.stk[e.level].xmin,e.stk[e.level].ymin),O-K>0&&(l.draw_lines(e,G,z.subarray(K,O),L.subarray(K,O),O-K,u,m),$&&(K+=1),0!==d&&O-K>1&&l.draw_symbols(e,t,z.subarray(K-1,O),L.subarray(K-1,O),O-K-1,d,h,N-O+o)),!p.fillStyle||e.fillMin||e.fillMax||(O>1||0!==X)&&l.fill_trace(e,p.fillStyle,z,L,O),p.highlight)for(D=0;D=e.stk[e.level].xmax||ne<=e.stk[e.level].xmin||!(O>1||0!==X))){for(var re=l.real_to_pixel(e,te,0),ie=l.real_to_pixel(e,ne,0),oe=re.x,ae=ie.x,le=[],se=[],ue=0;ue0||0!==X)&&(oe=Math.max(oe,le[0]),ae=Math.min(ae,le[le.length-1]),l.fill_trace(e,ee.fill,le,se,le.length,oe,ae))}}}}p.noclip||l.clip(e,0,0,0,0)}}else a.log.warn("No line or symbol to draw")},l.draw_mode=function(e,t,n){e.linewidth=void 0===t?1:t,e.style=n},l.draw_line=function(e,t,n,r,i,o,l,s){var u=e.active_canvas.getContext("2d");if(void 0===l&&(l=e.linewidth),void 0===s&&(s=e.style),"number"==typeof t)if(e.pixel){isNaN(t)&&(t=0);Math.max(0,Math.min(e.pixel.map.length,t));t=w((t=e.pixel.getColor(t)).red,t.green,t.blue)}else a.log.warn("COLORMAP not initialized, defaulting to foreground"),t=e.fg;v(u,n,r,i,o,s,t,l)},l.rubberline=function(e,t,n,r,i){v(e.active_canvas.getContext("2d"),t,n,r,i,{mode:"xor"},"white",1)},l.fill_trace=function(e,t,n,r,i,o,a){var s=e.active_canvas.getContext("2d");if(Array.isArray(t)?s.fillStyle=l.linear_gradient(e,0,0,0,e.b-e.t,t):s.fillStyle=t,i<1)s.fillRect(e.l,e.t,e.r-e.l,e.b-e.t);else if(void 0===o&&(o=e.l),void 0===a&&(a=e.r),t){var u=n[0],c=r[0];s.beginPath(),c===e.t?s.lineTo(o,e.t):s.lineTo(o,e.b),s.lineTo(u,c);for(var d=1;d=0;f--)null!=t[f].end&&t[f].end0&&null!=t[h].end&&t[h].end40&&2.5*e.text_h*t.length6&&(o=!1);s=0;var v=Math.max(1,e.height/e.text_h),g=Math.min(y,s+v-1),b=(a+2)*e.text_w+6,_=(g-s+1)*e.text_h+6;n||(n=e.xpos),r||(r=e.ypos);var w=Math.max(e.l,Math.min(n,e.r-b)),k=Math.max(e.t,Math.min(r,e.b-_)),M=w+3,E=k+3;l.widgetbox(e,w,k,b,_,M,E,0,"");for(d=E+e.text_h/3,c=M+e.text_w;s0){var c=u.globalAlpha;u.globalAlpha=a,u.fillStyle=l||t,u.fill(),u.globalAlpha=c}},l.draw_box=function(e,t,n,r,i,o,a,l){var s=e.active_canvas.getContext("2d");if("xor"!==t)s.lineWidth=1,s.strokeStyle=t,s.strokeRect(n,r,i,o);else if("undefined"==typeof Uint8ClampedArray)s.lineWidth=1,s.strokeStyle=e.fg,s.strokeRect(n,r,i,o);else{n=Math.floor(n),r=Math.floor(r),i=Math.floor(i),o=Math.floor(o);for(var u=e.canvas.getContext("2d"),c=(f=u.getImageData(n,r,i,1)).data,d=0;d0){var h=s.globalAlpha;s.globalAlpha=a,s.fillStyle=l||t,s.fillRect(n+1,r+1,i-1,o-1),s.globalAlpha=h}},l.set_font=function(e,t){var n=e.canvas.getContext("2d"),r=e.wid_canvas.getContext("2d");if(e.font&&e.font.width===t)n.font=e.font.font,r.font=e.font.font;else{var i=1;do{i+=1,n.font=i+"px "+e.font_family,r.font=i+"px "+e.font_family;var o=n.measureText("M");e.text_w=o.width,e.text_h=i}while(e.text_w=5&&h<=5140800?(c=h<17.5?5:h<37.5?15:h<270?60:h<1050?300:h<2250?900:h<7200?3600:h<16200?10800:h<32400?21600:h<129600?43200:h<518400?86400:604800,i=Math.round(h/c)*c):i=f<1.75?u:f<2.25?2*u:f<3.5?2.5*u:f<7?5*u:10*u;return 0===i&&(i=1),t>=e?(d=e>=0?e/i+.995:e/i-.005,o=(d=Math.floor(d))*i):(d=e>=0?e/i+.005:e/i-.995,o=(d=Math.floor(d))*i,i*=-1),o+i===o&&(i=t-e),{dtic:i,dtic1:o}},l.drawaxis=function(e,t,n,r,i,o,s){var u=l.origin(t.origin,1,t.stk[t.level]),c=0,d=0,f=0,h=0,p=0,m=0;i=void 0===i?30:i,o=void 0===o?30:o,s.exactbox?(c=Math.floor(u.x1),d=Math.floor(u.y1),p=(f=Math.floor(u.x2))-c,m=(h=Math.floor(u.y2))-d):(c=Math.max(Math.floor(u.x1)-2,0),d=Math.max(Math.floor(u.y1)-2,0),p=(f=Math.min(Math.floor(u.x2)+2,t.width))-c-4,m=(h=Math.min(Math.floor(u.y2)+2,t.height))-d-4);var x=t.active_canvas.getContext("2d");s.fillStyle?Array.isArray(s.fillStyle)?x.fillStyle=l.linear_gradient(t,0,0,0,h-d,s.fillStyle):x.fillStyle=s.fillStyle:x.fillStyle=t.bg,x.fillRect(c,d,f-c,h-d),s.noaxisbox||(l.textline(t,c,d,f,d),l.textline(t,f,d,f,h),l.textline(t,f,h,c,h),l.textline(t,c,h,c,d));var y={dtic:0,dtic1:0},v={dtic:0,dtic1:0};n<0?(y.dtic1=u.xmin,y.dtic=(u.xmin-u.xmax)/n):y=l.tics(u.xmin,u.xmax,n,s.xtimecode);var g=1;s.xmult?g=s.xmult:s.xtimecode||(g=l.mult(u.xmin,u.xmax)),r<0?(v.dtic1=u.ymin,v.dtic=(u.ymin-u.ymax)/r):v=l.tics(u.ymin,u.ymax,r,s.ytimecode);var b=1;s.ymult?b=s.ymult:s.ytimecode||(b=l.mult(u.ymin,u.ymax));var _,w,M=!s.noxtlab,E=!s.noytlab,S=Math.max(0,c-4*t.text_w),T=0;if((T=s.ontop?Math.min(t.height,Math.floor(h+1.5*t.text_h)):Math.max(t.text_h,Math.floor(d-.5*t.text_h)))>0){s.noyplab||(w=s.ylabel instanceof Function?s.ylabel(o,b):void 0!==s.ylabel?s.ylabel:a.label(o,b)),s.noxplab||(_=s.xlabel instanceof Function?s.xlabel(i,g):void 0!==s.xlabel?s.xlabel:a.label(i,g))}_&&w?l.text(t,S,T,w+" vs "+_):_?l.text(t,S,T,_):w&&l.text(t,S,T,w);var C,A,P=5.5*t.text_w,z=0;z=s.ontop?s.inside?d+1*t.text_h:d-.2*t.text_h:s.inside?h-.5*t.text_h:h+1*t.text_h+2,C=u.xmin!==u.xmax?p/(u.xmax-u.xmin):p/1,A=0!==g?1/g:1;var L,O,N,I,R,D=Math.min(12,Math.round(C*y.dtic)/t.text_w),G=1,B="";if(M)if(s.xtimecode)G=(B=a.sec2tod(y.dtic1)).length*t.text_w<(f-c)/2;else for(L=y.dtic1;L<=u.xmax;L+=y.dtic){if((B=l.format_f(L*A,D,D/2))===O){G=0;break}O=B}for(0===y.dtic&&(y.dtic=u.xmax-y.dtic1+1),S=0,B="",L=y.dtic1;L<=u.xmax;L+=y.dtic)if(!((N=c+Math.round(C*(L-u.xmin))+2)S&&(B=a.sec2tod(L,!0),S=N+t.text_w*(B.length+1)):B=k(B=l.format_f(L*A,D,D/2),!0),B){var U=Math.round(B.length/2)*t.text_w;s.inside&&(N=Math.max(c+U,N),N=Math.min(f-U,N)),N-U>=0&&l.text(t,N-U,z,B)}}else L===y.dtic1&&(s.xtimecode?(B=a.sec2tod(L,!0),s.inside&&(N=Math.floor(Math.max(c+P,N))),l.text(t,N-P,z,B+" +Δ "+a.sec2tod(y.dtic))):(B=(y.dtic1*A).toString(),s.inside&&(N=Math.floor(Math.max(c+P,N))),l.text(t,N-P,z,B+" +Δ "+y.dtic*A)));P=s.yonright?s.inside?Math.min(f-6*t.text_w,t.width-5*t.text_w):Math.min(f+t.text_w,t.width-5*t.text_w):s.inside?Math.max(0,c+t.text_w):Math.max(0,Math.floor(c-(t.l-.5)*t.text_w)),z=.4*t.text_h,C=u.ymin!==u.ymax?-m/(u.ymax-u.ymin):-m/1,A=0!==b?1/b:1,0===v.dtic&&u.ymax,I=u.ymax>=u.ymin?function(e){return e<=u.ymax}:function(e){return e>=u.ymax};for(var F=v.dtic1;I(F);F+=v.dtic)if(!((N=h+Math.round(C*(F-u.ymin))-2)>h)&&(s.grid&&"x"!==s.grid?(s.gridStyle||(s.gridStyle={mode:"dashed",on:1,off:3}),l.textline(t,c,N,f,N,s.gridStyle)):(l.textline(t,c-2,N,c+2,N),l.textline(t,f-2,N,f+2,N)),E))if(s.inside&&(Nh-2*t.text_h));else if(s.ytimecode){R=a.sec2tod(F);var H=N+z-t.text_h,W=R.indexOf("::");-1!==W&&(H>d&&Hd&&H=n&&e<=n+i&&t>=r&&t<=r+o};var h={GBorder:3,sidelab:0,toplab:1,n_show:0};function p(e,t){if(!t.animationFrameHandle){var n=e.canvas.height-70,r=1.5*e.text_h,i=Math.floor(n/r);i>=t.items.length?h.n_show=t.items.length:h.n_show=i,t.animationFrameHandle=requestAnimFrame(l.withWidgetLayer(e,(function(){l.erase_window(e),t.animationFrameHandle=void 0;var n=1.5*e.text_h;t.x=Math.max(t.x,0),t.y=Math.max(t.y,0),t.x=Math.min(t.x,e.width-t.w),t.y=Math.min(t.y,e.height-t.h);var r=t.x+h.GBorder+Math.max(0,h.sidelab),i=t.y+h.GBorder+h.toplab*(n+h.GBorder),o=t.w-2*h.GBorder-Math.abs(h.sidelab),a=t.h-2*h.GBorder-h.toplab*(n+h.GBorder);l.widgetbox(e,t.x,t.y,t.w,t.h,r,i,o,a,t.title);var s=e.wid_canvas.getContext("2d");s.lineWidth=1,s.strokeStyle=e.xwbs,s.beginPath(),s.moveTo(r,i-4+.5),s.lineTo(r+o-1,i-4+.5),s.stroke(),s.strokeStyle=e.xwts,s.beginPath(),s.moveTo(r,i-3+.5),s.lineTo(r+o-1,i-3+.5),s.stroke();var u=t.queue[0],c=t.queue[h.n_show-1];if(0===c){for(var d=0;d2&&Math.abs(e.ypos-t.drag_y)>2&&(t.x+=e.xpos-t.drag_x,t.y+=e.ypos-t.drag_y,t.drag_x=e.xpos,t.drag_y=e.ypos);for(var a=t.x+h.GBorder+Math.max(0,h.sidelab),s=t.w-2*h.GBorder-Math.abs(h.sidelab),u=1.5*e.text_h,c=t.y+h.GBorder+h.toplab*(u+h.GBorder),d=r;d<=o;d++){var f=c+u*d;(b=t.items[d]).selected=!1,l.inrect(e.xpos,e.ypos,a,f,s,u)&&(b.selected=!0)}p(e,t)}else if("mouseup"===n.type)1===n.which?void 0!==t.drag_x&&void 0!==t.drag_y?(t.drag_x=void 0,t.drag_y=void 0):m(e,t):3===n.which&&function(e,t){l.onWidgetLayer(e,(function(){l.erase_window(e)})),e.useDomMenu&&e.menu.remove(),e.menu=void 0,e.widget=null,!e.menu&&t.finalize&&t.finalize()}(e,t);else if("mousedown"===n.type)n.preventDefault(),1===n.which?e.xpos>t.x&&e.xpost.y&&e.ypos=48&&x<=57||x>=65&&x<=90){var v=String.fromCharCode(x).toUpperCase();void 0===t.keypresses?t.keypresses=v:t.keypresses=t.keypresses+v;var g=0;for(d=0;d0?r>n.tL?i=!1:r>n.tE&&(n.tE=r):e<0?r0&&(i=!1),i}function v(e,t,n,r,o,a,l,s){if(t<0&&(t=0),n<0&&(n=0),r<0&&(r=0),o<0&&(o=0),s&&(e.lineWidth=s),l&&(e.strokeStyle=l),e.lineWidth%2==1&&(t===r&&(r=t=Math.floor(t)+.5),n===o&&(o=n=Math.floor(n)+.5)),a&&a.mode){if("dashed"===a.mode){if(i.dashOn(e,a.on,a.off))e.beginPath(),e.moveTo(t,n),e.lineTo(r,o),e.stroke(),i.dashOff(e),e.beginPath();else{if(e.beginPath(),n===o){var u=Math.min(t,r);for(r=Math.max(t,r);u5||t);)r+=1;var i=e.substring(r,n+1);return-1===i.indexOf(".")&&(i+="."),i}function M(e,t,n,r,i,o,a,l){let s=e.pixel;var u=new Uint32Array(n);o||(o=n.width),a||(a=n.height),r||(r=0),i||(i=0);var c=t.width,d=t.height,f=t.getContext("2d");e.scaledImgd&&e.scaledImgd.width===c&&e.scaledImgd.height===d||(e.scaledImgd=f.createImageData(c,d));var h,p=new Uint32Array(e.scaledImgd.data.buffer),m=o/c,x=a/d,y=0,v=0,g=0,b=s.getNColors()/2;if(l)for(w=0;wMath.abs(u[g+_]-b)?h:u[g+_];p[w]=s.getColorByIndex(h).color}else for(var w=0;w=t.items.length?h.n_show=t.items.length:h.n_show=o,t){if(!e.widget){t.x=e.xpos,t.y=e.ypos,t.val=0,t.h=2*h.GBorder+n*h.n_show+h.toplab*(n+h.GBorder)-1,t.y=t.y-((h.toplab+Math.max(1,t.val)-.5)*n+(1+h.toplab)*h.GBorder)+1;for(var a=t.title.length,s=0,u=0;u0&&u>0){var p=e.active_canvas.getContext("2d");l.LEGACY_RENDER?(p.fillStyle=e.bg,p.fillRect(o,a,s,u)):(p.save(),p.globalAlpha=.1,p.fillStyle=e.bg,p.fillRect(o,a,s,u),p.restore())}},l.text=function(e,t,n,r,i){var o=e.active_canvas.getContext("2d");if(t=Math.max(0,t),n=Math.max(0,n),t<0||n<0)throw"On No!";o.textBaseline="bottom",o.textAlign="left",o.font=e.font.font,o.fillStyle=void 0===i?e.fg:i,o.fillText(r,t,n)},l.getcolor=function(e,t,n){for(var r=0;r<6&&0===t[r+1].pos;r++);for(;n>t[r].pos&&r<6;)r++;if(0===r||n>=t[r].pos)return w(_(t[r].red),_(t[r].green),_(t[r].blue));var i=_(100*((n-t[r-1].pos)/(t[r].pos-t[r-1].pos))),o=255-i;return w(i*(t[r].red/100)+o*(t[r-1].red/100),i*(t[r].green/100)+o*(t[r-1].green/100),i*(t[r].blue/100)+o*(t[r-1].blue/100))},l.redraw_warpbox=function(e){e.warpbox&&(e._animationFrameHandle&&cancelAnimFrame(e._animationFrameHandle),e._animationFrameHandle=requestAnimFrame((function(){!function(e){e._animationFrameHandle=void 0;var t=e.warpbox;e.active_canvas.getContext("2d");if(!t)return;if(e.xpos>=t.xmin&&e.xpos<=t.xmax&&e.ypos>=t.ymin&&e.ypos<=t.ymax){t.xl=e.xpos,t.yl=e.ypos;var n=Math.min(t.xo,t.xl),r=Math.min(t.yo,t.yl),i=Math.abs(t.xl-t.xo),o=Math.abs(t.yl-t.yo);if(0===i||0===o)return;"vertical"===t.mode?(n=e.l,i=e.r-e.l):"horizontal"===t.mode&&(r=e.t,o=e.b-e.t),l.onWidgetLayer(e,(function(){l.erase_window(e),l.draw_box(e,"xor",n,r,i,o,t.style.opacity,t.style.fill_color)}))}}(e)})))},l.format_g=function(e,t,n,r){t=Math.min(t,n+7);var i=Math.abs(e).toString(),o=i.indexOf(".");-1===o&&(o=(i+=".").length);var a=0,s=i.indexOf("e");-1!==s&&(a=parseInt(i.slice(s+1,i.length),10),i=i.slice(0,s));for(var u=Math.min(n-(i.length-o)+1,n),c=0;cn){a=Math.max(0,o-1);i=i[0]+"."+i.slice(1,n+1)}else i=i.slice(0,n+2);if(0===a)i+=" ";else{var d=l.pad(Math.abs(a).toString(),2,"0");i=a<0?i+"E-"+d:i+"E+"+d}return i=e<0?"-"+i:" "+i},l.format_f=function(e,t,n){n=Math.max(Math.min(n,20),0);var r=e.toFixed(n).toString();return r=l.pad(r,t+n," ")},l.pad=function(e,t,n){for(;e.length0&&(h=a.trunc(Math.min(r,i)/3),h=Math.max(1,Math.min(h,l.GBorder))),h>0){switch(p[0].x=p[1].x=t,p[8].x=p[9].x=t+r,p[1].y=p[8].y=n,p[0].y=p[9].y=n+i,o){case l.L_ArrowLeft:p[0].y=p[1].y=n+a.trunc(i/2),t+=2,--r;break;case l.L_ArrowRight:p[8].y=p[9].y=n+a.trunc(i/2),--t,--r;break;case l.L_ArrowUp:p[1].x=p[8].x=t+a.trunc(r/2),n+=2,--i;break;case l.L_ArrowDown:p[0].x=p[9].x=t+a.trunc(r/2),--n,--i}p[2]=p[8],p[10]=p[0],t+=h,n+=h,r-=2*h,i-=2*h}switch(p[4].x=p[5].x=t,p[3].x=p[6].x=t+r,p[3].y=p[4].y=n,p[5].y=p[6].y=n+i,o){case l.L_ArrowLeft:p[4].y=p[5].y=n+a.trunc(i/2);break;case l.L_ArrowRight:p[3].y=p[6].y=n+a.trunc(i/2);break;case l.L_ArrowUp:p[3].x=p[4].x=t+a.trunc(r/2);break;case l.L_ArrowDown:p[5].x=p[6].x=t+a.trunc(r/2)}p[7]=p[3];var y=e.active_canvas.getContext("2d");h>0&&(y.fillStyle=s>0?e.xwts:e.xwbs,g(y,p.slice(0,7)),y.fillStyle=s<0?e.xwts:e.xwbs,g(y,p.slice(5,11))),x&&(y.fillStyle=e.xwbg,g(y,p.slice(3,8))),y.fillStyle=e.xwfg,y.textBaseline="alphabetic",x&&c>0&&(c=Math.min(c,a.trunc(r/e.text_w)),c=Math.max(c,1),d=t+a.trunc((r-c*e.text_w)/2),f=n+a.trunc((i+.7*e.text_h)/2),y.fillText(u,d,f))},l.sigplot_shadowbox=function(e,t,n,r,i,o,s,u,c){var d=e.active_canvas.getContext("2d"),f=u.length,h=s<0?e.xwts:e.xwbs;c=c||1;for(var p=[],m=0;m<11;m++)p[m]={x:0,y:0};switch(o){case l.L_ArrowLeft:case l.L_ArrowRight:case l.L_ArrowUp:case l.L_ArrowDown:p=l.chevron(o,t,n,r,i);d.fillStyle=s>0?e.xwts:e.xwbs,g(d,p.slice(0,6));break;default:l.draw_round_box(e,h,t,n,r,i,c,e.xwbg,5,e.xwbs)}if(d.fillStyle=e.xwfg,d.textBaseline="alphabetic",!(1===s||-1===s)&&f>0){f=Math.min(f,a.trunc(r/e.text_w)),f=Math.max(f,1);var x=t+a.trunc((r-f*e.text_w)/2),y=n+a.trunc((i+.7*e.text_h)/2);d.fillText(u,x,y)}},l.LEGACY_RENDER?l.shadowbox=l.legacy_shadowbox:l.shadowbox=l.sigplot_shadowbox,l.chevron=function(e,t,n,r,i,o){var s=Math.min(r,i);o||(o=.25*s);for(var u=[],c=0;c<6;c++)u[c]={x:0,y:0};var d=a.trunc((r-s)/2+s/4-o/2.828),f=a.trunc((i-s)/2+s/4-o/2.828);switch(e){case l.L_ArrowLeft:u[0].x=t+d,u[0].y=n+a.trunc(s/2),u[1].x=t+d+a.trunc(s/2),u[1].y=n,u[2].x=t+d+a.trunc(s/2+o/1.414),u[2].y=n+a.trunc(o/1.414),u[3].x=t+d+a.trunc(2*o/1.414),u[3].y=n+a.trunc(s/2),u[4].x=t+d+a.trunc(s/2+o/1.414),u[4].y=n+i-a.trunc(o/1.414),u[5].x=t+d+a.trunc(s/2),u[5].y=n+s;break;case l.L_ArrowRight:u[0].x=t+r-d,u[0].y=n+a.trunc(s/2),u[1].x=t+r-d-a.trunc(s/2),u[1].y=n,u[2].x=t+r-d-a.trunc(s/2+o/1.414),u[2].y=n+a.trunc(o/1.414),u[3].x=t+r-d-a.trunc(2*o/1.414),u[3].y=n+a.trunc(s/2),u[4].x=t+r-d-a.trunc(s/2+o/1.414),u[4].y=n+i-a.trunc(o/1.414),u[5].x=t+r-d-a.trunc(s/2),u[5].y=n+s;break;case l.L_ArrowUp:u[0].x=t+a.trunc(s/2),u[0].y=n+f,u[1].x=t,u[1].y=n+f+a.trunc(s/2),u[2].x=t+a.trunc(o/1.414),u[2].y=n+f+a.trunc(s/2+o/1.414),u[3].x=t+a.trunc(s/2),u[3].y=n+f+a.trunc(2*o/1.414),u[4].x=t+r-a.trunc(o/1.414),u[4].y=n+f+a.trunc(s/2+o/1.414),u[5].x=t+s,u[5].y=n+f+a.trunc(s/2);break;case l.L_ArrowDown:u[0].x=t+a.trunc(s/2),u[0].y=n+i-f,u[1].x=t,u[1].y=n+i-f-a.trunc(s/2),u[2].x=t+a.trunc(o/1.414),u[2].y=n+i-f-a.trunc(s/2+o/1.414),u[3].x=t+a.trunc(s/2),u[3].y=n+i-f-a.trunc(2*o/1.414),u[4].x=t+r-a.trunc(o/1.414),u[4].y=n+i-f-a.trunc(s/2+o/1.414),u[5].x=t+s,u[5].y=n+i-f-a.trunc(s/2)}return u},l.ifevent=function(e,t){e.button_press=0,e.button_release=0,e.state_mask=0;var n=t.target.getBoundingClientRect(),r=void 0===t.offsetX?t.pageX-n.left-window.scrollX:t.offsetX,i=void 0===t.offsetX?t.pageY-n.top-window.scrollY:t.offsetY;switch(t.type){case"mousedown":switch(e.xpos=a.bound(r,0,e.width),e.ypos=a.bound(i,0,e.height),t.which){case 1:e.button_press=1;break;case 2:e.button_press=2;break;case 3:e.button_press=3;break;case 4:e.button_press=4;break;case 5:e.button_press=5}break;case"mouseup":switch(e.xpos=a.bound(r,0,e.width),e.ypos=a.bound(i,0,e.height),t.which){case 1:e.button_release=1;break;case 2:e.button_release=2;break;case 3:e.button_release=3;break;case 4:e.button_release=4;break;case 5:e.button_release=5}}},l.scroll_real2pix=function(e){return 0===e.range?{s1:e.a1,sw:e.a2-e.a1}:(t=(e.a2-e.a1)/e.trange,r=(n=e.a1+Math.floor(.5+(e.smin-e.tmin)*t))+Math.floor(.5+e.srange*t),n=n>e.a2-e.swmin?e.a2-e.swmin:Math.max(n,e.a1),r=ri.xmax||ti.ymin||n2?e.stk[o].ymin+(i-e.stk[o].y1)*e.stk[o].yscl:e.stk[o].ymin+(e.stk[o].y2-i)*e.stk[o].yscl}},l.colormap=function(e,t,n){e.pixel=new r(t,{ncolors:n})},l.colorbar=function(e,t,n,r,i){if(e.pixel){e.pixel.setRange(0,e.pixel.map.length);for(var o=1;o0?(n*=t.width,i.set(i.subarray(0,i.length-n),n),r&&i.fill(0,0,n)):n<0&&(n=Math.abs(n)*t.width,i.set(i.subarray(n)),r&&i.fill(0,i.length-n)),t},l.update_image_row=function(e,t,n,r,i,o,a){var l=new Uint32Array(t,r*t.width*4,t.width);e.pixel.setRange(i,o);for(var s=Math.max(1,n.length/t.width),u=0;u1)if(1===a){for(var f=1;f1)if(1===u){for(var v=1;v0?n*o:-o,p=Math.floor(p),m=Math.floor(i*l);var y=new ArrayBuffer(p*m*4);y.width=p,y.height=m;for(var v=new Uint32Array(y),g=0;g>3]>>7-(7&e)&1}},{key:"setBit",value:function(e,t){var n=7&e;t?this.u8[e>>3]|=128>>n:this.u8[e>>3]&=~(128>>n)}},{key:"setArray",value:function(e){for(var t=e.length,n=0;nthis.length?this.length:t;for(var r=e;re.length)&&(t=e.length);for(var n=0,r=new Array(t);n=r?(console.warn("Int is bigger than JS can represent."),1/0):u}function d(e,t){var n=new Uint8Array(e);return void 0===d._applySupportsTypedArray&&(d._applySupportsTypedArray=void 0!==t?t:function(){try{var e=new Uint8Array(new ArrayBuffer(4));if(e[0]=66,e[1]=76,e[2]=85,e[3]=69,"BLUE"!==String.fromCharCode.apply(null,e))return!1}catch(e){return!1}return!0}()),d._applySupportsTypedArray?String.fromCharCode.apply(null,n):n.reduce((function(e,t){return e+String.fromCharCode(t)}),"")}function f(e){return e>=0&&e<31?1<=e.length?t(i):setTimeout(a,0)}),0)}(r.responseText,(function(r){var i=new n.header_class(r,n.options),o=h(e);i.file_name=o.file,t(i)}))}},r.onerror=function(e){t(null)},r.send(null),r}}])&&p(t.prototype,n),e}();function x(e,t){return(x=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function y(e,t){return!t||"object"!==b(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function v(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function g(e){return(g=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function b(e){return(b="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function w(e,t){for(var n=0;n1&&console.warn("Only 1D arrays are currently supported."),this.getDataWithType(n,h,o-1,i),o+=s;var x=n.getUint32(o-1,i);o+=4;var y=0,v=!1;x>15&&(x&=255,v=!0,y=n.getUint16(o-5,i));var g=e.dataTypeNames[x].name;e.dataTypeNames[x].size,v||(y=this.getDataWithType(n,g,o-1,i),o+=4),o+=y+(v?(4-y%4)%4:(8-y%8)%8),this.setData(this.buf,n,o,i)}}var t,n;return t=e,(n=[{key:"createArray",value:function(t,n,r,i){var o=e._MAT_TO_TYPEDARRAY[i];if(void 0===o)throw"unknown type ".concat(i);return void 0===n&&(n=0),void 0===r&&(r=t.length),new o(t,n,r)}},{key:"getDataWithType",value:function(t,n,r,i){var o=e._MAT_TO_DATAVIEW[n];if(void 0===o)throw"Type name ".concat(n," is not supported");return t[o](r,i)}},{key:"setData",value:function(t,n,r,i){var o,a=n.getUint32(r-1,i),l=!1;a>15?(a&=255,l=!0,o=n.getUint16(r+1,2,i)):r+=4;var s=e.dataTypeNames[a].name,u=e.dataTypeNames[a].size;l||(o=n.getUint32(r-1,i),l=!1),r+=4,this.dview=this.createArray(t,r-1,o/u,s)}}])&&L(t.prototype,n),e}();O(N,"ARRAY_BUFFER_ENDIANNESS",u()),O(N,"versionNames",{256:"MAT-file"}),O(N,"_MAT_TO_TYPEDARRAY",{miINT8:Int8Array,miUINT8:Uint8Array,miInt16:Int16Array,miUINT16:Uint16Array,miINT32:Int32Array,miUINT32:Uint32Array,miDOUBLE:Float64Array}),O(N,"_MAT_TO_DATAVIEW",{miINT8:"getInt8",miUINT8:"getUint8",miINT16:"getInt16",miUINT16:"getUint16",miINT32:"getInt32",miUINT32:"getUint32",miSINGLE:"getFloat32",miDOUBLE:"getFloat64",miINT64:c}),O(N,"dataTypeNames",{1:{name:"miINT8",size:1},2:{name:"miUINT8",size:1},3:{name:"miINT16",size:2},4:{name:"miUINT16",size:2},5:{name:"miINT32",size:4},6:{name:"miUINT32",size:4},7:{name:"miSINGLE",size:4},9:{name:"miDOUBLE",size:8},12:{name:"miINT64",size:8},13:{name:"miUINT64",size:8},14:{name:"miMATRIX",size:null},15:{name:"miCOMPRESSED",size:null},16:{name:"miUTF8",size:null},17:{name:"miUTF16",size:null},18:{name:"miUTF32",size:null}}),O(N,"arrayClassNames",{1:"mxCELL_CLASS",2:"mxSTRUCT_CLASS",3:"mxOBJECT_CLASS",4:"mxCHAR_CLASS",5:"mxSPARSE_CLASS",6:"mxDOUBLE_CLASS",7:"mxSINGLE_CLASS",8:"mxINT8_CLASS",9:"mxUINT8_CLASS",10:"mxINT16_CLASS",11:"mxUINT16_CLASS",12:"mxINT32_CLASS",13:"mxUINT32_CLASS",14:"mxINT64_CLASS",15:"mxUINT64_CLASS"}),O(N,"headerTextBegin",1),O(N,"headerTextEnd",116),O(N,"subsysOffsetBegin",117),O(N,"subsysOffsetEnd",124),O(N,"versionOffsetBegin",125),O(N,"versionOffsetEnd",126),O(N,"endianCharsBegin",127),O(N,"endianCharsEnd",128),O(N,"firstDataTypeOffsetBegin",129),O(N,"firstDataTypeOffsetEnd",132),O(N,"numBytesOffsetBegin",133),O(N,"numBytesOffsetEnd",136);var I=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&T(e,t)}(r,e);var t,n=(t=r,function(){var e,n=P(t);if(A()){var r=P(this).constructor;e=Reflect.construct(n,arguments,r)}else e=n.apply(this,arguments);return C(this,e)});function r(e){return z(this,r),n.call(this,e,N)}return r}(m),R=n(0)}])},function(e,t,n){var r;!function(i){var o=/^\s+/,a=/\s+$/,l=0,s=i.round,u=i.min,c=i.max,d=i.random;function f(e,t){if(t=t||{},(e=e||"")instanceof f)return e;if(!(this instanceof f))return new f(e,t);var n=function(e){var t={r:0,g:0,b:0},n=1,r=null,l=null,s=null,d=!1,f=!1;"string"==typeof e&&(e=function(e){e=e.replace(o,"").replace(a,"").toLowerCase();var t,n=!1;if(P[e])e=P[e],n=!0;else if("transparent"==e)return{r:0,g:0,b:0,a:0,format:"name"};if(t=W.rgb.exec(e))return{r:t[1],g:t[2],b:t[3]};if(t=W.rgba.exec(e))return{r:t[1],g:t[2],b:t[3],a:t[4]};if(t=W.hsl.exec(e))return{h:t[1],s:t[2],l:t[3]};if(t=W.hsla.exec(e))return{h:t[1],s:t[2],l:t[3],a:t[4]};if(t=W.hsv.exec(e))return{h:t[1],s:t[2],v:t[3]};if(t=W.hsva.exec(e))return{h:t[1],s:t[2],v:t[3],a:t[4]};if(t=W.hex8.exec(e))return{r:I(t[1]),g:I(t[2]),b:I(t[3]),a:B(t[4]),format:n?"name":"hex8"};if(t=W.hex6.exec(e))return{r:I(t[1]),g:I(t[2]),b:I(t[3]),format:n?"name":"hex"};if(t=W.hex4.exec(e))return{r:I(t[1]+""+t[1]),g:I(t[2]+""+t[2]),b:I(t[3]+""+t[3]),a:B(t[4]+""+t[4]),format:n?"name":"hex8"};if(t=W.hex3.exec(e))return{r:I(t[1]+""+t[1]),g:I(t[2]+""+t[2]),b:I(t[3]+""+t[3]),format:n?"name":"hex"};return!1}(e));"object"==typeof e&&(j(e.r)&&j(e.g)&&j(e.b)?(h=e.r,p=e.g,m=e.b,t={r:255*O(h,255),g:255*O(p,255),b:255*O(m,255)},d=!0,f="%"===String(e.r).substr(-1)?"prgb":"rgb"):j(e.h)&&j(e.s)&&j(e.v)?(r=D(e.s),l=D(e.v),t=function(e,t,n){e=6*O(e,360),t=O(t,100),n=O(n,100);var r=i.floor(e),o=e-r,a=n*(1-t),l=n*(1-o*t),s=n*(1-(1-o)*t),u=r%6;return{r:255*[n,l,a,a,s,n][u],g:255*[s,n,n,l,a,a][u],b:255*[a,a,s,n,n,l][u]}}(e.h,r,l),d=!0,f="hsv"):j(e.h)&&j(e.s)&&j(e.l)&&(r=D(e.s),s=D(e.l),t=function(e,t,n){var r,i,o;function a(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}if(e=O(e,360),t=O(t,100),n=O(n,100),0===t)r=i=o=n;else{var l=n<.5?n*(1+t):n+t-n*t,s=2*n-l;r=a(s,l,e+1/3),i=a(s,l,e),o=a(s,l,e-1/3)}return{r:255*r,g:255*i,b:255*o}}(e.h,r,s),d=!0,f="hsl"),e.hasOwnProperty("a")&&(n=e.a));var h,p,m;return n=L(n),{ok:d,format:e.format||f,r:u(255,c(t.r,0)),g:u(255,c(t.g,0)),b:u(255,c(t.b,0)),a:n}}(e);this._originalInput=e,this._r=n.r,this._g=n.g,this._b=n.b,this._a=n.a,this._roundA=s(100*this._a)/100,this._format=t.format||n.format,this._gradientType=t.gradientType,this._r<1&&(this._r=s(this._r)),this._g<1&&(this._g=s(this._g)),this._b<1&&(this._b=s(this._b)),this._ok=n.ok,this._tc_id=l++}function h(e,t,n){e=O(e,255),t=O(t,255),n=O(n,255);var r,i,o=c(e,t,n),a=u(e,t,n),l=(o+a)/2;if(o==a)r=i=0;else{var s=o-a;switch(i=l>.5?s/(2-o-a):s/(o+a),o){case e:r=(t-n)/s+(t>1)+720)%360;--t;)r.h=(r.h+i)%360,o.push(f(r));return o}function A(e,t){t=t||6;for(var n=f(e).toHsv(),r=n.h,i=n.s,o=n.v,a=[],l=1/t;t--;)a.push(f({h:r,s:i,v:o})),o=(o+l)%1;return a}f.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var e=this.toRgb();return(299*e.r+587*e.g+114*e.b)/1e3},getLuminance:function(){var e,t,n,r=this.toRgb();return e=r.r/255,t=r.g/255,n=r.b/255,.2126*(e<=.03928?e/12.92:i.pow((e+.055)/1.055,2.4))+.7152*(t<=.03928?t/12.92:i.pow((t+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:i.pow((n+.055)/1.055,2.4))},setAlpha:function(e){return this._a=L(e),this._roundA=s(100*this._a)/100,this},toHsv:function(){var e=p(this._r,this._g,this._b);return{h:360*e.h,s:e.s,v:e.v,a:this._a}},toHsvString:function(){var e=p(this._r,this._g,this._b),t=s(360*e.h),n=s(100*e.s),r=s(100*e.v);return 1==this._a?"hsv("+t+", "+n+"%, "+r+"%)":"hsva("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHsl:function(){var e=h(this._r,this._g,this._b);return{h:360*e.h,s:e.s,l:e.l,a:this._a}},toHslString:function(){var e=h(this._r,this._g,this._b),t=s(360*e.h),n=s(100*e.s),r=s(100*e.l);return 1==this._a?"hsl("+t+", "+n+"%, "+r+"%)":"hsla("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHex:function(e){return m(this._r,this._g,this._b,e)},toHexString:function(e){return"#"+this.toHex(e)},toHex8:function(e){return function(e,t,n,r,i){var o=[R(s(e).toString(16)),R(s(t).toString(16)),R(s(n).toString(16)),R(G(r))];if(i&&o[0].charAt(0)==o[0].charAt(1)&&o[1].charAt(0)==o[1].charAt(1)&&o[2].charAt(0)==o[2].charAt(1)&&o[3].charAt(0)==o[3].charAt(1))return o[0].charAt(0)+o[1].charAt(0)+o[2].charAt(0)+o[3].charAt(0);return o.join("")}(this._r,this._g,this._b,this._a,e)},toHex8String:function(e){return"#"+this.toHex8(e)},toRgb:function(){return{r:s(this._r),g:s(this._g),b:s(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+s(this._r)+", "+s(this._g)+", "+s(this._b)+")":"rgba("+s(this._r)+", "+s(this._g)+", "+s(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:s(100*O(this._r,255))+"%",g:s(100*O(this._g,255))+"%",b:s(100*O(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+s(100*O(this._r,255))+"%, "+s(100*O(this._g,255))+"%, "+s(100*O(this._b,255))+"%)":"rgba("+s(100*O(this._r,255))+"%, "+s(100*O(this._g,255))+"%, "+s(100*O(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(z[m(this._r,this._g,this._b,!0)]||!1)},toFilter:function(e){var t="#"+x(this._r,this._g,this._b,this._a),n=t,r=this._gradientType?"GradientType = 1, ":"";if(e){var i=f(e);n="#"+x(i._r,i._g,i._b,i._a)}return"progid:DXImageTransform.Microsoft.gradient("+r+"startColorstr="+t+",endColorstr="+n+")"},toString:function(e){var t=!!e;e=e||this._format;var n=!1,r=this._a<1&&this._a>=0;return t||!r||"hex"!==e&&"hex6"!==e&&"hex3"!==e&&"hex4"!==e&&"hex8"!==e&&"name"!==e?("rgb"===e&&(n=this.toRgbString()),"prgb"===e&&(n=this.toPercentageRgbString()),"hex"!==e&&"hex6"!==e||(n=this.toHexString()),"hex3"===e&&(n=this.toHexString(!0)),"hex4"===e&&(n=this.toHex8String(!0)),"hex8"===e&&(n=this.toHex8String()),"name"===e&&(n=this.toName()),"hsl"===e&&(n=this.toHslString()),"hsv"===e&&(n=this.toHsvString()),n||this.toHexString()):"name"===e&&0===this._a?this.toName():this.toRgbString()},clone:function(){return f(this.toString())},_applyModification:function(e,t){var n=e.apply(null,[this].concat([].slice.call(t)));return this._r=n._r,this._g=n._g,this._b=n._b,this.setAlpha(n._a),this},lighten:function(){return this._applyModification(b,arguments)},brighten:function(){return this._applyModification(_,arguments)},darken:function(){return this._applyModification(w,arguments)},desaturate:function(){return this._applyModification(y,arguments)},saturate:function(){return this._applyModification(v,arguments)},greyscale:function(){return this._applyModification(g,arguments)},spin:function(){return this._applyModification(k,arguments)},_applyCombination:function(e,t){return e.apply(null,[this].concat([].slice.call(t)))},analogous:function(){return this._applyCombination(C,arguments)},complement:function(){return this._applyCombination(M,arguments)},monochromatic:function(){return this._applyCombination(A,arguments)},splitcomplement:function(){return this._applyCombination(T,arguments)},triad:function(){return this._applyCombination(E,arguments)},tetrad:function(){return this._applyCombination(S,arguments)}},f.fromRatio=function(e,t){if("object"==typeof e){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]="a"===r?e[r]:D(e[r]));e=n}return f(e,t)},f.equals=function(e,t){return!(!e||!t)&&f(e).toRgbString()==f(t).toRgbString()},f.random=function(){return f.fromRatio({r:d(),g:d(),b:d()})},f.mix=function(e,t,n){n=0===n?0:n||50;var r=f(e).toRgb(),i=f(t).toRgb(),o=n/100;return f({r:(i.r-r.r)*o+r.r,g:(i.g-r.g)*o+r.g,b:(i.b-r.b)*o+r.b,a:(i.a-r.a)*o+r.a})},f.readability=function(e,t){var n=f(e),r=f(t);return(i.max(n.getLuminance(),r.getLuminance())+.05)/(i.min(n.getLuminance(),r.getLuminance())+.05)},f.isReadable=function(e,t,n){var r,i,o=f.readability(e,t);switch(i=!1,(r=function(e){var t,n;t=((e=e||{level:"AA",size:"small"}).level||"AA").toUpperCase(),n=(e.size||"small").toLowerCase(),"AA"!==t&&"AAA"!==t&&(t="AA");"small"!==n&&"large"!==n&&(n="small");return{level:t,size:n}}(n)).level+r.size){case"AAsmall":case"AAAlarge":i=o>=4.5;break;case"AAlarge":i=o>=3;break;case"AAAsmall":i=o>=7}return i},f.mostReadable=function(e,t,n){var r,i,o,a,l=null,s=0;i=(n=n||{}).includeFallbackColors,o=n.level,a=n.size;for(var u=0;us&&(s=r,l=f(t[u]));return f.isReadable(e,l,{level:o,size:a})||!i?l:(n.includeFallbackColors=!1,f.mostReadable(e,["#fff","#000"],n))};var P=f.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},z=f.hexNames=function(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[e[n]]=n);return t}(P);function L(e){return e=parseFloat(e),(isNaN(e)||e<0||e>1)&&(e=1),e}function O(e,t){(function(e){return"string"==typeof e&&-1!=e.indexOf(".")&&1===parseFloat(e)})(e)&&(e="100%");var n=function(e){return"string"==typeof e&&-1!=e.indexOf("%")}(e);return e=u(t,c(0,parseFloat(e))),n&&(e=parseInt(e*t,10)/100),i.abs(e-t)<1e-6?1:e%t/parseFloat(t)}function N(e){return u(1,c(0,e))}function I(e){return parseInt(e,16)}function R(e){return 1==e.length?"0"+e:""+e}function D(e){return e<=1&&(e=100*e+"%"),e}function G(e){return i.round(255*parseFloat(e)).toString(16)}function B(e){return I(e)/255}var U,F,H,W=(F="[\\s|\\(]+("+(U="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+U+")[,|\\s]+("+U+")\\s*\\)?",H="[\\s|\\(]+("+U+")[,|\\s]+("+U+")[,|\\s]+("+U+")[,|\\s]+("+U+")\\s*\\)?",{CSS_UNIT:new RegExp(U),rgb:new RegExp("rgb"+F),rgba:new RegExp("rgba"+H),hsl:new RegExp("hsl"+F),hsla:new RegExp("hsla"+H),hsv:new RegExp("hsv"+F),hsva:new RegExp("hsva"+H),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});function j(e){return!!W.CSS_UNIT.exec(e)}e.exports?e.exports=f:void 0===(r=function(){return f}.call(t,n,t,e))||(e.exports=r)}(Math)},function(e,t,n){"use strict"; -/* -object-assign -(c) Sindre Sorhus -@license MIT -*/var r=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,l,s=a(e),u=1;uP.length&&P.push(e)}function O(e,t,n){return null==e?0:function e(t,n,r,i){var l=typeof t;"undefined"!==l&&"boolean"!==l||(t=null);var s=!1;if(null===t)s=!0;else switch(l){case"string":case"number":s=!0;break;case"object":switch(t.$$typeof){case o:case a:s=!0}}if(s)return r(i,t,""===n?"."+N(t,0):n),1;if(s=0,n=""===n?".":n+":",Array.isArray(t))for(var u=0;u>1):a.left+s)+"px",top:("auto"==a.top?r.y-t.y+(e.offsetHeight>>1):a.top+s)+"px"})),l.setAttribute("aria-role","progressbar"),i.lines(l,i.opts),!n){var u=0,c=a.fps,f=c/a.speed,p=(1-a.opacity)/(f*a.trail/100),m=f/a.lines;!function e(){u++;for(var t=a.lines;t;t--){var n=Math.max(1-(u+t*m)%f*p,a.opacity);i.opacity(l,a.lines-t,n,a)}i.timeout=i.el&&setTimeout(e,~~(1e3/c))}()}return i},stop:function(){var e=this.el;return e&&(clearTimeout(this.timeout),e.parentNode&&e.parentNode.removeChild(e),this.el=void 0),this},lines:function(e,t){var r,i=0;function l(e,n){return d(o(),{position:"absolute",width:t.length+t.width+"px",height:t.width+"px",background:e,boxShadow:n,transformOrigin:"left",transform:"rotate("+~~(360/t.lines*i+t.rotate)+"deg) translate("+t.radius+"px,0)",borderRadius:(t.width>>1)+"px"})}for(;i',t)}var t=d(o("group"),{behavior:"url(#default#VML)"});!c(t,"transform")&&t.adj?(s.addRule(".spin-vml","behavior:url(#default#VML)"),m.prototype.lines=function(t,n){var r=n.length+n.width,i=2*r;function o(){return d(e("group",{coordsize:i+" "+i,coordorigin:-r+" "+-r}),{width:i,height:i})}var l,s=2*-(n.width+n.length)+"px",u=d(o(),{position:"absolute",top:s,left:s});function c(t,i,l){a(u,a(d(o(),{rotation:360/n.lines*t+"deg",left:~~i}),a(d(e("roundrect",{arcsize:1}),{width:r,height:n.width,left:n.radius,top:-n.width>>1,filter:l}),e("fill",{color:n.color,opacity:n.opacity}),e("stroke",{opacity:0}))))}if(n.shadow)for(l=1;l<=n.lines;l++)c(l,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(l=1;l<=n.lines;l++)c(l);return a(t,u)},m.prototype.opacity=function(e,t,n,r){var i=e.firstChild;r=r.shadow&&r.lines||0,i&&t+r1)for(var n=1;n=0&&t<=o.levels.SILENT))throw"log.setLevel() called with invalid level: "+t;if(i=t,!1!==r&&function(e){var t=(n[e]||"silent").toUpperCase();if("undefined"!=typeof window&&l){try{return void(window.localStorage[l]=t)}catch(e){}try{window.document.cookie=encodeURIComponent(l)+"="+t+";"}catch(e){}}}(t),a.call(o,t,e),"undefined"==typeof console&&tu){if(o=e[r],void 0===(a=e[r+1]))break;if(o.pos>=100&&a.pos>=100)break;var u;l=1/(u=n*((a.pos-o.pos)/100)),i=1;r+=1}this._addColor(this.interpolate(o,a,l*i)),i+=1}this._addColor(e[r]),this._addColor(e[0],!0)};r.prototype={_addColor:function(e,t){e.hex=this._rgbToHex(e.red,e.green,e.blue),e.color=e.alpha<<24|e.blue<<16|e.green<<8|e.red,t?this.map.unshift(e):this.map.push(e)},_parseColors:function(e){for(var n=0,r=e.length;nthis.map.length-1?t=this.map.length-1:t<0&&(t=0),t},getNColors:function(){return this.map.length},setRange:function(e,t){this._low===e&&this._high===t||(this._low=e,this._high=t,this._fscale=this.map.length/Math.abs(this._high-this._low))},interpolate:function(e,t,n){return{red:e.red+n*(t.red-e.red),green:e.green+n*(t.green-e.green),blue:e.blue+n*(t.blue-e.blue),alpha:e.alpha+n*(t.alpha-e.alpha)}}},e.exports=r}()},function(e,t){ -/** - * @license - * File: CanvasInput.js - * CanvasInput v1.0.10 - * http://goldfirestudios.com/blog/108/CanvasInput-HTML5-Canvas-Text-Input - * - * (c) 2013, James Simpson of GoldFire Studios - * goldfirestudios.com - * - * (c) 2013, Axios, Inc. - * Modifications made by Axios, Inc. - * axiosengineering.com - * - * MIT License - */ -var n,r;n=[],(r=window.CanvasInput=function(e){var t=this;e=e||{},t._canvas=e.canvas||null,t._ctx=t._canvas?t._canvas.getContext("2d"):null,t._x=e.x||0,t._y=e.y||0,t._extraX=e.extraX||0,t._extraY=e.extraY||0,t._fontSize=e.fontSize||14,t._fontFamily=e.fontFamily||"Arial",t._fontColor=e.fontColor||"#000",t._placeHolderColor=e.placeHolderColor||"#bfbebd",t._fontWeight=e.fontWeight||"normal",t._fontStyle=e.fontStyle||"normal",t._readonly=e.readonly||!1,t._maxlength=e.maxlength||null,t._width=e.width||150,t._height=e.height||t._fontSize,t._padding=e.padding>=0?e.padding:5,t._borderWidth=e.borderWidth>=0?e.borderWidth:1,t._borderColor=e.borderColor||"#959595",t._borderRadius=e.borderRadius>=0?e.borderRadius:3,t._backgroundImage=e.backgroundImage||"",t._boxShadow=e.boxShadow||"1px 1px 0px rgba(255, 255, 255, 1)",t._innerShadow=e.innerShadow||"0px 0px 4px rgba(0, 0, 0, 0.4)",t._selectionColor=e.selectionColor||"rgba(179, 212, 253, 0.8)",t._placeHolder=e.placeHolder||"",t._value=e.value||t._placeHolder,t._onsubmit=e.onsubmit||function(){},t._onkeydown=e.onkeydown||function(){},t._onkeyup=e.onkeyup||function(){},t._onfocus=e.onfocus||function(){},t._onblur=e.onblur||function(){},t._cursor=!1,t._cursorPos=0,t._hasFocus=!1,t._selection=[0,0],t._wasOver=!1,t._renderOnReturn=void 0===e.renderOnReturn||e.renderOnReturn,t._disableBlur=e.disableBlur||!1,t._tabToClear=e.tabToClear||!1,t.boxShadow(t._boxShadow,!0),t._calcWH(),t._renderCanvas=document.createElement("canvas"),t._renderCanvas.setAttribute("width",t.outerW),t._renderCanvas.setAttribute("height",t.outerH),t._renderCtx=t._renderCanvas.getContext("2d"),t._shadowCanvas=document.createElement("canvas"),t._shadowCanvas.setAttribute("width",t._width+2*t._padding),t._shadowCanvas.setAttribute("height",t._height+2*t._padding),t._shadowCtx=t._shadowCanvas.getContext("2d"),void 0!==e.backgroundGradient?(t._backgroundColor=t._renderCtx.createLinearGradient(0,0,0,t.outerH),t._backgroundColor.addColorStop(0,e.backgroundGradient[0]),t._backgroundColor.addColorStop(1,e.backgroundGradient[1])):t._backgroundColor=e.backgroundColor||"#fff",t._canvas&&(t.mousemoveCanvasListener=function(e){e=e||window.event,t.mousemove(e,t)},t._canvas.addEventListener("mousemove",t.mousemoveCanvasListener,!1),t.mousedownCanvasListener=function(e){e=e||window.event,t.mousedown(e,t)},t._canvas.addEventListener("mousedown",t.mousedownCanvasListener,!1),t.mouseupCanvasListener=function(e){e=e||window.event,t.mouseup(e,t)},t._canvas.addEventListener("mouseup",t.mouseupCanvasListener,!1)),t.mouseupWindowListener=function(e){e=e||window.event,t._hasFocus&&!t._mouseDown&&t.blur()},window.addEventListener("mouseup",t.mouseupWindowListener,!0),t.keydownWindowListener=function(e){e=e||window.event,t._hasFocus&&t.keydown(e,t)},window.addEventListener("keydown",t.keydownWindowListener,!1),t.keyupWindowListener=function(e){e=e||window.event,t._hasFocus&&t._onkeyup(e,t)},window.addEventListener("keyup",t.keyupWindowListener,!1),t.pasteWindowListener=function(e){if(e=e||window.event,t._hasFocus){var n=e.clipboardData.getData("text/plain"),r=t._value.substr(0,t._cursorPos),i=t._value.substr(t._cursorPos);t._value=r+n+i,t._cursorPos+=n.length,t.render()}},window.addEventListener("paste",t.pasteWindowListener,!1),n.push(t),t._inputsIndex=n.length-1,t.render()}).prototype={canvas:function(e){return void 0!==e?(this._canvas=e,this._ctx=this._canvas.getContext("2d"),this.render()):this._canvas},x:function(e){return void 0!==e?(this._x=e,this.render()):this._x},y:function(e){return void 0!==e?(this._y=e,this.render()):this._y},extraX:function(e){return void 0!==e?(this._extraX=e,this.render()):this._extraX},extraY:function(e){return void 0!==e?(this._extraY=e,this.render()):this._extraY},fontSize:function(e){return void 0!==e?(this._fontSize=e,this.render()):this._fontSize},fontFamily:function(e){return void 0!==e?(this._fontFamily=e,this.render()):this._fontFamily},fontColor:function(e){return void 0!==e?(this._fontColor=e,this.render()):this._fontColor},placeHolderColor:function(e){return void 0!==e?(this._placeHolderColor=e,this.render()):this._placeHolderColor},fontWeight:function(e){return void 0!==e?(this._fontWeight=e,this.render()):this._fontWeight},fontStyle:function(e){return void 0!==e?(this._fontStyle=e,this.render()):this._fontStyle},width:function(e){return void 0!==e?(this._width=e,this._calcWH(),this._updateCanvasWH(),this.render()):this._width},height:function(e){return void 0!==e?(this._height=e,this._calcWH(),this._updateCanvasWH(),this.render()):this._height},padding:function(e){return void 0!==e?(this._padding=e,this._calcWH(),this._updateCanvasWH(),this.render()):this._padding},borderWidth:function(e){return void 0!==e?(this._borderWidth=e,this._calcWH(),this._updateCanvasWH(),this.render()):this._borderWidth},borderColor:function(e){return void 0!==e?(this._borderColor=e,this.render()):this._borderColor},borderRadius:function(e){return void 0!==e?(this._borderRadius=e,this.render()):this._borderRadius},backgroundColor:function(e){return void 0!==e?(this._backgroundColor=e,this.render()):this._backgroundColor},backgroundGradient:function(e){return void 0!==e?(this._backgroundColor=this._renderCtx.createLinearGradient(0,0,0,this.outerH),this._backgroundColor.addColorStop(0,e[0]),this._backgroundColor.addColorStop(1,e[1]),this.render()):this._backgroundColor},boxShadow:function(e,t){if(void 0===e)return this._boxShadow;var n=e.split("px ");return this._boxShadow={x:"none"===this._boxShadow?0:parseInt(n[0],10),y:"none"===this._boxShadow?0:parseInt(n[1],10),blur:"none"===this._boxShadow?0:parseInt(n[2],10),color:"none"===this._boxShadow?"":n[3]},this._boxShadow.x<0?(this.shadowL=Math.abs(this._boxShadow.x)+this._boxShadow.blur,this.shadowR=this._boxShadow.blur+this._boxShadow.x):(this.shadowL=Math.abs(this._boxShadow.blur-this._boxShadow.x),this.shadowR=this._boxShadow.blur+this._boxShadow.x),this._boxShadow.y<0?(this.shadowT=Math.abs(this._boxShadow.y)+this._boxShadow.blur,this.shadowB=this._boxShadow.blur+this._boxShadow.y):(this.shadowT=Math.abs(this._boxShadow.blur-this._boxShadow.y),this.shadowB=this._boxShadow.blur+this._boxShadow.y),this.shadowW=this.shadowL+this.shadowR,this.shadowH=this.shadowT+this.shadowB,this._calcWH(),t?void 0:(this._updateCanvasWH(),this.render())},innerShadow:function(e){return void 0!==e?(this._innerShadow=e,this.render()):this._innerShadow},selectionColor:function(e){return void 0!==e?(this._selectionColor=e,this.render()):this._selectionColor},placeHolder:function(e){return void 0!==e?(this._placeHolder=e,this.render()):this._placeHolder},value:function(e){return void 0!==e?(this._value=e,this.focus()):this._value},onsubmit:function(e){if(void 0!==e)return this._onsubmit=e,this;this._onsubmit()},onkeydown:function(e){if(void 0!==e)return this._onkeydown=e,this;this._onkeydown()},onkeyup:function(e){if(void 0!==e)return this._onkeyup=e,this;this._onkeyup()},focus:function(e){var t,n=this;if(!n._readonly){n._hasFocus||n._onfocus(n),n._selectionUpdated?delete n._selectionUpdated:n._selection=[0,0],n._cursorPos="number"==typeof e?e:n._clipText().length,n._placeHolder===n._value&&(n._value=""),n._hasFocus=!0,n._cursor=!0,n._cursorInterval&&clearInterval(n._cursorInterval),n._cursorInterval=setInterval((function(){n._cursor=!n._cursor,n.render()}),500);var r=navigator.userAgent.toLowerCase(),i=r.indexOf("chrome")>=0&&r.indexOf("mobile")>=0&&r.indexOf("android")>=0,o=void 0!==window.orientation;return o&&!i&&document&&document.createElement&&(t=document.createElement("input"))?(t.type="text",t.style.opacity=0,t.style.position="absolute",t.style.left=n._x+n._extraX+(n._canvas?n._canvas.offsetLeft:0)+"px",t.style.top=n._y+n._extraY+(n._canvas?n._canvas.offsetTop:0)+"px",t.style.width=n._width,t.style.height=0,document.body.appendChild(t),t.focus(),t.addEventListener("blur",(function(){n.blur(n)}),!1)):o&&n.value(prompt(n._placeHolder)||""),n.render()}},blur:function(e){var t=e||this;return t._disableBlur||(t._onblur(t),t._cursorInterval&&clearInterval(t._cursorInterval),t._hasFocus=!1,t._cursor=!1,t._selection=[0,0],""===t._value&&(t._value=t._placeHolder)),t.render()},disableBlur:function(e){(e||this)._disableBlur=!0},enableBlur:function(e){(e||this)._disableBlur=!1},keydown:function(e,t){var r,i,o=e.which,a=e.shiftKey,l=null;if(t._hasFocus){if(t._onkeydown(e,t),65===o&&(e.ctrlKey||e.metaKey))return t._selection=[0,t._value.length],e.preventDefault(),t.render();if(17===o||e.metaKey||e.ctrlKey)return t;if(e.preventDefault(),8===o)t._clearSelection()||t._cursorPos>0&&(r=t._value.substr(0,t._cursorPos-1),i=t._value.substr(t._cursorPos,t._value.length),t._value=r+i,t._cursorPos--);else if(37===o)t._cursorPos>0&&(t._cursorPos--,t._cursor=!0,t._selection=[0,0]);else if(39===o)t._cursorPos=0){var a=t._clickPos(r,i),l=Math.min(t._selectionStart,a),s=Math.max(t._selectionStart,a);if(!o)return t._selectionUpdated=!0,t._endSelection=!0,delete t._selectionStart,void t.render();t._selection[0]===l&&t._selection[1]===s||(t._selection=[l,s],t.render())}},mousedown:function(e,t){var n=t._mousePos(e),r=n.x,i=n.y,o=t._overInput(r,i);t._mouseDown=o,t._hasFocus&&o&&(t._selectionStart=t._clickPos(r,i))},mouseup:function(e,t){var n=t._mousePos(e),r=n.x,i=n.y,o=t._clickPos(r,i)!==t._selectionStart;t._hasFocus&&t._selectionStart>=0&&t._overInput(r,i)&&o?(t._selectionUpdated=!0,delete t._selectionStart,t.render()):delete t._selectionStart,t.click(e,t)},renderCanvas:function(){return this._renderCanvas},cleanup:function(){this._canvas.removeEventListener("mouseup",this.mouseupCanvasListener,!1),this._canvas.removeEventListener("mousedown",this.mousedownCanvasListener,!1),this._canvas.removeEventListener("mousemove",this.mousemoveCanvasListener,!1),window.removeEventListener("keydown",this.keydownWindowListener,!1),window.removeEventListener("keyup",this.keyupWindowListener,!1),window.removeEventListener("mouseup",this.mouseupWindowListener,!0),window.removeEventListener("paste",this.pasteWindowListener,!1),clearInterval(this._cursorInterval),this._canvas.style.cursor="default";for(var e=n.length-1;e>=0;e--)n[e]===this&&n.splice(e,1)},render:function(){var e=this,t=e._renderCtx,n=e.outerW,r=e.outerH,i=e._borderRadius,o=e._borderWidth,a=e.shadowW,l=e.shadowH;t.clearRect(0,0,t.canvas.width,t.canvas.height),t.shadowOffsetX=e._boxShadow.x,t.shadowOffsetY=e._boxShadow.y,t.shadowBlur=e._boxShadow.blur,t.shadowColor=e._boxShadow.color,e._borderWidth>0&&(t.fillStyle=e._borderColor,e._roundedRect(t,e.shadowL,e.shadowT,n-a,r-l,i),t.fill(),t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0),e._drawTextBox((function(){t.shadowOffsetX=0,t.shadowOffsetY=0,t.shadowBlur=0;var s=e._clipText(),u=e._padding+e._borderWidth+e.shadowT;if(e._selection[1]>0){var c=e._textWidth(s.substring(0,e._selection[0])),d=e._textWidth(s.substring(e._selection[0],e._selection[1]));t.fillStyle=e._selectionColor,t.fillRect(u+c,u,d,e._height)}if(t.fillStyle=e._placeHolder===e._value&&""!==e._value?e._placeHolderColor:e._fontColor,e._cursor){var f=e._textWidth(s.substring(0,e._cursorPos));t.fillRect(u+f,u,1,e._height)}var h=e._padding+e._borderWidth+e.shadowL,p=Math.round(u+e._height/2);t.font=e._fontStyle+" "+e._fontWeight+" "+e._fontSize+"px "+e._fontFamily,t.textAlign="left",t.textBaseline="middle",t.fillText(s,h,p);var m=e._innerShadow.split("px "),x="none"===e._innerShadow?0:parseInt(m[0],10),y="none"===e._innerShadow?0:parseInt(m[1],10),v="none"===e._innerShadow?0:parseInt(m[2],10),g="none"===e._innerShadow?"":m[3];if(v>0){var b=e._shadowCtx,_=b.canvas.width,w=b.canvas.height;b.clearRect(0,0,_,w),b.shadowBlur=v,b.shadowColor=g,b.shadowOffsetX=0,b.shadowOffsetY=y,b.fillRect(-1*n,-100,3*n,100),b.shadowOffsetX=x,b.shadowOffsetY=0,b.fillRect(_,-1*r,100,3*r),b.shadowOffsetX=0,b.shadowOffsetY=y,b.fillRect(-1*n,w,3*n,100),b.shadowOffsetX=x,b.shadowOffsetY=0,b.fillRect(-100,-1*r,100,3*r),e._roundedRect(t,o+e.shadowL,o+e.shadowT,n-2*o-a,r-2*o-l,i),t.clip(),t.drawImage(e._shadowCanvas,0,0,_,w,o+e.shadowL,o+e.shadowT,_,w)}return e._ctx&&(e._ctx.clearRect(e._x,e._y,t.canvas.width,t.canvas.height),e._ctx.drawImage(e._renderCanvas,e._x,e._y)),e}))},_drawTextBox:function(e){var t=this,n=t._renderCtx,r=t.outerW,i=t.outerH,o=t._borderRadius,a=t._borderWidth,l=t.shadowW,s=t.shadowH;if(""===t._backgroundImage)n.fillStyle=t._backgroundColor,t._roundedRect(n,a+t.shadowL,a+t.shadowT,r-2*a-l,i-2*a-s,o),n.fill(),e();else{var u=new Image;u.src=t._backgroundImage,u.onload=function(){n.drawImage(u,0,0,u.width,u.height,a+t.shadowL,a+t.shadowT,r,i),e()}}},_clearSelection:function(){if(this._selection[1]>0){var e=this._selection[0],t=this._selection[1];return this._value=this._value.substr(0,e)+this._value.substr(t),this._cursorPos=e,this._cursorPos=this._cursorPos<0?0:this._cursorPos,this._selection=[0,0],!0}return!1},_clipText:function(e){e=void 0===e?this._value:e;var t=this._textWidth(e)/(this._width-this._padding);return(t>1?e.substr(-1*Math.floor(e.length/t)):e)+""},_textWidth:function(e){var t=this._renderCtx;return t.font=this._fontStyle+" "+this._fontWeight+" "+this._fontSize+"px "+this._fontFamily,t.textAlign="left",t.measureText(e).width},_calcWH:function(){this.outerW=this._width+2*this._padding+2*this._borderWidth+this.shadowW,this.outerH=this._height+2*this._padding+2*this._borderWidth+this.shadowH},_updateCanvasWH:function(){var e=this._renderCanvas.width,t=this._renderCanvas.height;this._renderCanvas.setAttribute("width",this.outerW),this._renderCanvas.setAttribute("height",this.outerH),this._shadowCanvas.setAttribute("width",this._width+2*this._padding),this._shadowCanvas.setAttribute("height",this._height+2*this._padding),this._ctx&&this._ctx.clearRect(this._x,this._y,e,t)},_roundedRect:function(e,t,n,r,i,o){r<2*o&&(o=r/2),i<2*o&&(o=i/2),e.beginPath(),e.moveTo(t+o,n),e.lineTo(t+r-o,n),e.quadraticCurveTo(t+r,n,t+r,n+o),e.lineTo(t+r,n+i-o),e.quadraticCurveTo(t+r,n+i,t+r-o,n+i),e.lineTo(t+o,n+i),e.quadraticCurveTo(t,n+i,t,n+i-o),e.lineTo(t,n+o),e.quadraticCurveTo(t,n,t+o,n),e.closePath()},_overInput:function(e,t){var n=e>=this._x+this._extraX,r=e<=this._x+this._extraX+this._width+2*this._padding,i=t>=this._y+this._extraY,o=t<=this._y+this._extraY+this._height+2*this._padding;return n&&r&&i&&o},_clickPos:function(e,t){var n=this._value;this._value===this._placeHolder&&(n="");var r=this._clipText(n),i=0,o=r.length;if(e-(this._x+this._extraX)=e-(this._x+this._extraX)){o=a;break}return o},_mousePos:function(e){var t=e.target,n=document.defaultView.getComputedStyle(t,void 0),r=parseInt(n.paddingLeft,10)||0,i=parseInt(n.paddingLeft,10)||0,o=parseInt(n.borderLeftWidth,10)||0,a=parseInt(n.borderLeftWidth,10)||0,l=document.body.parentNode.offsetTop||0,s=document.body.parentNode.offsetLeft||0,u=0,c=0;if("unefined"!=typeof t.offsetParent)do{u+=t.offsetLeft,c+=t.offsetTop}while(t=t.offsetParent);return u+=r+o+s,c+=i+a+l,{x:e.pageX-u,y:e.pageY-c}},_mapCodeToKey:function(e,t){for(var n=[8,9,13,16,17,18,20,27,91,92],r=0;r=65&&t<=90?String.fromCharCode(t):{32:" ",48:")",49:"!",50:"@",51:"#",52:"$",53:"%",54:"^",55:"&",56:"*",57:"(",59:":",107:"+",173:"_",189:"_",186:":",187:"+",188:"<",190:">",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'}[t]:t>=65&&t<=90?String.fromCharCode(t).toLowerCase():96===t?"0":97===t?"1":98===t?"2":99===t?"3":100===t?"4":101===t?"5":102===t?"6":103===t?"7":104===t?"8":105===t?"9":188===t?",":190===t?".":191===t?"/":192===t?"`":220===t?"\\":187===t?"=":189===t||173===t?"-":222===t?"'":186===t?";":219===t?"[":221===t?"]":String.fromCharCode(t)}},e.exports=r},function(e,t,n){var r,i;r=n(6),(i=function(e,t,n){this.options={itemClass:"sigplot-menu-item"},r.update(this.options,n),this._Mx=e,this._container=e.root,this._menu=document.createElement("div");var i="z-index:2;float:left;position:relative;left:"+e.xpos+"px;top:"+e.ypos+"px;";this._menu.classList.add("sigplot-menu");var o=new Date;this._menuId="menu-"+o.getSeconds()+o.getMilliseconds(),this._menu.classList.add(this._menuId),this._menu.style=i,this._items=[],this.setCSS(),this.createMenu(t)}).prototype={createMenu:function(e){var t=this,n=this._Mx,r=e.finalize;e.finalize=function(){t.remove(),r()},this.finalize=e.finalize;var i=document.createElement("div");i.addEventListener("mousedown",(function(e){e.preventDefault(),t._movingOffsetX=e.offsetX,t._movingOffsetY=e.offsetY,t._moving=!0})),i.addEventListener("mouseup",(function(e){e.preventDefault(),t._moving=!1})),t._moveMenu=function(e){t._moving&&(t._menu.style.position="fixed",t._menu.style.top=e.clientY-t._movingOffsetY+"px",t._menu.style.left=e.clientX-t._movingOffsetX+"px")},document.body.addEventListener("mousemove",t._moveMenu),i.classList.add("sigplot-menu-title"),i.innerText=e.title,this._menu.append(i);var o=document.createElement("ul");o.classList.add("sigplot-menu-list"),e.items.forEach((function(n){var r=t._createMenuItem(n,e);o.append(r)})),this._menu.append(o),this._container.append(this._menu),this._menu.addEventListener("contextmenu",(function(e){e.preventDefault(),t.finalize()})),n.menu=this,n.widget={type:"MENU",callback:function(e){"mousedown"===e.type&&(1!==e.which&&2!==e.which&&3!==e.which||(t._Mx.menu!==t||e.target.classList.contains(t.options.itemClass)||t.finalize(),t._Mx.menu||t.finalize())),"mouseup"===e.type&&(t._moving=!1),"keydown"===e.type&&t._handleKeyEvents(e)}}},_handleKeyEvents:function(e){if("ArrowDown"===e.key)if(e.preventDefault(),this._active){if((t=this._items.indexOf(this._active)+1)>this._items.length-1)return;this._setActive(this._items[t])}else this._setActive(this._items[0]);if("ArrowUp"===e.key)if(e.preventDefault(),this._active){var t;if((t=this._items.indexOf(this._active)-1)<0)return;this._setActive(this._items[t])}else this._setActive(this._items[0]);if("Enter"===e.key){e.preventDefault(),this._active||this._setActive(this._items[0]);var n=this._active;n.onclick?n.onclick():n.click&&n.click()}},_setActive:function(e){this._active&&this._clearActive(),this._active=e,e.classList.add("active")},_clearActive:function(){this._active.classList.remove("active"),this._active=null},_createMenuItem:function(e,t){var n=this,r=this._Mx,o=document.createElement("li");return o.className+=" "+n.options.itemClass,o.innerText=e.text,e.style&&(o.className+=" "+e.style),e.hasOwnProperty("checked")&&(o.className+=" sigplot-menu-checkbox",e.checked&&(o.className+=" checked")),o.addEventListener("click",(function(){if(n.remove(),r.menu=void 0,r.widget=null,e.handler)e.handler();else if(e.menu){var o=e.menu;"function"==typeof e.menu&&(o=e.menu()),o.finalize=t.finalize,new i(r,o)}!r.menu&&t.finalize&&t.finalize()})),o.addEventListener("mouseenter",(function(e){n._setActive(e.target)})),o.addEventListener("mouseleave",(function(e){n._clearActive()})),n._items.push(o),o},remove:function(){var e=this._Mx;e.menu=void 0,e.widget=null,this._menu.remove(),document.body.removeEventListener("mousemove",this._moveMenu)},setCSS:function(){var e,t,n=this._Mx;(t=document.createElement("style")).id="mx-menu-css",e="."+this._menuId+"{\nbackground-color: "+n.xwbg+";\nfont: "+n.font.font+";\ncolor:"+n.xwfg+"\n} \n.sigplot-menu-list {\n margin: 0px;\n list-style: none;\n padding: 0px;\n}\n."+this._menuId+">div {\n cursor: move;\n text-align: center;\n border-bottom: 2px solid "+n.xwts+";\n}\n."+this._menuId+">ul>li{\n border-top: 2px solid "+n.bg+";\n background-color: "+n.xwlo+";\n padding: 1px;\n padding-right: 5px;\n padding-left: 5px;\n cursor:default;\n}\n."+this._menuId+">ul>li.active{\n background-color: "+n.hi+";\n}\n."+this._menuId+" {\n position: relative;\n color: white;\n float: left;\n border-radius: 5px;\n padding: 3px;\n font: "+n.font.font+";\n color:"+n.xwfg+"\n}\n."+this._menuId+">ul>li.separator {\n background-color: "+n.xwbs+";\n}\n.sigplot-menu-checkbox:before{\n margin-right: 3px; \n}\n.sigplot-menu-checkbox.checked:before {\n content: '\\25b8';\n width: 2px;\n height: 3px;\n}\n.sigplot-menu-checkbox.checkbox:before {\n content: '\\25A1';\n width: 2px;\n height: 3px;\n}\n.sigplot-menu-checkbox.checkbox.checked:before {\n content: '\\25A3';\n width: 2px;\n height: 3px;\n}\n",this._container.getElementsByTagName("style").length?(t=this._container.getElementsByTagName("style")[0]).textContent=e:((t=document.createElement("style")).textContent=e,this._container.appendChild(t))}},e.exports=i},function(e,t,n){ -/** - * @license - * File: sigplot.layer1d.js - * Copyright (c) 2012-2017, LGS Innovations Inc., All rights reserved. - * - * This file is part of SigPlot. - * - * Licensed to the LGS Innovations (LGS) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. LGS licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -!function(){var t=n(5),r=n(7),i=function(e){this.plot=e,this.xbuf=void 0,this.ybuf=void 0,this.offset=0,this.xstart=0,this.xdelta=0,this.imin=0,this.xmin=0,this.xmax=0,this.name="",this.cx=!1,this.hcb=void 0,this.size=0,this.display=!0,this.color=0,this.line=3,this.thick=1,this.symbol=0,this.radius=3,this.skip=0,this.xsub=0,this.ysub=0,this.xdata=!1,this.modified=!1,this.opacity=1,this.fillStyle=null,this.preferred_origin=1,this.pointbufsize=0,this.xptr=null,this.yptr=null,this.xpoint=null,this.ypoint=null,this.options={}};i.prototype={init:function(e,n){this.plot._Gx;if(this.hcb=e,this.hcb.buf_type="D",this.offset=0,this.size=0,this.xbufn=0,this.ybufn=0,this.hcb.pipe?2===e.class&&(t.force1000(e),this.size=e.subsize):2===e.class?(t.force1000(e),this.size=e.subsize):this.size=e.size,n.framesize&&(this.size=n.framesize),this.hcb.pipe&&!this.size)throw"1D layer could not determine appropriate size for pipe, use framesize option";e.class<=2&&(this.xsub=-1,this.ysub=1,this.cx="C"===e.format[0]),this.skip=1,this.cx&&(this.skip=2),this.xstart=e.xstart,this.xdelta=e.xdelta;var r=e.xstart+e.xdelta*(this.size-1);if(this.xmin=Math.min(e.xstart,r),this.xmax=Math.max(e.xstart,r),this.xlab=e.xunits,this.ylab=e.yunits,this.hcb.pipe){this.drawmode="scrolling",this.position=0,this.tle=n.tl,this.ybufn=this.size*Math.max(this.skip*t.PointArray.BYTES_PER_ELEMENT,t.PointArray.BYTES_PER_ELEMENT),this.ybuf=new ArrayBuffer(this.ybufn);var i=this;t.addPipeWriteListener(this.hcb,(function(){i._onpipewrite()}))}},_onpipewrite:function(){var e=new t.PointArray(this.ybuf),n=this.tle;void 0===n&&(n=Math.floor(t.pavail(this.hcb))/this.hcb.spa);for(var r=n*this.hcb.spa;t.pavail(this.hcb)>=r;){if("lefttoright"===this.drawmode)this.position=0,e.set(e.subarray(0,this.size-r),r);else if("righttoleft"===this.drawmode)this.position=this.size-n,e.set(e.subarray(r),0);else if("scrolling"!==this.drawmode)throw"Invalid draw mode";if(0===t.grabx(this.hcb,e,Math.min(n,this.size-this.position)*this.hcb.spa,this.position*this.hcb.spa))break;this.position=(this.position+n)%this.size,void 0===this.tle&&(n=Math.floor(t.pavail(this.hcb))/this.hcb.spa),r=n*this.hcb.spa}0!==this.plot._Gx.autol&&this.plot.rescale()},get_data:function(e,n){var r,i=this.plot._Gx,o=this.hcb,a=this.skip;r=2===o.class?o.subsize:o.size;var l=0,s=0;i.index?(l=Math.floor(e),s=Math.floor(n+.5)):o.xdelta>=0?(l=Math.floor((e-o.xstart)/o.xdelta)-1,s=Math.floor((n-o.xstart)/o.xdelta+.5)):(l=Math.floor((n-o.xstart)/o.xdelta)-1,s=Math.floor((e-o.xstart)/o.xdelta+.5)),l=Math.max(0,l),s=Math.min(r,s);var u=Math.max(0,Math.min(s-l+1,i.bufmax));if(o.xdelta<0&&(l=s-u+1),l>=this.imin&&l+u<=this.imin+this.size&&void 0!==this.ybuf);else if(this.modified);else if(o.class<=2){var c=this.offset+l;a=this.skip;this.ybufn=u*Math.max(a*t.PointArray.BYTES_PER_ELEMENT,t.PointArray.BYTES_PER_ELEMENT),(void 0===this.ybuf||this.ybuf.byteLength0&&t.filad(this.hcb,e,r),!!n},prep:function(e,n){var r=this.plot._Gx,i=this.plot._Mx,o=Math.ceil(this.size),a=this.skip;if(0===o)return{num:0,start:0,end:0};o*t.PointArray.BYTES_PER_ELEMENT>this.pointbufsize&&(this.pointbufsize=o*t.PointArray.BYTES_PER_ELEMENT,this.xptr=new ArrayBuffer(this.pointbufsize),this.yptr=new ArrayBuffer(this.pointbufsize),this.xpoint=new t.PointArray(this.xptr),this.ypoint=new t.PointArray(this.yptr));var l,s,u,c=new t.PointArray(this.ybuf),d=this.xmin,f=this.xmax;if(5===r.cmode||this.xsub>0)o<=0?(d=r.panxmin,f=r.panxmax):5!==r.cmode?this.xpoint=new t.PointArray(this.xbuf):this.cx?t.vmov(c,a,this.xpoint,1,o):0!==this.line?(u=t.vmxmn(c,o),this.xpoint[0]=u.smax,this.xpoint[1]=u.smin,l=0,s=2,o=2):this.xpoint=c,o>0&&(f=(u=t.vmxmn(this.xpoint,o)).smax,d=u.smin,l=0,s=o);else if(o>0){var h=this.xstart,p=this.xdelta,m=o;r.index?(l=0,s=o-1):p>=0?(l=Math.max(1,Math.min(m,Math.round((e-h)/p)))-1,s=Math.max(1,Math.min(m,Math.round((n-h)/p)+2))-1):(l=Math.max(1,Math.min(m,Math.round((n-h)/p)-1))-1,s=Math.max(1,Math.min(m,Math.round((e-h)/p)+2))-1),(o=s-l+1)<0&&(t.log.debug("Nothing to plot"),o=0),c=new t.PointArray(this.ybuf).subarray(l*a),h+=p*l;for(var x=0;xr.panxmax?(r.panxmin=d,r.panxmax=f):(r.panxmin=Math.min(r.panxmin,d),r.panxmax=Math.max(r.panxmax,f)),o<=0)return t.log.debug("Nothing to plot"),{num:o,start:l,end:s};if(this.cx)1===r.cmode?t.cvmag(c,this.ypoint,o):2===r.cmode?25===r.plab?(t.cvpha(c,this.ypoint,o),t.vsmul(this.ypoint,1/(2*Math.PI),this.ypoint,o)):24!==r.plab?t.cvpha(c,this.ypoint,o):t.cvphad(c,this.ypoint,o):3===r.cmode?t.vmov(c,a,this.ypoint,1,o):r.cmode>=6?t.cvmag2(c,this.ypoint,o):r.cmode>=4&&t.vmov(c.subarray(1),a,this.ypoint,1,o);else if(5===r.cmode)t.vfill(this.ypoint,0,o);else if(1===r.cmode||r.cmode>=6)for(x=0;x=6){t.vlog10(this.ypoint,r.dbmin,this.ypoint);var y=10;7===r.cmode&&(y=20),r.lyr.length>0&&r.lyr[0].cx&&(y/=2),t.vsmul(this.ypoint,y,this.ypoint)}var v=(f=(u=t.vmxmn(this.ypoint,o)).smax)-(d=u.smin);if(v<0&&(d=(f=d)+v,v=-v),v<=1e-20?(d-=1,f+=1):(d-=.02*v,f+=.02*v),0===i.level&&(r.panymin>r.panymax?(r.panymin=d,r.panymax=f):(r.panymin=Math.min(r.panymin,d),r.panymax=Math.max(r.panymax,f)),r.autol>1)){var g=1/Math.max(r.autol,1);r.panymin=r.panymin*g+i.stk[0].ymin*(1-g),r.panymax=r.panymax*g+i.stk[0].ymax*(1-g)}return{num:o,start:l,end:s}},draw:function(){var e=this.plot._Mx,n=this.plot._Gx,i=this.color,o=this.symbol,a=this.radius,l=0,s={};this.fillStyle?s.fillStyle=this.fillStyle:n.fillStyle&&(s.fillStyle=n.fillStyle),this.options&&(s.highlight=this.options.highlight,s.noclip=this.options.noclip),0===this.line?l=0:(l=1,this.thick>0?l=this.thick:this.thick<0&&(l=Math.abs(this.thick),s.dashed=!0),1===this.line&&(s.vertsym=!0),2===this.line&&(s.horzsym=!0),4===this.line&&(s.horzsym=!0,s.vertsym=!0));var u,c,d=n.segment&&5!==n.cmode&&this.xsub>0&&!0,f=this.xdelta;if(this.xdata?(u=this.xmin,c=this.xmax):(u=Math.max(this.xmin,e.stk[e.level].xmin))>=(c=Math.min(this.xmax,e.stk[e.level].xmax))&&(n.panxmin=Math.min(n.panxmin,this.xmin),n.panxmax=Math.max(n.panxmax,this.xmax)),!n.all){var h=(n.bufmax-1)*f;h>=-0?c=Math.min(c,u+h):u=Math.max(u,c+h)}if(0!==l||0!==o){for(;u0&&(d||r.trace(e,i,new t.PointArray(this.xptr),new t.PointArray(this.yptr),p.num,p.start,1,l,o,a,s)),n.all?0===this.size?u=c:n.index?u+=p.num:f>=0?u+=this.size*f:c+=this.size*f:u=c}if(this.position&&"scrolling"===this.drawmode){var m=r.real_to_pixel(e,this.position*this.xdelta,0);m.x>e.l&&m.x0){var c=n.size/n.subsize;u=Math.min(c,16-l.lyr.length)}var d=a.name;delete a.name;for(var f=[],h=0;h=this.hcb.subsize*this.hcb.spa;){if("scrolling"!==this.drawmode&&(this.hcb.ystart+=this.hcb.ydelta,this.ystart=this.hcb.ystart,this.ymin=this.hcb.ystart-this.hcb.ydelta*this.lps,this.ymax=this.hcb.ystart),"falling"===this.drawmode)this.position=0,this.img&&i.shift_image_rows(t,this.img,1);else if("rising"===this.drawmode)this.position=this.lps-1,this.img&&i.shift_image_rows(t,this.img,-1);else{if("scrolling"!==this.drawmode)throw"Invalid draw mode";var n=Math.abs(this.ymax-this.ymin);this.ystart=0,this.ymin=0,this.ymax=n,this.position>=this.lps&&(this.position=0)}if(!this.buf)return;if(0===r.grabx(this.hcb,this.buf,this.hcb.subsize*this.hcb.spa))return void r.log.error("Internal error");var o=new r.PointArray(this.hcb.subsize);this.cx?1===e.cmode?r.cvmag(this.buf,o,o.length):2===e.cmode?25===e.plab?(r.cvpha(this.buf,o,o.length),r.vsmul(o,1/(2*Math.PI),o,o.length)):24!==e.plab?r.cvpha(this.buf,o,o.length):r.cvphad(this.buf,o,o.length):3===e.cmode?r.vmov(this.buf,this.skip,o,1,o.length):4===e.cmode?r.vmov(this.buf.subarray(1),this.skip,o,1,o.length):5===e.cmode?r.vfill(o,0,o.length):6===e.cmode?r.cvmag2logscale(this.buf,e.dbmin,10,o):7===e.cmode&&r.cvmag2logscale(this.buf,e.dbmin,20,o):1===e.cmode?r.vabs(this.buf,o):2===e.cmode?r.vfill(o,0,o.length):3===e.cmode?r.vmov(this.buf,this.skip,o,1,o.length):4===e.cmode||5===e.cmode?r.vfill(o,0,o.length):6===e.cmode?r.vlogscale(this.buf,e.dbmin,10,o):7===e.cmode&&r.vlogscale(this.buf,e.dbmin,20,o);for(var a,l,s=o[0],u=o[0],c=0;cu&&(u=o[c]);if(1===e.autol)a=s,l=u;else if(e.autol>1){var d=1/Math.max(e.autol,1);a=e.zmin*d+s*(1-d),l=e.zmax*d+u*(1-d)}else e.autol<0&&(d=1/Math.max(5,1),a=e.zmin*d+s*(1-d),l=e.zmax*d+u*(1-d));if(0!=(1&e.autoz)&&(e.zmin=a),0!=(2&e.autoz)&&(e.zmax=l),e.p_cuts){if("scrolling"===this.drawmode){var f=this.position*this.hcb.subsize,h=f+this.hcb.subsize,p=0;for(c=f;c0&&r.filad(this.hcb,e,n),o},prep:function(e,t){var n,o,a=this.plot._Gx,l=this.plot._Mx,s=this.lps,u=(this.skip,this.xmin),c=this.xmax,d=this.hcb.subsize;if(this.xcompression>0&&(d=Math.min(this.hcb.subsize,Math.ceil(l.r-l.l))),this.get_data(e,t),this.hcb.pipe)a.panxmin>a.panxmax?(a.panxmin=u,a.panxmax=c):(a.panxmin=Math.min(a.panxmin,u),a.panxmax=Math.max(a.panxmax,c)),a.panymin>a.panxmax?(a.panymin=this.ymin,a.panymax=this.ymax):(a.panymin=Math.min(a.panymin,this.ymin),a.panymax=Math.max(a.panymax,this.ymax)),this.img||(void 0===a.zmin&&(a.zmin=0),void 0===a.zmax&&(a.zmax=0),this.img=i.create_image(l,null,this.hcb.subsize,d,this.lps,a.zmin+a.zoff,a.zmax+a.zoff,this.xcompression));else{if(5===a.cmode||this.xsub>0);else if(s>0){var f=this.xstart,h=this.xdelta,p=s;a.index?(n=0,o=s-1):h>=0?(n=Math.max(1,Math.min(p,Math.round((e-f)/h)))-1,o=Math.max(1,Math.min(p,Math.round((t-f)/h)+2))-1):(n=Math.max(1,Math.min(p,Math.round((t-f)/h)-1))-1,o=Math.max(1,Math.min(p,Math.round((e-f)/h)+2))-1),(s=o-n+1)<0&&(r.log.debug("Nothing to plot"),s=0)}if(a.panxmin>a.panxmax?(a.panxmin=u,a.panxmax=c):(a.panxmin=Math.min(a.panxmin,u),a.panxmax=Math.max(a.panxmax,c)),s<=0)return void r.log.debug("Nothing to plot");if(5===a.cmode||this.ysub>0);else if(s>0){var m=this.ystart,x=this.ydelta;p=s,a.index?(n=0,o=s-1):x>=0?(n=Math.max(1,Math.min(p,Math.round((e-m)/x)))-1,o=Math.max(1,Math.min(p,Math.round((t-m)/x)+2))-1):(n=Math.max(1,Math.min(p,Math.round((t-m)/x)-1))-1,o=Math.max(1,Math.min(p,Math.round((e-m)/x)+2))-1),(s=o-n+1)<0&&(r.log.debug("Nothing to plot"),s=0)}a.panymin>a.panymax?(a.panymin=this.ymin,a.panymax=this.ymax):(a.panymin=Math.min(a.panymin,this.ymin),a.panymax=Math.max(a.panymax,this.ymax)),this.cx?1===a.cmode?r.cvmag(this.buf,this.zbuf,this.zbuf.length):2===a.cmode?25===a.plab?(r.cvpha(this.buf,this.zbuf,this.zbuf.length),r.vsmul(this.zbuf,1/(2*Math.PI),this.zbuf,this.zbuf.length)):24!==a.plab?r.cvpha(this.buf,this.zbuf,this.zbuf.length):r.cvphad(this.buf,this.zbuf,this.zbuf.length):3===a.cmode?r.vmov(this.buf,this.skip,this.zbuf,1,this.zbuf.length):4===a.cmode?r.vmov(this.buf.subarray(1),this.skip,this.zbuf,1,this.zbuf.length):5===a.cmode?r.vfill(this.zbuf,0,this.zbuf.length):6===a.cmode?r.cvmag2logscale(this.buf,a.dbmin,10,this.zbuf):7===a.cmode&&r.cvmag2logscale(this.buf,a.dbmin,20,this.zbuf):1===a.cmode?r.vabs(this.buf,this.zbuf):2===a.cmode?r.vfill(this.zbuf,0,this.zbuf.length):3===a.cmode?r.vmov(this.buf,this.skip,this.zbuf,1,this.zbuf.length):4===a.cmode||5===a.cmode?r.vfill(this.zbuf,0,this.zbuf.length):6===a.cmode?r.vlogscale(this.buf,a.dbmin,10,this.zbuf):7===a.cmode&&r.vlogscale(this.buf,a.dbmin,20,this.zbuf);var y=this.zbuf,v=0,g=0;if(a.autol<=0||this.hcb.pipe){if(y.length>0){v=y[0],g=y[0];for(var b=0;b=this.lpb);b++)y[b]g&&(g=y[b])}0!=(1&a.autoz)&&(void 0!==a.zmin?a.zmin=Math.min(a.zmin,v):a.zmin=v),0!=(2&a.autoz)&&(void 0!==a.zmax?a.zmax=Math.min(a.zmax,g):a.zmax=g),this.img=i.create_image(l,this.zbuf,this.hcb.subsize,d,this.lps,a.zmin+a.zoff,a.zmax+a.zoff,this.xcompression)}else{var _=this.hcb.size,w=1/Math.max(a.autol,1);if(this.img||(this.img=i.create_image(l,this.zbuf,this.hcb.subsize,d,this.lps,a.zmin+a.zoff,a.zmax+a.zoff)),a.zmin=0,a.zmax=0,y.length>0)for(var k=0;k<_;k++){var M=k*this.xframe;for(v=y[M],g=y[M],b=0;b=this.lps&&(this.position=0),"scrolling"===this.drawmode){var a=n.ystart+n.ydelta*this.lps;this.ymin=Math.min(n.ystart,a),this.ymax=Math.max(n.ystart,a),this.img=i.resize_image_height(e,this.img,this.lps)}else"falling"===this.drawmode?(this.ymax=this.ymin+n.ydelta*this.lps,this.img=i.resize_image_height(e,this.img,this.lps)):"rising"===this.drawmode&&(this.ymin=this.ymax-n.ydelta*this.lps,o>0?(this.img=i.resize_image_height(e,this.img,this.lps),i.shift_image_rows(e,this.img,o,!0)):(i.shift_image_rows(e,this.img,o,!0),this.img=i.resize_image_height(e,this.img,this.lps)));this.plot.rescale()}}var l=Math.max(this.xmin,e.stk[e.level].xmin),s=Math.min(this.xmax,e.stk[e.level].xmax);if(l>=s)return t.panxmin=Math.min(t.panxmin,this.xmin),void(t.panxmax=Math.max(t.panxmax,this.xmax));var u=Math.max(this.ymin,e.stk[e.level].ymin),c=Math.min(this.ymax,e.stk[e.level].ymax),d=Math.abs(s-l)+1,f=Math.abs(c-u)+1;d=Math.floor(d/n.xdelta),f=Math.floor(f/n.ydelta),d=Math.min(d,n.subsize),f=Math.min(f,n.size);var h=i.real_to_pixel(e,l,u),p=i.real_to_pixel(e,s,c),m=(p.x-h.x)/d,x=(p.y-h.y)/f;if(t.xe=Math.max(1,Math.round(m)),t.ye=Math.max(1,Math.round(x)),this.img&&this.buf&&t.cmode===this.img.cmode&&e.origin===this.img.origin||this.prep(l,s),this.img&&i.draw_image(e,this.img,this.xmin,this.ymin,this.xmax,this.ymax,this.opacity,t.rasterSmoothing,this.downscale),null!==this.position&&"scrolling"===this.drawmode){var y=i.real_to_pixel(e,0,this.position*this.ydelta);y.y>e.t&&y.y=0&&n<=i.b}}function I(e){return function(t){return null==t?void 0:t[e]}}var R=I("byteLength"),D=N(R),G=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var B=i.r?function(e){return i.l?Object(i.l)(e)&&!S(e):D(e)&&G.test(i.t.call(e))}:O(!1),U=I("length");function F(e,t){t=function(e){for(var t={},n=e.length,r=0;r":">",'"':""","'":"'","`":"`"},Be=De(Ge),Ue=De(ue(Ge)),Fe=Y.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},He=/(.)^/,We={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},je=/\\|'|\r|\n|\u2028|\u2029/g;function Ye(e){return"\\"+We[e]}function Xe(e,t,n){!t&&n&&(t=n),t=pe({},t,Y.templateSettings);var r,i=RegExp([(t.escape||He).source,(t.interpolate||He).source,(t.evaluate||He).source].join("|")+"|$","g"),o=0,a="__p+='";e.replace(i,(function(t,n,r,i,l){return a+=e.slice(o,l).replace(je,Ye),o=l+t.length,n?a+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":r?a+="'+\n((__t=("+r+"))==null?'':__t)+\n'":i&&(a+="';\n"+i+"\n__p+='"),t})),a+="';\n",t.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{r=new Function(t.variable||"obj","_",a)}catch(e){throw e.source=a,e}var l=function(e){return r.call(this,e,Y)},s=t.variable||"obj";return l.source="function("+s+"){\n"+a+"}",l}function Ve(e,t,n){var r=(t=be(t)).length;if(!r)return _(n)?n.call(e):n;for(var i=0;i1)nt(l,t-1,n,r),i=r.length;else for(var s=0,u=l.length;st?(r&&(clearTimeout(r),r=null),l=u,a=e.apply(i,o),r||(i=o=null)):r||!1===n.trailing||(r=setTimeout(s,c)),a};return u.cancel=function(){clearTimeout(r),l=0,r=i=o=null},u}function st(e,t,n){var r,i,a=function(t,n){r=null,n&&(i=e.apply(t,n))},l=o((function(o){if(r&&clearTimeout(r),n){var l=!r;r=setTimeout(a,t),l&&(i=e.apply(this,o))}else r=ot(a,t,this,o);return i}));return l.cancel=function(){clearTimeout(r),r=null},l}function ut(e,t){return Je(t,e)}function ct(e){return function(){return!e.apply(this,arguments)}}function dt(){var e=arguments,t=e.length-1;return function(){for(var n=t,r=e[t].apply(this,arguments);n--;)r=e[n].call(this,r);return r}}function ft(e,t){return function(){if(--e<1)return t.apply(this,arguments)}}function ht(e,t){var n;return function(){return--e>0&&(n=t.apply(this,arguments)),e<=1&&(t=null),n}}var pt=Je(ht,2);function mt(e,t,n){t=Pe(t,n);for(var r,i=H(e),o=0,a=i.length;o0?0:i-1;o>=0&&o0?l=a>=0?a:Math.max(a+s,l):s=a>=0?Math.min(a+1,s):a+s+1;else if(n&&a&&s)return r[a=n(r,o)]===o?a:-1;if(o!=o)return(a=t(i.q.call(r,l,s),L))>=0?a+l:-1;for(a=e>0?l:s-1;a>=0&&a0?0:a-1;for(i||(r=t[o?o[l]:l],l+=e);l>=0&&l=3;return t(e,Te(n,i,4),r,o)}}var Ct=Tt(1),At=Tt(-1);function Pt(e,t,n){var r=[];return t=Pe(t,n),Et(e,(function(e,n,i){t(e,n,i)&&r.push(e)})),r}function zt(e,t,n){return Pt(e,ct(Pe(t)),n)}function Lt(e,t,n){t=Pe(t,n);for(var r=!tt(e)&&H(e),i=(r||e).length,o=0;o=0}var It=o((function(e,t,n){var r,i;return _(t)?i=t:(t=be(t),r=t.slice(0,-1),t=t[t.length-1]),St(e,(function(e){var o=i;if(!o){if(r&&r.length&&(e=_e(e,r)),null==e)return;o=e[t]}return null==o?o:o.apply(e,n)}))}));function Rt(e,t){return St(e,Se(t))}function Dt(e,t){return Pt(e,Ee(t))}function Gt(e,t,n){var r,i,o=-1/0,a=-1/0;if(null==t||"number"==typeof t&&"object"!=typeof e[0]&&null!=e)for(var l=0,s=(e=tt(e)?e:le(e)).length;lo&&(o=r);else t=Pe(t,n),Et(e,(function(e,n,r){((i=t(e,n,r))>a||i===-1/0&&o===-1/0)&&(o=e,a=i)}));return o}function Bt(e,t,n){var r,i,o=1/0,a=1/0;if(null==t||"number"==typeof t&&"object"!=typeof e[0]&&null!=e)for(var l=0,s=(e=tt(e)?e:le(e)).length;lr||void 0===n)return 1;if(n1&&(r=Te(r,t[1])),t=K(e)):(r=Qt,t=nt(t,!1,!1),e=Object(e));for(var i=0,o=t.length;i1&&(n=t[1])):(t=St(nt(t,!1,!1),String),r=function(e,n){return!Nt(t,n)}),Zt(e,r,n)}));function en(e,t,n){return i.q.call(e,0,Math.max(0,e.length-(null==t||n?1:t)))}function tn(e,t,n){return null==e||e.length<1?null==t||n?void 0:[]:null==t||n?e[0]:en(e,e.length-t)}function nn(e,t,n){return i.q.call(e,null==t||n?1:t)}function rn(e,t,n){return null==e||e.length<1?null==t||n?void 0:[]:null==t||n?e[e.length-1]:nn(e,Math.max(0,e.length-t))}function on(e){return Pt(e,Boolean)}function an(e,t){return nt(e,t,!1)}var ln=o((function(e,t){return t=nt(t,!0,!0),Pt(e,(function(e){return!Nt(t,e)}))})),sn=o((function(e,t){return ln(e,t)}));function un(e,t,n,r){u(t)||(r=n,n=t,t=!1),null!=n&&(n=Pe(n,r));for(var i=[],o=[],a=0,l=U(e);a