Full Code of stufreen/web-drum-sequencer for AI

master 84446c7aa128 cached
199 files
381.2 KB
125.4k tokens
331 symbols
1 requests
Download .txt
Showing preview only (429K chars total). Download the full file or copy to clipboard to get everything.
Repository: stufreen/web-drum-sequencer
Branch: master
Commit: 84446c7aa128
Files: 199
Total size: 381.2 KB

Directory structure:
gitextract_4_fwl4lt/

├── .circleci/
│   └── config.yml
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .prettierrc
├── CNAME
├── README.md
├── __mocks__/
│   ├── fileMock.js
│   └── styleMock.js
├── babel.config.js
├── index.html
├── manifest.json
├── package.json
├── public/
│   ├── assets/
│   │   └── icons/
│   │       └── browserconfig.xml
│   └── sw.js
├── src/
│   ├── __mocks__/
│   │   └── samples.config.js
│   ├── assets/
│   │   └── js/
│   │       ├── webaudio-controls.js
│   │       └── webcomponents-lite.js
│   ├── common/
│   │   ├── channels/
│   │   │   ├── channels.actions.js
│   │   │   ├── channels.constants.js
│   │   │   ├── channels.reducer.js
│   │   │   ├── channels.reducer.test.js
│   │   │   ├── channels.selectors.js
│   │   │   └── index.js
│   │   ├── index.js
│   │   ├── master/
│   │   │   ├── index.js
│   │   │   ├── master.actions.js
│   │   │   ├── master.constants.js
│   │   │   ├── master.reducer.js
│   │   │   ├── master.reducer.test.js
│   │   │   └── master.selectors.js
│   │   ├── notes/
│   │   │   ├── index.js
│   │   │   ├── notes.actions.js
│   │   │   ├── notes.constants.js
│   │   │   ├── notes.reducer.js
│   │   │   ├── notes.reducer.test.js
│   │   │   └── notes.selectors.js
│   │   ├── playbackSession/
│   │   │   ├── index.js
│   │   │   ├── playbackSession.actions.js
│   │   │   ├── playbackSession.constants.js
│   │   │   ├── playbackSession.reducer.js
│   │   │   ├── playbackSession.reducer.test.js
│   │   │   └── playbackSession.selectors.js
│   │   ├── presets/
│   │   │   ├── index.js
│   │   │   ├── presets.actions.js
│   │   │   ├── presets.constants.js
│   │   │   ├── presets.reducer.js
│   │   │   ├── presets.reducer.test.js
│   │   │   └── presets.selectors.js
│   │   ├── tempo/
│   │   │   ├── index.js
│   │   │   ├── tempo.actions.js
│   │   │   ├── tempo.constants.js
│   │   │   ├── tempo.reducer.js
│   │   │   ├── tempo.reducer.test.js
│   │   │   └── tempo.selectors.js
│   │   ├── userSamples/
│   │   │   ├── index.js
│   │   │   ├── userSamples.actions.js
│   │   │   ├── userSamples.constants.js
│   │   │   ├── userSamples.reducer.js
│   │   │   └── userSamples.selectors.js
│   │   └── window/
│   │       ├── index.js
│   │       ├── window.actions.js
│   │       ├── window.constants.js
│   │       ├── window.reducer.js
│   │       ├── window.reducer.test.js
│   │       └── window.selectors.js
│   ├── components/
│   │   ├── AddChannelButton/
│   │   │   ├── AddChannelButton.component.jsx
│   │   │   ├── AddChannelButton.container.js
│   │   │   └── index.js
│   │   ├── App.jsx
│   │   ├── BPMInput/
│   │   │   ├── BPMInput.component.jsx
│   │   │   ├── BPMInput.container.js
│   │   │   ├── BPMInput.selectors.js
│   │   │   └── index.js
│   │   ├── Branding.jsx
│   │   ├── Channel/
│   │   │   ├── Channel.component.jsx
│   │   │   ├── Channel.container.js
│   │   │   ├── Channel.selectors.js
│   │   │   ├── HitButton.component.jsx
│   │   │   ├── RemoveButton.component.jsx
│   │   │   └── index.js
│   │   ├── ChannelControls/
│   │   │   ├── ChannelControls.component.jsx
│   │   │   ├── ChannelControls.container.js
│   │   │   ├── ChannelControls.selectors.js
│   │   │   └── index.js
│   │   ├── ChannelHeader/
│   │   │   ├── ChannelHeader.component.jsx
│   │   │   ├── ChannelHeaderLabel.component.jsx
│   │   │   └── index.js
│   │   ├── ChannelList/
│   │   │   ├── ChannelList.component.jsx
│   │   │   ├── ChannelList.container.js
│   │   │   ├── ChannelList.selectors.js
│   │   │   └── index.js
│   │   ├── FancyButton.component.jsx
│   │   ├── FlashMessage/
│   │   │   ├── FlashMessage.component.jsx
│   │   │   ├── FlashMessage.container.js
│   │   │   ├── FlashMessage.selectors.js
│   │   │   └── index.js
│   │   ├── GithubLink.component.jsx
│   │   ├── InfoKnob.component.jsx
│   │   ├── InstallButton.jsx
│   │   ├── Knob.component.jsx
│   │   ├── LabelBox.jsx
│   │   ├── Logo.component.jsx
│   │   ├── Marker/
│   │   │   ├── Marker.component.jsx
│   │   │   ├── Marker.container.js
│   │   │   ├── Marker.selectors.js
│   │   │   └── index.js
│   │   ├── MasterControls/
│   │   │   ├── MasterControls.component.jsx
│   │   │   └── index.js
│   │   ├── Modal.component.jsx
│   │   ├── MuteSolo/
│   │   │   ├── MuteSolo.component.jsx
│   │   │   ├── MuteSolo.container.js
│   │   │   └── index.js
│   │   ├── PatternSelector/
│   │   │   ├── PatternSelector.component.jsx
│   │   │   ├── PatternSelector.container.js
│   │   │   ├── PatternSelector.selectors.js
│   │   │   └── index.js
│   │   ├── PlayButton/
│   │   │   ├── PlayButton.component.jsx
│   │   │   ├── PlayButton.container.js
│   │   │   ├── PlayButton.selectors.js
│   │   │   └── index.js
│   │   ├── PresetDeleted.component.jsx
│   │   ├── PresetSaved.component.jsx
│   │   ├── PresetSelector/
│   │   │   ├── PresetSelector.component.jsx
│   │   │   ├── PresetSelector.container.js
│   │   │   ├── PresetSelector.selectors.js
│   │   │   └── index.js
│   │   ├── SampleLoadError.component.jsx
│   │   ├── SampleSelect/
│   │   │   ├── SampleSelect.component.jsx
│   │   │   ├── SampleSelect.container.js
│   │   │   ├── SampleSelect.selectors.js
│   │   │   └── index.js
│   │   ├── SavePresetModal/
│   │   │   ├── SavePresetModal.component.jsx
│   │   │   ├── SavePresetModal.container.js
│   │   │   ├── SavePresetModal.selectors.js
│   │   │   └── index.js
│   │   ├── SwingControl/
│   │   │   ├── SwingControl.component.jsx
│   │   │   ├── SwingControl.container.js
│   │   │   ├── SwingControl.selectors.js
│   │   │   └── index.js
│   │   ├── Toggles/
│   │   │   ├── Toggle.component.jsx
│   │   │   ├── ToggleGroup.component.jsx
│   │   │   ├── Toggles.component.jsx
│   │   │   ├── Toggles.container.js
│   │   │   ├── Toggles.selectors.js
│   │   │   └── index.js
│   │   ├── VolumeMeter.component.jsx
│   │   ├── design-system/
│   │   │   ├── Box.js
│   │   │   ├── Button.js
│   │   │   ├── ControlLabel.js
│   │   │   ├── Form.js
│   │   │   ├── Heading.js
│   │   │   ├── HoverButton.js
│   │   │   ├── HoverLink.js
│   │   │   ├── Image.js
│   │   │   ├── Label.js
│   │   │   ├── Line.js
│   │   │   ├── Text.js
│   │   │   ├── TextInput.js
│   │   │   └── index.js
│   │   ├── index.js
│   │   └── timedCallback.hoc.jsx
│   ├── index.html
│   ├── index.jsx
│   ├── presets/
│   │   ├── 707.js
│   │   ├── 808.js
│   │   ├── __mocks__/
│   │   │   └── index.js
│   │   ├── ace.js
│   │   ├── empty.js
│   │   ├── hip-hop.js
│   │   ├── index.js
│   │   └── ldrum.js
│   ├── reducer.js
│   ├── samples.config.js
│   ├── services/
│   │   ├── __mocks__/
│   │   │   ├── audioContext.js
│   │   │   ├── audioRouter.js
│   │   │   └── featureChecks.js
│   │   ├── animations.js
│   │   ├── audioAnalyzer.js
│   │   ├── audioContext.js
│   │   ├── audioContext.test.js
│   │   ├── audioEngine.config.js
│   │   ├── audioLoop.js
│   │   ├── audioRouter.js
│   │   ├── audioScheduler.js
│   │   ├── audioScheduler.test.js
│   │   ├── database.js
│   │   ├── featureChecks.js
│   │   ├── fileUtils.js
│   │   ├── pwaInstall.js
│   │   ├── reverb.js
│   │   ├── sampleStore.js
│   │   ├── swing.js
│   │   ├── unmute.js
│   │   └── uuid.js
│   ├── store.js
│   └── styles/
│       ├── globalStyles.js
│       └── theme.js
└── vite.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: cimg/node:16.13.2

      # Specify service dependencies here if necessary
      # CircleCI maintains a library of pre-built images
      # documented at https://circleci.com/docs/2.0/circleci-images/
      # - image: circleci/mongo:3.4.4

    working_directory: ~/repo

    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "package.json" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run: npm install

      - run: npm run build

      - persist_to_workspace:
          root: ~/repo
          paths:
            - dist

      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}

  test:
    docker:
      - image: cimg/node:16.13.2
    working_directory: ~/repo
    steps:
      - checkout

      # Download and cache dependencies
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "package.json" }}
            # fallback to using the latest cache if no exact match is found
            - v1-dependencies-

      - run: npm install
      - run:
          name: Test
          command: npm run test
      - run:
          name: Lint
          command: npm run lint

      # run tests!
      #- run: yarn test
  deploy:
    docker:
      - image: circleci/python:2.7-jessie
    working_directory: ~/repo
    steps:
      - attach_workspace:
          # Must be absolute path or relative path from working_directory
          at: ~/repo
      - run:
          name: Install awscli
          command: sudo pip install awscli
      - run:
          name: Deploy to S3
          command: aws s3 sync --acl public-read ~/repo/dist s3://wds-1.com/ --delete

workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - test:
          requires:
            - build
      - deploy:
          requires:
            - test
          filters:
            branches:
              only: master


================================================
FILE: .eslintignore
================================================
src/assets/**/*.js

================================================
FILE: .eslintrc
================================================
{
  "extends": ["eslint:recommended", "plugin:react/recommended"],
  "env": {
    "browser": true,
    "jest": true,
    "es6": true
  },
  "rules": {
    "import/prefer-default-export": 0,
    "global-require": 0,
    "jsx-a11y/label-has-for": [0],
    "jsx-a11y/label-has-associated-control": [0],
    "default-param-last": 0,
    "implicit-arrow-linebreak": 0
  },
  "parser": "@babel/eslint-parser"
}


================================================
FILE: .gitignore
================================================
node_modules
.vscode
.DS_Store
dist/*

================================================
FILE: .prettierrc
================================================
{
  "trailingComma": "all",
  "singleQuote": true
}

================================================
FILE: CNAME
================================================
wds-1.com

================================================
FILE: README.md
================================================
# Web Drum Sequencer

A browser-based drum machine and sequencer built with the Web Audio API, React, and Redux.

## Demo

https://wds-1.com

## Features
 * Swap drum samples
 * Choose drum samples from file
 * Pattern selector to save up to 8 patterns per drum kit
 * BPM and swing control
 * Sample hit buttons
 * Gain and pan
 * Reverb
 * Mute and solo
 * Pitch shift
 * Preset system for saving and loading drum kits
 * Works offline with service worker and caching
 * Installable as PWA
 * Drag to reorder channels

## Circle CI status

[![CircleCI](https://circleci.com/gh/stufreen/web-drum-sequencer.svg?style=svg)](https://circleci.com/gh/stufreen/web-drum-sequencer)

## Installation

To run a local development server:
```
npm install
npm run start
```

To build a production version: `npm run build`

## Tests

```
npm run test
```

## Thank You
 * [React-Select](https://github.com/JedWatson/react-select)
 * [Webaudio-Controls](https://github.com/g200kg/webaudio-controls)
 * Chris Wilson's article [here](https://www.html5rocks.com/en/tutorials/audio/scheduling/)
 * [Voxengo impluse response](https://www.voxengo.com/impulses/)
 * [Jost* typeface](https://github.com/indestructible-type/Jost)
 * [Draggable](https://shopify.github.io/draggable/)


================================================
FILE: __mocks__/fileMock.js
================================================
module.exports = 'test-file-stub';


================================================
FILE: __mocks__/styleMock.js
================================================
module.exports = {};


================================================
FILE: babel.config.js
================================================
const presets = [
  [
    "@babel/env",
    {
      targets: "> 0.25%, not dead",
      useBuiltIns: "usage",
    },
  ],
  "@babel/preset-react",
];

module.exports = { presets };

================================================
FILE: index.html
================================================
<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script
      async
      src="https://www.googletagmanager.com/gtag/js?id=UA-66781633-3"
    ></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag() {
        dataLayer.push(arguments);
      }
      gtag('js', new Date());
      gtag('config', 'UA-66781633-3');
    </script>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta
      name="Description"
      content="Browser-based drum machine and sequencer for crafting beats on the go. You can save your creations and work offline."
    />
    <title>WDS-1: Web Drum Sequencer</title>
    <link rel="manifest" href="manifest.json" crossorigin="use-credentials" />
    <link rel="shortcut icon" href="./assets/icons/favicon.ico" />
    <meta name="mobile-web-app-capable" content="yes" />
    <meta name="theme-color" content="#000000" />
    <meta name="application-name" content="web-drum-sequencer" />
    <link
      rel="apple-touch-icon"
      sizes="57x57"
      href="assets/icons/apple-icon-57x57.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="60x60"
      href="assets/icons/apple-icon-60x60.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="72x72"
      href="assets/icons/apple-icon-72x72.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="76x76"
      href="assets/icons/apple-icon-76x76.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="114x114"
      href="assets/icons/apple-icon-114x114.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="120x120"
      href="assets/icons/apple-icon-120x120.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="144x144"
      href="assets/icons/apple-icon-144x144.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="152x152"
      href="assets/icons/apple-icon-152x152.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="180x180"
      href="assets/icons/apple-icon-180x180.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="192x192"
      href="assets/icons/android-icon-192x192.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="32x32"
      href="assets/icons/favicon-32x32.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="96x96"
      href="assets/icons/favicon-96x96.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="16x16"
      href="assets/icons/favicon-16x16.png"
    />
    <meta name="msapplication-TileColor" content="#202429" />
    <meta
      name="msapplication-TileImage"
      content="assets/icons/mstile-144x144.png"
    />
    <meta
      name="msapplication-config"
      content="assets/icons/browserconfig.xml"
    />
    <meta
      property="og:url"
      content="https://stufreen.github.io/web-drum-sequencer"
    />
    <meta property="og:type" content="website" />
    <meta property="og:title" content="WDS-1: Web Drum Sequencer" />
    <meta
      property="og:image"
      content="https://stufreen.github.io/web-drum-sequencer/wds-1-screen.png"
    />
    <meta
      property="og:description"
      content="Browser-based drum machine and sequencer for crafting beats on the go. You can save your creations and work offline."
    />
    <meta property="og:locale" content="en_US" />
    <meta property="og:article:author" content="Stu Freen" />
    <meta name="twitter:card" content="summary" />
    <meta name="twitter:creator" content="@stafree" />
    <meta
      name="twitter:url"
      content="https://stufreen.github.io/web-drum-sequencer"
    />
    <meta name="twitter:title" content="WDS-1: Web Drum Sequencer" />
    <meta
      name="twitter:description"
      content="Browser-based drum machine and sequencer for crafting beats on the go. You can save your creations and work offline."
    />
    <meta
      name="twitter:image"
      content="https://stufreen.github.io/web-drum-sequencer/wds-1-screen.png"
    />
  </head>
  <body>
    <div id="root"></div>
    <noscript> You need to enable JavaScript to run this app. </noscript>
    <script type="module" src="src/index.jsx"></script>
  </body>
</html>


================================================
FILE: manifest.json
================================================
{
  "icons": [
    {
      "src": "/assets/icons/icon-48x48.png",
      "sizes": "48x48",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "/assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable any"
    }
  ],
  "name": "WDS-1: Wed Drum Sequencer",
  "short_name": "WDS-1",
  "orientation": "portrait",
  "display": "standalone",
  "start_url": "/",
  "background_color": "#202429",
  "theme_color": "#000000"
}


================================================
FILE: package.json
================================================
{
  "name": "web-drum-sequencer",
  "version": "0.2.4",
  "description": "A drum machine and sequencer built with the Web Audio API and React.",
  "main": "dist/index.html",
  "scripts": {
    "start": "vite --host",
    "build": "rm -rf dist && vite build",
    "lint": "eslint src",
    "test": "jest",
    "gh-pages": "git subtree push --prefix dist origin gh-pages"
  },
  "author": "Stu Freen (http://www.stufreen.com)",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/stufreen/web-drum-sequencer.git"
  },
  "keywords": [
    "Web Audio",
    "Web Audio API",
    "Drum Machine",
    "Playback",
    "Effect",
    "Instrument",
    "React",
    "Redux",
    "Interactive Music"
  ],
  "dependencies": {
    "@shopify/draggable": "^1.0.0-beta.8",
    "animol": "1.0.9",
    "prop-types": "^15.6.2",
    "ramda": "^0.25.0",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-redux": "^5.0.7",
    "react-select": "^2.0.0",
    "recompose": "^0.27.1",
    "redux": "^4.0.0",
    "redux-persist": "^5.10.0",
    "redux-thunk": "^2.3.0",
    "reselect": "^3.0.1",
    "serviceworker-webpack-plugin": "^1.0.1",
    "styled-components": "^3.3.3",
    "styled-system": "^3.0.2",
    "uuid": "^3.3.2"
  },
  "jest": {
    "testURL": "http://localhost",
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
    }
  },
  "devDependencies": {
    "@babel/core": "^7.22.9",
    "@babel/eslint-parser": "^7.22.9",
    "@babel/preset-env": "^7.22.9",
    "@babel/preset-react": "^7.22.5",
    "@vitejs/plugin-react-refresh": "^1.3.6",
    "eslint": "^8.46.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-plugin-import": "^2.27.5",
    "eslint-plugin-jsx-a11y": "^6.7.1",
    "eslint-plugin-react": "^7.33.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "jest": "^29.6.2",
    "vite": "^4.4.7"
  }
}


================================================
FILE: public/assets/icons/browserconfig.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>

================================================
FILE: public/sw.js
================================================
/* eslint no-restricted-globals: 1 */

const addToCache = (event, fetchResponse) => {
  // Check if we received a valid response
  if (!fetchResponse || fetchResponse.status !== 200 || fetchResponse.type !== 'basic') {
    return fetchResponse;
  }

  // IMPORTANT: Clone the response. A response is a stream
  // and because we want the browser to consume the response
  // as well as the cache consuming the response, we need
  // to clone it so we have two streams.
  const responseToCache = fetchResponse.clone();

  caches.open('wdsCache').then((cache) => {
    cache.put(event.request, responseToCache);
  });

  return fetchResponse;
};

const fetchAndCache = (event, fetchRequest) => fetch(fetchRequest)
  .then(fetchResponse => addToCache(event, fetchResponse));

self.addEventListener('fetch', (event) => {
  // IMPORTANT: Clone the request. A request is a stream and
  // can only be consumed once. Since we are consuming this
  // once by cache and once by the browser for fetch, we need
  // to clone the response.
  const fetchRequest = event.request.clone();

  // Try to get files from the "assets" directory from cache first
  if (fetchRequest.url.indexOf('/assets/') >= 0) {
    event.respondWith(
      caches.match(fetchRequest)
        .then(response => response || fetchAndCache(event, fetchRequest)),
    );
  } else {
    event.respondWith(
      fetchAndCache(event, fetchRequest),
    );
  }
});


================================================
FILE: src/__mocks__/samples.config.js
================================================
export default [
  {
    name: 'Fake sample A',
    url: '/fake/sample/a/url.wav',
  },
  {
    name: 'Fake sample B',
    url: '/fake/sample/b/url.wav',
  },
];


================================================
FILE: src/assets/js/webaudio-controls.js
================================================
/* *
 *
 *  WebAudio-Controls is based on
 *    webaudio-knob by Eiji Kitamura http://google.com/+agektmr
 *    webaudio-slider by RYoya Kawai https://plus.google.com/108242669191458983485/posts
 *    webaudio-switch by Keisuke Ai http://d.hatena.ne.jp/aike/
 *  Integrated and enhanced by g200kg http://www.g200kg.com/
 *
 *	Copyright 2013 Eiji Kitamura / Ryoya KAWAI / Keisuke Ai / g200kg(Tatsuya Shinyagaito)
 *
 *	 Licensed 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.
 *
 * */
if(window.customElements){
  let styles=document.createElement("style");
  styles.innerHTML=
`#webaudioctrl-context-menu {
  display: none;
  position: absolute;
  z-index: 10;
  padding: 0;
  width: 100px;
  color:#eee;
  background-color: #268;
  border: solid 1px #888;
  box-shadow: 1px 1px 2px #888;
  font-family: sans-serif;
  font-size: 11px;
  line-height:1.7em;
  text-align:center;
  cursor:pointer;
  color:#fff;
  list-style: none;
}
#webaudioctrl-context-menu.active {
  display: block;
}
.webaudioctrl-context-menu__item {
  display: block;
  margin: 0;
  padding: 0;
  color: #000;
  background-color:#eee;
  text-decoration: none;
}
.webaudioctrl-context-menu__title{
  font-weight:bold;
}
.webaudioctrl-context-menu__item:last-child {
  margin-bottom: 0;
}
.webaudioctrl-context-menu__item:hover {
  background-color: #b8b8b8;
}
`;
  document.head.appendChild(styles);
  let midimenu=document.createElement("ul");
  midimenu.id="webaudioctrl-context-menu";
  midimenu.innerHTML=
`<li class="webaudioctrl-context-menu__title">MIDI Learn</li>
<li class="webaudioctrl-context-menu__item" id="webaudioctrl-context-menu-learn" onclick="webAudioControlsMidiManager.contextMenuLearn()">Learn</li>
<li class="webaudioctrl-context-menu__item" onclick="webAudioControlsMidiManager.contextMenuClear()">Clear</li>
<li class="webaudioctrl-context-menu__item" onclick="webAudioControlsMidiManager.contextMenuClose()">Close</li>
`;
  let opt={
    useMidi:0,
    midilearn:0,
    mididump:0,
    outline:0,
    knobSrc:null,
    knobSprites:0,
    knobWidth:0,
    knobHeight:0,
    knobDiameter:64,
    knobColors:"#e00;#000;#000",
    sliderSrc:null,
    sliderKnobsrc:null,
    sliderWidth:0,
    sliderHeight:0,
    sliderKnobwidth:0,
    sliderKnobheight:0,
    sliderDitchlength:0,
    sliderColors:"#e00;#000;#fcc",
    switchWidth:0,
    switchHeight:0,
    switchDiameter:24,
    switchColors:"#e00;#000;#fcc",
    paramWidth:32,
    paramHeight:16,
    paramColors:"#fff;#000",
    xypadColors:"#e00;#000;#fcc",
  };
  if(window.WebAudioControlsOptions)
    Object.assign(opt,window.WebAudioControlsOptions);
  class WebAudioControlsWidget extends HTMLElement{
    constructor(){
      super();
      this.addEventListener("keydown",this.keydown);
      this.addEventListener("mousedown",this.pointerdown,{passive:false});
      this.addEventListener("touchstart",this.pointerdown,{passive:false});
      this.addEventListener("wheel",this.wheel,{passive:false});
      this.addEventListener("mouseover",this.pointerover);
      this.addEventListener("mouseout",this.pointerout);
      this.addEventListener("contextmenu",this.contextMenu);
      this.hover=this.drag=0;
      document.body.appendChild(midimenu);
      this.basestyle=`
.webaudioctrl-tooltip{
  display:inline-block;
  position:absolute;
  margin:0 -1000px;
  z-index: 999;
  background:#eee;
  color:#000;
  border:1px solid #666;
  border-radius:4px;
  padding:5px 10px;
  text-align:center;
  left:0; top:0;
  font-size:11px;
  opacity:0;
  visibility:hidden;
}
.webaudioctrl-tooltip:before{
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -8px;
  border: 8px solid transparent;
  border-top: 8px solid #666;
}
.webaudioctrl-tooltip:after{
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -6px;
  border: 6px solid transparent;
  border-top: 6px solid #eee;
}
`;
    }
    sendEvent(ev){
      let event;
      event=document.createEvent("HTMLEvents");
      event.initEvent(ev,false,true);
      this.dispatchEvent(event);
    }
    getAttr(n,def){
      let v=this.getAttribute(n);
      if(v==""||v==null) return def;
      switch(typeof(def)){
      case "number":
        if(v=="true") return 1;
        v=+v;
        if(isNaN(v)) return 0;
        return v;
      }
      return v;
    }
    showtip(d){
      function valstr(x,c,type){
        switch(type){
        case "x": return (x|0).toString(16);
        case "X": return (x|0).toString(16).toUpperCase();
        case "d": return (x|0).toString();
        case "f": return x.toFixed(c);
        case "s": return x.toString();
        }
        return "";
      }
      function numformat(s,x){
        if(typeof(x)=="undefined")
          return;
        let i=s.indexOf("%");
        let c=[0,0],type=0,m=0,r="",j=i+1;
        for(;j<s.length;++j){
          if("dfxXs".indexOf(s[j])>=0){
            type=s[j];
            break;
          }
          if(s[j]==".")
            m=1;
          else
            c[m]=c[m]*10+parseInt(s[j]);
        }
        if(typeof(x)=="number")
          r=valstr(x,c[1],type);
        else
          r=valstr(x.x,c[1],type)+","+valstr(x.y,c[1],type);
        if(c[0]>0)
          r=("               "+r).slice(-c[0]);
        r=s.replace(/%.*[xXdfs]/,r);
        return r;
      }
      let s=this.tooltip;
      if(this.drag||this.hover){
        if(this.valuetip){
          if(s==null)
            s=`%.${this.digits}f`;
          else if(s.indexOf("%")<0)
            s+=` : %.${this.digits}f`;
        }
        if(s){
          this.ttframe.innerHTML=numformat(s,this.convValue);
          this.ttframe.style.display="inline-block";
          this.ttframe.style.width="auto";
          this.ttframe.style.height="auto";
          this.ttframe.style.transition="opacity 0.5s "+d+"s,visibility 0.5s "+d+"s";
          this.ttframe.style.opacity=0.9;
          this.ttframe.style.visibility="visible";
          let rc=this.getBoundingClientRect(),rc2=this.ttframe.getBoundingClientRect(),rc3=document.documentElement.getBoundingClientRect();
          this.ttframe.style.left=((rc.width-rc2.width)*0.5+1000)+"px";
          this.ttframe.style.top=(-rc2.height-8)+"px";
          return;
        }
      }
      this.ttframe.style.transition="opacity 0.1s "+d+"s,visibility 0.1s "+d+"s";
      this.ttframe.style.opacity=0;
      this.ttframe.style.visibility="hidden";
    }
    pointerover(e) {
      this.hover=1;
      this.showtip(0.6);
    }
    pointerout(e) {
      this.hover=0;
      this.showtip(0);
    }
    contextMenu(e){
      if(window.webAudioControlsMidiManager && this.midilearn)
        webAudioControlsMidiManager.contextMenuOpen(e,this);
      e.preventDefault();
      e.stopPropagation();
    }
    setMidiController(channel, cc) {
      if (this.listeningToThisMidiController(channel, cc)) return;
      this.midiController={ 'channel': channel, 'cc': cc};
      console.log("Added mapping for channel=" + channel + " cc=" + cc + " tooltip=" + this.tooltip);
    }
    listeningToThisMidiController(channel, cc) {
      const c = this.midiController;
      if((c.channel === channel || c.channel < 0) && c.cc === cc)
        return true;
      return false;
    }
    processMidiEvent(event){
      const channel = event.data[0] & 0xf;
      const controlNumber = event.data[1];
      if(this.midiMode == 'learn') {
        this.setMidiController(channel, controlNumber);
        webAudioControlsMidiManager.contextMenuClose();
        this.midiMode = 'normal';
      }
      if(this.listeningToThisMidiController(channel, controlNumber)) {
        if(this.tagName=="WEBAUDIO-SWITCH"){
          switch(this.type){
          case "toggle":
            if(event.data[2]>=64)
              this.setValue(1-this.value,true);
            break;
          case "kick":
            this.setValue(event.data[2]>=64?1:0);
            break;
          case "radio":
            let els=document.querySelectorAll("webaudio-switch[type='radio'][group='"+this.group+"']");
            for(let i=0;i<els.length;++i){
              if(els[i]==this)
                els[i].setValue(1);
              else
                els[i].setValue(0);
            }
            break;
          }
        }
        else{
          const val = this.min+(this.max-this.min)*event.data[2]/127;
          this.setValue(val, true);
        }
      }
    }
  }

try{
    customElements.define("webaudio-knob", class WebAudioKnob extends WebAudioControlsWidget {
    constructor(){
      super();
    }
    connectedCallback(){
      let root;
//      if(this.attachShadow)
//        root=this.attachShadow({mode: 'open'});
//      else
        root=this;
      root.innerHTML=
`<style>
${this.basestyle}
webaudio-knob{
  display:inline-block;
  position:relative;
  margin:0;
  padding:0;
  cursor:pointer;
  font-family: sans-serif;
  font-size: 11px;
}
.webaudio-knob-body{
  display:inline-block;
  position:relative;
  margin:0;
  padding:0;
  vertical-align:bottom;
}
</style>
<div class='webaudio-knob-body' tabindex='1' touch-action='none'></div><div class='webaudioctrl-tooltip'></div>
`;
      this.elem=root.childNodes[2];
      this.ttframe=root.childNodes[3];
      this.enable=this.getAttr("enable",1);
      this._src=this.getAttr("src",opt.knobSrc); Object.defineProperty(this,"src",{get:()=>{return this._src},set:(v)=>{this._src=v;this.setupImage()}});
      this._value=this.getAttr("value",0); Object.defineProperty(this,"value",{get:()=>{return this._value},set:(v)=>{this._value=v;this.redraw()}});
      this.defvalue=this.getAttr("defvalue",0);
      this._min=this.getAttr("min",0); Object.defineProperty(this,"min",{get:()=>{return this._min},set:(v)=>{this._min=+v;this.redraw()}});
      this._max=this.getAttr("max",100); Object.defineProperty(this,"max",{get:()=>{return this._max},set:(v)=>{this._max=+v;this.redraw()}});
      this._step=this.getAttr("step",1); Object.defineProperty(this,"step",{get:()=>{return this._step},set:(v)=>{this._step=+v;this.redraw()}});
      this._sprites=this.getAttr("sprites",opt.knobSprites); Object.defineProperty(this,"sprites",{get:()=>{return this._sprites},set:(v)=>{this._sprites=v;this.setupImage()}});
      this._width=this.getAttr("width",opt.knobWidth); Object.defineProperty(this,"width",{get:()=>{return this._width},set:(v)=>{this._width=v;this.setupImage()}});
      this._height=this.getAttr("height",opt.knobHeight); Object.defineProperty(this,"height",{get:()=>{return this._height},set:(v)=>{this._height=v;this.setupImage()}});
      this._diameter=this.getAttr("diameter",opt.knobDiameter); Object.defineProperty(this,"diameter",{get:()=>{return this._diameter},set:(v)=>{this._diameter=v;this.setupImage()}});
      this._colors=this.getAttr("colors",opt.knobColors); Object.defineProperty(this,"colors",{get:()=>{return this._colors},set:(v)=>{this._colors=v;this.setupImage()}});
      this.outline=this.getAttr("outline",opt.outline);
      this.sensitivity=this.getAttr("sensitivity",1);
      this.valuetip=this.getAttr("valuetip",1);
      this.tooltip=this.getAttr("tooltip",null);
      this.conv=this.getAttr("conv",null);
      if(this.conv)
        this.convValue=eval(this.conv)(this._value);
      else
        this.convValue=this._value;
      this.midilearn=this.getAttr("midilearn",opt.midilearn);
      this.midicc=this.getAttr("midicc",null);

      this.midiController={};
      this.midiMode="normal";
      if(this.midicc) {
          let ch = parseInt(this.midicc.substring(0, this.midicc.lastIndexOf("."))) - 1;
          let cc = parseInt(this.midicc.substring(this.midicc.lastIndexOf(".") + 1));
          this.setMidiController(ch, cc);
      }
      this.setupImage();
      this.digits=0;
      this.coltab=["#e00","#000","#000"];
      if(window.webAudioControlsMidiManager)
//        window.webAudioControlsMidiManager.updateWidgets();
        window.webAudioControlsMidiManager.addWidget(this);
    }
    disconnectedCallback(){}
    setupImage(){
      this.kw=this.width||this.diameter;
      this.kh=this.height||this.diameter;
      if(!this.src){
        if(this.colors)
          this.coltab = this.colors.split(";");
        if(!this.coltab)
          this.coltab=["#e00","#000","#000"];
        let svg=
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="6464" preserveAspectRatio="none">
<radialGradient id="gr" cx="30%" cy="30%"><stop offset="0%" stop-color="${this.coltab[2]}"/><stop offset="100%" stop-color="${this.coltab[1]}"/></radialGradient>
<defs><circle id="B" cx="32" cy="32" r="30" fill="url(#gr)"/></defs>
<defs><line id="K" x1="32" y1="28" x2="32" y2="7" stroke-linecap="round" stroke-width="6" stroke="${this.coltab[0]}"/></defs>`;
        for(let i=0;i<101;++i){
          svg += `<use xlink:href="#B" y="${64*i}"/>`;
          svg += `<use xlink:href="#K" y="${64*i}" transform="rotate(${(-135+270*i/101).toFixed(2)},32,${64*i+32})"/>`;
        }
        svg += "</svg>";
        this.elem.style.backgroundImage = "url(data:image/svg+xml;base64,"+btoa(svg)+")";
//        this.elem.style.backgroundSize = "100% 10100%";
        this.elem.style.backgroundSize = `${this.kw}px ${this.kh*101}px`;
      }
      else{
        this.elem.style.backgroundImage = "url("+(this.src)+")";
        if(!this.sprites)
          this.elem.style.backgroundSize = "100% 100%";
        else{
//          this.elem.style.backgroundSize = `100% ${(this.sprites+1)*100}%`;
          this.elem.style.backgroundSize = `${this.kw}px ${this.kh*(this.sprites+1)}px`;
        }
      }
      this.elem.style.outline=this.outline?"":"none";
      this.elem.style.width=this.kw+"px";
      this.elem.style.height=this.kh+"px";
      this.style.height=this.kh+"px";
      this.redraw();
    }
    redraw() {
      this.digits=0;
      if(this.step && this.step < 1) {
        for(let n = this.step ; n < 1; n *= 10)
          ++this.digits;
      }
      if(this.value<this.min){
        this.value=this.min;
        return;
      }
      if(this.value>this.max){
        this.value=this.max;
        return;
      }
      let range = this.max - this.min;
      let style = this.elem.style;
      let sp = this.src?this.sprites:100;
      if(sp>=1){
        let offset = ((sp * (this.value - this.min) / range) | 0);
        style.backgroundPosition = "0px " + (-offset*this.kh) + "px";
        style.transform = 'rotate(0deg)';
      } else {
        let deg = 270 * ((this.value - this.min) / range - 0.5);
        style.backgroundPosition="0px 0px";
        style.transform = 'rotate(' + deg + 'deg)';
      }
    }
    _setValue(v){
      if(this.step)
        v=(Math.round((v-this.min)/this.step))*this.step+this.min;
      this._value=Math.min(this.max,Math.max(this.min,v));
      if(this._value!=this.oldvalue){
        this.oldvalue=this._value;
        if(this.conv)
          this.convValue=eval(this.conv)(this._value);
        else
          this.convValue=this._value;
        this.redraw();
        this.showtip(0);
        return 1;
      }
      return 0;
    }
    setValue(v,f){
      if(this._setValue(v) && f)
        this.sendEvent("input"),this.sendEvent("change");
    }
    wheel(e) {
      if (!this.enable)
        return;
      let delta=(this.max-this.min)*0.01;
      delta=e.deltaY>0?-delta:delta;
      if(!e.shiftKey)
        delta*=5;
      if(Math.abs(delta) < this.step)
        delta = (delta > 0) ? +this.step : -this.step;
      this.setValue(+this.value+delta,true);
      e.preventDefault();
      e.stopPropagation();
    }
    pointerdown(ev){
      if(!this.enable)
        return;
      let e=ev;
      if(ev.touches){
        e = ev.changedTouches[0];
        this.identifier=e.identifier;
      }
      else {
        if(e.buttons!=1 && e.button!=0)
          return;
      }
      this.elem.focus();
      this.drag=1;
      this.showtip(0);
      let pointermove=(ev)=>{
        let e=ev;
        if(ev.touches){
          for(let i=0;i<ev.touches.length;++i){
            if(ev.touches[i].identifier==this.identifier){
              e = ev.touches[i];
              break;
            }
          }
        }
        if(this.lastShift !== e.shiftKey) {
          this.lastShift = e.shiftKey;
          this.startPosX = e.pageX;
          this.startPosY = e.pageY;
          this.startVal = this.value;
        }
        let offset = (this.startPosY - e.pageY - this.startPosX + e.pageX) * this.sensitivity;
        this._setValue(this.min + ((((this.startVal + (this.max - this.min) * offset / ((e.shiftKey ? 4 : 1) * 128)) - this.min) / this.step) | 0) * this.step);
        this.sendEvent("input");
        if(e.preventDefault)
          e.preventDefault();
        if(e.stopPropagation)
          e.stopPropagation();
        return false;
      }
      let pointerup=(ev)=>{
        let e=ev;
        if(ev.touches){
          for(let i=0;;){
            if(ev.changedTouches[i].identifier==this.identifier){
              break;
            }
            if(++i>=ev.changedTouches.length)
              return;
          }
        }
        this.drag=0;
        this.showtip(0);
        this.startPosX = this.startPosY = null;
        window.removeEventListener('mousemove', pointermove);
        window.removeEventListener('touchmove', pointermove, {passive:false});
        window.removeEventListener('mouseup', pointerup);
        window.removeEventListener('touchend', pointerup);
        window.removeEventListener('touchcancel', pointerup);
        document.body.removeEventListener('touchstart', preventScroll,{passive:false});
        this.sendEvent("change");
      }
      let preventScroll=(e)=>{
        e.preventDefault();
      }
      if(e.ctrlKey || e.metaKey)
        this.setValue(this.defvalue,true);
      else {
        this.startPosX = e.pageX;
        this.startPosY = e.pageY;
        this.startVal = this.value;
        window.addEventListener('mousemove', pointermove);
        window.addEventListener('touchmove', pointermove, {passive:false});
      }
      window.addEventListener('mouseup', pointerup);
      window.addEventListener('touchend', pointerup);
      window.addEventListener('touchcancel', pointerup);
      document.body.addEventListener('touchstart', preventScroll,{passive:false});
      ev.preventDefault();
      ev.stopPropagation();
      return false;
    }
  });
} catch(error){
  console.log("webaudio-knob already defined");
}

try{
  customElements.define("webaudio-slider", class WebAudioSlider extends WebAudioControlsWidget {
    constructor(){
      super();
    }
    connectedCallback(){
      let root;
//      if(this.attachShadow)
//        root=this.attachShadow({mode: 'open'});
//      else
        root=this;
      root.innerHTML=
`<style>
${this.basestyle}
webaudio-slider{
  display:inline-block;
  position:relative;
  margin:0;
  padding:0;
  font-family: sans-serif;
  font-size: 11px;
  cursor:pointer;
}
.webaudio-slider-body{
  display:inline-block;
  position:relative;
  margin:0;
  padding:0;
  vertical-align:bottom;
}
.webaudio-slider-knob{
  display:inline-block;
  position:absolute;
  margin:0;
  padding:0;
}
</style>
<div class='webaudio-slider-body' tabindex='1' touch-action='none'><div class='webaudio-slider-knob' touch-action='none'></div></div><div class='webaudioctrl-tooltip'></div>
`;
      this.elem=root.childNodes[2];
      this.knob=this.elem.childNodes[0];
      this.ttframe=root.childNodes[3];
      this.enable=this.getAttr("enable",1);
      this._src=this.getAttr("src",opt.sliderSrc); Object.defineProperty(this,"src",{get:()=>{return this._src},set:(v)=>{this._src=v;this.setupImage()}});
      this._knobsrc=this.getAttr("knobsrc",opt.sliderKnobsrc); Object.defineProperty(this,"knobsrc",{get:()=>{return this._knobsrc},set:(v)=>{this._knobsrc=v;this.setupImage()}});
      this._value=this.getAttr("value",0); Object.defineProperty(this,"value",{get:()=>{return this._value},set:(v)=>{this._value=v;this.redraw()}});
      this.defvalue=this.getAttr("defvalue",0);
      this._min=this.getAttr("min",0); Object.defineProperty(this,"min",{get:()=>{return this._min},set:(v)=>{this._min=v;this.redraw()}});
      this._max=this.getAttr("max",100); Object.defineProperty(this,"max",{get:()=>{return this._max},set:(v)=>{this._max=v;this.redraw()}});
      this._step=this.getAttr("step",1); Object.defineProperty(this,"step",{get:()=>{return this._step},set:(v)=>{this._step=v;this.redraw()}});
      this._sprites=this.getAttr("sprites",0); Object.defineProperty(this,"sprites",{get:()=>{return this._sprites},set:(v)=>{this._sprites=v;this.setupImage()}});
      this._direction=this.getAttr("direction",null); Object.defineProperty(this,"direction",{get:()=>{return this._direction},set:(v)=>{this._direction=v;this.setupImage()}});
      this._width=this.getAttr("width",opt.sliderWidth); Object.defineProperty(this,"width",{get:()=>{return this._width},set:(v)=>{this._width=v;this.setupImage()}});
      this._height=this.getAttr("height",opt.sliderHeight); Object.defineProperty(this,"height",{get:()=>{return this._height},set:(v)=>{this._height=v;this.setupImage()}});
      if(this._direction=="horz"){
        if(this._width==0) this._width=128;
        if(this._height==0) this._height=24;
      }
      else{
        if(this._width==0) this._width=24;
        if(this._height==0) this._height=128;
      }
      this._knobwidth=this.getAttr("knobwidth",opt.sliderKnobwidth); Object.defineProperty(this,"knobwidth",{get:()=>{return this._knobwidth},set:(v)=>{this._knobwidth=v;this.setupImage()}});
      this._knobheight=this.getAttr("knbheight",opt.sliderKnobheight); Object.defineProperty(this,"knobheight",{get:()=>{return this._knobheight},set:(v)=>{this._knobheight=v;this.setupImage()}});
      this._ditchlength=this.getAttr("ditchlength",opt.sliderDitchlength); Object.defineProperty(this,"ditchlength",{get:()=>{return this._ditchlength},set:(v)=>{this._ditchlength=v;this.setupImage()}});
      this._colors=this.getAttr("colors",opt.sliderColors); Object.defineProperty(this,"colors",{get:()=>{return this._colors},set:(v)=>{this._colors=v;this.setupImage()}});
      this.outline=this.getAttr("outline",opt.outline);
      this.sensitivity=this.getAttr("sensitivity",1);
      this.valuetip=this.getAttr("valuetip",1);
      this.tooltip=this.getAttr("tooltip",null);
      this.conv=this.getAttr("conv",null);
      if(this.conv)
        this.convValue=eval(this.conv)(this._value);
      else
        this.convValue=this._value;
      this.midilearn=this.getAttr("midilearn",opt.midilearn);
      this.midicc=this.getAttr("midicc",null);
      this.midiController={};
      this.midiMode="normal";
      if(this.midicc) {
          let ch = parseInt(this.midicc.substring(0, this.midicc.lastIndexOf("."))) - 1;
          let cc = parseInt(this.midicc.substring(this.midicc.lastIndexOf(".") + 1));
          this.setMidiController(ch, cc);
      }
      this.setupImage();
      this.digits=0;
      if(window.webAudioControlsMidiManager)
//        window.webAudioControlsMidiManager.updateWidgets();
        window.webAudioControlsMidiManager.addWidget(this);
      this.elem.onclick=(e)=>{e.stopPropagation()};
    }
    disconnectedCallback(){}
    setupImage(){
      this.coltab = this.colors.split(";");
      this.dr=this.direction;
      this.dlen=this.ditchlength;
      if(!this.width){
        if(this.dr=="horz")
          this.width=128;
        else
          this.width=24;
      }
      if(!this.height){
        if(this.dr=="horz")
          this.height=24;
        else
          this.height=128;
      }
      if(!this.dr)
        this.dr=(this.width<=this.height)?"vert":"horz";
      if(this.dr=="vert"){
        if(!this.dlen)
          this.dlen=this.height-this.width;
      }
      else{
        if(!this.dlen)
          this.dlen=this.width-this.height;
      }
      this.knob.style.backgroundSize = "100% 100%";
      this.elem.style.backgroundSize = "100% 100%";
      this.elem.style.width=this.width+"px";
      this.elem.style.height=this.height+"px";
      this.style.height=this.height+"px";
      this.kwidth=this.knobwidth||(this.dr=="horz"?this.height:this.width);
      this.kheight=this.knobheight||(this.dr=="horz"?this.height:this.width);
      this.knob.style.width = this.kwidth+"px";
      this.knob.style.height = this.kheight+"px";
      if(!this.src){
        let r=Math.min(this.width,this.height)*0.5;
        let svgbody=
`<svg xmlns="http://www.w3.org/2000/svg" width="${this.width}" height="${this.height}" preserveAspectRatio="none">
<rect x="1" y="1" rx="${r}" ry="${r}" width="${this.width-2}" height="${this.height-2}" fill="${this.coltab[1]}"/></svg>`;
        this.elem.style.backgroundImage = "url(data:image/svg+xml;base64,"+btoa(svgbody)+")";
      }
      else{
        this.elem.style.backgroundImage = "url("+(this.src)+")";
      }
      if(!this.knobsrc){
        let svgthumb=
`<svg xmlns="http://www.w3.org/2000/svg" width="${this.kwidth}" height="${this.kheight}" preserveAspectRatio="none">
<radialGradient id="gr" cx="30%" cy="30%"><stop offset="0%" stop-color="${this.coltab[2]}"/><stop offset="100%" stop-color="${this.coltab[0]}"/></radialGradient>
<rect x="2" y="2" width="${this.kwidth-4}" height="${this.kheight-4}" rx="${this.kwidth*0.5}" ry="${this.kheight*0.5}" fill="url(#gr)"/></svg>`;
        this.knob.style.backgroundImage = "url(data:image/svg+xml;base64,"+btoa(svgthumb)+")";
      }
      else{
        this.knob.style.backgroundImage = "url("+(this.knobsrc)+")";
      }
      this.elem.style.outline=this.outline?"":"none";
      this.redraw();
    }
    redraw() {
      this.digits=0;
      if(this.step && this.step < 1) {
        for(let n = this.step ; n < 1; n *= 10)
          ++this.digits;
      }
      if(this.value<this.min){
        this.value=this.min;
        return;
      }
      if(this.value>this.max){
        this.value=this.max;
        return;
      }
      let range = this.max - this.min;
      let style = this.knob.style;
      if(this.dr=="vert"){
        style.left=(this.width-this.kwidth)*0.5+"px";
        style.top=(1-(this.value-this.min)/range)*this.dlen+"px";
        this.sensex=0; this.sensey=1;
      }
      else{
        style.top=(this.height-this.kheight)*0.5+"px";
        style.left=(this.value-this.min)/range*this.dlen+"px";
        this.sensex=1; this.sensey=0;
      }
    }
    _setValue(v){
      v=(Math.round((v-this.min)/this.step))*this.step+this.min;
      this._value=Math.min(this.max,Math.max(this.min,v));
      if(this._value!=this.oldvalue){
        this.oldvalue=this._value;
        if(this.conv)
          this.convValue=eval(this.conv)(this._value);
        else
          this.convValue=this._value;
        this.redraw();
        this.showtip(0);
        return 1;
      }
      return 0;
    }
    setValue(v,f){
      if(this._setValue(v)&&f)
        this.sendEvent("input"),this.sendEvent("change");
    }
    wheel(e) {
      let delta=(this.max-this.min)*0.01;
      delta=e.deltaY>0?-delta:delta;
      if(!e.shiftKey)
        delta*=5;
      if(Math.abs(delta) < this.step)
        delta = (delta > 0) ? +this.step : -this.step;
      this.setValue(+this.value+delta,true);
      e.preventDefault();
      e.stopPropagation();
      this.redraw();
    }
    pointerdown(ev){
      if(!this.enable)
        return;
      let e=ev;
      if(ev.touches){
        e = ev.changedTouches[0];
        this.identifier=e.identifier;
      }
      else {
        if(e.buttons!=1 && e.button!=0)
          return;
      }
      this.elem.focus();
      this.drag=1;
      this.showtip(0);
      let pointermove=(ev)=>{
        let e=ev;
        if(ev.touches){
          for(let i=0;i<ev.touches.length;++i){
            if(ev.touches[i].identifier==this.identifier){
              e = ev.touches[i];
              break;
            }
          }
        }
        if(this.lastShift !== e.shiftKey) {
          this.lastShift = e.shiftKey;
          this.startPosX = e.pageX;
          this.startPosY = e.pageY;
          this.startVal = this.value;
        }
        let offset = ((this.startPosY - e.pageY)*this.sensey - (this.startPosX - e.pageX)*this.sensex) * this.sensitivity;
        this._setValue(this.min + ((((this.startVal + (this.max - this.min) * offset / ((e.shiftKey ? 4 : 1) * this.dlen)) - this.min) / this.step) | 0) * this.step);
        this.sendEvent("input");
        if(e.preventDefault)
          e.preventDefault();
        if(e.stopPropagation)
          e.stopPropagation();
        return false;
      }
      let pointerup=(ev)=>{
        let e=ev;
        if(ev.touches){
          for(let i=0;;){
            if(ev.changedTouches[i].identifier==this.identifier){
              break;
            }
            if(++i>=ev.changedTouches.length)
              return;
          }
        }
        this.drag=0;
        this.showtip(0);
        this.startPosX = this.startPosY = null;
        window.removeEventListener('mousemove', pointermove);
        window.removeEventListener('touchmove', pointermove, {passive:false});
        window.removeEventListener('mouseup', pointerup);
        window.removeEventListener('touchend', pointerup);
        window.removeEventListener('touchcancel', pointerup);
        document.body.removeEventListener('touchstart', preventScroll,{passive:false});
        this.sendEvent("change");
      }
      let preventScroll=(e)=>{
        e.preventDefault();
      }
      if(e.touches)
        e = e.touches[0];
      if(e.ctrlKey || e.metaKey)
        this.setValue(this.defvalue,true);
      else {
        this.startPosX = e.pageX;
        this.startPosY = e.pageY;
        this.startVal = this.value;
        window.addEventListener('mousemove', pointermove);
        window.addEventListener('touchmove', pointermove, {passive:false});
      }
      window.addEventListener('mouseup', pointerup);
      window.addEventListener('touchend', pointerup);
      window.addEventListener('touchcancel', pointerup);
      document.body.addEventListener('touchstart', preventScroll,{passive:false});
      e.preventDefault();
      e.stopPropagation();
      return false;
    }
  });
} catch(error){
  console.log("webaudio-slider already defined");
}

try{
  customElements.define("webaudio-switch", class WebAudioSwitch extends WebAudioControlsWidget {
    constructor(){
      super();
    }
    connectedCallback(){
      let root;
//      if(this.attachShadow)
//        root=this.attachShadow({mode: 'open'});
//      else
        root=this;
      root.innerHTML=
`<style>
${this.basestyle}
webaudio-switch{
  display:inline-block;
  margin:0;
  padding:0;
  font-family: sans-serif;
  font-size: 11px;
  cursor:pointer;
}
.webaudio-switch-body{
  display:inline-block;
  margin:0;
  padding:0;
  vertical-align:bottom;
}
</style>
<div class='webaudio-switch-body' tabindex='1' touch-action='none'><div class='webaudioctrl-tooltip'></div></div>
`;
      this.elem=root.childNodes[2];
      this.ttframe=this.elem.childNodes[0];

      this.enable=this.getAttr("enable",1);
      this._src=this.getAttr("src",null); Object.defineProperty(this,"src",{get:()=>{return this._src},set:(v)=>{this._src=v;this.setupImage()}});
      this._value=this.getAttr("value",0); Object.defineProperty(this,"value",{get:()=>{return this._value},set:(v)=>{this._value=v;this.redraw()}});
      this.defvalue=this.getAttr("defvalue",0);
      this.type=this.getAttr("type","toggle");
      this.group=this.getAttr("group","");
      this._width=this.getAttr("width",0); Object.defineProperty(this,"width",{get:()=>{return this._width},set:(v)=>{this._width=v;this.setupImage()}});
      this._height=this.getAttr("height",0); Object.defineProperty(this,"height",{get:()=>{return this._height},set:(v)=>{this._height=v;this.setupImage()}});
      this._diameter=this.getAttr("diameter",0); Object.defineProperty(this,"diameter",{get:()=>{return this._diameter},set:(v)=>{this._diameter=v;this.setupImage()}});
      this.invert=this.getAttr("invert",0);
      this._colors=this.getAttr("colors",opt.switchColors); Object.defineProperty(this,"colors",{get:()=>{return this._colors},set:(v)=>{this._colors=v;this.setupImage()}});
      this.outline=this.getAttr("outline",opt.outline);
      this.valuetip=0;
      this.tooltip=this.getAttr("tooltip",null);
      this.midilearn=this.getAttr("midilearn",opt.midilearn);
      this.midicc=this.getAttr("midicc",null);
      this.midiController={};
      this.midiMode="normal";
      if(this.midicc) {
          let ch = parseInt(this.midicc.substring(0, this.midicc.lastIndexOf("."))) - 1;
          let cc = parseInt(this.midicc.substring(this.midicc.lastIndexOf(".") + 1));
          this.setMidiController(ch, cc);
      }
      this.setupImage();
      this.digits=0;
      if(window.webAudioControlsMidiManager)
//        window.webAudioControlsMidiManager.updateWidgets();
        window.webAudioControlsMidiManager.addWidget(this);
      this.elem.onclick=(e)=>{e.stopPropagation()};
    }
    disconnectedCallback(){}
    setupImage(){
      let w=this.width||this.diameter||opt.switchWidth||opt.switchDiameter;
      let h=this.height||this.diameter||opt.switchHeight||opt.switchDiameter;
      if(!this.src){
        this.coltab = this.colors.split(";");
        let mm=Math.min(w,h);
        let svg=
`<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h*2}" preserveAspectRatio="none">
<radialGradient id="gr" cx="30%" cy="30%"><stop offset="0%" stop-color="${this.coltab[2]}"/><stop offset="100%" stop-color="${this.coltab[0]}"/></radialGradient>
<rect x="${w*0.05}" y="${h*0.05}" width="${w*0.9}" height="${h*0.9}" rx="${mm*0.1}" ry="${mm*0.1}" fill="${this.coltab[1]}"/>
<rect x="${w*0.05}" y="${h*1.05}" width="${w*0.9}" height="${h*0.9}" rx="${mm*0.1}" ry="${mm*0.1}" fill="${this.coltab[1]}"/>
<circle cx="${w*0.5}" cy="${h*0.5}" r="${mm*0.3}" stroke="${this.coltab[0]}" stroke-width="2"/>
<circle cx="${w*0.5}" cy="${h*1.5}" r="${mm*0.3}" stroke="${this.coltab[0]}" stroke-width="2" fill="url(#gr)"/></svg>`;
        this.elem.style.backgroundImage = "url(data:image/svg+xml;base64,"+btoa(svg)+")";
        this.elem.style.backgroundSize = "100% 200%";
      }
      else{
        this.elem.style.backgroundImage = "url("+(this.src)+")";
        if(!this.sprites)
          this.elem.style.backgroundSize = "100% 200%";
        else
          this.elem.style.backgroundSize = `100% ${(this.sprites+1)*100}%`;
      }
      this.elem.style.width=w+"px";
      this.elem.style.height=h+"px";
      this.style.height=h+"px";
      this.elem.style.outline=this.outline?"":"none";
      this.redraw();
    }
    redraw() {
      let style = this.elem.style;
      if(this.value^this.invert)
        style.backgroundPosition = "0px -100%";
      else
        style.backgroundPosition = "0px 0px";
    }
    setValue(v,f){
      this.value=v;
      this.checked=(!!v);
      if(this.value!=this.oldvalue){
        this.redraw();
        this.showtip(0);
        if(f){
          this.sendEvent("input");
          this.sendEvent("change");
        }
        this.oldvalue=this.value;
      }
    }
    pointerdown(ev){
      if(!this.enable)
        return;
      let e=ev;
      if(ev.touches){
        e = ev.changedTouches[0];
        this.identifier=e.identifier;
      }
      else {
        if(e.buttons!=1 && e.button!=0)
          return;
      }
      this.elem.focus();
      this.drag=1;
      this.showtip(0);
      let pointermove=(e)=>{
        e.preventDefault();
        e.stopPropagation();
        return false;
      }
      let pointerup=(e)=>{
        this.drag=0;
        this.showtip(0);
        window.removeEventListener('mousemove', pointermove);
        window.removeEventListener('touchmove', pointermove, {passive:false});
        window.removeEventListener('mouseup', pointerup);
        window.removeEventListener('touchend', pointerup);
        window.removeEventListener('touchcancel', pointerup);
        document.body.removeEventListener('touchstart', preventScroll,{passive:false});
        if(this.type=="kick"){
          this.value=0;
          this.checked=false;
          this.redraw();
          this.sendEvent("change");
        }
        this.sendEvent("click");
        e.preventDefault();
        e.stopPropagation();
      }
      let preventScroll=(e)=>{
        e.preventDefault();
      }
      switch(this.type){
      case "kick":
        this.setValue(1);
        this.sendEvent("change");
        break;
      case "toggle":
        if(e.ctrlKey || e.metaKey)
          this.value=defvalue;
        else
          this.value=1-this.value;
        this.checked=!!this.value;
        this.sendEvent("change");
        break;
      case "radio":
        let els=document.querySelectorAll("webaudio-switch[type='radio'][group='"+this.group+"']");
        for(let i=0;i<els.length;++i){
          if(els[i]==this)
            els[i].setValue(1);
          else
            els[i].setValue(0);
        }
        this.sendEvent("change");
        break;
      }

      window.addEventListener('mouseup', pointerup);
      window.addEventListener('touchend', pointerup);
      window.addEventListener('touchcancel', pointerup);
      document.body.addEventListener('touchstart', preventScroll,{passive:false});
      this.redraw();
      e.preventDefault();
      e.stopPropagation();
      return false;
    }
  });
} catch(error){
  console.log("webaudio-switch already defined");
}

try{
  customElements.define("webaudio-param", class WebAudioParam extends WebAudioControlsWidget {
    constructor(){
      super();
      this.addEventListener("keydown",this.keydown);
      this.addEventListener("mousedown",this.pointerdown,{passive:false});
      this.addEventListener("touchstart",this.pointerdown,{passive:false});
      this.addEventListener("wheel",this.wheel);
      this.addEventListener("mouseover",this.pointerover);
      this.addEventListener("mouseout",this.pointerout);
      this.addEventListener("contextmenu",this.contextMenu);
    }
    connectedCallback(){
      let root;
//      if(this.attachShadow)
//        root=this.attachShadow({mode: 'open'});
//      else
        root=this;
      root.innerHTML=
`<style>
${this.basestyle}
webaudio-param{
  display:inline-block;
  user-select:none;
  margin:0;
  padding:0;
  font-family: sans-serif;
  font-size: 8px;
  cursor:pointer;
  position:relative;
  vertical-align:baseline;
}
.webaudio-param-body{
  display:inline-block;
  position:relative;
  text-align:center;
  border:1px solid #888;
  background:none;
  border-radius:4px;
  margin:0;
  padding:0;
  font-family:sans-serif;
  font-size:11px;
  vertical-align:bottom;
}
</style>
<input class='webaudio-param-body' value='0' tabindex='1' touch-action='none'/><div class='webaudioctrl-tooltip'></div>
`;
      this.elem=root.childNodes[2];
      this.ttframe=root.childNodes[3];
      this.enable=this.getAttr("enable",1);
      this._value=this.getAttr("value",0); Object.defineProperty(this,"value",{get:()=>{return this._value},set:(v)=>{this._value=v;this.redraw()}});
      this.defvalue=this.getAttr("defvalue",0);
      this._fontsize=this.getAttr("fontsize",9); Object.defineProperty(this,"fontsize",{get:()=>{return this._fontsize},set:(v)=>{this._fontsize=v;this.setupImage()}});
      this._src=this.getAttr("src",null); Object.defineProperty(this,"src",{get:()=>{return this._src},set:(v)=>{this._src=v;this.setupImage()}});
      this.link=this.getAttr("link","");
      this._width=this.getAttr("width",32); Object.defineProperty(this,"width",{get:()=>{return this._width},set:(v)=>{this._width=v;this.setupImage()}});
      this._height=this.getAttr("height",20); Object.defineProperty(this,"height",{get:()=>{return this._height},set:(v)=>{this._height=v;this.setupImage()}});
      this._colors=this.getAttr("colors","#fff;#000"); Object.defineProperty(this,"colors",{get:()=>{return this._colors},set:(v)=>{this._colors=v;this.setupImage()}});
      this.outline=this.getAttr("outline",opt.outline);
      this.midiController={};
      this.midiMode="normal";
      if(this.midicc) {
        let ch = parseInt(this.midicc.substring(0, this.midicc.lastIndexOf("."))) - 1;
        let cc = parseInt(this.midicc.substring(this.midicc.lastIndexOf(".") + 1));
        this.setMidiController(ch, cc);
      }
      this.setupImage();
      if(window.webAudioControlsMidiManager)
//        window.webAudioControlsMidiManager.updateWidgets();
        window.webAudioControlsMidiManager.addWidget(this);
      this.fromLink=((e)=>{
        this.setValue(e.target.convValue.toFixed(e.target.digits));
      }).bind(this);
      this.elem.onchange=()=>{
        this.value=this.elem.value;
        let le=document.getElementById(this.link);
        if(le)
          le.setValue(+this.elem.value);
      }
    }
    disconnectedCallback(){}
    setupImage(){
      this.coltab = this.colors.split(";");
      this.elem.style.color=this.coltab[0];
      if(!this.src){
        this.elem.style.backgroundColor=this.coltab[1];
      }
      else{
        this.elem.style.backgroundImage = "url("+(this.src)+")";
        this.elem.style.backgroundSize = "100% 100%";
      }
      this.elem.style.width=this.width+"px";
      this.elem.style.height=this.height+"px";
      this.elem.style.fontSize=this.fontsize+"px";
      this.elem.style.outline=this.outline?"":"none";
      let l=document.getElementById(this.link);
      if(l&&typeof(l.value)!="undefined"){
        this.setValue(l.value.toFixed(l.digits));
        l.addEventListener("input",(e)=>{this.setValue(l.value.toFixed(l.digits))});
      }
      this.redraw();
    }
    redraw() {
      this.elem.value=this.value;
    }
    setValue(v,f){
      this.value=v;
      if(this.value!=this.oldvalue){
        this.redraw();
        this.showtip(0);
        if(f){
          let event=document.createEvent("HTMLEvents");
          event.initEvent("change",false,true);
          this.dispatchEvent(event);
        }
        this.oldvalue=this.value;
      }
    }
    pointerdown(ev){
      if(!this.enable)
        return;
      let e=ev;
      if(ev.touches)
          e = ev.touches[0];
      else {
        if(e.buttons!=1 && e.button!=0)
          return;
      }
      this.elem.focus();
      this.redraw();
    }
  });
} catch(error){
  console.log("webaudio-param already defined");
}

try{
  customElements.define("webaudio-keyboard", class WebAudioKeyboard extends WebAudioControlsWidget {
    constructor(){
      super();
    }
    connectedCallback(){
      let root;
//      if(this.attachShadow)
//        root=this.attachShadow({mode: 'open'});
//      else
        root=this;
      root.innerHTML=
`<style>
${this.basestyle}
webaudio-keyboard{
  display:inline-block;
  position:relative;
  margin:0;
  padding:0;
  font-family: sans-serif;
  font-size: 11px;
}
.webaudio-keyboard-body{
  display:inline-block;
  margin:0;
  padding:0;
  vertical-align:bottom;
}
</style>
<canvas class='webaudio-keyboard-body' tabindex='1' touch-action='none'></canvas><div class='webauioctrl-tooltip'></div>
`;
      this.cv=root.childNodes[2];
      this.ttframe=root.childNodes[3];
      this.ctx=this.cv.getContext("2d");
      this._values=[];
      this.enable=this.getAttr("enable",1);
      this._width=this.getAttr("width",480); Object.defineProperty(this,"width",{get:()=>{return this._width},set:(v)=>{this._width=v;this.setupImage()}});
      this._height=this.getAttr("height",128); Object.defineProperty(this,"height",{get:()=>{return this._height},set:(v)=>{this._height=v;this.setupImage()}});
      this._min=this.getAttr("min",0); Object.defineProperty(this,"min",{get:()=>{return this._min},set:(v)=>{this._min=+v;this.redraw()}});
      this._keys=this.getAttr("keys",25); Object.defineProperty(this,"keys",{get:()=>{return this._keys},set:(v)=>{this._keys=+v;this.setupImage()}});
      this._colors=this.getAttr("colors","#222;#eee;#ccc;#333;#000;#e88;#c44;#c33;#800"); Object.defineProperty(this,"colors",{get:()=>{return this._colors},set:(v)=>{this._colors=v;this.setupImage()}});
      this.outline=this.getAttr("outline",opt.outline);
      this.midilearn=this.getAttr("midilearn",0);
      this.midicc=this.getAttr("midicc",null);
      this.press=0;
      this.keycodes1=[90,83,88,68,67,86,71,66,72,78,74,77,188,76,190,187,191,226];
      this.keycodes2=[81,50,87,51,69,82,53,84,54,89,55,85,73,57,79,48,80,192,222,219];
      this.addEventListener("keyup",this.keyup);
      this.midiController={};
      this.midiMode="normal";
      if(this.midicc) {
          let ch = parseInt(this.midicc.substring(0, this.midicc.lastIndexOf("."))) - 1;
          let cc = parseInt(this.midicc.substring(this.midicc.lastIndexOf(".") + 1));
          this.setMidiController(ch, cc);
      }
      this.setupImage();
      this.digits=0;
      if(window.webAudioControlsMidiManager)
        window.webAudioControlsMidiManager.addWidget(this);
    }
    disconnectedCallback(){}
    setupImage(){
      this.cv.style.width=this.width+"px";
      this.cv.style.height=this.height+"px";
      this.bheight = this.height * 0.55;
      this.kp=[0,7/12,1,3*7/12,2,3,6*7/12,4,8*7/12,5,10*7/12,6];
      this.kf=[0,1,0,1,0,0,1,0,1,0,1,0];
      this.ko=[0,0,(7*2)/12-1,0,(7*4)/12-2,(7*5)/12-3,0,(7*7)/12-4,0,(7*9)/12-5,0,(7*11)/12-6];
      this.kn=[0,2,4,5,7,9,11];
      this.coltab=this.colors.split(";");
      this.cv.width = this.width;
      this.cv.height = this.height;
      this.cv.style.width = this.width+'px';
      this.cv.style.height = this.height+'px';
      this.style.height = this.height+'px';
      this.cv.style.outline=this.outline?"":"none";
      this.bheight = this.height * 0.55;
      this.max=this.min+this.keys-1;
      this.dispvalues=[];
      this.valuesold=[];
      if(this.kf[this.min%12])
        --this.min;
      if(this.kf[this.max%12])
        ++this.max;
      this.redraw();
    }
    redraw(){
      function rrect(ctx, x, y, w, h, r, c1, c2) {
        if(c2) {
          let g=ctx.createLinearGradient(x,y,x+w,y);
          g.addColorStop(0,c1);
          g.addColorStop(1,c2);
          ctx.fillStyle=g;
        }
        else
          ctx.fillStyle=c1;
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x+w, y);
        ctx.lineTo(x+w, y+h-r);
        ctx.quadraticCurveTo(x+w, y+h, x+w-r, y+h);
        ctx.lineTo(x+r, y+h);
        ctx.quadraticCurveTo(x, y+h, x, y+h-r);
        ctx.lineTo(x, y);
        ctx.fill();
      }
      this.ctx.fillStyle = this.coltab[0];
      this.ctx.fillRect(0,0,this.width,this.height);
      let x0=7*((this.min/12)|0)+this.kp[this.min%12];
      let x1=7*((this.max/12)|0)+this.kp[this.max%12];
      let n=x1-x0;
      this.wwidth=(this.width-1)/(n+1);
      this.bwidth=this.wwidth*7/12;
      let h2=this.bheight;
      let r=Math.min(8,this.wwidth*0.2);
      for(let i=this.min,j=0;i<=this.max;++i) {
        if(this.kf[i%12]==0) {
          let x=this.wwidth*(j++)+1;
          if(this.dispvalues.indexOf(i)>=0)
            rrect(this.ctx,x,1,this.wwidth-1,this.height-2,r,this.coltab[5],this.coltab[6]);
          else
            rrect(this.ctx,x,1,this.wwidth-1,this.height-2,r,this.coltab[1],this.coltab[2]);
        }
      }
      r=Math.min(8,this.bwidth*0.3);
      for(let i=this.min;i<this.max;++i) {
        if(this.kf[i%12]) {
          let x=this.wwidth*this.ko[this.min%12]+this.bwidth*(i-this.min)+1;
          if(this.dispvalues.indexOf(i)>=0)
            rrect(this.ctx,x,1,this.bwidth,h2,r,this.coltab[7],this.coltab[8]);
          else
            rrect(this.ctx,x,1,this.bwidth,h2,r,this.coltab[3],this.coltab[4]);
          this.ctx.strokeStyle=this.coltab[0];
          this.ctx.stroke();
        }
      }
    }
    _setValue(v){
      if(this.step)
        v=(Math.round((v-this.min)/this.step))*this.step+this.min;
      this._value=Math.min(this.max,Math.max(this.min,v));
      if(this._value!=this.oldvalue){
        this.oldvalue=this._value;
        this.redraw();
        this.showtip(0);
        return 1;
      }
      return 0;
    }
    setValue(v,f){
      if(this._setValue(v) && f)
        this.sendEvent("input"),this.sendEvent("change");
    }
    wheel(e){}
    keydown(e){
      let m=Math.floor((this.min+11)/12)*12;
      let k=this.keycodes1.indexOf(e.keyCode);
      if(k<0) {
        k=this.keycodes2.indexOf(e.keyCode);
        if(k>=0) k+=12;
      }
      if(k>=0){
        k+=m;
        if(this.currentKey!=k){
          this.currentKey=k;
          this.sendEventFromKey(1,k);
          this.setNote(1,k);
        }
      }
    }
    keyup(e){
      let m=Math.floor((this.min+11)/12)*12;
      let k=this.keycodes1.indexOf(e.keyCode);
      if(k<0) {
        k=this.keycodes2.indexOf(e.keyCode);
        if(k>=0) k+=12;
      }
      if(k>=0){
        k+=m;
        this.currentKey=-1;
        this.sendEventFromKey(0,k);
        this.setNote(0,k);
      }
    }
    pointerdown(ev){
      this.cv.focus();
      if(this.enable) {
        ++this.press;
      }
      let pointermove=(ev)=>{
        if(!this.enable)
          return;
        let r=this.getBoundingClientRect();
        let v=[],p;
        if(ev.touches)
          p=ev.targetTouches;
        else if(this.press)
          p=[ev];
        else
          p=[];
        if(p.length>0)
          this.drag=1;
        for(let i=0;i<p.length;++i) {
          let px=p[i].clientX-r.left;
          let py=p[i].clientY-r.top;
          let x,k,ko;
          if(py>=0&&py<this.height){
            if(py<this.bheight) {
              x=px-this.wwidth*this.ko[this.min%12];
              k=this.min+((x/this.bwidth)|0);
            }
            else {
              k=(px/this.wwidth)|0;
              ko=this.kp[this.min%12];
              k+=ko;
              k=this.min+((k/7)|0)*12+this.kn[k%7]-this.kn[ko%7];
            }
            if(k>=this.min&&k<=this.max)
              v.push(k);
          }
        }
        v.sort();
        this.values=v;
        this.sendevent();
        this.redraw();
      }
        
      let pointerup=(ev)=>{
        if(this.enable) {
          if(ev.touches)
            this.press=ev.touches.length;
          else
            this.press=0;
          pointermove(ev);
          this.sendevent();
          if(this.press==0){
            window.removeEventListener('mousemove', pointermove);
            window.removeEventListener('touchmove', pointermove, {passive:false});
            window.removeEventListener('mouseup', pointerup);
            window.removeEventListener('touchend', pointerup);
            window.removeEventListener('touchcancel', pointerup);
            document.body.removeEventListener('touchstart', preventScroll,{passive:false});
          }
          this.redraw();
        }
        this.drag=0;
        ev.preventDefault();
      }
      let preventScroll=(ev)=>{
        ev.preventDefault();
      }
      window.addEventListener('mousemove', pointermove);
      window.addEventListener('touchmove', pointermove, {passive:false});
      window.addEventListener('mouseup', pointerup);
      window.addEventListener('touchend', pointerup);
      window.addEventListener('touchcancel', pointerup);
      document.body.addEventListener('touchstart', preventScroll,{passive:false});
      pointermove(ev);
      ev.preventDefault();
      ev.stopPropagation();
    }
    sendEventFromKey(s,k){
      let ev=document.createEvent('HTMLEvents');
      ev.initEvent('change',true,true);
      ev.note=[s,k];
      this.dispatchEvent(ev);
    }
    sendevent(){
      let notes=[];
      for(let i=0,j=this.valuesold.length;i<j;++i) {
        if(this.values.indexOf(this.valuesold[i])<0)
          notes.push([0,this.valuesold[i]]);
      }
      for(let i=0,j=this.values.length;i<j;++i) {
        if(this.valuesold.indexOf(this.values[i])<0)
          notes.push([1,this.values[i]]);
      }
      if(notes.length) {
        this.valuesold=this.values;
        for(let i=0;i<notes.length;++i) {
          this.setdispvalues(notes[i][0],notes[i][1]);
          let ev=document.createEvent('HTMLEvents');
          ev.initEvent('change',true,true);
          ev.note=notes[i];
          this.dispatchEvent(ev);
        }
      }
    }
    setdispvalues(state,note) {
      let n=this.dispvalues.indexOf(note);
      if(state) {
        if(n<0) this.dispvalues.push(note);
      }
      else {
        if(n>=0) this.dispvalues.splice(n,1);
      }
    }
    setNote(state,note) {
      this.setdispvalues(state,note);
      this.redraw();
    }
  });
} catch(error){
  console.log("webaudio-keyboard already defined");
}

try{
  customElements.define("webaudio-xypad", class WebAudioXYPad extends WebAudioControlsWidget {
    constructor(){
      super();
    }
    connectedCallback(){
      let root;
//      if(this.attachShadow)
//        root=this.attachShadow({mode: 'open'});
//      else
        root=this;
      root.innerHTML=
`<style>
${this.basestyle}
webaudio-xypad{
  display:inline-block;
  position:relative;
  margin:0;
  padding:0;
  font-family: sans-serif;
  font-size: 11px;
  cursor:pointer;
}
.webaudio-xypad-body{
  display:inline-block;
  position:relative;
  margin:0;
  padding:0;
  vertical-align:bottom;
}
.webaudio-xypad-knob{
  display:inline-block;
  position:absolute;
  margin:0;
  padding:0;
}
</style>
<div class='webaudio-xypad-body' tabindex='1' touch-action='none'><div class='webaudio-xypad-knob' touch-action='none'></div></div><div class='webaudioctrl-tooltip'></div>
`;
      this.elem=root.childNodes[2];
      this.knob=this.elem.childNodes[0];
      this.ttframe=root.childNodes[3];

      this.enable=this.getAttr("enable",1);
      this._src=this.getAttr("src",opt.sliderSrc); Object.defineProperty(this,"src",{get:()=>{return this._src},set:(v)=>{this._src=v;this.setupImage()}});
      this._knobsrc=this.getAttr("knobsrc",opt.sliderKnobsrc); Object.defineProperty(this,"knobsrc",{get:()=>{return this._knobsrc},set:(v)=>{this._knobsrc=v;this.setupImage()}});
      this._x=this.getAttr("x",50); Object.defineProperty(this,"x",{get:()=>{return this._x},set:(v)=>{this._x=v;this.redraw()}});
      this._y=this.getAttr("y",50); Object.defineProperty(this,"y",{get:()=>{return this._y},set:(v)=>{this._y=v;this.redraw()}});
      this.defx=this.getAttr("defx",50);
      this.defy=this.getAttr("defy",50);
      this._min=this.getAttr("min",0); Object.defineProperty(this,"min",{get:()=>{return this._min},set:(v)=>{this._min=v;this.redraw()}});
      this._max=this.getAttr("max",100); Object.defineProperty(this,"max",{get:()=>{return this._max},set:(v)=>{this._max=v;this.redraw()}});
      this._step=this.getAttr("step",1); Object.defineProperty(this,"step",{get:()=>{return this._step},set:(v)=>{this._step=v;this.redraw()}});
      this._sprites=this.getAttr("sprites",0); Object.defineProperty(this,"sprites",{get:()=>{return this._sprites},set:(v)=>{this._sprites=v;this.setupImage()}});
      this._width=this.getAttr("width",128); Object.defineProperty(this,"width",{get:()=>{return this._width},set:(v)=>{this._width=v;this.setupImage()}});
      this._height=this.getAttr("height",128); Object.defineProperty(this,"height",{get:()=>{return this._height},set:(v)=>{this._height=v;this.setupImage()}});
      this._knobwidth=this.getAttr("knobwidth",28); Object.defineProperty(this,"knobwidth",{get:()=>{return this._knobwidth},set:(v)=>{this._knobwidth=v;this.setupImage()}});
      this._knobheight=this.getAttr("knbheight",28); Object.defineProperty(this,"knobheight",{get:()=>{return this._knobheight},set:(v)=>{this._knobheight=v;this.setupImage()}});
      this._colors=this.getAttr("colors",opt.sliderColors); Object.defineProperty(this,"colors",{get:()=>{return this._colors},set:(v)=>{this._colors=v;this.setupImage()}});
      this.outline=this.getAttr("outline",opt.outline);
      this.valuetip=this.getAttr("valuetip",1);
      this.tooltip=this.getAttr("tooltip",null);
      this.conv=this.getAttr("conv",null);
      if(this.conv){
        this.convValue={x:eval(this.conv)(this._x),y:eval(this.conv)(this._y)};
      }
      else
        this.convValue={x:this._x,y:this._y};
      this.midilearn=this.getAttr("midilearn",opt.midilearn);
      this.midicc=this.getAttr("midicc",null);
      this.midiController={};
      this.midiMode="normal";
      if(this.midicc) {
          let ch = parseInt(this.midicc.substring(0, this.midicc.lastIndexOf("."))) - 1;
          let cc = parseInt(this.midicc.substring(this.midicc.lastIndexOf(".") + 1));
          this.setMidiController(ch, cc);
      }
      this.setupImage();
      this.digits=0;
      if(window.webAudioControlsMidiManager)
//        window.webAudioControlsMidiManager.updateWidgets();
        window.webAudioControlsMidiManager.addWidget(this);
      this.elem.onclick=(e)=>{e.stopPropagation()};
    }
    disconnectedCallback(){}
    setupImage(){
      this.coltab = this.colors.split(";");
      this.dr=this.direction;
      this.dlen=this.ditchlength;
      if(!this.width)
        this.width=256;
      if(!this.height)
        this.height=256;
      this.knob.style.backgroundSize = "100% 100%";
      this.elem.style.backgroundSize = "100% 100%";
      this.elem.style.width=this.width+"px";
      this.elem.style.height=this.height+"px";
      this.kwidth=this.knobwidth||(this.width*0.15|0);
      this.kheight=this.knobheight||(this.height*0.15|0);
      this.knob.style.width = this.kwidth+"px";
      this.knob.style.height = this.kheight+"px";
      if(!this.src){
        let r=Math.min(this.width,this.height)*0.02;
        let svgbody=
`<svg xmlns="http://www.w3.org/2000/svg" width="${this.width}" height="${this.height}" preserveAspectRatio="none">
<rect x="1" y="1" rx="${r}" ry="${r}" width="${this.width-2}" height="${this.height-2}" fill="${this.coltab[1]}"/></svg>`;
        this.elem.style.backgroundImage = "url(data:image/svg+xml;base64,"+btoa(svgbody)+")";
      }
      else{
        this.elem.style.backgroundImage = "url("+(this.src)+")";
      }
      if(!this.knobsrc){
        let svgthumb=
`<svg xmlns="http://www.w3.org/2000/svg" width="${this.kwidth}" height="${this.kheight}" preserveAspectRatio="none">
<radialGradient id="gr" cx="30%" cy="30%"><stop offset="0%" stop-color="${this.coltab[2]}"/><stop offset="100%" stop-color="${this.coltab[0]}"/></radialGradient>
<rect x="2" y="2" width="${this.kwidth-4}" height="${this.kheight-4}" rx="${this.kwidth*0.5}" ry="${this.kheight*0.5}" fill="url(#gr)"/></svg>`;
        this.knob.style.backgroundImage = "url(data:image/svg+xml;base64,"+btoa(svgthumb)+")";
      }
      else{
        this.knob.style.backgroundImage = "url("+(this.knobsrc)+")";
      }
      this.elem.style.outline=this.outline?"":"none";
      this.redraw();
    }
    redraw() {
      this.digits=0;
      if(this.step && this.step < 1) {
        for(let n = this.step ; n < 1; n *= 10)
          ++this.digits;
      }
      if(this.value<this.min){
        this.value=this.min;
        return;
      }
      if(this.value>this.max){
        this.value=this.max;
        return;
      }
      let range = this.max - this.min;
      let style = this.knob.style;
      style.left=(this.width-this.kwidth)*(this._x-this.min)/(this.max-this.min)+"px"; style.top=(this.height-this.kheight)*(1-(this._y-this.min)/(this.max-this.min))+"px";
      this.sensex=0; this.sensey=1;
    }
    _setX(v){
      v=(Math.round((v-this.min)/this.step))*this.step+this.min;
      this._x=Math.min(this.max,Math.max(this.min,v));
      if(this._x!=this.oldx){
        this.oldx=this._x;
        if(this.conv){
          this.convValue={x:eval(this.conv)(this._x),y:eval(this.conv)(this._y)};
        }
        else
          this.convValue={x:this._x,y:this._y};
        this.redraw();
        this.showtip(0);
        return 1;
      }
      return 0;
    }
    _setY(v){
      v=(Math.round((v-this.min)/this.step))*this.step+this.min;
      this._y=Math.min(this.max,Math.max(this.min,v));
      if(this._y!=this.oldy){
        this.oldy=this._y;
        if(this.conv){
          this.convValue={x:eval(this.conv)(this._x),y:eval(this.conv)(this._y)};
        }
        else
          this.convValue={x:this._x,y:this._y};
        this.redraw();
        this.showtip(0);
        return 1;
      }
      return 0;
    }
    setX(v,f){
      if(this._setX(v)&&f)
        this.sendEvent("input"),this.sendEvent("change");
    }
    setY(v,f){
      if(this._setY(v)&&f)
        this.sendEvent("input"),this.sendEvent("change");
    }
    wheel(e) {
      let delta=(this.max-this.min)*0.01;
      delta=e.deltaY>0?-delta:delta;
      if(!e.shiftKey)
        delta*=5;
      if(Math.abs(delta) < this.step)
        delta = (delta > 0) ? +this.step : -this.step;
      this.setValue(+this.value+delta,true);
      e.preventDefault();
      e.stopPropagation();
      this.redraw();
    }
    pointerdown(ev){
      if(!this.enable)
        return;
      let e=ev;
      if(ev.touches){
        e = ev.changedTouches[0];
        this.identifier=e.identifier;
      }
      else {
        if(e.buttons!=1 && e.button!=0)
          return;
      }
      this.elem.focus();
      this.drag=1;
      this.showtip(0);
      let pointermove=(ev)=>{
        let e=ev;
        if(ev.touches){
          for(let i=0;i<ev.touches.length;++i){
            if(ev.touches[i].identifier==this.identifier){
              e = ev.touches[i];
              break;
            }
          }
        }
        if(this.lastShift !== e.shiftKey) {
          this.lastShift = e.shiftKey;
          this.startPosX = e.pageX;
          this.startPosY = e.pageY;
          this.startVal = this.value;
        }
        let offsetX = (e.pageX - this.startPosX);
        let offsetY = (this.startPosY - e.pageY);
        let rc=this.getBoundingClientRect();
        this._setX(this.min+(this.max-this.min)*(e.pageX-rc.x-this.kwidth*.5)/(this.width-this.kwidth));
        this._setY(this.min+(this.max-this.min)*(1-(e.pageY-rc.y-this.kheight*.5)/(this.height-this.kheight)));
        this.sendEvent("input");
        if(e.preventDefault)
          e.preventDefault();
        if(e.stopPropagation)
          e.stopPropagation();
        return false;
      }
      let pointerup=(ev)=>{
        let e=ev;
        if(ev.touches){
          for(let i=0;;){
            if(ev.changedTouches[i].identifier==this.identifier){
              break;
            }
            if(++i>=ev.changedTouches.length)
              return;
          }
        }
        this.drag=0;
        this.showtip(0);
        this.startPosX = this.startPosY = null;
        window.removeEventListener('mousemove', pointermove);
        window.removeEventListener('touchmove', pointermove, {passive:false});
        window.removeEventListener('mouseup', pointerup);
        window.removeEventListener('touchend', pointerup);
        window.removeEventListener('touchcancel', pointerup);
        document.body.removeEventListener('touchstart', preventScroll,{passive:false});
        this.sendEvent("change");
      }
      pointermove(ev);
      let preventScroll=(e)=>{
        e.preventDefault();
      }
      if(e.touches)
        e = e.touches[0];
      if(e.ctrlKey || e.metaKey)
        this.setValue(this.defvalue,true);
      else {
        this.startPosX = e.pageX;
        this.startPosY = e.pageY;
        this.startVal = this.value;
        window.addEventListener('mousemove', pointermove);
        window.addEventListener('touchmove', pointermove, {passive:false});
      }
      window.addEventListener('mouseup', pointerup);
      window.addEventListener('touchend', pointerup);
      window.addEventListener('touchcancel', pointerup);
      document.body.addEventListener('touchstart', preventScroll,{passive:false});
      e.preventDefault();
      e.stopPropagation();
      return false;
    }
  });
} catch(error){
  console.log("webaudio-xypad already defined");
}



  // FOR MIDI LEARN
  class WebAudioControlsMidiManager {
    constructor(){
      this.midiAccess = null;
      this.listOfWidgets = [];
      this.listOfExternalMidiListeners = [];
      this.updateWidgets();
      this.initWebAudioControls();
    }
    addWidget(w){
      this.listOfWidgets.push(w);
    }
    updateWidgets(){
//      this.listOfWidgets = document.querySelectorAll("webaudio-knob,webaudio-slider,webaudio-switch");
    }
    initWebAudioControls() {
      if(navigator.requestMIDIAccess) {
        navigator.requestMIDIAccess().then(
          (ma)=>{this.midiAccess = ma,this.enableInputs()},
          (err)=>{ console.log("MIDI not initialized - error encountered:" + err.code)}
        );
      }
    }
    enableInputs() {
      let inputs = this.midiAccess.inputs.values();
      console.log("Found " + this.midiAccess.inputs.size + " MIDI input(s)");
      for(let input = inputs.next(); input && !input.done; input = inputs.next()) {
        console.log("Connected input: " + input.value.name);
        input.value.onmidimessage = this.handleMIDIMessage.bind(this);
      }
    }
    midiConnectionStateChange(e) {
      console.log("connection: " + e.port.name + " " + e.port.connection + " " + e.port.state);
      enableInputs();
    }

    onMIDIStarted(midi) {
      this.midiAccess = midi;
      midi.onstatechange = this.midiConnectionStateChange;
      enableInputs(midi);
    }
    // Add hooks for external midi listeners support
    addMidiListener(callback) {
      this.listOfExternalMidiListeners.push(callback);
    }
    getCurrentConfigAsJSON() {
      return currentConfig.stringify();
    }
    handleMIDIMessage(event) {
      this.listOfExternalMidiListeners.forEach(function (externalListener) {
        externalListener(event);
      });
      if(((event.data[0] & 0xf0) == 0xf0) || ((event.data[0] & 0xf0) == 0xb0 && event.data[1] >= 120))
        return;
      for(let w of this.listOfWidgets) {
        if(w.processMidiEvent)
          w.processMidiEvent(event);
      }
      if(opt.mididump)
        console.log(event.data);
    }
    contextMenuOpen(e,knob){
      if(!this.midiAccess)
        return;
      let menu=document.getElementById("webaudioctrl-context-menu");
      menu.style.left=e.pageX+"px";
      menu.style.top=e.pageY+"px";
      menu.knob=knob;
      menu.classList.add("active");
      menu.knob.focus();
//      document.activeElement.onblur=this.contextMenuClose;
      menu.knob.addEventListener("keydown",this.contextMenuCloseByKey.bind(this));
    }
    contextMenuCloseByKey(e){
      if(e.keyCode==27)
       this.contextMenuClose();
    }
    contextMenuClose(){
      let menu=document.getElementById("webaudioctrl-context-menu");
      menu.knob.removeEventListener("keydown",this.contextMenuCloseByKey);
      menu.classList.remove("active");
      let menuItemLearn=document.getElementById("webaudioctrl-context-menu-learn");
      menuItemLearn.innerHTML = 'Learn';
      menu.knob.midiMode = 'normal';
    }
    contextMenuLearn(){
      let menu=document.getElementById("webaudioctrl-context-menu");
      let menuItemLearn=document.getElementById("webaudioctrl-context-menu-learn");
      menuItemLearn.innerHTML = 'Listening...';
      menu.knob.midiMode = 'learn';
    }
    contextMenuClear(e){
      let menu=document.getElementById("webaudioctrl-context-menu");
      menu.knob.midiController={};
      this.contextMenuClose();
    }
  }
  if(window.UseWebAudioControlsMidi||opt.useMidi)
    window.webAudioControlsMidiManager = new WebAudioControlsMidiManager();
}


================================================
FILE: src/assets/js/webcomponents-lite.js
================================================
(function(){/*

 Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 Code distributed by Google as part of the polymer project is also
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
'use strict';var p,q="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this,ba="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)};function ca(){ca=function(){};q.Symbol||(q.Symbol=da)}var da=function(){var a=0;return function(b){return"jscomp_symbol_"+(b||"")+a++}}();
function ea(){ca();var a=q.Symbol.iterator;a||(a=q.Symbol.iterator=q.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&ba(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return fa(this)}});ea=function(){}}function fa(a){var b=0;return ha(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})}function ha(a){ea();a={next:a};a[q.Symbol.iterator]=function(){return this};return a}function ia(a){ea();var b=a[Symbol.iterator];return b?b.call(a):fa(a)}
function ja(a){for(var b,c=[];!(b=a.next()).done;)c.push(b.value);return c}
(function(){if(!function(){var a=document.createEvent("Event");a.initEvent("foo",!0,!0);a.preventDefault();return a.defaultPrevented}()){var a=Event.prototype.preventDefault;Event.prototype.preventDefault=function(){this.cancelable&&(a.call(this),Object.defineProperty(this,"defaultPrevented",{get:function(){return!0},configurable:!0}))}}var b=/Trident/.test(navigator.userAgent);if(!window.CustomEvent||b&&"function"!==typeof window.CustomEvent)window.CustomEvent=function(a,b){b=b||{};var c=document.createEvent("CustomEvent");
c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c},window.CustomEvent.prototype=window.Event.prototype;if(!window.Event||b&&"function"!==typeof window.Event){var c=window.Event;window.Event=function(a,b){b=b||{};var c=document.createEvent("Event");c.initEvent(a,!!b.bubbles,!!b.cancelable);return c};if(c)for(var d in c)window.Event[d]=c[d];window.Event.prototype=c.prototype}if(!window.MouseEvent||b&&"function"!==typeof window.MouseEvent){b=window.MouseEvent;window.MouseEvent=function(a,
b){b=b||{};var c=document.createEvent("MouseEvent");c.initMouseEvent(a,!!b.bubbles,!!b.cancelable,b.view||window,b.detail,b.screenX,b.screenY,b.clientX,b.clientY,b.ctrlKey,b.altKey,b.shiftKey,b.metaKey,b.button,b.relatedTarget);return c};if(b)for(d in b)window.MouseEvent[d]=b[d];window.MouseEvent.prototype=b.prototype}Array.from||(Array.from=function(a){return[].slice.call(a)});Object.assign||(Object.assign=function(a,b){for(var c=[].slice.call(arguments,1),d=0,e;d<c.length;d++)if(e=c[d])for(var f=
a,m=e,n=Object.getOwnPropertyNames(m),t=0;t<n.length;t++)e=n[t],f[e]=m[e];return a})})(window.WebComponents);(function(){function a(){}function b(a,b){if(!a.childNodes.length)return[];switch(a.nodeType){case Node.DOCUMENT_NODE:return t.call(a,b);case Node.DOCUMENT_FRAGMENT_NODE:return C.call(a,b);default:return n.call(a,b)}}var c="undefined"===typeof HTMLTemplateElement,d=!(document.createDocumentFragment().cloneNode()instanceof DocumentFragment),e=!1;/Trident/.test(navigator.userAgent)&&function(){function a(a,b){if(a instanceof DocumentFragment)for(var d;d=a.firstChild;)c.call(this,d,b);else c.call(this,
a,b);return a}e=!0;var b=Node.prototype.cloneNode;Node.prototype.cloneNode=function(a){a=b.call(this,a);this instanceof DocumentFragment&&(a.__proto__=DocumentFragment.prototype);return a};DocumentFragment.prototype.querySelectorAll=HTMLElement.prototype.querySelectorAll;DocumentFragment.prototype.querySelector=HTMLElement.prototype.querySelector;Object.defineProperties(DocumentFragment.prototype,{nodeType:{get:function(){return Node.DOCUMENT_FRAGMENT_NODE},configurable:!0},localName:{get:function(){},
configurable:!0},nodeName:{get:function(){return"#document-fragment"},configurable:!0}});var c=Node.prototype.insertBefore;Node.prototype.insertBefore=a;var d=Node.prototype.appendChild;Node.prototype.appendChild=function(b){b instanceof DocumentFragment?a.call(this,b,null):d.call(this,b);return b};var f=Node.prototype.removeChild,h=Node.prototype.replaceChild;Node.prototype.replaceChild=function(b,c){b instanceof DocumentFragment?(a.call(this,b,c),f.call(this,c)):h.call(this,b,c);return c};Document.prototype.createDocumentFragment=
function(){var a=this.createElement("df");a.__proto__=DocumentFragment.prototype;return a};var g=Document.prototype.importNode;Document.prototype.importNode=function(a,b){b=g.call(this,a,b||!1);a instanceof DocumentFragment&&(b.__proto__=DocumentFragment.prototype);return b}}();var f=Node.prototype.cloneNode,h=Document.prototype.createElement,g=Document.prototype.importNode,k=Node.prototype.removeChild,l=Node.prototype.appendChild,m=Node.prototype.replaceChild,n=Element.prototype.querySelectorAll,
t=Document.prototype.querySelectorAll,C=DocumentFragment.prototype.querySelectorAll,eb=function(){if(!c){var a=document.createElement("template"),b=document.createElement("template");b.content.appendChild(document.createElement("div"));a.content.appendChild(b);a=a.cloneNode(!0);return 0===a.content.childNodes.length||0===a.content.firstChild.content.childNodes.length||d}}();if(c){var J=document.implementation.createHTMLDocument("template"),Ca=!0,Da=document.createElement("style");Da.textContent="template{display:none;}";
var Ea=document.head;Ea.insertBefore(Da,Ea.firstElementChild);a.prototype=Object.create(HTMLElement.prototype);var x=!document.createElement("div").hasOwnProperty("innerHTML");a.D=function(b){if(!b.content){b.content=J.createDocumentFragment();for(var c;c=b.firstChild;)l.call(b.content,c);if(x)b.__proto__=a.prototype;else if(b.cloneNode=function(b){return a.ca(this,b)},Ca)try{na(b),aa(b)}catch(Mg){Ca=!1}a.J(b.content)}};var na=function(b){Object.defineProperty(b,"innerHTML",{get:function(){for(var a=
"",b=this.content.firstChild;b;b=b.nextSibling)a+=b.outerHTML||b.data.replace(oa,U);return a},set:function(b){J.body.innerHTML=b;for(a.J(J);this.content.firstChild;)k.call(this.content,this.content.firstChild);for(;J.body.firstChild;)l.call(this.content,J.body.firstChild)},configurable:!0})},aa=function(a){Object.defineProperty(a,"outerHTML",{get:function(){return"<template>"+this.innerHTML+"</template>"},set:function(a){if(this.parentNode){J.body.innerHTML=a;for(a=this.ownerDocument.createDocumentFragment();J.body.firstChild;)l.call(a,
J.body.firstChild);m.call(this.parentNode,a,this)}else throw Error("Failed to set the 'outerHTML' property on 'Element': This element has no parent node.");},configurable:!0})};na(a.prototype);aa(a.prototype);a.J=function(c){c=b(c,"template");for(var d=0,e=c.length,f;d<e&&(f=c[d]);d++)a.D(f)};document.addEventListener("DOMContentLoaded",function(){a.J(document)});Document.prototype.createElement=function(){var b=h.apply(this,arguments);"template"===b.localName&&a.D(b);return b};var oa=/[&\u00A0<>]/g,
U=function(a){switch(a){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case "\u00a0":return"&nbsp;"}}}if(c||eb){a.ca=function(a,b){var c=f.call(a,!1);this.D&&this.D(c);b&&(l.call(c.content,f.call(a.content,!0)),fb(c.content,a.content));return c};var fb=function(c,d){if(d.querySelectorAll&&(d=b(d,"template"),0!==d.length)){c=b(c,"template");for(var e=0,f=c.length,h,g;e<f;e++)g=d[e],h=c[e],a&&a.D&&a.D(g),m.call(h.parentNode,pa.call(g,!0),h)}},pa=Node.prototype.cloneNode=function(b){if(!e&&
d&&this instanceof DocumentFragment)if(b)var c=qa.call(this.ownerDocument,this,!0);else return this.ownerDocument.createDocumentFragment();else c=this.nodeType===Node.ELEMENT_NODE&&"template"===this.localName?a.ca(this,b):f.call(this,b);b&&fb(c,this);return c},qa=Document.prototype.importNode=function(c,d){d=d||!1;if("template"===c.localName)return a.ca(c,d);var e=g.call(this,c,d);if(d){fb(e,c);c=b(e,'script:not([type]),script[type="application/javascript"],script[type="text/javascript"]');for(var f,
k=0;k<c.length;k++){f=c[k];d=h.call(document,"script");d.textContent=f.textContent;for(var l=f.attributes,qa=0,pa;qa<l.length;qa++)pa=l[qa],d.setAttribute(pa.name,pa.value);m.call(f.parentNode,d,f)}}return e}}c&&(window.HTMLTemplateElement=a)})();var ka=Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)};var la=0,ma,ra="undefined"!==typeof window?window:void 0,sa=ra||{},ta=sa.MutationObserver||sa.WebKitMutationObserver,ua="undefined"!==typeof Uint8ClampedArray&&"undefined"!==typeof importScripts&&"undefined"!==typeof MessageChannel;function va(){return"undefined"!==typeof ma?function(){ma(wa)}:xa()}function ya(){var a=0,b=new ta(wa),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=a=++a%2}}
function za(){var a=new MessageChannel;a.port1.onmessage=wa;return function(){return a.port2.postMessage(0)}}function xa(){var a=setTimeout;return function(){return a(wa,1)}}var Aa=Array(1E3);function wa(){for(var a=0;a<la;a+=2)(0,Aa[a])(Aa[a+1]),Aa[a]=void 0,Aa[a+1]=void 0;la=0}var Ba,Fa;
if("undefined"===typeof self&&"undefined"!==typeof process&&"[object process]"==={}.toString.call(process))Fa=function(){return process.ib(wa)};else{var Ga;if(ta)Ga=ya();else{var Ha;if(ua)Ha=za();else{var Ia;if(void 0===ra&&"function"===typeof require)try{var Ja=require("vertx");ma=Ja.kb||Ja.jb;Ia=va()}catch(a){Ia=xa()}else Ia=xa();Ha=Ia}Ga=Ha}Fa=Ga}Ba=Fa;function Ka(a,b){Aa[la]=a;Aa[la+1]=b;la+=2;2===la&&Ba()};function La(a,b){var c=this,d=new this.constructor(Ma);void 0===d[Na]&&Oa(d);var e=c.g;if(e){var f=arguments[e-1];Ka(function(){return Pa(e,d,f,c.f)})}else Qa(c,d,a,b);return d};function Ra(a){if(a&&"object"===typeof a&&a.constructor===this)return a;var b=new this(Ma);Sa(b,a);return b};var Na=Math.random().toString(36).substring(16);function Ma(){}var Ua=new Ta;function Va(a){try{return a.then}catch(b){return Ua.error=b,Ua}}function Wa(a,b,c,d){try{a.call(b,c,d)}catch(e){return e}}function Xa(a,b,c){Ka(function(a){var d=!1,f=Wa(c,b,function(c){d||(d=!0,b!==c?Sa(a,c):r(a,c))},function(b){d||(d=!0,u(a,b))});!d&&f&&(d=!0,u(a,f))},a)}function Ya(a,b){1===b.g?r(a,b.f):2===b.g?u(a,b.f):Qa(b,void 0,function(b){return Sa(a,b)},function(b){return u(a,b)})}
function Za(a,b,c){b.constructor===a.constructor&&c===La&&b.constructor.resolve===Ra?Ya(a,b):c===Ua?(u(a,Ua.error),Ua.error=null):void 0===c?r(a,b):"function"===typeof c?Xa(a,b,c):r(a,b)}function Sa(a,b){if(a===b)u(a,new TypeError("You cannot resolve a promise with itself"));else{var c=typeof b;null===b||"object"!==c&&"function"!==c?r(a,b):Za(a,b,Va(b))}}function $a(a){a.na&&a.na(a.f);ab(a)}function r(a,b){void 0===a.g&&(a.f=b,a.g=1,0!==a.I.length&&Ka(ab,a))}
function u(a,b){void 0===a.g&&(a.g=2,a.f=b,Ka($a,a))}function Qa(a,b,c,d){var e=a.I,f=e.length;a.na=null;e[f]=b;e[f+1]=c;e[f+2]=d;0===f&&a.g&&Ka(ab,a)}function ab(a){var b=a.I,c=a.g;if(0!==b.length){for(var d,e,f=a.f,h=0;h<b.length;h+=3)d=b[h],e=b[h+c],d?Pa(c,d,e,f):e(f);a.I.length=0}}function Ta(){this.error=null}var bb=new Ta;
function Pa(a,b,c,d){var e="function"===typeof c;if(e){try{var f=c(d)}catch(l){bb.error=l,f=bb}if(f===bb){var h=!0;var g=f.error;f.error=null}else var k=!0;if(b===f){u(b,new TypeError("A promises callback cannot return that same promise."));return}}else f=d,k=!0;void 0===b.g&&(e&&k?Sa(b,f):h?u(b,g):1===a?r(b,f):2===a&&u(b,f))}function cb(a,b){try{b(function(b){Sa(a,b)},function(b){u(a,b)})}catch(c){u(a,c)}}var db=0;function Oa(a){a[Na]=db++;a.g=void 0;a.f=void 0;a.I=[]};function gb(a,b){this.Ea=a;this.A=new a(Ma);this.A[Na]||Oa(this.A);if(ka(b))if(this.S=this.length=b.length,this.f=Array(this.length),0===this.length)r(this.A,this.f);else{this.length=this.length||0;for(a=0;void 0===this.g&&a<b.length;a++)hb(this,b[a],a);0===this.S&&r(this.A,this.f)}else u(this.A,Error("Array Methods must be provided an Array"))}
function hb(a,b,c){var d=a.Ea,e=d.resolve;e===Ra?(e=Va(b),e===La&&void 0!==b.g?ib(a,b.g,c,b.f):"function"!==typeof e?(a.S--,a.f[c]=b):d===v?(d=new d(Ma),Za(d,b,e),jb(a,d,c)):jb(a,new d(function(a){return a(b)}),c)):jb(a,e(b),c)}function ib(a,b,c,d){var e=a.A;void 0===e.g&&(a.S--,2===b?u(e,d):a.f[c]=d);0===a.S&&r(e,a.f)}function jb(a,b,c){Qa(b,void 0,function(b){return ib(a,1,c,b)},function(b){return ib(a,2,c,b)})};function kb(a){return(new gb(this,a)).A};function lb(a){var b=this;return ka(a)?new b(function(c,d){for(var e=a.length,f=0;f<e;f++)b.resolve(a[f]).then(c,d)}):new b(function(a,b){return b(new TypeError("You must pass an array to race."))})};function mb(a){var b=new this(Ma);u(b,a);return b};function v(a){this[Na]=db++;this.f=this.g=void 0;this.I=[];if(Ma!==a){if("function"!==typeof a)throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(this instanceof v)cb(this,a);else throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");}}v.prototype={constructor:v,then:La,a:function(a){return this.then(null,a)}};/*

Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
window.Promise||(window.Promise=v,v.prototype["catch"]=v.prototype.a,v.prototype.then=v.prototype.then,v.all=kb,v.race=lb,v.resolve=Ra,v.reject=mb);(function(a){function b(a,b){if("function"===typeof window.CustomEvent)return new CustomEvent(a,b);var c=document.createEvent("CustomEvent");c.initCustomEvent(a,!!b.bubbles,!!b.cancelable,b.detail);return c}function c(a){if(C)return a.ownerDocument!==document?a.ownerDocument:null;var b=a.__importDoc;if(!b&&a.parentNode){b=a.parentNode;if("function"===typeof b.closest)b=b.closest("link[rel=import]");else for(;!g(b)&&(b=b.parentNode););a.__importDoc=b}return b}function d(a){var b=m(document,"link[rel=import]:not([import-dependency])"),
c=b.length;c?n(b,function(b){return h(b,function(){0===--c&&a()})}):a()}function e(a){function b(){"loading"!==document.readyState&&document.body&&(document.removeEventListener("readystatechange",b),a())}document.addEventListener("readystatechange",b);b()}function f(a){e(function(){return d(function(){return a&&a()})})}function h(a,b){if(a.__loaded)b&&b();else if("script"===a.localName&&!a.src||"style"===a.localName&&!a.firstChild)a.__loaded=!0,b&&b();else{var c=function(d){a.removeEventListener(d.type,
c);a.__loaded=!0;b&&b()};a.addEventListener("load",c);aa&&"style"===a.localName||a.addEventListener("error",c)}}function g(a){return a.nodeType===Node.ELEMENT_NODE&&"link"===a.localName&&"import"===a.rel}function k(){var a=this;this.a={};this.b=0;this.c=new MutationObserver(function(b){return a.Ra(b)});this.c.observe(document.head,{childList:!0,subtree:!0});this.loadImports(document)}function l(a){n(m(a,"template"),function(a){n(m(a.content,'script:not([type]),script[type="application/javascript"],script[type="text/javascript"]'),
function(a){var b=document.createElement("script");n(a.attributes,function(a){return b.setAttribute(a.name,a.value)});b.textContent=a.textContent;a.parentNode.replaceChild(b,a)});l(a.content)})}function m(a,b){return a.childNodes.length?a.querySelectorAll(b):eb}function n(a,b,c){var d=a?a.length:0,e=c?-1:1;for(c=c?d-1:0;c<d&&0<=c;c+=e)b(a[c],c)}var t=document.createElement("link"),C="import"in t,eb=t.querySelectorAll("*"),J=null;!1==="currentScript"in document&&Object.defineProperty(document,"currentScript",
{get:function(){return J||("complete"!==document.readyState?document.scripts[document.scripts.length-1]:null)},configurable:!0});var Ca=/(url\()([^)]*)(\))/g,Da=/(@import[\s]+(?!url\())([^;]*)(;)/g,Ea=/(<link[^>]*)(rel=['|"]?stylesheet['|"]?[^>]*>)/g,x={La:function(a,b){a.href&&a.setAttribute("href",x.Y(a.getAttribute("href"),b));a.src&&a.setAttribute("src",x.Y(a.getAttribute("src"),b));if("style"===a.localName){var c=x.ta(a.textContent,b,Ca);a.textContent=x.ta(c,b,Da)}},ta:function(a,b,c){return a.replace(c,
function(a,c,d,e){a=d.replace(/["']/g,"");b&&(a=x.Y(a,b));return c+"'"+a+"'"+e})},Y:function(a,b){if(void 0===x.ba){x.ba=!1;try{var c=new URL("b","http://a");c.pathname="c%20d";x.ba="http://a/c%20d"===c.href}catch(Lg){}}if(x.ba)return(new URL(a,b)).href;c=x.Ba;c||(c=document.implementation.createHTMLDocument("temp"),x.Ba=c,c.ma=c.createElement("base"),c.head.appendChild(c.ma),c.la=c.createElement("a"));c.ma.href=b;c.la.href=a;return c.la.href||a}},na={async:!0,load:function(a,b,c){if(a)if(a.match(/^data:/)){a=
a.split(",");var d=a[1];d=-1<a[0].indexOf(";base64")?atob(d):decodeURIComponent(d);b(d)}else{var e=new XMLHttpRequest;e.open("GET",a,na.async);e.onload=function(){var a=e.responseURL||e.getResponseHeader("Location");a&&0===a.indexOf("/")&&(a=(location.origin||location.protocol+"//"+location.host)+a);var d=e.response||e.responseText;304===e.status||0===e.status||200<=e.status&&300>e.status?b(d,a):c(d)};e.send()}else c("error: href must be specified")}},aa=/Trident/.test(navigator.userAgent)||/Edge\/\d./i.test(navigator.userAgent);
k.prototype.loadImports=function(a){var b=this;a=m(a,"link[rel=import]");n(a,function(a){return b.s(a)})};k.prototype.s=function(a){var b=this,c=a.href;if(void 0!==this.a[c]){var d=this.a[c];d&&d.__loaded&&(a.__import=d,this.h(a))}else this.b++,this.a[c]="pending",na.load(c,function(a,d){a=b.Sa(a,d||c);b.a[c]=a;b.b--;b.loadImports(a);b.L()},function(){b.a[c]=null;b.b--;b.L()})};k.prototype.Sa=function(a,b){if(!a)return document.createDocumentFragment();aa&&(a=a.replace(Ea,function(a,b,c){return-1===
a.indexOf("type=")?b+" type=import-disable "+c:a}));var c=document.createElement("template");c.innerHTML=a;if(c.content)a=c.content,l(a);else for(a=document.createDocumentFragment();c.firstChild;)a.appendChild(c.firstChild);if(c=a.querySelector("base"))b=x.Y(c.getAttribute("href"),b),c.removeAttribute("href");c=m(a,'link[rel=import],link[rel=stylesheet][href][type=import-disable],style:not([type]),link[rel=stylesheet][href]:not([type]),script:not([type]),script[type="application/javascript"],script[type="text/javascript"]');
var d=0;n(c,function(a){h(a);x.La(a,b);a.setAttribute("import-dependency","");"script"===a.localName&&!a.src&&a.textContent&&(a.setAttribute("src","data:text/javascript;charset=utf-8,"+encodeURIComponent(a.textContent+("\n//# sourceURL="+b+(d?"-"+d:"")+".js\n"))),a.textContent="",d++)});return a};k.prototype.L=function(){var a=this;if(!this.b){this.c.disconnect();this.flatten(document);var b=!1,c=!1,d=function(){c&&b&&(a.loadImports(document),a.b||(a.c.observe(document.head,{childList:!0,subtree:!0}),
a.Pa()))};this.Ua(function(){c=!0;d()});this.Ta(function(){b=!0;d()})}};k.prototype.flatten=function(a){var b=this;a=m(a,"link[rel=import]");n(a,function(a){var c=b.a[a.href];(a.__import=c)&&c.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&(b.a[a.href]=a,a.readyState="loading",a.__import=a,b.flatten(c),a.appendChild(c))})};k.prototype.Ta=function(a){function b(e){if(e<d){var f=c[e],g=document.createElement("script");f.removeAttribute("import-dependency");n(f.attributes,function(a){return g.setAttribute(a.name,
a.value)});J=g;f.parentNode.replaceChild(g,f);h(g,function(){J=null;b(e+1)})}else a()}var c=m(document,"script[import-dependency]"),d=c.length;b(0)};k.prototype.Ua=function(a){var b=m(document,"style[import-dependency],link[rel=stylesheet][import-dependency]"),d=b.length;if(d){var e=aa&&!!document.querySelector("link[rel=stylesheet][href][type=import-disable]");n(b,function(b){h(b,function(){b.removeAttribute("import-dependency");0===--d&&a()});if(e&&b.parentNode!==document.head){var f=document.createElement(b.localName);
f.__appliedElement=b;f.setAttribute("type","import-placeholder");b.parentNode.insertBefore(f,b.nextSibling);for(f=c(b);f&&c(f);)f=c(f);f.parentNode!==document.head&&(f=null);document.head.insertBefore(b,f);b.removeAttribute("type")}})}else a()};k.prototype.Pa=function(){var a=this,b=m(document,"link[rel=import]");n(b,function(b){return a.h(b)},!0)};k.prototype.h=function(a){a.__loaded||(a.__loaded=!0,a.import&&(a.import.readyState="complete"),a.dispatchEvent(b(a.import?"load":"error",{bubbles:!1,
cancelable:!1,detail:void 0})))};k.prototype.Ra=function(a){var b=this;n(a,function(a){return n(a.addedNodes,function(a){a&&a.nodeType===Node.ELEMENT_NODE&&(g(a)?b.s(a):b.loadImports(a))})})};var oa=null;if(C)t=m(document,"link[rel=import]"),n(t,function(a){a.import&&"loading"===a.import.readyState||(a.__loaded=!0)}),t=function(a){a=a.target;g(a)&&(a.__loaded=!0)},document.addEventListener("load",t,!0),document.addEventListener("error",t,!0);else{var U=Object.getOwnPropertyDescriptor(Node.prototype,
"baseURI");Object.defineProperty((!U||U.configurable?Node:Element).prototype,"baseURI",{get:function(){var a=g(this)?this:c(this);return a?a.href:U&&U.get?U.get.call(this):(document.querySelector("base")||window.location).href},configurable:!0,enumerable:!0});Object.defineProperty(HTMLLinkElement.prototype,"import",{get:function(){return this.__import||null},configurable:!0,enumerable:!0});e(function(){oa=new k})}f(function(){return document.dispatchEvent(b("HTMLImportsLoaded",{cancelable:!0,bubbles:!0,
detail:void 0}))});a.useNative=C;a.whenReady=f;a.importForElement=c;a.loadImports=function(a){oa&&oa.loadImports(a)}})(window.HTMLImports=window.HTMLImports||{});/*

 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 Code distributed by Google as part of the polymer project is also
 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
window.WebComponents=window.WebComponents||{flags:{}};var nb=document.querySelector('script[src*="webcomponents-lite.js"]'),ob=/wc-(.+)/,w={};if(!w.noOpts){location.search.slice(1).split("&").forEach(function(a){a=a.split("=");var b;a[0]&&(b=a[0].match(ob))&&(w[b[1]]=a[1]||!0)});if(nb)for(var pb=0,qb;qb=nb.attributes[pb];pb++)"src"!==qb.name&&(w[qb.name]=qb.value||!0);if(w.log&&w.log.split){var rb=w.log.split(",");w.log={};rb.forEach(function(a){w.log[a]=!0})}else w.log={}}
window.WebComponents.flags=w;var sb=w.shadydom;sb&&(window.ShadyDOM=window.ShadyDOM||{},window.ShadyDOM.force=sb);var tb=w.register||w.ce;tb&&window.customElements&&(window.customElements.forcePolyfill=tb);/*

Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
var y=window.ShadyDOM||{};y.Na=!(!Element.prototype.attachShadow||!Node.prototype.getRootNode);var ub=Object.getOwnPropertyDescriptor(Node.prototype,"firstChild");y.M=!!(ub&&ub.configurable&&ub.get);y.sa=y.force||!y.Na;function vb(a){return a.__shady&&void 0!==a.__shady.firstChild}function z(a){return"ShadyRoot"===a.ya}function wb(a){a=a.getRootNode();if(z(a))return a}var xb=Element.prototype,yb=xb.matches||xb.matchesSelector||xb.mozMatchesSelector||xb.msMatchesSelector||xb.oMatchesSelector||xb.webkitMatchesSelector;
function zb(a,b){if(a&&b)for(var c=Object.getOwnPropertyNames(b),d=0,e;d<c.length&&(e=c[d]);d++){var f=Object.getOwnPropertyDescriptor(b,e);f&&Object.defineProperty(a,e,f)}}function Ab(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=arguments[d];for(d=0;d<c.length;d++)zb(a,c[d]);return a}function Bb(a,b){for(var c in b)a[c]=b[c]}var Cb=document.createTextNode(""),Db=0,Eb=[];(new MutationObserver(function(){for(;Eb.length;)try{Eb.shift()()}catch(a){throw Cb.textContent=Db++,a;}})).observe(Cb,{characterData:!0});
function Fb(a){Eb.push(a);Cb.textContent=Db++}var Gb=!!document.contains;function Hb(a,b){for(;b;){if(b==a)return!0;b=b.parentNode}return!1};var Ib=[],Jb;function Kb(a){Jb||(Jb=!0,Fb(Lb));Ib.push(a)}function Lb(){Jb=!1;for(var a=!!Ib.length;Ib.length;)Ib.shift()();return a}Lb.list=Ib;function Mb(){this.a=!1;this.addedNodes=[];this.removedNodes=[];this.V=new Set}function Nb(a){a.a||(a.a=!0,Fb(function(){Ob(a)}))}function Ob(a){if(a.a){a.a=!1;var b=a.takeRecords();b.length&&a.V.forEach(function(a){a(b)})}}Mb.prototype.takeRecords=function(){if(this.addedNodes.length||this.removedNodes.length){var a=[{addedNodes:this.addedNodes,removedNodes:this.removedNodes}];this.addedNodes=[];this.removedNodes=[];return a}return[]};
function Pb(a,b){a.__shady=a.__shady||{};a.__shady.N||(a.__shady.N=new Mb);a.__shady.N.V.add(b);var c=a.__shady.N;return{Ca:b,C:c,Ga:a,takeRecords:function(){return c.takeRecords()}}}function Qb(a){var b=a&&a.C;b&&(b.V.delete(a.Ca),b.V.size||(a.Ga.__shady.N=null))}
function Rb(a,b){var c=b.getRootNode();return a.map(function(a){var b=c===a.target.getRootNode();if(b&&a.addedNodes){if(b=Array.from(a.addedNodes).filter(function(a){return c===a.getRootNode()}),b.length)return a=Object.create(a),Object.defineProperty(a,"addedNodes",{value:b,configurable:!0}),a}else if(b)return a}).filter(function(a){return a})};var A={},Sb=Element.prototype.insertBefore,Tb=Element.prototype.removeChild,Ub=Element.prototype.setAttribute,Vb=Element.prototype.removeAttribute,Wb=Element.prototype.cloneNode,Xb=Document.prototype.importNode,Yb=Element.prototype.addEventListener,Zb=Element.prototype.removeEventListener,$b=Window.prototype.addEventListener,ac=Window.prototype.removeEventListener,bc=Element.prototype.dispatchEvent,cc=Element.prototype.querySelector,dc=Element.prototype.querySelectorAll,ec=Node.prototype.contains||
HTMLElement.prototype.contains;A.appendChild=Element.prototype.appendChild;A.insertBefore=Sb;A.removeChild=Tb;A.setAttribute=Ub;A.removeAttribute=Vb;A.cloneNode=Wb;A.importNode=Xb;A.addEventListener=Yb;A.removeEventListener=Zb;A.ab=$b;A.bb=ac;A.dispatchEvent=bc;A.querySelector=cc;A.querySelectorAll=dc;A.contains=ec;var fc=/[&\u00A0"]/g,gc=/[&\u00A0<>]/g;function hc(a){switch(a){case "&":return"&amp;";case "<":return"&lt;";case ">":return"&gt;";case '"':return"&quot;";case "\u00a0":return"&nbsp;"}}function ic(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}var jc=ic("area base br col command embed hr img input keygen link meta param source track wbr".split(" ")),kc=ic("style script xmp iframe noembed noframes plaintext noscript".split(" "));
function lc(a,b){"template"===a.localName&&(a=a.content);for(var c="",d=b?b(a):a.childNodes,e=0,f=d.length,h;e<f&&(h=d[e]);e++){a:{var g=h;var k=a;var l=b;switch(g.nodeType){case Node.ELEMENT_NODE:for(var m=g.localName,n="<"+m,t=g.attributes,C=0;k=t[C];C++)n+=" "+k.name+'="'+k.value.replace(fc,hc)+'"';n+=">";g=jc[m]?n:n+lc(g,l)+"</"+m+">";break a;case Node.TEXT_NODE:g=g.data;g=k&&kc[k.localName]?g:g.replace(gc,hc);break a;case Node.COMMENT_NODE:g="\x3c!--"+g.data+"--\x3e";break a;default:throw window.console.error(g),
Error("not implemented");}}c+=g}return c};var B={},D=document.createTreeWalker(document,NodeFilter.SHOW_ALL,null,!1),E=document.createTreeWalker(document,NodeFilter.SHOW_ELEMENT,null,!1);function mc(a){var b=[];D.currentNode=a;for(a=D.firstChild();a;)b.push(a),a=D.nextSibling();return b}B.parentNode=function(a){D.currentNode=a;return D.parentNode()};B.firstChild=function(a){D.currentNode=a;return D.firstChild()};B.lastChild=function(a){D.currentNode=a;return D.lastChild()};B.previousSibling=function(a){D.currentNode=a;return D.previousSibling()};
B.nextSibling=function(a){D.currentNode=a;return D.nextSibling()};B.childNodes=mc;B.parentElement=function(a){E.currentNode=a;return E.parentNode()};B.firstElementChild=function(a){E.currentNode=a;return E.firstChild()};B.lastElementChild=function(a){E.currentNode=a;return E.lastChild()};B.previousElementSibling=function(a){E.currentNode=a;return E.previousSibling()};B.nextElementSibling=function(a){E.currentNode=a;return E.nextSibling()};
B.children=function(a){var b=[];E.currentNode=a;for(a=E.firstChild();a;)b.push(a),a=E.nextSibling();return b};B.innerHTML=function(a){return lc(a,function(a){return mc(a)})};B.textContent=function(a){switch(a.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:a=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,null,!1);for(var b="",c;c=a.nextNode();)b+=c.nodeValue;return b;default:return a.nodeValue}};var nc=Object.getOwnPropertyDescriptor(Element.prototype,"innerHTML")||Object.getOwnPropertyDescriptor(HTMLElement.prototype,"innerHTML"),oc=document.implementation.createHTMLDocument("inert"),pc=Object.getOwnPropertyDescriptor(Document.prototype,"activeElement"),qc={parentElement:{get:function(){var a=this.__shady&&this.__shady.parentNode;a&&a.nodeType!==Node.ELEMENT_NODE&&(a=null);return void 0!==a?a:B.parentElement(this)},configurable:!0},parentNode:{get:function(){var a=this.__shady&&this.__shady.parentNode;
return void 0!==a?a:B.parentNode(this)},configurable:!0},nextSibling:{get:function(){var a=this.__shady&&this.__shady.nextSibling;return void 0!==a?a:B.nextSibling(this)},configurable:!0},previousSibling:{get:function(){var a=this.__shady&&this.__shady.previousSibling;return void 0!==a?a:B.previousSibling(this)},configurable:!0},className:{get:function(){return this.getAttribute("class")||""},set:function(a){this.setAttribute("class",a)},configurable:!0},nextElementSibling:{get:function(){if(this.__shady&&
void 0!==this.__shady.nextSibling){for(var a=this.nextSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}return B.nextElementSibling(this)},configurable:!0},previousElementSibling:{get:function(){if(this.__shady&&void 0!==this.__shady.previousSibling){for(var a=this.previousSibling;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}return B.previousElementSibling(this)},configurable:!0}},rc={childNodes:{get:function(){if(vb(this)){if(!this.__shady.childNodes){this.__shady.childNodes=
[];for(var a=this.firstChild;a;a=a.nextSibling)this.__shady.childNodes.push(a)}var b=this.__shady.childNodes}else b=B.childNodes(this);b.item=function(a){return b[a]};return b},configurable:!0},childElementCount:{get:function(){return this.children.length},configurable:!0},firstChild:{get:function(){var a=this.__shady&&this.__shady.firstChild;return void 0!==a?a:B.firstChild(this)},configurable:!0},lastChild:{get:function(){var a=this.__shady&&this.__shady.lastChild;return void 0!==a?a:B.lastChild(this)},
configurable:!0},textContent:{get:function(){if(vb(this)){for(var a=[],b=0,c=this.childNodes,d;d=c[b];b++)d.nodeType!==Node.COMMENT_NODE&&a.push(d.textContent);return a.join("")}return B.textContent(this)},set:function(a){if("undefined"===typeof a||null===a)a="";switch(this.nodeType){case Node.ELEMENT_NODE:case Node.DOCUMENT_FRAGMENT_NODE:for(;this.firstChild;)this.removeChild(this.firstChild);(0<a.length||this.nodeType===Node.ELEMENT_NODE)&&this.appendChild(document.createTextNode(a));break;default:this.nodeValue=
a}},configurable:!0},firstElementChild:{get:function(){if(this.__shady&&void 0!==this.__shady.firstChild){for(var a=this.firstChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.nextSibling;return a}return B.firstElementChild(this)},configurable:!0},lastElementChild:{get:function(){if(this.__shady&&void 0!==this.__shady.lastChild){for(var a=this.lastChild;a&&a.nodeType!==Node.ELEMENT_NODE;)a=a.previousSibling;return a}return B.lastElementChild(this)},configurable:!0},children:{get:function(){var a=vb(this)?
Array.prototype.filter.call(this.childNodes,function(a){return a.nodeType===Node.ELEMENT_NODE}):B.children(this);a.item=function(b){return a[b]};return a},configurable:!0},innerHTML:{get:function(){var a="template"===this.localName?this.content:this;return vb(this)?lc(a):B.innerHTML(a)},set:function(a){for(var b="template"===this.localName?this.content:this;b.firstChild;)b.removeChild(b.firstChild);var c=this.localName;c&&"template"!==c||(c="div");c=oc.createElement(c);for(nc&&nc.set?nc.set.call(c,
a):c.innerHTML=a;c.firstChild;)b.appendChild(c.firstChild)},configurable:!0}},sc={shadowRoot:{get:function(){return this.__shady&&this.__shady.Va||null},configurable:!0}},tc={activeElement:{get:function(){var a=pc&&pc.get?pc.get.call(document):y.M?void 0:document.activeElement;if(a&&a.nodeType){var b=!!z(this);if(this===document||b&&this.host!==a&&A.contains.call(this.host,a)){for(b=wb(a);b&&b!==this;)a=b.host,b=wb(a);a=this===document?b?null:a:b===this?a:null}else a=null}else a=null;return a},set:function(){},
configurable:!0}};function F(a,b,c){for(var d in b){var e=Object.getOwnPropertyDescriptor(a,d);e&&e.configurable||!e&&c?Object.defineProperty(a,d,b[d]):c&&console.warn("Could not define",d,"on",a)}}function G(a){F(a,qc);F(a,rc);F(a,tc)}var uc=y.M?function(){}:function(a){a.__shady&&a.__shady.za||(a.__shady=a.__shady||{},a.__shady.za=!0,F(a,qc,!0))},vc=y.M?function(){}:function(a){a.__shady&&a.__shady.xa||(a.__shady=a.__shady||{},a.__shady.xa=!0,F(a,rc,!0),F(a,sc,!0))};function wc(a,b,c){uc(a);c=c||null;a.__shady=a.__shady||{};b.__shady=b.__shady||{};c&&(c.__shady=c.__shady||{});a.__shady.previousSibling=c?c.__shady.previousSibling:b.lastChild;var d=a.__shady.previousSibling;d&&d.__shady&&(d.__shady.nextSibling=a);(d=a.__shady.nextSibling=c)&&d.__shady&&(d.__shady.previousSibling=a);a.__shady.parentNode=b;c?c===b.__shady.firstChild&&(b.__shady.firstChild=a):(b.__shady.lastChild=a,b.__shady.firstChild||(b.__shady.firstChild=a));b.__shady.childNodes=null}
function xc(a){if(!a.__shady||void 0===a.__shady.firstChild){a.__shady=a.__shady||{};a.__shady.firstChild=B.firstChild(a);a.__shady.lastChild=B.lastChild(a);vc(a);for(var b=a.__shady.childNodes=B.childNodes(a),c=0,d;c<b.length&&(d=b[c]);c++)d.__shady=d.__shady||{},d.__shady.parentNode=a,d.__shady.nextSibling=b[c+1]||null,d.__shady.previousSibling=b[c-1]||null,uc(d)}};function yc(a,b,c){if(b===a)throw Error("Failed to execute 'appendChild' on 'Node': The new child element contains the parent.");if(c){var d=c.__shady&&c.__shady.parentNode;if(void 0!==d&&d!==a||void 0===d&&B.parentNode(c)!==a)throw Error("Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.");}if(c===b)return b;b.parentNode&&zc(b.parentNode,b);d=wb(a);var e;if(e=d)a:{if(!b.__noInsertionPoint){var f;"slot"===b.localName?f=[b]:
b.querySelectorAll&&(f=b.querySelectorAll("slot"));if(f&&f.length){e=f;break a}}e=void 0}(f=e)&&d.H.push.apply(d.H,[].concat(f instanceof Array?f:ja(ia(f))));d&&("slot"===a.localName||f)&&Ac(d);if(vb(a)){d=c;vc(a);a.__shady=a.__shady||{};void 0!==a.__shady.firstChild&&(a.__shady.childNodes=null);if(b.nodeType===Node.DOCUMENT_FRAGMENT_NODE){f=b.childNodes;for(e=0;e<f.length;e++)wc(f[e],a,d);b.__shady=b.__shady||{};d=void 0!==b.__shady.firstChild?null:void 0;b.__shady.firstChild=b.__shady.lastChild=
d;b.__shady.childNodes=d}else wc(b,a,d);if(Bc(a)){Ac(a.__shady.root);var h=!0}else a.__shady.root&&(h=!0)}h||(h=z(a)?a.host:a,c?(c=Cc(c),A.insertBefore.call(h,b,c)):A.appendChild.call(h,b));Dc(a,b);return b}
function zc(a,b){if(b.parentNode!==a)throw Error("The node to be removed is not a child of this node: "+b);var c=wb(b);if(vb(a)){b.__shady=b.__shady||{};a.__shady=a.__shady||{};b===a.__shady.firstChild&&(a.__shady.firstChild=b.__shady.nextSibling);b===a.__shady.lastChild&&(a.__shady.lastChild=b.__shady.previousSibling);var d=b.__shady.previousSibling,e=b.__shady.nextSibling;d&&(d.__shady=d.__shady||{},d.__shady.nextSibling=e);e&&(e.__shady=e.__shady||{},e.__shady.previousSibling=d);b.__shady.parentNode=
b.__shady.previousSibling=b.__shady.nextSibling=void 0;void 0!==a.__shady.childNodes&&(a.__shady.childNodes=null);if(Bc(a)){Ac(a.__shady.root);var f=!0}}Ec(b);if(c){(d=a&&"slot"===a.localName)&&(f=!0);Fc(c);e=c.l;for(var h in e)for(var g=e[h],k=0;k<g.length;k++){var l=g[k];if(Hb(b,l)){g.splice(k,1);var m=c.o.indexOf(l);0<=m&&c.o.splice(m,1);k--;if(m=l.__shady.K)for(l=0;l<m.length;l++){var n=m[l],t=B.parentNode(n);t&&A.removeChild.call(t,n)}m=!0}}(m||d)&&Ac(c)}f||(f=z(a)?a.host:a,(!a.__shady.root&&
"slot"!==b.localName||f===B.parentNode(b))&&A.removeChild.call(f,b));Dc(a,null,b);return b}function Ec(a){if(a.__shady&&void 0!==a.__shady.ka)for(var b=a.childNodes,c=0,d=b.length,e;c<d&&(e=b[c]);c++)Ec(e);a.__shady&&(a.__shady.ka=void 0)}function Cc(a){var b=a;a&&"slot"===a.localName&&(b=(b=a.__shady&&a.__shady.K)&&b.length?b[0]:Cc(a.nextSibling));return b}function Bc(a){return(a=a&&a.__shady&&a.__shady.root)&&Gc(a)}
function Hc(a,b){if("slot"===b)a=a.parentNode,Bc(a)&&Ac(a.__shady.root);else if("slot"===a.localName&&"name"===b&&(b=wb(a))){var c=a.Aa,d=Ic(a);if(d!==c){c=b.l[c];var e=c.indexOf(a);0<=e&&c.splice(e,1);c=b.l[d]||(b.l[d]=[]);c.push(a);1<c.length&&(b.l[d]=Jc(c))}Ac(b)}}function Dc(a,b,c){if(a=a.__shady&&a.__shady.N)b&&a.addedNodes.push(b),c&&a.removedNodes.push(c),Nb(a)}
function Kc(a){if(a&&a.nodeType){a.__shady=a.__shady||{};var b=a.__shady.ka;void 0===b&&(b=z(a)?a:(b=a.parentNode)?Kc(b):a,A.contains.call(document.documentElement,a)&&(a.__shady.ka=b));return b}}function Lc(a,b,c){var d=[];Mc(a.childNodes,b,c,d);return d}function Mc(a,b,c,d){for(var e=0,f=a.length,h;e<f&&(h=a[e]);e++){var g;if(g=h.nodeType===Node.ELEMENT_NODE){g=h;var k=b,l=c,m=d,n=k(g);n&&m.push(g);l&&l(n)?g=n:(Mc(g.childNodes,k,l,m),g=void 0)}if(g)break}}var Nc=null;
function Oc(a,b,c){Nc||(Nc=window.ShadyCSS&&window.ShadyCSS.ScopingShim);Nc&&"class"===b?Nc.setElementClass(a,c):(A.setAttribute.call(a,b,c),Hc(a,b))}function Pc(a,b){if(a.ownerDocument!==document)return A.importNode.call(document,a,b);var c=A.importNode.call(document,a,!1);if(b){a=a.childNodes;b=0;for(var d;b<a.length;b++)d=Pc(a[b],!0),c.appendChild(d)}return c};var Qc="__eventWrappers"+Date.now(),Rc={blur:!0,focus:!0,focusin:!0,focusout:!0,click:!0,dblclick:!0,mousedown:!0,mouseenter:!0,mouseleave:!0,mousemove:!0,mouseout:!0,mouseover:!0,mouseup:!0,wheel:!0,beforeinput:!0,input:!0,keydown:!0,keyup:!0,compositionstart:!0,compositionupdate:!0,compositionend:!0,touchstart:!0,touchend:!0,touchmove:!0,touchcancel:!0,pointerover:!0,pointerenter:!0,pointerdown:!0,pointermove:!0,pointerup:!0,pointercancel:!0,pointerout:!0,pointerleave:!0,gotpointercapture:!0,lostpointercapture:!0,
dragstart:!0,drag:!0,dragenter:!0,dragleave:!0,dragover:!0,drop:!0,dragend:!0,DOMActivate:!0,DOMFocusIn:!0,DOMFocusOut:!0,keypress:!0};function Sc(a,b){var c=[],d=a;for(a=a===window?window:a.getRootNode();d;)c.push(d),d=d.assignedSlot?d.assignedSlot:d.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&d.host&&(b||d!==a)?d.host:d.parentNode;c[c.length-1]===document&&c.push(window);return c}
function Tc(a,b){if(!z)return a;a=Sc(a,!0);for(var c=0,d,e,f,h;c<b.length;c++)if(d=b[c],f=d===window?window:d.getRootNode(),f!==e&&(h=a.indexOf(f),e=f),!z(f)||-1<h)return d}
var Uc={get composed(){!1!==this.isTrusted&&void 0===this.Z&&(this.Z=Rc[this.type]);return this.Z||!1},composedPath:function(){this.b||(this.b=Sc(this.__target,this.composed));return this.b},get target(){return Tc(this.currentTarget,this.composedPath())},get relatedTarget(){if(!this.$)return null;this.c||(this.c=Sc(this.$,!0));return Tc(this.currentTarget,this.c)},stopPropagation:function(){Event.prototype.stopPropagation.call(this);this.a=!0},stopImmediatePropagation:function(){Event.prototype.stopImmediatePropagation.call(this);
this.a=this.h=!0}};function Vc(a){function b(b,d){b=new a(b,d);b.Z=d&&!!d.composed;return b}Bb(b,a);b.prototype=a.prototype;return b}var Wc={focus:!0,blur:!0};function Xc(a){return a.__target!==a.target||a.$!==a.relatedTarget}function Yc(a,b,c){if(c=b.__handlers&&b.__handlers[a.type]&&b.__handlers[a.type][c])for(var d=0,e;(e=c[d])&&(!Xc(a)||a.target!==a.relatedTarget)&&(e.call(b,a),!a.h);d++);}
function Zc(a){var b=a.composedPath();Object.defineProperty(a,"currentTarget",{get:function(){return d},configurable:!0});for(var c=b.length-1;0<=c;c--){var d=b[c];Yc(a,d,"capture");if(a.a)return}Object.defineProperty(a,"eventPhase",{get:function(){return Event.AT_TARGET}});var e;for(c=0;c<b.length;c++){d=b[c];var f=d.__shady&&d.__shady.root;if(0===c||f&&f===e)if(Yc(a,d,"bubble"),d!==window&&(e=d.getRootNode()),a.a)break}}
function $c(a,b,c,d,e,f){for(var h=0;h<a.length;h++){var g=a[h],k=g.type,l=g.capture,m=g.once,n=g.passive;if(b===g.node&&c===k&&d===l&&e===m&&f===n)return h}return-1}
function ad(a,b,c){if(b){var d=typeof b;if("function"===d||"object"===d)if("object"!==d||b.handleEvent&&"function"===typeof b.handleEvent){if(c&&"object"===typeof c){var e=!!c.capture;var f=!!c.once;var h=!!c.passive}else e=!!c,h=f=!1;var g=c&&c.aa||this,k=b[Qc];if(k){if(-1<$c(k,g,a,e,f,h))return}else b[Qc]=[];k=function(e){f&&this.removeEventListener(a,b,c);e.__target||bd(e);if(g!==this){var h=Object.getOwnPropertyDescriptor(e,"currentTarget");Object.defineProperty(e,"currentTarget",{get:function(){return g},
configurable:!0})}if(e.composed||-1<e.composedPath().indexOf(g))if(Xc(e)&&e.target===e.relatedTarget)e.eventPhase===Event.BUBBLING_PHASE&&e.stopImmediatePropagation();else if(e.eventPhase===Event.CAPTURING_PHASE||e.bubbles||e.target===g||g instanceof Window){var k="function"===d?b.call(g,e):b.handleEvent&&b.handleEvent(e);g!==this&&(h?(Object.defineProperty(e,"currentTarget",h),h=null):delete e.currentTarget);return k}};b[Qc].push({node:this,type:a,capture:e,once:f,passive:h,cb:k});Wc[a]?(this.__handlers=
this.__handlers||{},this.__handlers[a]=this.__handlers[a]||{capture:[],bubble:[]},this.__handlers[a][e?"capture":"bubble"].push(k)):(this instanceof Window?A.ab:A.addEventListener).call(this,a,k,c)}}}
function cd(a,b,c){if(b){if(c&&"object"===typeof c){var d=!!c.capture;var e=!!c.once;var f=!!c.passive}else d=!!c,f=e=!1;var h=c&&c.aa||this,g=void 0;var k=null;try{k=b[Qc]}catch(l){}k&&(e=$c(k,h,a,d,e,f),-1<e&&(g=k.splice(e,1)[0].cb,k.length||(b[Qc]=void 0)));(this instanceof Window?A.bb:A.removeEventListener).call(this,a,g||b,c);g&&Wc[a]&&this.__handlers&&this.__handlers[a]&&(a=this.__handlers[a][d?"capture":"bubble"],g=a.indexOf(g),-1<g&&a.splice(g,1))}}
function dd(){for(var a in Wc)window.addEventListener(a,function(a){a.__target||(bd(a),Zc(a))},!0)}function bd(a){a.__target=a.target;a.$=a.relatedTarget;if(y.M){var b=Object.getPrototypeOf(a);if(!b.hasOwnProperty("__patchProto")){var c=Object.create(b);c.fb=b;zb(c,Uc);b.__patchProto=c}a.__proto__=b.__patchProto}else zb(a,Uc)}var ed=Vc(window.Event),fd=Vc(window.CustomEvent),gd=Vc(window.MouseEvent);function hd(a,b){return{index:a,O:[],U:b}}
function id(a,b,c,d){var e=0,f=0,h=0,g=0,k=Math.min(b-e,d-f);if(0==e&&0==f)a:{for(h=0;h<k;h++)if(a[h]!==c[h])break a;h=k}if(b==a.length&&d==c.length){g=a.length;for(var l=c.length,m=0;m<k-h&&jd(a[--g],c[--l]);)m++;g=m}e+=h;f+=h;b-=g;d-=g;if(0==b-e&&0==d-f)return[];if(e==b){for(b=hd(e,0);f<d;)b.O.push(c[f++]);return[b]}if(f==d)return[hd(e,b-e)];k=e;h=f;d=d-h+1;g=b-k+1;b=Array(d);for(l=0;l<d;l++)b[l]=Array(g),b[l][0]=l;for(l=0;l<g;l++)b[0][l]=l;for(l=1;l<d;l++)for(m=1;m<g;m++)if(a[k+m-1]===c[h+l-1])b[l][m]=
b[l-1][m-1];else{var n=b[l-1][m]+1,t=b[l][m-1]+1;b[l][m]=n<t?n:t}k=b.length-1;h=b[0].length-1;d=b[k][h];for(a=[];0<k||0<h;)0==k?(a.push(2),h--):0==h?(a.push(3),k--):(g=b[k-1][h-1],l=b[k-1][h],m=b[k][h-1],n=l<m?l<g?l:g:m<g?m:g,n==g?(g==d?a.push(0):(a.push(1),d=g),k--,h--):n==l?(a.push(3),k--,d=l):(a.push(2),h--,d=m));a.reverse();b=void 0;k=[];for(h=0;h<a.length;h++)switch(a[h]){case 0:b&&(k.push(b),b=void 0);e++;f++;break;case 1:b||(b=hd(e,0));b.U++;e++;b.O.push(c[f]);f++;break;case 2:b||(b=hd(e,0));
b.U++;e++;break;case 3:b||(b=hd(e,0)),b.O.push(c[f]),f++}b&&k.push(b);return k}function jd(a,b){return a===b};var kd={};function H(a,b,c){if(a!==kd)throw new TypeError("Illegal constructor");a=document.createDocumentFragment();a.__proto__=H.prototype;a.ya="ShadyRoot";xc(b);xc(a);a.host=b;a.Fa=c&&c.mode;b.__shady=b.__shady||{};b.__shady.root=a;b.__shady.Va="closed"!==a.Fa?a:null;a.T=!1;a.o=[];a.l={};a.H=[];c=B.childNodes(b);for(var d=0,e=c.length;d<e;d++)A.removeChild.call(b,c[d]);return a}H.prototype=Object.create(DocumentFragment.prototype);function Ac(a){a.T||(a.T=!0,Kb(function(){return ld(a)}))}
function ld(a){for(var b;a;){a.T&&(b=a);a:{var c=a;a=c.host.getRootNode();if(z(a))for(var d=c.host.childNodes,e=0;e<d.length;e++)if(c=d[e],"slot"==c.localName)break a;a=void 0}}b&&b._renderRoot()}
H.prototype._renderRoot=function(){this.T=!1;Fc(this);for(var a=0,b;a<this.o.length;a++){b=this.o[a];var c=b.__shady.assignedNodes;b.__shady.assignedNodes=[];b.__shady.K=[];if(b.__shady.oa=c)for(var d=0;d<c.length;d++){var e=c[d];e.__shady.ga=e.__shady.assignedSlot;e.__shady.assignedSlot===b&&(e.__shady.assignedSlot=null)}}for(b=this.host.firstChild;b;b=b.nextSibling)md(this,b);for(a=0;a<this.o.length;a++){b=this.o[a];if(!b.__shady.assignedNodes.length)for(c=b.firstChild;c;c=c.nextSibling)md(this,
c,b);c=b.parentNode;(c=c.__shady&&c.__shady.root)&&Gc(c)&&c._renderRoot();nd(this,b.__shady.K,b.__shady.assignedNodes);if(c=b.__shady.oa){for(d=0;d<c.length;d++)c[d].__shady.ga=null;b.__shady.oa=null;c.length>b.__shady.assignedNodes.length&&(b.__shady.ia=!0)}b.__shady.ia&&(b.__shady.ia=!1,od(this,b))}a=this.o;b=[];for(c=0;c<a.length;c++)d=a[c].parentNode,d.__shady&&d.__shady.root||!(0>b.indexOf(d))||b.push(d);for(a=0;a<b.length;a++){c=b[a];d=c===this?this.host:c;e=[];c=c.childNodes;for(var f=0;f<
c.length;f++){var h=c[f];if("slot"==h.localName){h=h.__shady.K;for(var g=0;g<h.length;g++)e.push(h[g])}else e.push(h)}c=void 0;f=B.childNodes(d);h=id(e,e.length,f,f.length);for(var k=g=0;g<h.length&&(c=h[g]);g++){for(var l=0,m;l<c.O.length&&(m=c.O[l]);l++)B.parentNode(m)===d&&A.removeChild.call(d,m),f.splice(c.index+k,1);k-=c.U}for(k=0;k<h.length&&(c=h[k]);k++)for(g=f[c.index],l=c.index;l<c.index+c.U;l++)m=e[l],A.insertBefore.call(d,m,g),f.splice(l,0,m)}};
function md(a,b,c){b.__shady=b.__shady||{};var d=b.__shady.ga;b.__shady.ga=null;c||(c=(a=a.l[b.slot||"__catchall"])&&a[0]);c?(c.__shady.assignedNodes.push(b),b.__shady.assignedSlot=c):b.__shady.assignedSlot=void 0;d!==b.__shady.assignedSlot&&b.__shady.assignedSlot&&(b.__shady.assignedSlot.__shady.ia=!0)}function nd(a,b,c){for(var d=0,e;d<c.length&&(e=c[d]);d++)if("slot"==e.localName){var f=e.__shady.assignedNodes;f&&f.length&&nd(a,b,f)}else b.push(c[d])}
function od(a,b){A.dispatchEvent.call(b,new Event("slotchange"));b.__shady.assignedSlot&&od(a,b.__shady.assignedSlot)}function Fc(a){if(a.H.length){for(var b=a.H,c,d=0;d<b.length;d++){var e=b[d];e.__shady=e.__shady||{};xc(e);xc(e.parentNode);var f=Ic(e);a.l[f]?(c=c||{},c[f]=!0,a.l[f].push(e)):a.l[f]=[e];a.o.push(e)}if(c)for(var h in c)a.l[h]=Jc(a.l[h]);a.H=[]}}function Ic(a){var b=a.name||a.getAttribute("name")||"__catchall";return a.Aa=b}
function Jc(a){return a.sort(function(a,c){a=pd(a);for(var b=pd(c),e=0;e<a.length;e++){c=a[e];var f=b[e];if(c!==f)return a=Array.from(c.parentNode.childNodes),a.indexOf(c)-a.indexOf(f)}})}function pd(a){var b=[];do b.unshift(a);while(a=a.parentNode);return b}function Gc(a){Fc(a);return!!a.o.length}H.prototype.addEventListener=function(a,b,c){"object"!==typeof c&&(c={capture:!!c});c.aa=this;this.host.addEventListener(a,b,c)};
H.prototype.removeEventListener=function(a,b,c){"object"!==typeof c&&(c={capture:!!c});c.aa=this;this.host.removeEventListener(a,b,c)};H.prototype.getElementById=function(a){return Lc(this,function(b){return b.id==a},function(a){return!!a})[0]||null};var qd=H.prototype;F(qd,rc,!0);F(qd,tc,!0);function rd(a){var b=a.getRootNode();z(b)&&ld(b);return a.__shady&&a.__shady.assignedSlot||null}
var sd={addEventListener:ad.bind(window),removeEventListener:cd.bind(window)},td={addEventListener:ad,removeEventListener:cd,appendChild:function(a){return yc(this,a)},insertBefore:function(a,b){return yc(this,a,b)},removeChild:function(a){return zc(this,a)},replaceChild:function(a,b){yc(this,a,b);zc(this,b);return a},cloneNode:function(a){if("template"==this.localName)var b=A.cloneNode.call(this,a);else if(b=A.cloneNode.call(this,!1),a){a=this.childNodes;for(var c=0,d;c<a.length;c++)d=a[c].cloneNode(!0),
b.appendChild(d)}return b},getRootNode:function(){return Kc(this)},contains:function(a){return Hb(this,a)},get isConnected(){var a=this.ownerDocument;if(Gb&&A.contains.call(a,this)||a.documentElement&&A.contains.call(a.documentElement,this))return!0;for(a=this;a&&!(a instanceof Document);)a=a.parentNode||(a instanceof H?a.host:void 0);return!!(a&&a instanceof Document)},dispatchEvent:function(a){Lb();return A.dispatchEvent.call(this,a)}},ud={get assignedSlot(){return rd(this)}},vd={querySelector:function(a){return Lc(this,
function(b){return yb.call(b,a)},function(a){return!!a})[0]||null},querySelectorAll:function(a){return Lc(this,function(b){return yb.call(b,a)})}},wd={assignedNodes:function(a){if("slot"===this.localName){var b=this.getRootNode();z(b)&&ld(b);return this.__shady?(a&&a.flatten?this.__shady.K:this.__shady.assignedNodes)||[]:[]}}},xd=Ab({setAttribute:function(a,b){Oc(this,a,b)},removeAttribute:function(a){A.removeAttribute.call(this,a);Hc(this,a)},attachShadow:function(a){if(!this)throw"Must provide a host.";
if(!a)throw"Not enough arguments.";return new H(kd,this,a)},get slot(){return this.getAttribute("slot")},set slot(a){Oc(this,"slot",a)},get assignedSlot(){return rd(this)}},vd,wd);Object.defineProperties(xd,sc);var yd=Ab({importNode:function(a,b){return Pc(a,b)},getElementById:function(a){return Lc(this,function(b){return b.id==a},function(a){return!!a})[0]||null}},vd);Object.defineProperties(yd,{_activeElement:tc.activeElement});
var zd=HTMLElement.prototype.blur,Ad=Ab({blur:function(){var a=this.__shady&&this.__shady.root;(a=a&&a.activeElement)?a.blur():zd.call(this)}});function I(a,b){for(var c=Object.getOwnPropertyNames(b),d=0;d<c.length;d++){var e=c[d],f=Object.getOwnPropertyDescriptor(b,e);f.value?a[e]=f.value:Object.defineProperty(a,e,f)}};if(y.sa){var ShadyDOM={inUse:y.sa,patch:function(a){return a},isShadyRoot:z,enqueue:Kb,flush:Lb,settings:y,filterMutations:Rb,observeChildren:Pb,unobserveChildren:Qb,nativeMethods:A,nativeTree:B};window.ShadyDOM=ShadyDOM;window.Event=ed;window.CustomEvent=fd;window.MouseEvent=gd;dd();var Bd=window.customElements&&window.customElements.nativeHTMLElement||HTMLElement;I(window.Node.prototype,td);I(window.Window.prototype,sd);I(window.Text.prototype,ud);I(window.DocumentFragment.prototype,vd);I(window.Element.prototype,
xd);I(window.Document.prototype,yd);window.HTMLSlotElement&&I(window.HTMLSlotElement.prototype,wd);I(Bd.prototype,Ad);y.M&&(G(window.Node.prototype),G(window.Text.prototype),G(window.DocumentFragment.prototype),G(window.Element.prototype),G(Bd.prototype),G(window.Document.prototype),window.HTMLSlotElement&&G(window.HTMLSlotElement.prototype));window.ShadowRoot=H};var Cd=new Set("annotation-xml color-profile font-face font-face-src font-face-uri font-face-format font-face-name missing-glyph".split(" "));function Dd(a){var b=Cd.has(a);a=/^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test(a);return!b&&a}function K(a){var b=a.isConnected;if(void 0!==b)return b;for(;a&&!(a.__CE_isImportDocument||a instanceof Document);)a=a.parentNode||(window.ShadowRoot&&a instanceof ShadowRoot?a.host:void 0);return!(!a||!(a.__CE_isImportDocument||a instanceof Document))}
function Ed(a,b){for(;b&&b!==a&&!b.nextSibling;)b=b.parentNode;return b&&b!==a?b.nextSibling:null}
function L(a,b,c){c=void 0===c?new Set:c;for(var d=a;d;){if(d.nodeType===Node.ELEMENT_NODE){var e=d;b(e);var f=e.localName;if("link"===f&&"import"===e.getAttribute("rel")){d=e.import;if(d instanceof Node&&!c.has(d))for(c.add(d),d=d.firstChild;d;d=d.nextSibling)L(d,b,c);d=Ed(a,e);continue}else if("template"===f){d=Ed(a,e);continue}if(e=e.__CE_shadowRoot)for(e=e.firstChild;e;e=e.nextSibling)L(e,b,c)}d=d.firstChild?d.firstChild:Ed(a,d)}}function M(a,b,c){a[b]=c};function Fd(){this.a=new Map;this.s=new Map;this.h=[];this.c=!1}function Gd(a,b,c){a.a.set(b,c);a.s.set(c.constructor,c)}function Hd(a,b){a.c=!0;a.h.push(b)}function Id(a,b){a.c&&L(b,function(b){return a.b(b)})}Fd.prototype.b=function(a){if(this.c&&!a.__CE_patched){a.__CE_patched=!0;for(var b=0;b<this.h.length;b++)this.h[b](a)}};function N(a,b){var c=[];L(b,function(a){return c.push(a)});for(b=0;b<c.length;b++){var d=c[b];1===d.__CE_state?a.connectedCallback(d):Jd(a,d)}}
function O(a,b){var c=[];L(b,function(a){return c.push(a)});for(b=0;b<c.length;b++){var d=c[b];1===d.__CE_state&&a.disconnectedCallback(d)}}
function P(a,b,c){c=void 0===c?{}:c;var d=c.$a||new Set,e=c.va||function(b){return Jd(a,b)},f=[];L(b,function(b){if("link"===b.localName&&"import"===b.getAttribute("rel")){var c=b.import;c instanceof Node&&(c.__CE_isImportDocument=!0,c.__CE_hasRegistry=!0);c&&"complete"===c.readyState?c.__CE_documentLoadHandled=!0:b.addEventListener("load",function(){var c=b.import;if(!c.__CE_documentLoadHandled){c.__CE_documentLoadHandled=!0;var f=new Set(d);f.delete(c);P(a,c,{$a:f,va:e})}})}else f.push(b)},d);if(a.c)for(b=
0;b<f.length;b++)a.b(f[b]);for(b=0;b<f.length;b++)e(f[b])}
function Jd(a,b){if(void 0===b.__CE_state){var c=b.ownerDocument;if(c.defaultView||c.__CE_isImportDocument&&c.__CE_hasRegistry)if(c=a.a.get(b.localName)){c.constructionStack.push(b);var d=c.constructor;try{try{if(new d!==b)throw Error("The custom element constructor did not produce the element being upgraded.");}finally{c.constructionStack.pop()}}catch(h){throw b.__CE_state=2,h;}b.__CE_state=1;b.__CE_definition=c;if(c.attributeChangedCallback)for(c=c.observedAttributes,d=0;d<c.length;d++){var e=c[d],
f=b.getAttribute(e);null!==f&&a.attributeChangedCallback(b,e,null,f,null)}K(b)&&a.connectedCallback(b)}}}Fd.prototype.connectedCallback=function(a){var b=a.__CE_definition;b.connectedCallback&&b.connectedCallback.call(a)};Fd.prototype.disconnectedCallback=function(a){var b=a.__CE_definition;b.disconnectedCallback&&b.disconnectedCallback.call(a)};
Fd.prototype.attributeChangedCallback=function(a,b,c,d,e){var f=a.__CE_definition;f.attributeChangedCallback&&-1<f.observedAttributes.indexOf(b)&&f.attributeChangedCallback.call(a,b,c,d,e)};function Kd(a){var b=document;this.j=a;this.a=b;this.C=void 0;P(this.j,this.a);"loading"===this.a.readyState&&(this.C=new MutationObserver(this.b.bind(this)),this.C.observe(this.a,{childList:!0,subtree:!0}))}Kd.prototype.disconnect=function(){this.C&&this.C.disconnect()};Kd.prototype.b=function(a){var b=this.a.readyState;"interactive"!==b&&"complete"!==b||this.disconnect();for(b=0;b<a.length;b++)for(var c=a[b].addedNodes,d=0;d<c.length;d++)P(this.j,c[d])};function Ld(){var a=this;this.b=this.a=void 0;this.c=new Promise(function(b){a.b=b;a.a&&b(a.a)})}Ld.prototype.resolve=function(a){if(this.a)throw Error("Already resolved.");this.a=a;this.b&&this.b(a)};function Q(a){this.da=!1;this.j=a;this.ha=new Map;this.ea=function(a){return a()};this.R=!1;this.fa=[];this.Da=new Kd(a)}
Q.prototype.define=function(a,b){var c=this;if(!(b instanceof Function))throw new TypeError("Custom element constructors must be functions.");if(!Dd(a))throw new SyntaxError("The element name '"+a+"' is not valid.");if(this.j.a.get(a))throw Error("A custom element with name '"+a+"' has already been defined.");if(this.da)throw Error("A custom element is already being defined.");this.da=!0;try{var d=function(a){var b=e[a];if(void 0!==b&&!(b instanceof Function))throw Error("The '"+a+"' callback must be a function.");
return b},e=b.prototype;if(!(e instanceof Object))throw new TypeError("The custom element constructor's prototype is not an object.");var f=d("connectedCallback");var h=d("disconnectedCallback");var g=d("adoptedCallback");var k=d("attributeChangedCallback");var l=b.observedAttributes||[]}catch(m){return}finally{this.da=!1}b={localName:a,constructor:b,connectedCallback:f,disconnectedCallback:h,adoptedCallback:g,attributeChangedCallback:k,observedAttributes:l,constructionStack:[]};Gd(this.j,a,b);this.fa.push(b);
this.R||(this.R=!0,this.ea(function(){return Md(c)}))};function Md(a){if(!1!==a.R){a.R=!1;for(var b=a.fa,c=[],d=new Map,e=0;e<b.length;e++)d.set(b[e].localName,[]);P(a.j,document,{va:function(b){if(void 0===b.__CE_state){var e=b.localName,f=d.get(e);f?f.push(b):a.j.a.get(e)&&c.push(b)}}});for(e=0;e<c.length;e++)Jd(a.j,c[e]);for(;0<b.length;){var f=b.shift();e=f.localName;f=d.get(f.localName);for(var h=0;h<f.length;h++)Jd(a.j,f[h]);(e=a.ha.get(e))&&e.resolve(void 0)}}}
Q.prototype.get=function(a){if(a=this.j.a.get(a))return a.constructor};Q.prototype.a=function(a){if(!Dd(a))return Promise.reject(new SyntaxError("'"+a+"' is not a valid custom element name."));var b=this.ha.get(a);if(b)return b.c;b=new Ld;this.ha.set(a,b);this.j.a.get(a)&&!this.fa.some(function(b){return b.localName===a})&&b.resolve(void 0);return b.c};Q.prototype.b=function(a){this.Da.disconnect();var b=this.ea;this.ea=function(c){return a(function(){return b(c)})}};
window.CustomElementRegistry=Q;Q.prototype.define=Q.prototype.define;Q.prototype.get=Q.prototype.get;Q.prototype.whenDefined=Q.prototype.a;Q.prototype.polyfillWrapFlushCallback=Q.prototype.b;var Nd=window.Document.prototype.createElement,Od=window.Document.prototype.createElementNS,Pd=window.Document.prototype.importNode,Qd=window.Document.prototype.prepend,Rd=window.Document.prototype.append,Sd=window.DocumentFragment.prototype.prepend,Td=window.DocumentFragment.prototype.append,Ud=window.Node.prototype.cloneNode,Vd=window.Node.prototype.appendChild,Wd=window.Node.prototype.insertBefore,Xd=window.Node.prototype.removeChild,Yd=window.Node.prototype.replaceChild,Zd=Object.getOwnPropertyDescriptor(window.Node.prototype,
"textContent"),$d=window.Element.prototype.attachShadow,ae=Object.getOwnPropertyDescriptor(window.Element.prototype,"innerHTML"),be=window.Element.prototype.getAttribute,ce=window.Element.prototype.setAttribute,de=window.Element.prototype.removeAttribute,ee=window.Element.prototype.getAttributeNS,fe=window.Element.prototype.setAttributeNS,ge=window.Element.prototype.removeAttributeNS,he=window.Element.prototype.insertAdjacentElement,ie=window.Element.prototype.prepend,je=window.Element.prototype.append,
ke=window.Element.prototype.before,le=window.Element.prototype.after,me=window.Element.prototype.replaceWith,ne=window.Element.prototype.remove,oe=window.HTMLElement,pe=Object.getOwnPropertyDescriptor(window.HTMLElement.prototype,"innerHTML"),qe=window.HTMLElement.prototype.insertAdjacentElement;var re=new function(){};function se(){var a=te;window.HTMLElement=function(){function b(){var b=this.constructor,d=a.s.get(b);if(!d)throw Error("The custom element being constructed was not registered with `customElements`.");var e=d.constructionStack;if(0===e.length)return e=Nd.call(document,d.localName),Object.setPrototypeOf(e,b.prototype),e.__CE_state=1,e.__CE_definition=d,a.b(e),e;d=e.length-1;var f=e[d];if(f===re)throw Error("The HTMLElement constructor was either called reentrantly for this constructor or called multiple times.");
e[d]=re;Object.setPrototypeOf(f,b.prototype);a.b(f);return f}b.prototype=oe.prototype;return b}()};function ue(a,b,c){function d(b){return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];e=[];for(var f=[],l=0;l<d.length;l++){var m=d[l];m instanceof Element&&K(m)&&f.push(m);if(m instanceof DocumentFragment)for(m=m.firstChild;m;m=m.nextSibling)e.push(m);else e.push(m)}b.apply(this,d);for(d=0;d<f.length;d++)O(a,f[d]);if(K(this))for(d=0;d<e.length;d++)f=e[d],f instanceof Element&&N(a,f)}}void 0!==c.X&&(b.prepend=d(c.X));void 0!==c.append&&(b.append=d(c.append))};function ve(){var a=te;M(Document.prototype,"createElement",function(b){if(this.__CE_hasRegistry){var c=a.a.get(b);if(c)return new c.constructor}b=Nd.call(this,b);a.b(b);return b});M(Document.prototype,"importNode",function(b,c){b=Pd.call(this,b,c);this.__CE_hasRegistry?P(a,b):Id(a,b);return b});M(Document.prototype,"createElementNS",function(b,c){if(this.__CE_hasRegistry&&(null===b||"http://www.w3.org/1999/xhtml"===b)){var d=a.a.get(c);if(d)return new d.constructor}b=Od.call(this,b,c);a.b(b);return b});
ue(a,Document.prototype,{X:Qd,append:Rd})};function we(){var a=te;function b(b,d){Object.defineProperty(b,"textContent",{enumerable:d.enumerable,configurable:!0,get:d.get,set:function(b){if(this.nodeType===Node.TEXT_NODE)d.set.call(this,b);else{var c=void 0;if(this.firstChild){var e=this.childNodes,g=e.length;if(0<g&&K(this)){c=Array(g);for(var k=0;k<g;k++)c[k]=e[k]}}d.set.call(this,b);if(c)for(b=0;b<c.length;b++)O(a,c[b])}}})}M(Node.prototype,"insertBefore",function(b,d){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);
b=Wd.call(this,b,d);if(K(this))for(d=0;d<c.length;d++)N(a,c[d]);return b}c=K(b);d=Wd.call(this,b,d);c&&O(a,b);K(this)&&N(a,b);return d});M(Node.prototype,"appendChild",function(b){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=Vd.call(this,b);if(K(this))for(var e=0;e<c.length;e++)N(a,c[e]);return b}c=K(b);e=Vd.call(this,b);c&&O(a,b);K(this)&&N(a,b);return e});M(Node.prototype,"cloneNode",function(b){b=Ud.call(this,b);this.ownerDocument.__CE_hasRegistry?P(a,b):
Id(a,b);return b});M(Node.prototype,"removeChild",function(b){var c=K(b),e=Xd.call(this,b);c&&O(a,b);return e});M(Node.prototype,"replaceChild",function(b,d){if(b instanceof DocumentFragment){var c=Array.prototype.slice.apply(b.childNodes);b=Yd.call(this,b,d);if(K(this))for(O(a,d),d=0;d<c.length;d++)N(a,c[d]);return b}c=K(b);var f=Yd.call(this,b,d),h=K(this);h&&O(a,d);c&&O(a,b);h&&N(a,b);return f});Zd&&Zd.get?b(Node.prototype,Zd):Hd(a,function(a){b(a,{enumerable:!0,configurable:!0,get:function(){for(var a=
[],b=0;b<this.childNodes.length;b++)a.push(this.childNodes[b].textContent);return a.join("")},set:function(a){for(;this.firstChild;)Xd.call(this,this.firstChild);Vd.call(this,document.createTextNode(a))}})})};function xe(a){var b=Element.prototype;function c(b){return function(c){for(var d=[],e=0;e<arguments.length;++e)d[e-0]=arguments[e];e=[];for(var g=[],k=0;k<d.length;k++){var l=d[k];l instanceof Element&&K(l)&&g.push(l);if(l instanceof DocumentFragment)for(l=l.firstChild;l;l=l.nextSibling)e.push(l);else e.push(l)}b.apply(this,d);for(d=0;d<g.length;d++)O(a,g[d]);if(K(this))for(d=0;d<e.length;d++)g=e[d],g instanceof Element&&N(a,g)}}void 0!==ke&&(b.before=c(ke));void 0!==ke&&(b.after=c(le));void 0!==
me&&M(b,"replaceWith",function(b){for(var c=[],d=0;d<arguments.length;++d)c[d-0]=arguments[d];d=[];for(var h=[],g=0;g<c.length;g++){var k=c[g];k instanceof Element&&K(k)&&h.push(k);if(k instanceof DocumentFragment)for(k=k.firstChild;k;k=k.nextSibling)d.push(k);else d.push(k)}g=K(this);me.apply(this,c);for(c=0;c<h.length;c++)O(a,h[c]);if(g)for(O(a,this),c=0;c<d.length;c++)h=d[c],h instanceof Element&&N(a,h)});void 0!==ne&&M(b,"remove",function(){var b=K(this);ne.call(this);b&&O(a,this)})};function ye(){var a=te;function b(b,c){Object.defineProperty(b,"innerHTML",{enumerable:c.enumerable,configurable:!0,get:c.get,set:function(b){var d=this,e=void 0;K(this)&&(e=[],L(this,function(a){a!==d&&e.push(a)}));c.set.call(this,b);if(e)for(var f=0;f<e.length;f++){var l=e[f];1===l.__CE_state&&a.disconnectedCallback(l)}this.ownerDocument.__CE_hasRegistry?P(a,this):Id(a,this);return b}})}function c(b,c){M(b,"insertAdjacentElement",function(b,d){var e=K(d);b=c.call(this,b,d);e&&O(a,d);K(b)&&N(a,d);
return b})}$d&&M(Element.prototype,"attachShadow",function(a){return this.__CE_shadowRoot=a=$d.call(this,a)});ae&&ae.get?b(Element.prototype,ae):pe&&pe.get?b(HTMLElement.prototype,pe):Hd(a,function(a){b(a,{enumerable:!0,configurable:!0,get:function(){return Ud.call(this,!0).innerHTML},set:function(a){var b="template"===this.localName,c=b?this.content:this,d=Nd.call(document,this.localName);for(d.innerHTML=a;0<c.childNodes.length;)Xd.call(c,c.childNodes[0]);for(a=b?d.content:d;0<a.childNodes.length;)Vd.call(c,
a.childNodes[0])}})});M(Element.prototype,"setAttribute",function(b,c){if(1!==this.__CE_state)return ce.call(this,b,c);var d=be.call(this,b);ce.call(this,b,c);c=be.call(this,b);a.attributeChangedCallback(this,b,d,c,null)});M(Element.prototype,"setAttributeNS",function(b,c,f){if(1!==this.__CE_state)return fe.call(this,b,c,f);var d=ee.call(this,b,c);fe.call(this,b,c,f);f=ee.call(this,b,c);a.attributeChangedCallback(this,c,d,f,b)});M(Element.prototype,"removeAttribute",function(b){if(1!==this.__CE_state)return de.call(this,
b);var c=be.call(this,b);de.call(this,b);null!==c&&a.attributeChangedCallback(this,b,c,null,null)});M(Element.prototype,"removeAttributeNS",function(b,c){if(1!==this.__CE_state)return ge.call(this,b,c);var d=ee.call(this,b,c);ge.call(this,b,c);var e=ee.call(this,b,c);d!==e&&a.attributeChangedCallback(this,c,d,e,b)});qe?c(HTMLElement.prototype,qe):he?c(Element.prototype,he):console.warn("Custom Elements: `Element#insertAdjacentElement` was not patched.");ue(a,Element.prototype,{X:ie,append:je});xe(a)}
;var ze=window.customElements;if(!ze||ze.forcePolyfill||"function"!=typeof ze.define||"function"!=typeof ze.get){var te=new Fd;se();ve();ue(te,DocumentFragment.prototype,{X:Sd,append:Td});we();ye();document.__CE_hasRegistry=!0;var customElements=new Q(te);Object.defineProperty(window,"customElements",{configurable:!0,enumerable:!0,value:customElements})};function Ae(){this.end=this.start=0;this.rules=this.parent=this.previous=null;this.cssText=this.parsedCssText="";this.atRule=!1;this.type=0;this.parsedSelector=this.selector=this.keyframesName=""}
function Be(a){a=a.replace(Ce,"").replace(De,"");var b=Ee,c=a,d=new Ae;d.start=0;d.end=c.length;for(var e=d,f=0,h=c.length;f<h;f++)if("{"===c[f]){e.rules||(e.rules=[]);var g=e,k=g.rules[g.rules.length-1]||null;e=new Ae;e.start=f+1;e.parent=g;e.previous=k;g.rules.push(e)}else"}"===c[f]&&(e.end=f+1,e=e.parent||d);return b(d,a)}
function Ee(a,b){var c=b.substring(a.start,a.end-1);a.parsedCssText=a.cssText=c.trim();a.parent&&(c=b.substring(a.previous?a.previous.end:a.parent.start,a.start-1),c=Fe(c),c=c.replace(Ge," "),c=c.substring(c.lastIndexOf(";")+1),c=a.parsedSelector=a.selector=c.trim(),a.atRule=0===c.indexOf("@"),a.atRule?0===c.indexOf("@media")?a.type=He:c.match(Ie)&&(a.type=Je,a.keyframesName=a.selector.split(Ge).pop()):a.type=0===c.indexOf("--")?Ke:Le);if(c=a.rules)for(var d=0,e=c.length,f;d<e&&(f=c[d]);d++)Ee(f,
b);return a}function Fe(a){return a.replace(/\\([0-9a-f]{1,6})\s/gi,function(a,c){a=c;for(c=6-a.length;c--;)a="0"+a;return"\\"+a})}
function Me(a,b,c){c=void 0===c?"":c;var d="";if(a.cssText||a.rules){var e=a.rules,f;if(f=e)f=e[0],f=!(f&&f.selector&&0===f.selector.indexOf("--"));if(f){f=0;for(var h=e.length,g;f<h&&(g=e[f]);f++)d=Me(g,b,d)}else b?b=a.cssText:(b=a.cssText,b=b.replace(Ne,"").replace(Oe,""),b=b.replace(Pe,"").replace(Qe,"")),(d=b.trim())&&(d="  "+d+"\n")}d&&(a.selector&&(c+=a.selector+" {\n"),c+=d,a.selector&&(c+="}\n\n"));return c}
var Le=1,Je=7,He=4,Ke=1E3,Ce=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,De=/@import[^;]*;/gim,Ne=/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,Oe=/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,Pe=/@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim,Qe=/[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,Ie=/^@[^\s]*keyframes/,Ge=/\s+/g;var R=!(window.ShadyDOM&&window.ShadyDOM.inUse),Re;function Se(a){Re=a&&a.shimcssproperties?!1:R||!(navigator.userAgent.match(/AppleWebKit\/601|Edge\/15/)||!window.CSS||!CSS.supports||!CSS.supports("box-shadow","0 0 0 var(--foo)"))}window.ShadyCSS&&void 0!==window.ShadyCSS.nativeCss?Re=window.ShadyCSS.nativeCss:window.ShadyCSS?(Se(window.ShadyCSS),window.ShadyCSS=void 0):Se(window.WebComponents&&window.WebComponents.flags);var S=Re;var Te=/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};{])+)|\{([^}]*)\}(?:(?=[;\s}])|$))/gi,Ue=/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,Ve=/(--[\w-]+)\s*([:,;)]|$)/gi,We=/(animation\s*:)|(animation-name\s*:)/,Xe=/@media\s(.*)/,Ye=/\{[^}]*\}/g;var Ze=new Set;function $e(a,b){if(!a)return"";"string"===typeof a&&(a=Be(a));b&&af(a,b);return Me(a,S)}function bf(a){!a.__cssRules&&a.textContent&&(a.__cssRules=Be(a.textContent));return a.__cssRules||null}function cf(a){return!!a.parent&&a.parent.type===Je}function af(a,b,c,d){if(a){var e=!1,f=a.type;if(d&&f===He){var h=a.selector.match(Xe);h&&(window.matchMedia(h[1]).matches||(e=!0))}f===Le?b(a):c&&f===Je?c(a):f===Ke&&(e=!0);if((a=a.rules)&&!e){e=0;f=a.length;for(var g;e<f&&(g=a[e]);e++)af(g,b,c,d)}}}
function df(a,b,c,d){var e=document.createElement("style");b&&e.setAttribute("scope",b);e.textContent=a;ef(e,c,d);return e}var T=null;function ef(a,b,c){b=b||document.head;b.insertBefore(a,c&&c.nextSibling||b.firstChild);T?a.compareDocumentPosition(T)===Node.DOCUMENT_POSITION_PRECEDING&&(T=a):T=a}
function ff(a,b){var c=a.indexOf("var(");if(-1===c)return b(a,"","","");a:{var d=0;var e=c+3;for(var f=a.length;e<f;e++)if("("===a[e])d++;else if(")"===a[e]&&0===--d)break a;e=-1}d=a.substring(c+4,e);c=a.substring(0,c);a=ff(a.substring(e+1),b);e=d.indexOf(",");return-1===e?b(c,d.trim(),"",a):b(c,d.substring(0,e).trim(),d.substring(e+1).trim(),a)}function gf(a,b){R?a.setAttribute("class",b):window.ShadyDOM.nativeMethods.setAttribute.call(a,"class",b)}
function V(a){var b=a.localName,c="";b?-1<b.indexOf("-")||(c=b,b=a.getAttribute&&a.getAttribute("is")||""):(b=a.is,c=a.extends);return{is:b,P:c}};function hf(){}function jf(a,b,c){var d=W;a.__styleScoped?a.__styleScoped=null:kf(d,a,b||"",c)}function kf(a,b,c,d){b.nodeType===Node.ELEMENT_NODE&&lf(b,c,d);if(b="template"===b.localName?(b.content||b.gb).childNodes:b.children||b.childNodes)for(var e=0;e<b.length;e++)kf(a,b[e],c,d)}
function lf(a,b,c){if(b)if(a.classList)c?(a.classList.remove("style-scope"),a.classList.remove(b)):(a.classList.add("style-scope"),a.classList.add(b));else if(a.getAttribute){var d=a.getAttribute(mf);c?d&&(b=d.replace("style-scope","").replace(b,""),gf(a,b)):gf(a,(d?d+" ":"")+"style-scope "+b)}}function nf(a,b,c){var d=W,e=a.__cssBuild;R||"shady"===e?b=$e(b,c):(a=V(a),b=of(d,b,a.is,a.P,c)+"\n\n");return b.trim()}
function of(a,b,c,d,e){var f=pf(c,d);c=c?qf+c:"";return $e(b,function(b){b.c||(b.selector=b.m=rf(a,b,a.b,c,f),b.c=!0);e&&e(b,c,f)})}function pf(a,b){return b?"[is="+a+"]":a}function rf(a,b,c,d,e){var f=b.selector.split(sf);if(!cf(b)){b=0;for(var h=f.length,g;b<h&&(g=f[b]);b++)f[b]=c.call(a,g,d,e)}return f.join(sf)}function tf(a){return a.replace(uf,function(a,c,d){-1<d.indexOf("+")?d=d.replace(/\+/g,"___"):-1<d.indexOf("___")&&(d=d.replace(/___/g,"+"));return":"+c+"("+d+")"})}
hf.prototype.b=function(a,b,c){var d=!1;a=a.trim();var e=uf.test(a);e&&(a=a.replace(uf,function(a,b,c){return":"+b+"("+c.replace(/\s/g,"")+")"}),a=tf(a));a=a.replace(vf,wf+" $1");a=a.replace(xf,function(a,e,g){d||(a=yf(g,e,b,c),d=d||a.stop,e=a.Ka,g=a.value);return e+g});e&&(a=tf(a));return a};
function yf(a,b,c,d){var e=a.indexOf(zf);0<=a.indexOf(wf)?a=Af(a,d):0!==e&&(a=c?Bf(a,c):a);c=!1;0<=e&&(b="",c=!0);if(c){var f=!0;c&&(a=a.replace(Cf,function(a,b){return" > "+b}))}a=a.replace(Df,function(a,b,c){return'[dir="'+c+'"] '+b+", "+b+'[dir="'+c+'"]'});return{value:a,Ka:b,stop:f}}function Bf(a,b){a=a.split(Ef);a[0]+=b;return a.join(Ef)}
function Af(a,b){var c=a.match(Ff);return(c=c&&c[2].trim()||"")?c[0].match(Gf)?a.replace(Ff,function(a,c,f){return b+f}):c.split(Gf)[0]===b?c:Hf:a.replace(wf,b)}function If(a){a.selector===Jf&&(a.selector="html")}hf.prototype.c=function(a){return a.match(zf)?this.b(a,Kf):Bf(a.trim(),Kf)};q.Object.defineProperties(hf.prototype,{a:{configurable:!0,enumerable:!0,get:function(){return"style-scope"}}});
var uf=/:(nth[-\w]+)\(([^)]+)\)/,Kf=":not(.style-scope)",sf=",",xf=/(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=[])+)/g,Gf=/[[.:#*]/,wf=":host",Jf=":root",zf="::slotted",vf=new RegExp("^("+zf+")"),Ff=/(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/,Cf=/(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/,Df=/(.*):dir\((?:(ltr|rtl))\)/,qf=".",Ef=":",mf="class",Hf="should_not_match",W=new hf;function Lf(a,b,c,d){this.w=a||null;this.b=b||null;this.ja=c||[];this.G=null;this.P=d||"";this.a=this.u=this.B=null}function X(a){return a?a.__styleInfo:null}function Mf(a,b){return a.__styleInfo=b}Lf.prototype.c=function(){return this.w};Lf.prototype._getStyleRules=Lf.prototype.c;var Nf,Of=window.Element.prototype;Nf=Of.matches||Of.matchesSelector||Of.mozMatchesSelector||Of.msMatchesSelector||Of.oMatchesSelector||Of.webkitMatchesSelector;var Pf=navigator.userAgent.match("Trident");function Qf(){}function Rf(a){var b={},c=[],d=0;af(a,function(a){Sf(a);a.index=d++;a=a.i.cssText;for(var c;c=Ve.exec(a);){var e=c[1];":"!==c[2]&&(b[e]=!0)}},function(a){c.push(a)});a.b=c;a=[];for(var e in b)a.push(e);return a}
function Sf(a){if(!a.i){var b={},c={};Tf(a,c)&&(b.v=c,a.rules=null);b.cssText=a.parsedCssText.replace(Ye,"").replace(Te,"");a.i=b}}function Tf(a,b){var c=a.i;if(c){if(c.v)return Object.assign(b,c.v),!0}else{c=a.parsedCssText;for(var d;a=Te.exec(c);){d=(a[2]||a[3]).trim();if("inherit"!==d||"unset"!==d)b[a[1].trim()]=d;d=!0}return d}}
function Uf(a,b,c){b&&(b=0<=b.indexOf(";")?Vf(a,b,c):ff(b,function(b,e,f,h){if(!e)return b+h;(e=Uf(a,c[e],c))&&"initial"!==e?"apply-shim-inherit"===e&&(e="inherit"):e=Uf(a,c[f]||f,c)||f;return b+(e||"")+h}));return b&&b.trim()||""}
function Vf(a,b,c){b=b.split(";");for(var d=0,e,f;d<b.length;d++)if(e=b[d]){Ue.lastIndex=0;if(f=Ue.exec(e))e=Uf(a,c[f[1]],c);else if(f=e.indexOf(":"),-1!==f){var h=e.substring(f);h=h.trim();h=Uf(a,h,c)||h;e=e.substring(0,f)+h}b[d]=e&&e.lastIndexOf(";")===e.length-1?e.slice(0,-1):e||""}return b.join(";")}
function Wf(a,b){var c={},d=[];af(a,function(a){a.i||Sf(a);var e=a.m||a.parsedSelector;b&&a.i.v&&e&&Nf.call(b,e)&&(Tf(a,c),a=a.index,e=parseInt(a/32,10),d[e]=(d[e]||0)|1<<a%32)},null,!0);return{v:c,key:d}}
function Xf(a,b,c,d){b.i||Sf(b);if(b.i.v){var e=V(a);a=e.is;e=e.P;e=a?pf(a,e):"html";var f=b.parsedSelector,h=":host > *"===f||"html"===f,g=0===f.indexOf(":host")&&!h;"shady"===c&&(h=f===e+" > *."+e||-1!==f.indexOf("html"),g=!h&&0===f.indexOf(e));"shadow"===c&&(h=":host > *"===f||"html"===f,g=g&&!h);if(h||g)c=e,g&&(R&&!b.m&&(b.m=rf(W,b,W.b,a?qf+a:"",e)),c=b.m||e),d({Xa:c,Qa:g,hb:h})}}
function Yf(a,b){var c={},d={},e=b&&b.__cssBuild;af(b,function(b){Xf(a,b,e,function(e){Nf.call(a.b||a,e.Xa)&&(e.Qa?Tf(b,c):Tf(b,d))})},null,!0);return{Wa:d,Oa:c}}
function Zf(a,b,c,d){var e=V(b),f=pf(e.is,e.P),h=new RegExp("(?:^|[^.#[:])"+(b.extends?"\\"+f.slice(0,-1)+"\\]":f)+"($|[.:[\\s>+~])");e=X(b).w;var g=$f(e,d);return nf(b,e,function(b){var e="";b.i||Sf(b);b.i.cssText&&(e=Vf(a,b.i.cssText,c));b.cssText=e;if(!R&&!cf(b)&&b.cssText){var k=e=b.cssText;null==b.ra&&(b.ra=We.test(e));if(b.ra)if(null==b.W){b.W=[];for(var n in g)k=g[n],k=k(e),e!==k&&(e=k,b.W.push(n))}else{for(n=0;n<b.W.length;++n)k=g[b.W[n]],e=k(e);k=e}b.cssText=k;b.m=b.m||b.selector;e="."+d;
n=b.m.split(",");k=0;for(var t=n.length,C;k<t&&(C=n[k]);k++)n[k]=C.match(h)?C.replace(f,e):e+" "+C;b.selector=n.join(",")}})}function $f(a,b){a=a.b;var c={};if(!R&&a)for(var d=0,e=a[d];d<a.length;e=a[++d]){var f=e,h=b;f.h=new RegExp("\\b"+f.keyframesName+"(?!\\B|-)","g");f.a=f.keyframesName+"-"+h;f.m=f.m||f.selector;f.selector=f.m.replace(f.keyframesName,f.a);c[e.keyframesName]=ag(e)}return c}function ag(a){return function(b){return b.replace(a.h,a.a)}}
function bg(a,b){var c=cg,d=bf(a);a.textContent=$e(d,function(a){var d=a.cssText=a.parsedCssText;a.i&&a.i.cssText&&(d=d.replace(Ne,"").replace(Oe,""),a.cssText=Vf(c,d,b))})}q.Object.defineProperties(Qf.prototype,{a:{configurable:!0,enumerable:!0,get:function(){return"x-scope"}}});var cg=new Qf;var dg={},eg=window.customElements;if(eg&&!R){var fg=eg.define;eg.define=function(a,b,c){var d=document.createComment(" Shady DOM styles for "+a+" "),e=document.head;e.insertBefore(d,(T?T.nextSibling:null)||e.firstChild);T=d;dg[a]=d;return fg.call(eg,a,b,c)}};function gg(){this.cache={}}gg.prototype.store=function(a,b,c,d){var e=this.cache[a]||[];e.push({v:b,styleElement:c,u:d});100<e.length&&e.shift();this.cache[a]=e};gg.prototype.fetch=function(a,b,c){if(a=this.cache[a])for(var d=a.length-1;0<=d;d--){var e=a[d],f;a:{for(f=0;f<c.length;f++){var h=c[f];if(e.v[h]!==b[h]){f=!1;break a}}f=!0}if(f)return e}};function hg(){}
function ig(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.target!==document.documentElement&&c.target!==document.head)for(var d=0;d<c.addedNodes.length;d++){var e=c.addedNodes[d];if(e.nodeType===Node.ELEMENT_NODE){var f=e.getRootNode();var h=e;var g=[];h.classList?g=Array.from(h.classList):h instanceof window.SVGElement&&h.hasAttribute("class")&&(g=h.getAttribute("class").split(/\s+/));h=g;g=h.indexOf(W.a);if((h=-1<g?h[g+1]:"")&&f===e.ownerDocument)jf(e,h,!0);else if(f.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&
(f=f.host))if(f=V(f).is,h===f)for(e=window.ShadyDOM.nativeMethods.querySelectorAll.call(e,":not(."+W.a+")"),f=0;f<e.length;f++)lf(e[f],h);else h&&jf(e,h,!0),jf(e,f)}}}}
if(!R){var jg=new MutationObserver(ig),kg=function(a){jg.observe(a,{childList:!0,subtree:!0})};if(window.customElements&&!window.customElements.polyfillWrapFlushCallback)kg(document);else{var lg=function(){kg(document.body)};window.HTMLImports?window.HTMLImports.whenReady(lg):requestAnimationFrame(function(){if("loading"===document.readyState){var a=function(){lg();document.removeEventListener("readystatechange",a)};document.addEventListener("readystatechange",a)}else lg()})}hg=function(){ig(jg.takeRecords())}}
var mg=hg;var ng={};var og=Promise.resolve();function pg(a){if(a=ng[a])a._applyShimCurrentVersion=a._applyShimCurrentVersion||0,a._applyShimValidatingVersion=a._applyShimValidatingVersion||0,a._applyShimNextVersion=(a._applyShimNextVersion||0)+1}function qg(a){return a._applyShimCurrentVersion===a._applyShimNextVersion}function rg(a){a._applyShimValidatingVersion=a._applyShimNextVersion;a.qa||(a.qa=!0,og.then(function(){a._applyShimCurrentVersion=a._applyShimNextVersion;a.qa=!1}))};var sg=null,tg=window.HTMLImports&&window.HTMLImports.whenReady||null,ug;function vg(a){requestAnimationFrame(function(){tg?tg(a):(sg||(sg=new Promise(function(a){ug=a}),"complete"===document.readyState?ug():document.addEventListener("readystatechange",function(){"complete"===document.readyState&&ug()})),sg.then(function(){a&&a()}))})};var wg=new gg;function Y(){var a=this;this.L={};this.c=document.documentElement;var b=new Ae;b.rules=[];this.h=Mf(this.c,new Lf(b));this.s=!1;this.b=this.a=null;vg(function(){xg(a)})}p=Y.prototype;p.wa=function(){mg()};p.Ma=function(a){return bf(a)};p.Za=function(a){return $e(a)};
p.prepareTemplate=function(a,b,c){if(!a.Ia){a.Ia=!0;a.name=b;a.extends=c;ng[b]=a;var d=(d=a.content.querySelector("style"))?d.getAttribute("css-build")||"":"";var e=[];for(var f=a.content.querySelectorAll("style"),h=0;h<f.length;h++){var g=f[h];if(g.hasAttribute("shady-unscoped")){if(!R){var k=g.textContent;Ze.has(k)||(Ze.add(k),k=g.cloneNode(!0),document.head.appendChild(k));g.parentNode.removeChild(g)}}else e.push(g.textContent),g.parentNode.removeChild(g)}e=e.join("").trim();c={is:b,extends:c,
eb:d};R||jf(a.content,b);xg(this);f=Ue.test(e)||Te.test(e);Ue.lastIndex=0;Te.lastIndex=0;e=Be(e);f&&S&&this.a&&this.a.transformRules(e,b);a._styleAst=e;a.a=d;d=[];S||(d=Rf(a._styleAst));if(!d.length||S)e=R?a.content:null,b=dg[b],f=nf(c,a._styleAst),b=f.length?df(f,c.is,e,b):void 0,a.pa=b;a.Ha=d}};
function yg(a){!a.b&&window.ShadyCSS&&window.ShadyCSS.CustomStyleInterface&&(a.b=window.ShadyCSS.CustomStyleInterface,a.b.transformCallback=function(b){a.ua(b)},a.b.validateCallback=function(){requestAnimationFrame(function(){(a.b.enqueued||a.s)&&a.F()})})}function xg(a){!a.a&&window.ShadyCSS&&window.ShadyCSS.ApplyShim&&(a.a=window.ShadyCSS.ApplyShim,a.a.invalidCallback=pg);yg(a)}
p.F=function(){xg(this);if(this.b){var a=this.b.processStyles();if(this.b.enqueued){if(S)for(var b=0;b<a.length;b++){var c=this.b.getStyleForCustomStyle(a[b]);if(c&&S&&this.a){var d=bf(c);xg(this);this.a.transformRules(d);c.textContent=$e(d)}}else for(zg(this,this.c,this.h),b=0;b<a.length;b++)(c=this.b.getStyleForCustomStyle(a[b]))&&bg(c,this.h.B);this.b.enqueued=!1;this.s&&!S&&this.styleDocument()}}};
p.styleElement=function(a,b){var c=V(a).is,d=X(a);if(!d){var e=V(a);d=e.is;e=e.P;var f=dg[d];d=ng[d];if(d){var h=d._styleAst;var g=d.Ha}d=Mf(a,new Lf(h,f,g,e))}a!==this.c&&(this.s=!0);b&&(d.G=d.G||{},Object.assign(d.G,b));if(S){if(d.G){b=d.G;for(var k in b)null===k?a.style.removeProperty(k):a.style.setProperty(k,b[k])}if(((k=ng[c])||a===this.c)&&k&&k.pa&&!qg(k)){if(qg(k)||k._applyShimValidatingVersion!==k._applyShimNextVersion)xg(this),this.a&&this.a.transformRules(k._styleAst,c),k.pa.textContent=
nf(a,d.w),rg(k);R&&(c=a.shadowRoot)&&(c.querySelector("style").textContent=nf(a,d.w));d.w=k._styleAst}}else if(zg(this,a,d),d.ja&&d.ja.length){c=d;k=V(a).is;d=(b=wg.fetch(k,c.B,c.ja))?b.styleElement:null;h=c.u;(g=b&&b.u)||(g=this.L[k]=(this.L[k]||0)+1,g=k+"-"+g);c.u=g;g=c.u;e=cg;e=d?d.textContent||"":Zf(e,a,c.B,g);f=X(a);var l=f.a;l&&!R&&l!==d&&(l._useCount--,0>=l._useCount&&l.parentNode&&l.parentNode.removeChild(l));R?f.a?(f.a.textContent=e,d=f.a):e&&(d=df(e,g,a.shadowRoot,f.b)):d?d.parentNode||
(Pf&&-1<e.indexOf("@media")&&(d.textContent=e),ef(d,null,f.b)):e&&(d=df(e,g,null,f.b));d&&(d._useCount=d._useCount||0,f.a!=d&&d._useCount++,f.a=d);g=d;R||(d=c.u,f=e=a.getAttribute("class")||"",h&&(f=e.replace(new RegExp("\\s*x-scope\\s*"+h+"\\s*","g")," ")),f+=(f?" ":"")+"x-scope "+d,e!==f&&gf(a,f));b||wg.store(k,c.B,g,c.u)}};function Ag(a,b){return(b=b.getRootNode().host)?X(b)?b:Ag(a,b):a.c}
function zg(a,b,c){a=Ag(a,b);var d=X(a);a=Object.create(d.B||null);var e=Yf(b,c.w);b=Wf(d.w,b).v;Object.assign(a,e.Oa,b,e.Wa);b=c.G;for(var f in b)if((e=b[f])||0===e)a[f]=e;f=cg;b=Object.getOwnPropertyNames(a);for(e=0;e<b.length;e++)d=b[e],a[d]=Uf(f,a[d],a);c.B=a}p.styleDocument=function(a){this.styleSubtree(this.c,a)};
p.styleSubtree=function(a,b){var c=a.shadowRoot;(c||a===this.c)&&this.styleElement(a,b);if(b=c&&(c.children||c.childNodes))for(a=0;a<b.length;a++)this.styleSubtree(b[a]);else if(a=a.children||a.childNodes)for(b=0;b<a.length;b++)this.styleSubtree(a[b])};p.ua=function(a){var b=this,c=bf(a);af(c,function(a){if(R)If(a);else{var c=W;a.selector=a.parsedSelector;If(a);a.selector=a.m=rf(c,a,c.c,void 0,void 0)}S&&(xg(b),b.a&&b.a.transformRule(a))});S?a.textContent=$e(c):this.h.w.rules.push(c)};
p.getComputedStyleValue=function(a,b){var c;S||(c=(X(a)||X(Ag(this,a))).B[b]);return(c=c||window.getComputedStyle(a).getPropertyValue(b))?c.trim():""};p.Ya=function(a,b){var c=a.getRootNode();b=b?b.split(/\s/):[];c=c.host&&c.host.localName;if(!c){var d=a.getAttribute("class");if(d){d=d.split(/\s/);for(var e=0;e<d.length;e++)if(d[e]===W.a){c=d[e+1];break}}}c&&b.push(W.a,c);S||(c=X(a))&&c.u&&b.push(cg.a,c.u);gf(a,b.join(" "))};p.Ja=function(a){return X(a)};Y.prototype.flush=Y.prototype.wa;
Y.prototype.prepareTemplate=Y.prototype.prepareTemplate;Y.prototype.styleElement=Y.prototype.styleElement;Y.prototype.styleDocument=Y.prototype.styleDocument;Y.prototype.styleSubtree=Y.prototype.styleSubtree;Y.prototype.getComputedStyleValue=Y.prototype.getComputedStyleValue;Y.prototype.setElementClass=Y.prototype.Ya;Y.prototype._styleInfoForNode=Y.prototype.Ja;Y.prototype.transformCustomStyleForDocument=Y.prototype.ua;Y.prototype.getStyleAst=Y.prototype.Ma;Y.prototype.styleAstToString=Y.prototype.Za;
Y.prototype.flushCustomStyles=Y.prototype.F;Object.defineProperties(Y.prototype,{nativeShadow:{get:function(){return R}},nativeCss:{get:function(){return S}}});var Z=new Y,Bg,Cg;window.ShadyCSS&&(Bg=window.ShadyCSS.ApplyShim,Cg=window.ShadyCSS.CustomStyleInterface);window.ShadyCSS={ScopingShim:Z,prepareTemplate:function(a,b,c){Z.F();Z.prepareTemplate(a,b,c)},styleSubtree:function(a,b){Z.F();Z.styleSubtree(a,b)},styleElement:function(a){Z.F();Z.styleElement(a)},styleDocument:function(a){Z.F();Z.styleDocument(a)},getComputedStyleValue:function(a,b){return Z.getComputedStyleValue(a,b)},nativeCss:S,nativeShadow:R};Bg&&(window.ShadyCSS.ApplyShim=Bg);
Cg&&(window.ShadyCSS.CustomStyleInterface=Cg);var Dg=window.customElements,Eg=window.HTMLImports,Fg=window.HTMLTemplateElement;window.WebComponents=window.WebComponents||{};if(Dg&&Dg.polyfillWrapFlushCallback){var Gg,Hg=function(){if(Gg){Fg.J&&Fg.J(window.document);var a=Gg;Gg=null;a();return!0}},Ig=Eg.whenReady;Dg.polyfillWrapFlushCallback(function(a){Gg=a;Ig(Hg)});Eg.whenReady=function(a){Ig(function(){Hg()?Eg.whenReady(a):a()})}}
Eg.whenReady(function(){requestAnimationFrame(function(){window.WebComponents.ready=!0;document.dispatchEvent(new CustomEvent("WebComponentsReady",{bubbles:!0}))})});var Jg=document.createElement("style");Jg.textContent="body {transition: opacity ease-in 0.2s; } \nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \n";var Kg=document.querySelector("head");Kg.insertBefore(Jg,Kg.firstChild);}).call(this);

//# sourceMappingURL=webcomponents-lite.js.map


================================================
FILE: src/common/channels/channels.actions.js
================================================
import { loadSample } from '../../services/sampleStore';
import { CHANNELS_CONSTANTS } from './channels.constants';
import { setNotes, initializeChannelNotes } from '../notes';
import { uuid } from '../../services/uuid';
import factorySamples from '../../samples.config';
import { setSelectedChannel } from '../master';
import { showFlashMessage, FLASH_MESSAGES } from '../window';

export const setChannelGain = (channel, gain) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_GAIN,
  payload: {
    channel,
    gain,
  },
});

export const setChannelPan = (channel, pan) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_PAN,
  payload: {
    channel,
    pan,
  },
});

export const setChannelPitchCoarse = (channel, pitchCoarse) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_PITCH_COARSE,
  payload: {
    channel,
    pitchCoarse,
  },
});

export const setChannelPitchFine = (channel, pitchFine) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_PITCH_FINE,
  payload: {
    channel,
    pitchFine,
  },
});

export const setChannelMuted = (channel, muted) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_MUTED,
  payload: {
    channel,
    muted,
  },
});

export const setChannelSolo = (channel, solo) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_SOLO,
  payload: {
    channel,
    solo,
  },
});

export const addChannel = (channel) => ({
  type: CHANNELS_CONSTANTS.ADD_CHANNEL,
  payload: channel,
});

export const removeChannel = (id) => ({
  type: CHANNELS_CONSTANTS.REMOVE_CHANNEL,
  payload: id,
});

export const updateChannelOrder = (oldIndex, newIndex) => ({
  type: CHANNELS_CONSTANTS.UPDATE_CHANNEL_ORDER,
  payload: {
    oldIndex,
    newIndex,
  },
});

export const replaceChannels = (channels) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNELS,
  payload: channels,
});

export const sampleLoaded = (channelID, isLoaded) => ({
  type: CHANNELS_CONSTANTS.SAMPLE_LOADED,
  payload: {
    channelID,
    isLoaded,
  },
});

export const setChannelSample = (channel, sampleURL) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_SAMPLE,
  payload: {
    channel,
    sampleURL,
  },
});

export const setChannelReverb = (channel, reverb) => ({
  type: CHANNELS_CONSTANTS.SET_CHANNEL_REVERB,
  payload: {
    channel,
    reverb,
  },
});

export const loadSampleStatefully = (dispatch, channel) => {
  dispatch(sampleLoaded(channel.id, false));
  loadSample(channel.sample).then((success) => {
    if (success) {
      dispatch(sampleLoaded(channel.id, true));
    }
  });
};

export const loadChannels = (channels, notes) => (dispatch) => {
  channels.forEach((channel) => {
    loadSampleStatefully(dispatch, channel);
  });
  dispatch(replaceChannels(channels));
  dispatch(setNotes(notes));
};

export const newChannel = () => (dispatch) => {
  const channelToAdd = {
    id: uuid(),
    sample: factorySamples[0].url,
    gain: 1,
    pitchCoarse: 0,
    pitchFine: 0,
    pan: 0,
  };
  dispatch(addChannel(channelToAdd));
  dispatch(initializeChannelNotes(channelToAdd.id));
  dispatch(setSelectedChannel(channelToAdd.id));
  loadSampleStatefully(dispatch, channelToAdd);
};

export const loadAndSetChannelSample = (channelID, sampleURL) => (dispatch) => {
  dispatch(sampleLoaded(channelID, false));
  loadSample(sampleURL).then((success) => {
    if (success) {
      dispatch(sampleLoaded(channelID, true));
    } else {
      dispatch(showFlashMessage(FLASH_MESSAGES.SAMPLE_LOAD_ERROR));
    }
  });
  dispatch(setChannelSample(channelID, sampleURL));
};

export const deleteChannel = (channelID, channels, selectedChannelId) => (dispatch) => {
  if (channels.length === 1) {
    dispatch(newChannel());
  }
  if (selectedChannelId === channelID) {
    dispatch(setSelectedChannel(channels[0].id));
  }
  dispatch(removeChannel(channelID));
};


================================================
FILE: src/common/channels/channels.constants.js
================================================
export const CHANNELS_CONSTANTS = {
  ADD_CHANNEL: 'ADD_CHANNEL',
  REMOVE_CHANNEL: 'REMOVE_CHANNEL',
  SET_CHANNEL_SAMPLE: 'SET_CHANNEL_SAMPLE',
  SET_CHANNEL_PITCH_COARSE: 'SET_CHANNEL_PITCH_COARSE',
  SET_CHANNEL_FINE: 'SET_CHANNEL_FINE',
  SET_CHANNEL_GAIN: 'SET_CHANNEL_GAIN',
  SET_CHANNEL_PAN: 'SET_CHANNEL_PAN',
  SET_CHANNEL_REVERB: 'SET_CHANNEL_REVERB',
  SET_CHANNEL_MUTED: 'SET_CHANNEL_MUTED',
  SET_CHANNEL_SOLO: 'SET_CHANNEL_SOLO',
  SET_CHANNELS: 'SET_CHANNELS',
  SAMPLE_LOADED: 'SAMPLE_LOADED',
  UPDATE_CHANNEL_ORDER: 'UPDATE_CHANNEL_ORDER',
};


================================================
FILE: src/common/channels/channels.reducer.js
================================================
import * as R from 'ramda';
import { CHANNELS_CONSTANTS } from './channels.constants';
import presets from '../../presets';

export const channelsInitialState = R.clone(presets[1].channels);

export const channelsReducer = (state = channelsInitialState, action) => {
  switch (action.type) {
    case CHANNELS_CONSTANTS.SET_CHANNEL_SAMPLE:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return { ...channel, sample: action.payload.sampleURL };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.SET_CHANNEL_GAIN:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return { ...channel, gain: action.payload.gain };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.SET_CHANNEL_PAN:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return { ...channel, pan: action.payload.pan };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.SET_CHANNEL_PITCH_COARSE:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return { ...channel, pitchCoarse: action.payload.pitchCoarse };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.SET_CHANNEL_PITCH_FINE:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return { ...channel, pitchFine: action.payload.pitchFine };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.SET_CHANNEL_REVERB:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return { ...channel, reverb: action.payload.reverb };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.ADD_CHANNEL:
      return [...state, action.payload];
    case CHANNELS_CONSTANTS.REMOVE_CHANNEL:
      return state.filter((channel) => channel.id !== action.payload);
    case CHANNELS_CONSTANTS.SAMPLE_LOADED:
      return state.map((channel) => {
        if (channel.id === action.payload.channelID) {
          return { ...channel, sampleLoaded: action.payload.isLoaded };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.SET_CHANNEL_MUTED:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return {
            ...channel,
            muted: action.payload.muted,
            solo: false,
          };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.SET_CHANNEL_SOLO:
      return state.map((channel) => {
        if (channel.id === action.payload.channel) {
          return {
            ...channel,
            solo: action.payload.solo,
            muted: false,
          };
        }
        return channel;
      });
    case CHANNELS_CONSTANTS.UPDATE_CHANNEL_ORDER:
      return R.insert(
        action.payload.newIndex,
        state[action.payload.oldIndex],
        R.remove(action.payload.oldIndex, 1, state),
      );
    case CHANNELS_CONSTANTS.SET_CHANNELS:
      return [...action.payload];
    default:
      return state;
  }
};


================================================
FILE: src/common/channels/channels.reducer.test.js
================================================
import { channelsInitialState, channelsReducer } from './channels.reducer';
import {
  setChannelSample,
  setChannelGain,
  setChannelPan,
  addChannel,
  removeChannel,
  replaceChannels,
  setChannelPitchCoarse,
  setChannelPitchFine,
  setChannelReverb,
  setChannelMuted,
  setChannelSolo,
} from './channels.actions';

jest.mock('../../presets');
jest.mock('../../samples.config');
jest.mock('../../services/featureChecks');

const testSample = '/fake/sample/b/url.wav';

describe('setChannelSample', () => {
  test('should change a sample', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelSample(channelsInitialState[0].id, testSample),
    );
    expect(state[0].sample).toEqual(testSample);
  });
});

describe('setChannelGain', () => {
  test('should change gain for a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelGain(channelsInitialState[0].id, 0.5),
    );
    expect(state[0].gain).toEqual(0.5);
  });
});

describe('setChannelPan', () => {
  test('should change pan for a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelPan(channelsInitialState[0].id, 0.5),
    );
    expect(state[0].pan).toEqual(0.5);
  });
});

describe('setChannelPitchCoarse', () => {
  test('should change pitch (coarse) for a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelPitchCoarse(channelsInitialState[0].id, 5),
    );
    expect(state[0].pitchCoarse).toEqual(5);
  });
});

describe('setChannelPitchFine', () => {
  test('should change pitch (fine) for a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelPitchFine(channelsInitialState[0].id, -50),
    );
    expect(state[0].pitchFine).toEqual(-50);
  });
});

describe('setChannelReverb', () => {
  test('should change reverb for a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelReverb(channelsInitialState[0].id, 0.5),
    );
    expect(state[0].reverb).toEqual(0.5);
  });
});

describe('setChannelMuted', () => {
  test('should mute a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelMuted(channelsInitialState[0].id, true),
    );
    expect(state[0].muted).toEqual(true);
  });

  test('should set solo to false if it was true', () => {
    const soloState = channelsReducer(
      channelsInitialState,
      setChannelSolo(channelsInitialState[0].id, true),
    );
    expect(soloState[0].solo).toEqual(true);
    const state = channelsReducer(
      soloState,
      setChannelMuted(channelsInitialState[0].id, true),
    );
    expect(state[0].solo).toEqual(false);
  });
});

describe('setChannelSolo', () => {
  test('should solo a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      setChannelSolo(channelsInitialState[0].id, true),
    );
    expect(state[0].solo).toEqual(true);
  });

  test('should set muted to false if it was true', () => {
    const mutedState = channelsReducer(
      channelsInitialState,
      setChannelMuted(channelsInitialState[0].id, true),
    );
    expect(mutedState[0].muted).toEqual(true);
    const state = channelsReducer(
      mutedState,
      setChannelSolo(channelsInitialState[0].id, true),
    );
    expect(state[0].muted).toEqual(false);
  });
});

describe('addChannel', () => {
  test('should add a channel', () => {
    const state = channelsReducer(
      channelsInitialState,
      addChannel({
        id: '12345',
        gain: 1,
        sample: {},
      }),
    );
    expect(state.length).toEqual(channelsInitialState.length + 1);
  });
});

describe('removeChannel', () => {
  test('should remove a channel that exists', () => {
    const state = channelsReducer(
      channelsInitialState,
      removeChannel(channelsInitialState[0].id),
    );
    expect(state.length).toEqual(channelsInitialState.length - 1);
  });

  test('should do nothing if no channel matches the ID', () => {
    const state = channelsReducer(
      channelsInitialState,
      removeChannel('foo'),
    );
    expect(state.length).toEqual(channelsInitialState.length);
  });
});

describe('replaceChannels', () => {
  test('should replace existing channels', () => {
    const state = channelsReducer(
      channelsInitialState,
      replaceChannels([
        {
          id: 'empty_channel',
          sample: 'test',
          gain: 1,
        },
      ]),
    );
    expect(state.length).toEqual(1);
  });
});


================================================
FILE: src/common/channels/channels.selectors.js
================================================
import * as R from 'ramda';

export const channelsSelector = R.path(['channels']);


================================================
FILE: src/common/channels/index.js
================================================
export * from './channels.reducer';
export * from './channels.selectors';
export * from './channels.actions';


================================================
FILE: src/common/index.js
================================================
export * from './playbackSession';
export * from './channels';
export * from './tempo';
export * from './master';
export * from './notes';
export * from './presets';
export * from './window';
export * from './userSamples';


================================================
FILE: src/common/master/index.js
================================================
export * from './master.reducer';
export * from './master.selectors';
export * from './master.actions';


================================================
FILE: src/common/master/master.actions.js
================================================
import { MASTER_CONSTANTS } from './master.constants';

export const setPattern = (patternIndex) => ({
  type: MASTER_CONSTANTS.SET_PATTERN,
  payload: patternIndex,
});

export const setSelectedChannel = (channelID) => ({
  type: MASTER_CONSTANTS.SET_SELECTED_CHANNEL,
  payload: channelID,
});


================================================
FILE: src/common/master/master.constants.js
================================================
export const MASTER_CONSTANTS = {
  SET_PATTERN: 'SET_PATTERN',
  SET_SELECTED_CHANNEL: 'SET_SELECTED_CHANNEL',
};


================================================
FILE: src/common/master/master.reducer.js
================================================
import { MASTER_CONSTANTS } from './master.constants';
import presets from '../../presets';

export const masterInitialState = {
  pattern: 0,
  selectedChannel: presets[1].channels[0].id,
};

export const masterReducer = (state = masterInitialState, action) => {
  switch (action.type) {
    case MASTER_CONSTANTS.SET_PATTERN:
      return {
        ...state,
        pattern: action.payload,
      };
    case MASTER_CONSTANTS.SET_SELECTED_CHANNEL:
      return {
        ...state,
        selectedChannel: action.payload,
      };
    default:
      return state;
  }
};


================================================
FILE: src/common/master/master.reducer.test.js
================================================
import { masterInitialState, masterReducer } from './master.reducer';
import {
  setPattern,
} from './master.actions';

describe('setPattern', () => {
  test('should change the pattern', () => {
    const state = masterReducer(masterInitialState, setPattern(1));
    expect(state.pattern).toEqual(1);
  });
});


================================================
FILE: src/common/master/master.selectors.js
================================================
import * as R from 'ramda';

export const patternSelector = R.path(['master', 'pattern']);

export const selectedChannelSelector = R.path(['master', 'selectedChannel']);


================================================
FILE: src/common/notes/index.js
================================================
export * from './notes.reducer';
export * from './notes.selectors';
export * from './notes.actions';


================================================
FILE: src/common/notes/notes.actions.js
================================================
import { NOTES_CONSTANTS } from './notes.constants';

export const initializeChannelNotes = (channelID) => ({
  type: NOTES_CONSTANTS.INITIALIZE_CHANNEL,
  payload: channelID,
});

export const removeChannelNotes = (channelID) => ({
  type: NOTES_CONSTANTS.REMOVE_CHANNEL,
  payload: channelID,
});

export const setNotes = (notes) => ({
  type: NOTES_CONSTANTS.SET_NOTES,
  payload: notes,
});

export const toggleNote = (channelID, pattern, beat) => ({
  type: NOTES_CONSTANTS.TOGGLE_NOTE,
  payload: {
    channelID,
    pattern,
    beat,
  },
});


================================================
FILE: src/common/notes/notes.constants.js
================================================
export const NOTES_CONSTANTS = {
  INITIALIZE_CHANNEL: 'INITIALIZE_CHANNEL_NOTES',
  REMOVE_CHANNEL: 'REMOVE_CHANNEL_NOTES',
  TOGGLE_NOTE: 'TOGGLE_NOTE',
  SET_NOTES: 'SET_NOTES',
};


================================================
FILE: src/common/notes/notes.reducer.js
================================================
import { uuid } from '../../services/uuid';
import presets from '../../presets';
import { EMPTY_NOTE_ROW } from '../../presets/empty';
import { NOTES_CONSTANTS } from './notes.constants';

export const notesInitialState = presets[1].notes;

// Returns a new noteAr clone with a note at beat either added or removed
const toggleNote = (noteAr, beat) => {
  if (noteAr.find((note) => note.beat === beat)) {
    return noteAr.filter((note) => note.beat !== beat);
  }
  return [
    ...noteAr,
    {
      beat,
      id: uuid(),
    },
  ];
};

// Returns new state object with note at beat on pattern toggled
const toggleNoteState = (state, { channelID, pattern, beat }) => ({
  ...state,
  [channelID]: state[channelID].map((noteAr, patternIndex) => {
    if (patternIndex === pattern) {
      // This is the active pattern
      return toggleNote(noteAr, beat);
    }
    return noteAr; // Do nothing to other patterns
  }),
});

export const notesReducer = (state = notesInitialState, action) => {
  switch (action.type) {
    case NOTES_CONSTANTS.TOGGLE_NOTE:
      return toggleNoteState(state, action.payload);
    case NOTES_CONSTANTS.INITIALIZE_CHANNEL:
      return {
        ...state,
        [action.payload]: EMPTY_NOTE_ROW, // TO DO: add empty array for each pattern
      };
    case NOTES_CONSTANTS.REMOVE_CHANNEL:
      return {
        ...state,
        [action.payload]: undefined,
      };
    case NOTES_CONSTANTS.SET_NOTES:
      return {
        ...action.payload,
      };
    default:
      return state;
  }
};


================================================
FILE: src/common/notes/notes.reducer.test.js
================================================
import { notesReducer } from './notes.reducer';
import {
  toggleNote,
  initializeChannelNotes,
  removeChannelNotes,
  setNotes,
} from './notes.actions';

jest.mock('../../presets');
jest.mock('../../samples.config');

const testNotes = {
  bongo: [
    [
      {
        id: 'bing',
        beat: 1,
      },
      {
        id: 'bong',
        beat: 3,
      },
    ],
    [
      {
        id: 'ping',
        beat: 2,
      },
      {
        id: 'pang',
        beat: 4,
      },
    ],
  ],
};

describe('toggleNote', () => {
  test('should toggle a note off', () => {
    const state = notesReducer(testNotes, toggleNote('bongo', 0, 1));
    expect(state.bongo[0].length).toBe(1);
  });

  test('should toggle a note on', () => {
    const state = notesReducer(testNotes, toggleNote('bongo', 0, 2));
    expect(state.bongo[0].length).toBe(3);
  });

  test('should toggle a note on the second preset on', () => {
    const state = notesReducer(testNotes, toggleNote('bongo', 1, 1));
    expect(state.bongo[1].length).toBe(3);
  });
});

describe('initializeChannel', () => {
  test('should add a channel', () => {
    const state = notesReducer(
      testNotes,
      initializeChannelNotes('cowbell'),
    );
    expect(state.cowbell).not.toBeUndefined();
  });
});

describe('removeChannel', () => {
  test('should remove a channel that exists', () => {
    const state = notesReducer(
      testNotes,
      removeChannelNotes('bongo'),
    );
    expect(state.bongo).toBeUndefined();
  });

  test('should do nothing if no channel matches the ID', () => {
    const state = notesReducer(
      testNotes,
      removeChannelNotes('foobar'),
    );
    expect(state.bongo).not.toBeUndefined();
    expect(state.foobar).toBeUndefined();
  });
});

describe('setNotes', () => {
  test('should replace existing channels', () => {
    const state = notesReducer(
      testNotes,
      setNotes({
        maracas: [
          [],
          [],
        ],
      }),
    );
    expect(state.bongo).toBeUndefined();
    expect(state.maracas).not.toBeUndefined();
  });
});


================================================
FILE: src/common/notes/notes.selectors.js
================================================
import * as R from 'ramda';

export const notesSelector = R.path(['notes']);


================================================
FILE: src/common/playbackSession/index.js
================================================
export * from './playbackSession.actions';
export * from './playbackSession.reducer';
export * from './playbackSession.selectors';


================================================
FILE: src/common/playbackSession/playbackSession.actions.js
================================================
import { PLAYBACK_SESSION_CONSTANTS } from './playbackSession.constants';
import { getAudioContext } from '../../services/audioContext';
import { unmute } from '../../services/unmute';

export const startPlayback = () => ({
  type: PLAYBACK_SESSION_CONSTANTS.START_PLAYBACK,
});

export const stopPlayback = () => ({
  type: PLAYBACK_SESSION_CONSTANTS.STOP_PLAYBACK,
});

export const setStartTime = (val) => ({
  type: PLAYBACK_SESSION_CONSTANTS.SET_START_TIME,
  payload: val,
});

export const startPlaybackAndResume = () => (dispatch) => {
  unmute();
  getAudioContext().resume();
  dispatch(startPlayback());
};


================================================
FILE: src/common/playbackSession/playbackSession.constants.js
================================================
export const PLAYBACK_SESSION_CONSTANTS = {
  START_PLAYBACK: 'START_PLAYBACK',
  STOP_PLAYBACK: 'STOP_PLAYBACK',
  SET_START_TIME: 'SET_START_TIME',
};


================================================
FILE: src/common/playbackSession/playbackSession.reducer.js
================================================
import { PLAYBACK_SESSION_CONSTANTS } from './playbackSession.constants';
import { getAudioContext } from '../../services/audioContext';
import { LOOKAHEAD } from '../../services/audioEngine.config';

export const playbackSessionInitialState = {
  playing: false,
  startTime: null,
  currentBeat: 1,
};

export const playbackSessionReducer = (state = playbackSessionInitialState, action) => {
  switch (action.type) {
    case PLAYBACK_SESSION_CONSTANTS.START_PLAYBACK:
      return {
        ...state,
        playing: true,
        startTime: getAudioContext().currentTime + LOOKAHEAD + LOOKAHEAD,
      };
    case PLAYBACK_SESSION_CONSTANTS.STOP_PLAYBACK:
      return {
        ...state,
        playing: false,
        startTime: null,
      };
    case PLAYBACK_SESSION_CONSTANTS.SET_START_TIME:
      return {
        ...state,
        startTime: action.payload,
      };
    default:
      return state;
  }
};


================================================
FILE: src/common/playbackSession/playbackSession.reducer.test.js
================================================
import {
  playbackSessionInitialState,
  playbackSessionReducer,
} from './playbackSession.reducer';
import {
  startPlayback,
  stopPlayback,
  setStartTime,
} from './playbackSession.actions';
import { LOOKAHEAD } from '../../services/audioEngine.config';

jest.mock('../../services/audioContext.js');

describe('startPlayback', () => {
  test('should set playing to true', () => {
    const state = playbackSessionReducer(playbackSessionInitialState, startPlayback());
    expect(state.playing).toBe(true);
  });

  test('should set startTime to current time plus lookahead', () => {
    const state = playbackSessionReducer(playbackSessionInitialState, startPlayback());
    expect(state.startTime).toBe(1 + LOOKAHEAD + LOOKAHEAD);
  });
});

describe('startPlayback', () => {
  test('should set playing to false', () => {
    const state = playbackSessionReducer(playbackSessionInitialState, stopPlayback());
    expect(state.playing).toBe(false);
  });

  test('should set startTime to null', () => {
    const state = playbackSessionReducer(playbackSessionInitialState, stopPlayback());
    expect(state.startTime).toBeNull();
  });
});

describe('setStartTime', () => {
  test('should set startTime', () => {
    const state = playbackSessionReducer(playbackSessionInitialState, setStartTime(2.1234));
    expect(state.startTime).toBe(2.1234);
  });
});


================================================
FILE: src/common/playbackSession/playbackSession.selectors.js
================================================
import * as R from 'ramda';

export const playingSelector = R.path(['playbackSession', 'playing']);
export const startTimeSelector = R.path(['playbackSession', 'startTime']);


================================================
FILE: src/common/presets/index.js
================================================
export * from './presets.actions';
export * from './presets.reducer';
export * from './presets.selectors';


================================================
FILE: src/common/presets/presets.actions.js
================================================
import { setBPM, setSwing } from '../tempo';
import { loadChannels } from '../channels';
import { setPattern, setSelectedChannel } from '../master';
import { PRESETS_CONSTANTS } from './presets.constants';
import presets from '../../presets';
import { showFlashMessage, FLASH_MESSAGES } from '../window';
import { currentStateSelector } from './presets.selectors';

export const setPreset = (presetName) => ({
  type: PRESETS_CONSTANTS.SET_PRESET,
  payload: presetName,
});

export const savePreset = (preset) => ({
  type: PRESETS_CONSTANTS.SAVE_PRESET,
  payload: preset,
});

export const savePresetAs = (preset) => ({
  type: PRESETS_CONSTANTS.SAVE_PRESET_AS,
  payload: preset,
});

export const deletePreset = (presetName) => ({
  type: PRESETS_CONSTANTS.DELETE_PRESET,
  payload: presetName,
});

export const loadPreset = (preset) => (dispatch) => {
  dispatch(setBPM(preset.bpm));
  dispatch(setSwing(preset.swing));
  dispatch(loadChannels(preset.channels, preset.notes));
  dispatch(setPreset(preset.name));
  dispatch(setPattern(0));
  dispatch(setSelectedChannel(preset.channels[0].id));
};

export const erasePreset = (presetName) => (dispatch) => {
  dispatch(setBPM(presets[0].bpm));
  dispatch(setSwing(presets[0].swing));
  dispatch(loadChannels(presets[0].channels, presets[0].notes));
  dispatch(setPreset(presets[0].name));
  dispatch(setPattern(0));
  dispatch(setSelectedChannel(presets[0].channels[0].id));
  dispatch(deletePreset(presetName));
  dispatch(showFlashMessage(FLASH_MESSAGES.PRESET_DELETED));
};

export const doSavePresetAs = (presetName) => (dispatch, getState) => {
  const currentState = currentStateSelector(getState());
  dispatch(savePresetAs({
    ...currentState,
    name: presetName,
  }));
  dispatch(setPreset(presetName));
  dispatch(showFlashMessage(FLASH_MESSAGES.PRESET_SAVED));
};

export const doSavePreset = (presetName) => (dispatch, getState) => {
  const currentState = currentStateSelector(getState());
  dispatch(savePreset({
    ...currentState,
    name: presetName,
  }));
  dispatch(showFlashMessage(FLASH_MESSAGES.PRESET_SAVED));
};


================================================
FILE: src/common/presets/presets.constants.js
================================================
export const PRESETS_CONSTANTS = {
  SAVE_PRESET: 'SAVE_PRESET',
  SAVE_PRESET_AS: 'SAVE_PRESET_AS',
  DELETE_PRESET: 'DELETE_PRESET',
  SET_PRESET: 'SET_PRESET',
};


================================================
FILE: src/common/presets/presets.reducer.js
================================================
import { PRESETS_CONSTANTS } from './presets.constants';
import defaultPresets from '../../presets';

export const presetsInitialState = {
  userPresets: [],
  preset: defaultPresets[1].name,
};

export const presetsReducer = (state = presetsInitialState, action) => {
  switch (action.type) {
    case PRESETS_CONSTANTS.SET_PRESET:
      return {
        ...state,
        preset: action.payload,
      };
    case PRESETS_CONSTANTS.SAVE_PRESET:
      return {
        ...state,
        userPresets: state.userPresets.map(
          (userPreset) => (userPreset.name === action.payload.name
            ? action.payload
            : userPreset),
        ),
      };
    case PRESETS_CONSTANTS.SAVE_PRESET_AS:
      return {
        ...state,
        userPresets: [
          ...state.userPresets.filter(
            (userPreset) => userPreset.name !== action.payload.name,
          ),
          action.payload,
        ],
      };
    case PRESETS_CONSTANTS.DELETE_PRESET:
      return {
        ...state,
        userPresets: state.userPresets.filter(
          (userPreset) => userPreset.name !== action.payload,
        ),
      };
    default:
      return state;
  }
};


================================================
FILE: src/common/presets/presets.reducer.test.js
================================================
import { presetsInitialState, presetsReducer } from './presets.reducer';
import {
  setPreset,
  savePreset,
  savePresetAs,
  deletePreset,
} from './presets.actions';

jest.mock('../../presets');
jest.mock('../../services/featureChecks');

const testPreset = {
  name: 'Test preset',
  bpm: 120,
};

describe('setPreset', () => {
  test('should change the preset', () => {
    const state = presetsReducer(presetsInitialState, setPreset('hello'));
    expect(state.preset).toEqual('hello');
  });
});

describe('savePresetAs', (
Download .txt
gitextract_4_fwl4lt/

├── .circleci/
│   └── config.yml
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .prettierrc
├── CNAME
├── README.md
├── __mocks__/
│   ├── fileMock.js
│   └── styleMock.js
├── babel.config.js
├── index.html
├── manifest.json
├── package.json
├── public/
│   ├── assets/
│   │   └── icons/
│   │       └── browserconfig.xml
│   └── sw.js
├── src/
│   ├── __mocks__/
│   │   └── samples.config.js
│   ├── assets/
│   │   └── js/
│   │       ├── webaudio-controls.js
│   │       └── webcomponents-lite.js
│   ├── common/
│   │   ├── channels/
│   │   │   ├── channels.actions.js
│   │   │   ├── channels.constants.js
│   │   │   ├── channels.reducer.js
│   │   │   ├── channels.reducer.test.js
│   │   │   ├── channels.selectors.js
│   │   │   └── index.js
│   │   ├── index.js
│   │   ├── master/
│   │   │   ├── index.js
│   │   │   ├── master.actions.js
│   │   │   ├── master.constants.js
│   │   │   ├── master.reducer.js
│   │   │   ├── master.reducer.test.js
│   │   │   └── master.selectors.js
│   │   ├── notes/
│   │   │   ├── index.js
│   │   │   ├── notes.actions.js
│   │   │   ├── notes.constants.js
│   │   │   ├── notes.reducer.js
│   │   │   ├── notes.reducer.test.js
│   │   │   └── notes.selectors.js
│   │   ├── playbackSession/
│   │   │   ├── index.js
│   │   │   ├── playbackSession.actions.js
│   │   │   ├── playbackSession.constants.js
│   │   │   ├── playbackSession.reducer.js
│   │   │   ├── playbackSession.reducer.test.js
│   │   │   └── playbackSession.selectors.js
│   │   ├── presets/
│   │   │   ├── index.js
│   │   │   ├── presets.actions.js
│   │   │   ├── presets.constants.js
│   │   │   ├── presets.reducer.js
│   │   │   ├── presets.reducer.test.js
│   │   │   └── presets.selectors.js
│   │   ├── tempo/
│   │   │   ├── index.js
│   │   │   ├── tempo.actions.js
│   │   │   ├── tempo.constants.js
│   │   │   ├── tempo.reducer.js
│   │   │   ├── tempo.reducer.test.js
│   │   │   └── tempo.selectors.js
│   │   ├── userSamples/
│   │   │   ├── index.js
│   │   │   ├── userSamples.actions.js
│   │   │   ├── userSamples.constants.js
│   │   │   ├── userSamples.reducer.js
│   │   │   └── userSamples.selectors.js
│   │   └── window/
│   │       ├── index.js
│   │       ├── window.actions.js
│   │       ├── window.constants.js
│   │       ├── window.reducer.js
│   │       ├── window.reducer.test.js
│   │       └── window.selectors.js
│   ├── components/
│   │   ├── AddChannelButton/
│   │   │   ├── AddChannelButton.component.jsx
│   │   │   ├── AddChannelButton.container.js
│   │   │   └── index.js
│   │   ├── App.jsx
│   │   ├── BPMInput/
│   │   │   ├── BPMInput.component.jsx
│   │   │   ├── BPMInput.container.js
│   │   │   ├── BPMInput.selectors.js
│   │   │   └── index.js
│   │   ├── Branding.jsx
│   │   ├── Channel/
│   │   │   ├── Channel.component.jsx
│   │   │   ├── Channel.container.js
│   │   │   ├── Channel.selectors.js
│   │   │   ├── HitButton.component.jsx
│   │   │   ├── RemoveButton.component.jsx
│   │   │   └── index.js
│   │   ├── ChannelControls/
│   │   │   ├── ChannelControls.component.jsx
│   │   │   ├── ChannelControls.container.js
│   │   │   ├── ChannelControls.selectors.js
│   │   │   └── index.js
│   │   ├── ChannelHeader/
│   │   │   ├── ChannelHeader.component.jsx
│   │   │   ├── ChannelHeaderLabel.component.jsx
│   │   │   └── index.js
│   │   ├── ChannelList/
│   │   │   ├── ChannelList.component.jsx
│   │   │   ├── ChannelList.container.js
│   │   │   ├── ChannelList.selectors.js
│   │   │   └── index.js
│   │   ├── FancyButton.component.jsx
│   │   ├── FlashMessage/
│   │   │   ├── FlashMessage.component.jsx
│   │   │   ├── FlashMessage.container.js
│   │   │   ├── FlashMessage.selectors.js
│   │   │   └── index.js
│   │   ├── GithubLink.component.jsx
│   │   ├── InfoKnob.component.jsx
│   │   ├── InstallButton.jsx
│   │   ├── Knob.component.jsx
│   │   ├── LabelBox.jsx
│   │   ├── Logo.component.jsx
│   │   ├── Marker/
│   │   │   ├── Marker.component.jsx
│   │   │   ├── Marker.container.js
│   │   │   ├── Marker.selectors.js
│   │   │   └── index.js
│   │   ├── MasterControls/
│   │   │   ├── MasterControls.component.jsx
│   │   │   └── index.js
│   │   ├── Modal.component.jsx
│   │   ├── MuteSolo/
│   │   │   ├── MuteSolo.component.jsx
│   │   │   ├── MuteSolo.container.js
│   │   │   └── index.js
│   │   ├── PatternSelector/
│   │   │   ├── PatternSelector.component.jsx
│   │   │   ├── PatternSelector.container.js
│   │   │   ├── PatternSelector.selectors.js
│   │   │   └── index.js
│   │   ├── PlayButton/
│   │   │   ├── PlayButton.component.jsx
│   │   │   ├── PlayButton.container.js
│   │   │   ├── PlayButton.selectors.js
│   │   │   └── index.js
│   │   ├── PresetDeleted.component.jsx
│   │   ├── PresetSaved.component.jsx
│   │   ├── PresetSelector/
│   │   │   ├── PresetSelector.component.jsx
│   │   │   ├── PresetSelector.container.js
│   │   │   ├── PresetSelector.selectors.js
│   │   │   └── index.js
│   │   ├── SampleLoadError.component.jsx
│   │   ├── SampleSelect/
│   │   │   ├── SampleSelect.component.jsx
│   │   │   ├── SampleSelect.container.js
│   │   │   ├── SampleSelect.selectors.js
│   │   │   └── index.js
│   │   ├── SavePresetModal/
│   │   │   ├── SavePresetModal.component.jsx
│   │   │   ├── SavePresetModal.container.js
│   │   │   ├── SavePresetModal.selectors.js
│   │   │   └── index.js
│   │   ├── SwingControl/
│   │   │   ├── SwingControl.component.jsx
│   │   │   ├── SwingControl.container.js
│   │   │   ├── SwingControl.selectors.js
│   │   │   └── index.js
│   │   ├── Toggles/
│   │   │   ├── Toggle.component.jsx
│   │   │   ├── ToggleGroup.component.jsx
│   │   │   ├── Toggles.component.jsx
│   │   │   ├── Toggles.container.js
│   │   │   ├── Toggles.selectors.js
│   │   │   └── index.js
│   │   ├── VolumeMeter.component.jsx
│   │   ├── design-system/
│   │   │   ├── Box.js
│   │   │   ├── Button.js
│   │   │   ├── ControlLabel.js
│   │   │   ├── Form.js
│   │   │   ├── Heading.js
│   │   │   ├── HoverButton.js
│   │   │   ├── HoverLink.js
│   │   │   ├── Image.js
│   │   │   ├── Label.js
│   │   │   ├── Line.js
│   │   │   ├── Text.js
│   │   │   ├── TextInput.js
│   │   │   └── index.js
│   │   ├── index.js
│   │   └── timedCallback.hoc.jsx
│   ├── index.html
│   ├── index.jsx
│   ├── presets/
│   │   ├── 707.js
│   │   ├── 808.js
│   │   ├── __mocks__/
│   │   │   └── index.js
│   │   ├── ace.js
│   │   ├── empty.js
│   │   ├── hip-hop.js
│   │   ├── index.js
│   │   └── ldrum.js
│   ├── reducer.js
│   ├── samples.config.js
│   ├── services/
│   │   ├── __mocks__/
│   │   │   ├── audioContext.js
│   │   │   ├── audioRouter.js
│   │   │   └── featureChecks.js
│   │   ├── animations.js
│   │   ├── audioAnalyzer.js
│   │   ├── audioContext.js
│   │   ├── audioContext.test.js
│   │   ├── audioEngine.config.js
│   │   ├── audioLoop.js
│   │   ├── audioRouter.js
│   │   ├── audioScheduler.js
│   │   ├── audioScheduler.test.js
│   │   ├── database.js
│   │   ├── featureChecks.js
│   │   ├── fileUtils.js
│   │   ├── pwaInstall.js
│   │   ├── reverb.js
│   │   ├── sampleStore.js
│   │   ├── swing.js
│   │   ├── unmute.js
│   │   └── uuid.js
│   ├── store.js
│   └── styles/
│       ├── globalStyles.js
│       └── theme.js
└── vite.config.js
Download .txt
SYMBOL INDEX (331 symbols across 23 files)

FILE: src/assets/js/webaudio-controls.js
  class WebAudioControlsWidget (line 105) | class WebAudioControlsWidget extends HTMLElement{
    method constructor (line 106) | constructor(){
    method sendEvent (line 154) | sendEvent(ev){
    method getAttr (line 160) | getAttr(n,def){
    method showtip (line 172) | showtip(d){
    method pointerover (line 233) | pointerover(e) {
    method pointerout (line 237) | pointerout(e) {
    method contextMenu (line 241) | contextMenu(e){
    method setMidiController (line 247) | setMidiController(channel, cc) {
    method listeningToThisMidiController (line 252) | listeningToThisMidiController(channel, cc) {
    method processMidiEvent (line 258) | processMidiEvent(event){
  method constructor (line 297) | constructor(){
  method connectedCallback (line 300) | connectedCallback(){
  method disconnectedCallback (line 368) | disconnectedCallback(){}
  method setupImage (line 369) | setupImage(){
  method redraw (line 406) | redraw() {
  method _setValue (line 433) | _setValue(v){
  method setValue (line 449) | setValue(v,f){
  method wheel (line 453) | wheel(e) {
  method pointerdown (line 466) | pointerdown(ev){
  method constructor (line 555) | constructor(){
  method connectedCallback (line 558) | connectedCallback(){
  method disconnectedCallback (line 644) | disconnectedCallback(){}
  method setupImage (line 645) | setupImage(){
  method redraw (line 703) | redraw() {
  method _setValue (line 730) | _setValue(v){
  method setValue (line 745) | setValue(v,f){
  method wheel (line 749) | wheel(e) {
  method pointerdown (line 761) | pointerdown(ev){
  method constructor (line 852) | constructor(){
  method connectedCallback (line 855) | connectedCallback(){
  method disconnectedCallback (line 914) | disconnectedCallback(){}
  method setupImage (line 915) | setupImage(){
  method redraw (line 944) | redraw() {
  method setValue (line 951) | setValue(v,f){
  method pointerdown (line 964) | pointerdown(ev){
  method constructor (line 1047) | constructor(){
  method connectedCallback (line 1057) | connectedCallback(){
  method disconnectedCallback (line 1126) | disconnectedCallback(){}
  method setupImage (line 1127) | setupImage(){
  method redraw (line 1148) | redraw() {
  method setValue (line 1151) | setValue(v,f){
  method pointerdown (line 1164) | pointerdown(ev){
  method constructor (line 1184) | constructor(){
  method connectedCallback (line 1187) | connectedCallback(){
  method disconnectedCallback (line 1242) | disconnectedCallback(){}
  method setupImage (line 1243) | setupImage(){
  method redraw (line 1268) | redraw(){
  method _setValue (line 1319) | _setValue(v){
  method setValue (line 1331) | setValue(v,f){
  method wheel (line 1335) | wheel(e){}
  method keydown (line 1336) | keydown(e){
  method keyup (line 1352) | keyup(e){
  method pointerdown (line 1366) | pointerdown(ev){
  method sendEventFromKey (line 1443) | sendEventFromKey(s,k){
  method sendevent (line 1449) | sendevent(){
  method setdispvalues (line 1470) | setdispvalues(state,note) {
  method setNote (line 1479) | setNote(state,note) {
  method constructor (line 1490) | constructor(){
  method connectedCallback (line 1493) | connectedCallback(){
  method disconnectedCallback (line 1572) | disconnectedCallback(){}
  method setupImage (line 1573) | setupImage(){
  method redraw (line 1612) | redraw() {
  method _setX (line 1631) | _setX(v){
  method _setY (line 1647) | _setY(v){
  method setX (line 1663) | setX(v,f){
  method setY (line 1667) | setY(v,f){
  method wheel (line 1671) | wheel(e) {
  method pointerdown (line 1683) | pointerdown(ev){
  class WebAudioControlsMidiManager (line 1779) | class WebAudioControlsMidiManager {
    method constructor (line 1780) | constructor(){
    method addWidget (line 1787) | addWidget(w){
    method updateWidgets (line 1790) | updateWidgets(){
    method initWebAudioControls (line 1793) | initWebAudioControls() {
    method enableInputs (line 1801) | enableInputs() {
    method midiConnectionStateChange (line 1809) | midiConnectionStateChange(e) {
    method onMIDIStarted (line 1814) | onMIDIStarted(midi) {
    method addMidiListener (line 1820) | addMidiListener(callback) {
    method getCurrentConfigAsJSON (line 1823) | getCurrentConfigAsJSON() {
    method handleMIDIMessage (line 1826) | handleMIDIMessage(event) {
    method contextMenuOpen (line 1839) | contextMenuOpen(e,knob){
    method contextMenuCloseByKey (line 1851) | contextMenuCloseByKey(e){
    method contextMenuClose (line 1855) | contextMenuClose(){
    method contextMenuLearn (line 1863) | contextMenuLearn(){
    method contextMenuClear (line 1869) | contextMenuClear(e){

FILE: src/assets/js/webcomponents-lite.js
  function ca (line 10) | function ca(){ca=function(){};q.Symbol||(q.Symbol=da)}
  function ea (line 11) | function ea(){ca();var a=q.Symbol.iterator;a||(a=q.Symbol.iterator=q.Sym...
  function fa (line 11) | function fa(a){var b=0;return ha(function(){return b<a.length?{done:!1,v...
  function ha (line 11) | function ha(a){ea();a={next:a};a[q.Symbol.iterator]=function(){return th...
  function ia (line 11) | function ia(a){ea();var b=a[Symbol.iterator];return b?b.call(a):fa(a)}
  function ja (line 12) | function ja(a){for(var b,c=[];!(b=a.next()).done;)c.push(b.value);return c}
  function a (line 16) | function a(){}
  function b (line 16) | function b(a,b){if(!a.childNodes.length)return[];switch(a.nodeType){case...
  function a (line 16) | function a(a,b){if(a instanceof DocumentFragment)for(var d;d=a.firstChil...
  function va (line 26) | function va(){return"undefined"!==typeof ma?function(){ma(wa)}:xa()}
  function ya (line 26) | function ya(){var a=0,b=new ta(wa),c=document.createTextNode("");b.obser...
  function za (line 27) | function za(){var a=new MessageChannel;a.port1.onmessage=wa;return funct...
  function xa (line 27) | function xa(){var a=setTimeout;return function(){return a(wa,1)}}
  function wa (line 27) | function wa(){for(var a=0;a<la;a+=2)(0,Aa[a])(Aa[a+1]),Aa[a]=void 0,Aa[a...
  function Ka (line 28) | function Ka(a,b){Aa[la]=a;Aa[la+1]=b;la+=2;2===la&&Ba()}
  function La (line 28) | function La(a,b){var c=this,d=new this.constructor(Ma);void 0===d[Na]&&O...
  function Ra (line 28) | function Ra(a){if(a&&"object"===typeof a&&a.constructor===this)return a;...
  function Ma (line 28) | function Ma(){}
  function Va (line 28) | function Va(a){try{return a.then}catch(b){return Ua.error=b,Ua}}
  function Wa (line 28) | function Wa(a,b,c,d){try{a.call(b,c,d)}catch(e){return e}}
  function Xa (line 28) | function Xa(a,b,c){Ka(function(a){var d=!1,f=Wa(c,b,function(c){d||(d=!0...
  function Ya (line 28) | function Ya(a,b){1===b.g?r(a,b.f):2===b.g?u(a,b.f):Qa(b,void 0,function(...
  function Za (line 29) | function Za(a,b,c){b.constructor===a.constructor&&c===La&&b.constructor....
  function Sa (line 29) | function Sa(a,b){if(a===b)u(a,new TypeError("You cannot resolve a promis...
  function $a (line 29) | function $a(a){a.na&&a.na(a.f);ab(a)}
  function r (line 29) | function r(a,b){void 0===a.g&&(a.f=b,a.g=1,0!==a.I.length&&Ka(ab,a))}
  function u (line 30) | function u(a,b){void 0===a.g&&(a.g=2,a.f=b,Ka($a,a))}
  function Qa (line 30) | function Qa(a,b,c,d){var e=a.I,f=e.length;a.na=null;e[f]=b;e[f+1]=c;e[f+...
  function ab (line 30) | function ab(a){var b=a.I,c=a.g;if(0!==b.length){for(var d,e,f=a.f,h=0;h<...
  function Ta (line 30) | function Ta(){this.error=null}
  function Pa (line 31) | function Pa(a,b,c,d){var e="function"===typeof c;if(e){try{var f=c(d)}ca...
  function cb (line 31) | function cb(a,b){try{b(function(b){Sa(a,b)},function(b){u(a,b)})}catch(c...
  function Oa (line 31) | function Oa(a){a[Na]=db++;a.g=void 0;a.f=void 0;a.I=[]}
  function gb (line 31) | function gb(a,b){this.Ea=a;this.A=new a(Ma);this.A[Na]||Oa(this.A);if(ka...
  function hb (line 32) | function hb(a,b,c){var d=a.Ea,e=d.resolve;e===Ra?(e=Va(b),e===La&&void 0...
  function ib (line 32) | function ib(a,b,c,d){var e=a.A;void 0===e.g&&(a.S--,2===b?u(e,d):a.f[c]=...
  function jb (line 32) | function jb(a,b,c){Qa(b,void 0,function(b){return ib(a,1,c,b)},function(...
  function kb (line 32) | function kb(a){return(new gb(this,a)).A}
  function lb (line 32) | function lb(a){var b=this;return ka(a)?new b(function(c,d){for(var e=a.l...
  function mb (line 32) | function mb(a){var b=new this(Ma);u(b,a);return b}
  function v (line 32) | function v(a){this[Na]=db++;this.f=this.g=void 0;this.I=[];if(Ma!==a){if...
  function b (line 41) | function b(a,b){if("function"===typeof window.CustomEvent)return new Cus...
  function c (line 41) | function c(a){if(C)return a.ownerDocument!==document?a.ownerDocument:nul...
  function d (line 41) | function d(a){var b=m(document,"link[rel=import]:not([import-dependency]...
  function e (line 42) | function e(a){function b(){"loading"!==document.readyState&&document.bod...
  function f (line 42) | function f(a){e(function(){return d(function(){return a&&a()})})}
  function h (line 42) | function h(a,b){if(a.__loaded)b&&b();else if("script"===a.localName&&!a....
  function g (line 43) | function g(a){return a.nodeType===Node.ELEMENT_NODE&&"link"===a.localNam...
  function k (line 43) | function k(){var a=this;this.a={};this.b=0;this.c=new MutationObserver(f...
  function l (line 43) | function l(a){n(m(a,"template"),function(a){n(m(a.content,'script:not([t...
  function m (line 44) | function m(a,b){return a.childNodes.length?a.querySelectorAll(b):eb}
  function n (line 44) | function n(a,b,c){var d=a?a.length:0,e=c?-1:1;for(c=c?d-1:0;c<d&&0<=c;c+...
  function b (line 51) | function b(e){if(e<d){var f=c[e],g=document.createElement("script");f.re...
  function vb (line 75) | function vb(a){return a.__shady&&void 0!==a.__shady.firstChild}
  function z (line 75) | function z(a){return"ShadyRoot"===a.ya}
  function wb (line 75) | function wb(a){a=a.getRootNode();if(z(a))return a}
  function zb (line 76) | function zb(a,b){if(a&&b)for(var c=Object.getOwnPropertyNames(b),d=0,e;d...
  function Ab (line 76) | function Ab(a,b){for(var c=[],d=1;d<arguments.length;++d)c[d-1]=argument...
  function Bb (line 76) | function Bb(a,b){for(var c in b)a[c]=b[c]}
  function Fb (line 77) | function Fb(a){Eb.push(a);Cb.textContent=Db++}
  function Hb (line 77) | function Hb(a,b){for(;b;){if(b==a)return!0;b=b.parentNode}return!1}
  function Kb (line 77) | function Kb(a){Jb||(Jb=!0,Fb(Lb));Ib.push(a)}
  function Lb (line 77) | function Lb(){Jb=!1;for(var a=!!Ib.length;Ib.length;)Ib.shift()();return a}
  function Mb (line 77) | function Mb(){this.a=!1;this.addedNodes=[];this.removedNodes=[];this.V=n...
  function Nb (line 77) | function Nb(a){a.a||(a.a=!0,Fb(function(){Ob(a)}))}
  function Ob (line 77) | function Ob(a){if(a.a){a.a=!1;var b=a.takeRecords();b.length&&a.V.forEac...
  function Pb (line 78) | function Pb(a,b){a.__shady=a.__shady||{};a.__shady.N||(a.__shady.N=new M...
  function Qb (line 78) | function Qb(a){var b=a&&a.C;b&&(b.V.delete(a.Ca),b.V.size||(a.Ga.__shady...
  function Rb (line 79) | function Rb(a,b){var c=b.getRootNode();return a.map(function(a){var b=c=...
  function hc (line 80) | function hc(a){switch(a){case "&":return"&amp;";case "<":return"&lt;";ca...
  function ic (line 80) | function ic(a){for(var b={},c=0;c<a.length;c++)b[a[c]]=!0;return b}
  function lc (line 81) | function lc(a,b){"template"===a.localName&&(a=a.content);for(var c="",d=...
  function mc (line 82) | function mc(a){var b=[];D.currentNode=a;for(a=D.firstChild();a;)b.push(a...
  function F (line 92) | function F(a,b,c){for(var d in b){var e=Object.getOwnPropertyDescriptor(...
  function G (line 92) | function G(a){F(a,qc);F(a,rc);F(a,tc)}
  function wc (line 92) | function wc(a,b,c){uc(a);c=c||null;a.__shady=a.__shady||{};b.__shady=b._...
  function xc (line 93) | function xc(a){if(!a.__shady||void 0===a.__shady.firstChild){a.__shady=a...
  function yc (line 93) | function yc(a,b,c){if(b===a)throw Error("Failed to execute 'appendChild'...
  function zc (line 96) | function zc(a,b){if(b.parentNode!==a)throw Error("The node to be removed...
  function Ec (line 98) | function Ec(a){if(a.__shady&&void 0!==a.__shady.ka)for(var b=a.childNode...
  function Cc (line 98) | function Cc(a){var b=a;a&&"slot"===a.localName&&(b=(b=a.__shady&&a.__sha...
  function Bc (line 98) | function Bc(a){return(a=a&&a.__shady&&a.__shady.root)&&Gc(a)}
  function Hc (line 99) | function Hc(a,b){if("slot"===b)a=a.parentNode,Bc(a)&&Ac(a.__shady.root);...
  function Dc (line 99) | function Dc(a,b,c){if(a=a.__shady&&a.__shady.N)b&&a.addedNodes.push(b),c...
  function Kc (line 100) | function Kc(a){if(a&&a.nodeType){a.__shady=a.__shady||{};var b=a.__shady...
  function Lc (line 100) | function Lc(a,b,c){var d=[];Mc(a.childNodes,b,c,d);return d}
  function Mc (line 100) | function Mc(a,b,c,d){for(var e=0,f=a.length,h;e<f&&(h=a[e]);e++){var g;i...
  function Oc (line 101) | function Oc(a,b,c){Nc||(Nc=window.ShadyCSS&&window.ShadyCSS.ScopingShim)...
  function Pc (line 101) | function Pc(a,b){if(a.ownerDocument!==document)return A.importNode.call(...
  function Sc (line 102) | function Sc(a,b){var c=[],d=a;for(a=a===window?window:a.getRootNode();d;...
  function Tc (line 103) | function Tc(a,b){if(!z)return a;a=Sc(a,!0);for(var c=0,d,e,f,h;c<b.lengt...
  method composed (line 104) | get composed(){!1!==this.isTrusted&&void 0===this.Z&&(this.Z=Rc[this.typ...
  method target (line 104) | get target(){return Tc(this.currentTarget,this.composedPath())}
  method relatedTarget (line 104) | get relatedTarget(){if(!this.$)return null;this.c||(this.c=Sc(this.$,!0)...
  function Vc (line 105) | function Vc(a){function b(b,d){b=new a(b,d);b.Z=d&&!!d.composed;return b...
  function Xc (line 105) | function Xc(a){return a.__target!==a.target||a.$!==a.relatedTarget}
  function Yc (line 105) | function Yc(a,b,c){if(c=b.__handlers&&b.__handlers[a.type]&&b.__handlers...
  function Zc (line 106) | function Zc(a){var b=a.composedPath();Object.defineProperty(a,"currentTa...
  function $c (line 107) | function $c(a,b,c,d,e,f){for(var h=0;h<a.length;h++){var g=a[h],k=g.type...
  function ad (line 108) | function ad(a,b,c){if(b){var d=typeof b;if("function"===d||"object"===d)...
  function cd (line 111) | function cd(a,b,c){if(b){if(c&&"object"===typeof c){var d=!!c.capture;va...
  function dd (line 112) | function dd(){for(var a in Wc)window.addEventListener(a,function(a){a.__...
  function bd (line 112) | function bd(a){a.__target=a.target;a.$=a.relatedTarget;if(y.M){var b=Obj...
  function hd (line 112) | function hd(a,b){return{index:a,O:[],U:b}}
  function id (line 113) | function id(a,b,c,d){var e=0,f=0,h=0,g=0,k=Math.min(b-e,d-f);if(0==e&&0=...
  function jd (line 115) | function jd(a,b){return a===b}
  function H (line 115) | function H(a,b,c){if(a!==kd)throw new TypeError("Illegal constructor");a...
  function Ac (line 115) | function Ac(a){a.T||(a.T=!0,Kb(function(){return ld(a)}))}
  function ld (line 116) | function ld(a){for(var b;a;){a.T&&(b=a);a:{var c=a;a=c.host.getRootNode(...
  function md (line 120) | function md(a,b,c){b.__shady=b.__shady||{};var d=b.__shady.ga;b.__shady....
  function nd (line 120) | function nd(a,b,c){for(var d=0,e;d<c.length&&(e=c[d]);d++)if("slot"==e.l...
  function od (line 121) | function od(a,b){A.dispatchEvent.call(b,new Event("slotchange"));b.__sha...
  function Fc (line 121) | function Fc(a){if(a.H.length){for(var b=a.H,c,d=0;d<b.length;d++){var e=...
  function Ic (line 121) | function Ic(a){var b=a.name||a.getAttribute("name")||"__catchall";return...
  function Jc (line 122) | function Jc(a){return a.sort(function(a,c){a=pd(a);for(var b=pd(c),e=0;e...
  function pd (line 122) | function pd(a){var b=[];do b.unshift(a);while(a=a.parentNode);return b}
  function Gc (line 122) | function Gc(a){Fc(a);return!!a.o.length}
  function rd (line 123) | function rd(a){var b=a.getRootNode();z(b)&&ld(b);return a.__shady&&a.__s...
  method isConnected (line 125) | get isConnected(){var a=this.ownerDocument;if(Gb&&A.contains.call(a,this...
  method assignedSlot (line 125) | get assignedSlot(){return rd(this)}
  method slot (line 127) | get slot(){return this.getAttribute("slot")}
  method slot (line 127) | set slot(a){Oc(this,"slot",a)}
  method assignedSlot (line 127) | get assignedSlot(){return rd(this)}
  function I (line 128) | function I(a,b){for(var c=Object.getOwnPropertyNames(b),d=0;d<c.length;d...
  function Dd (line 129) | function Dd(a){var b=Cd.has(a);a=/^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/.test...
  function K (line 129) | function K(a){var b=a.isConnected;if(void 0!==b)return b;for(;a&&!(a.__C...
  function Ed (line 130) | function Ed(a,b){for(;b&&b!==a&&!b.nextSibling;)b=b.parentNode;return b&...
  function L (line 131) | function L(a,b,c){c=void 0===c?new Set:c;for(var d=a;d;){if(d.nodeType==...
  function M (line 131) | function M(a,b,c){a[b]=c}
  function Fd (line 131) | function Fd(){this.a=new Map;this.s=new Map;this.h=[];this.c=!1}
  function Gd (line 131) | function Gd(a,b,c){a.a.set(b,c);a.s.set(c.constructor,c)}
  function Hd (line 131) | function Hd(a,b){a.c=!0;a.h.push(b)}
  function Id (line 131) | function Id(a,b){a.c&&L(b,function(b){return a.b(b)})}
  function N (line 131) | function N(a,b){var c=[];L(b,function(a){return c.push(a)});for(b=0;b<c....
  function O (line 132) | function O(a,b){var c=[];L(b,function(a){return c.push(a)});for(b=0;b<c....
  function P (line 133) | function P(a,b,c){c=void 0===c?{}:c;var d=c.$a||new Set,e=c.va||function...
  function Jd (line 135) | function Jd(a,b){if(void 0===b.__CE_state){var c=b.ownerDocument;if(c.de...
  function Kd (line 137) | function Kd(a){var b=document;this.j=a;this.a=b;this.C=void 0;P(this.j,t...
  function Ld (line 137) | function Ld(){var a=this;this.b=this.a=void 0;this.c=new Promise(functio...
  function Q (line 137) | function Q(a){this.da=!1;this.j=a;this.ha=new Map;this.ea=function(a){re...
  function Md (line 140) | function Md(a){if(!1!==a.R){a.R=!1;for(var b=a.fa,c=[],d=new Map,e=0;e<b...
  function se (line 144) | function se(){var a=te;window.HTMLElement=function(){function b(){var b=...
  function ue (line 145) | function ue(a,b,c){function d(b){return function(c){for(var d=[],e=0;e<a...
  function ve (line 145) | function ve(){var a=te;M(Document.prototype,"createElement",function(b){...
  function we (line 146) | function we(){var a=te;function b(b,d){Object.defineProperty(b,"textCont...
  function xe (line 149) | function xe(a){var b=Element.prototype;function c(b){return function(c){...
  function ye (line 150) | function ye(){var a=te;function b(b,c){Object.defineProperty(b,"innerHTM...
  function Ae (line 154) | function Ae(){this.end=this.start=0;this.rules=this.parent=this.previous...
  function Be (line 155) | function Be(a){a=a.replace(Ce,"").replace(De,"");var b=Ee,c=a,d=new Ae;d...
  function Ee (line 156) | function Ee(a,b){var c=b.substring(a.start,a.end-1);a.parsedCssText=a.cs...
  function Fe (line 157) | function Fe(a){return a.replace(/\\([0-9a-f]{1,6})\s/gi,function(a,c){a=...
  function Me (line 158) | function Me(a,b,c){c=void 0===c?"":c;var d="";if(a.cssText||a.rules){var...
  function Se (line 159) | function Se(a){Re=a&&a.shimcssproperties?!1:R||!(navigator.userAgent.mat...
  function $e (line 159) | function $e(a,b){if(!a)return"";"string"===typeof a&&(a=Be(a));b&&af(a,b...
  function bf (line 159) | function bf(a){!a.__cssRules&&a.textContent&&(a.__cssRules=Be(a.textCont...
  function cf (line 159) | function cf(a){return!!a.parent&&a.parent.type===Je}
  function af (line 159) | function af(a,b,c,d){if(a){var e=!1,f=a.type;if(d&&f===He){var h=a.selec...
  function df (line 160) | function df(a,b,c,d){var e=document.createElement("style");b&&e.setAttri...
  function ef (line 160) | function ef(a,b,c){b=b||document.head;b.insertBefore(a,c&&c.nextSibling|...
  function ff (line 161) | function ff(a,b){var c=a.indexOf("var(");if(-1===c)return b(a,"","","");...
  function gf (line 161) | function gf(a,b){R?a.setAttribute("class",b):window.ShadyDOM.nativeMetho...
  function V (line 162) | function V(a){var b=a.localName,c="";b?-1<b.indexOf("-")||(c=b,b=a.getAt...
  function hf (line 162) | function hf(){}
  function jf (line 162) | function jf(a,b,c){var d=W;a.__styleScoped?a.__styleScoped=null:kf(d,a,b...
  function kf (line 162) | function kf(a,b,c,d){b.nodeType===Node.ELEMENT_NODE&&lf(b,c,d);if(b="tem...
  function lf (line 163) | function lf(a,b,c){if(b)if(a.classList)c?(a.classList.remove("style-scop...
  function nf (line 163) | function nf(a,b,c){var d=W,e=a.__cssBuild;R||"shady"===e?b=$e(b,c):(a=V(...
  function of (line 164) | function of(a,b,c,d,e){var f=pf(c,d);c=c?qf+c:"";return $e(b,function(b)...
  function pf (line 164) | function pf(a,b){return b?"[is="+a+"]":a}
  function rf (line 164) | function rf(a,b,c,d,e){var f=b.selector.split(sf);if(!cf(b)){b=0;for(var...
  function tf (line 164) | function tf(a){return a.replace(uf,function(a,c,d){-1<d.indexOf("+")?d=d...
  function yf (line 166) | function yf(a,b,c,d){var e=a.indexOf(zf);0<=a.indexOf(wf)?a=Af(a,d):0!==...
  function Bf (line 166) | function Bf(a,b){a=a.split(Ef);a[0]+=b;return a.join(Ef)}
  function Af (line 167) | function Af(a,b){var c=a.match(Ff);return(c=c&&c[2].trim()||"")?c[0].mat...
  function If (line 167) | function If(a){a.selector===Jf&&(a.selector="html")}
  function Lf (line 168) | function Lf(a,b,c,d){this.w=a||null;this.b=b||null;this.ja=c||[];this.G=...
  function X (line 168) | function X(a){return a?a.__styleInfo:null}
  function Mf (line 168) | function Mf(a,b){return a.__styleInfo=b}
  function Qf (line 168) | function Qf(){}
  function Rf (line 168) | function Rf(a){var b={},c=[],d=0;af(a,function(a){Sf(a);a.index=d++;a=a....
  function Sf (line 169) | function Sf(a){if(!a.i){var b={},c={};Tf(a,c)&&(b.v=c,a.rules=null);b.cs...
  function Tf (line 169) | function Tf(a,b){var c=a.i;if(c){if(c.v)return Object.assign(b,c.v),!0}e...
  function Uf (line 170) | function Uf(a,b,c){b&&(b=0<=b.indexOf(";")?Vf(a,b,c):ff(b,function(b,e,f...
  function Vf (line 171) | function Vf(a,b,c){b=b.split(";");for(var d=0,e,f;d<b.length;d++)if(e=b[...
  function Wf (line 172) | function Wf(a,b){var c={},d=[];af(a,function(a){a.i||Sf(a);var e=a.m||a....
  function Xf (line 173) | function Xf(a,b,c,d){b.i||Sf(b);if(b.i.v){var e=V(a);a=e.is;e=e.P;e=a?pf...
  function Yf (line 174) | function Yf(a,b){var c={},d={},e=b&&b.__cssBuild;af(b,function(b){Xf(a,b...
  function Zf (line 175) | function Zf(a,b,c,d){var e=V(b),f=pf(e.is,e.P),h=new RegExp("(?:^|[^.#[:...
  function $f (line 176) | function $f(a,b){a=a.b;var c={};if(!R&&a)for(var d=0,e=a[d];d<a.length;e...
  function ag (line 176) | function ag(a){return function(b){return b.replace(a.h,a.a)}}
  function bg (line 177) | function bg(a,b){var c=cg,d=bf(a);a.textContent=$e(d,function(a){var d=a...
  function gg (line 177) | function gg(){this.cache={}}
  function hg (line 177) | function hg(){}
  function ig (line 178) | function ig(a){for(var b=0;b<a.length;b++){var c=a[b];if(c.target!==docu...
  function pg (line 181) | function pg(a){if(a=ng[a])a._applyShimCurrentVersion=a._applyShimCurrent...
  function qg (line 181) | function qg(a){return a._applyShimCurrentVersion===a._applyShimNextVersion}
  function rg (line 181) | function rg(a){a._applyShimValidatingVersion=a._applyShimNextVersion;a.q...
  function vg (line 181) | function vg(a){requestAnimationFrame(function(){tg?tg(a):(sg||(sg=new Pr...
  function Y (line 181) | function Y(){var a=this;this.L={};this.c=document.documentElement;var b=...
  function yg (line 184) | function yg(a){!a.b&&window.ShadyCSS&&window.ShadyCSS.CustomStyleInterfa...
  function xg (line 184) | function xg(a){!a.a&&window.ShadyCSS&&window.ShadyCSS.ApplyShim&&(a.a=wi...
  function Ag (line 188) | function Ag(a,b){return(b=b.getRootNode().host)?X(b)?b:Ag(a,b):a.c}
  function zg (line 189) | function zg(a,b,c){a=Ag(a,b);var d=X(a);a=Object.create(d.B||null);var e...

FILE: src/common/channels/channels.constants.js
  constant CHANNELS_CONSTANTS (line 1) | const CHANNELS_CONSTANTS = {

FILE: src/common/master/master.constants.js
  constant MASTER_CONSTANTS (line 1) | const MASTER_CONSTANTS = {

FILE: src/common/notes/notes.constants.js
  constant NOTES_CONSTANTS (line 1) | const NOTES_CONSTANTS = {

FILE: src/common/playbackSession/playbackSession.constants.js
  constant PLAYBACK_SESSION_CONSTANTS (line 1) | const PLAYBACK_SESSION_CONSTANTS = {

FILE: src/common/presets/presets.constants.js
  constant PRESETS_CONSTANTS (line 1) | const PRESETS_CONSTANTS = {

FILE: src/common/tempo/tempo.constants.js
  constant TEMPO_CONSTANTS (line 1) | const TEMPO_CONSTANTS = {

FILE: src/common/userSamples/userSamples.constants.js
  constant USER_SAMPLES_CONSTANTS (line 1) | const USER_SAMPLES_CONSTANTS = {

FILE: src/common/window/window.constants.js
  constant WINDOW_CONSTANTS (line 1) | const WINDOW_CONSTANTS = {
  constant FLASH_MESSAGES (line 9) | const FLASH_MESSAGES = {

FILE: src/components/ChannelList/ChannelList.component.jsx
  class ChannelListComponent (line 12) | class ChannelListComponent extends React.Component {
    method componentDidMount (line 13) | componentDidMount() {
    method render (line 29) | render() {

FILE: src/components/FlashMessage/FlashMessage.component.jsx
  class FlashMessageComponent (line 27) | class FlashMessageComponent extends React.Component {
    method componentDidMount (line 28) | componentDidMount() {
    method componentDidUpdate (line 32) | componentDidUpdate() {
    method animateBox (line 36) | animateBox() {
    method render (line 61) | render() {

FILE: src/components/Knob.component.jsx
  class Knob (line 7) | class Knob extends React.Component {
    method componentDidMount (line 8) | componentDidMount() {
    method componentDidUpdate (line 13) | componentDidUpdate() {
    method render (line 18) | render() {

FILE: src/components/Marker/Marker.component.jsx
  class MarkerComponent (line 11) | class MarkerComponent extends React.PureComponent {
    method componentDidMount (line 12) | componentDidMount() {
    method updateMarker (line 17) | updateMarker() {
    method render (line 29) | render() {

FILE: src/components/PlayButton/PlayButton.component.jsx
  function PlayButtonComponent (line 15) | function PlayButtonComponent({

FILE: src/components/SavePresetModal/SavePresetModal.component.jsx
  class SavePresetModalComponent (line 13) | class SavePresetModalComponent extends React.Component {
    method componentDidUpdate (line 14) | componentDidUpdate() {
    method render (line 21) | render() {

FILE: src/components/Toggles/Toggles.component.jsx
  class TogglesComponent (line 12) | class TogglesComponent extends React.PureComponent {
    method render (line 13) | render() {

FILE: src/components/VolumeMeter.component.jsx
  constant DECAY (line 5) | const DECAY = 0.95;
  function updateVolumeMeter (line 12) | function updateVolumeMeter() {

FILE: src/components/timedCallback.hoc.jsx
  method constructor (line 4) | constructor() {
  method componentWillUnmount (line 9) | componentWillUnmount() {
  method render (line 13) | render() {

FILE: src/presets/empty.js
  constant EMPTY_NOTE_ROW (line 3) | const EMPTY_NOTE_ROW = [[], [], [], [], [], [], [], []];

FILE: src/services/audioAnalyzer.js
  function getVolume (line 5) | function getVolume() {

FILE: src/services/audioEngine.config.js
  constant LOOKAHEAD (line 1) | const LOOKAHEAD = 0.2;
  constant INTERVAL (line 2) | const INTERVAL = 50;

FILE: src/services/database.js
  constant DB_NAME (line 1) | const DB_NAME = 'wds-1';
  constant DB_VERSION (line 2) | const DB_VERSION = 1;
  constant USER_SAMPLES (line 3) | const USER_SAMPLES = 'USER_SAMPLES';
Condensed preview — 199 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (419K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 2286,
    "preview": "# Javascript Node CircleCI 2.0 configuration file\n#\n# Check https://circleci.com/docs/2.0/language-javascript/ for more "
  },
  {
    "path": ".eslintignore",
    "chars": 18,
    "preview": "src/assets/**/*.js"
  },
  {
    "path": ".eslintrc",
    "chars": 405,
    "preview": "{\n  \"extends\": [\"eslint:recommended\", \"plugin:react/recommended\"],\n  \"env\": {\n    \"browser\": true,\n    \"jest\": true,\n   "
  },
  {
    "path": ".gitignore",
    "chars": 37,
    "preview": "node_modules\n.vscode\n.DS_Store\ndist/*"
  },
  {
    "path": ".prettierrc",
    "chars": 51,
    "preview": "{\n  \"trailingComma\": \"all\",\n  \"singleQuote\": true\n}"
  },
  {
    "path": "CNAME",
    "chars": 9,
    "preview": "wds-1.com"
  },
  {
    "path": "README.md",
    "chars": 1261,
    "preview": "# Web Drum Sequencer\n\nA browser-based drum machine and sequencer built with the Web Audio API, React, and Redux.\n\n## Dem"
  },
  {
    "path": "__mocks__/fileMock.js",
    "chars": 35,
    "preview": "module.exports = 'test-file-stub';\n"
  },
  {
    "path": "__mocks__/styleMock.js",
    "chars": 21,
    "preview": "module.exports = {};\n"
  },
  {
    "path": "babel.config.js",
    "chars": 180,
    "preview": "const presets = [\n  [\n    \"@babel/env\",\n    {\n      targets: \"> 0.25%, not dead\",\n      useBuiltIns: \"usage\",\n    },\n  ]"
  },
  {
    "path": "index.html",
    "chars": 4307,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <!-- Global site tag (gtag.js) - Google Analytics -->\n    <script\n      as"
  },
  {
    "path": "manifest.json",
    "chars": 1514,
    "preview": "{\n  \"icons\": [\n    {\n      \"src\": \"/assets/icons/icon-48x48.png\",\n      \"sizes\": \"48x48\",\n      \"type\": \"image/png\",\n   "
  },
  {
    "path": "package.json",
    "chars": 2012,
    "preview": "{\n  \"name\": \"web-drum-sequencer\",\n  \"version\": \"0.2.4\",\n  \"description\": \"A drum machine and sequencer built with the We"
  },
  {
    "path": "public/assets/icons/browserconfig.xml",
    "chars": 281,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig><msapplication><tile><square70x70logo src=\"/ms-icon-70x70.png\"/><s"
  },
  {
    "path": "public/sw.js",
    "chars": 1422,
    "preview": "/* eslint no-restricted-globals: 1 */\n\nconst addToCache = (event, fetchResponse) => {\n  // Check if we received a valid "
  },
  {
    "path": "src/__mocks__/samples.config.js",
    "chars": 162,
    "preview": "export default [\n  {\n    name: 'Fake sample A',\n    url: '/fake/sample/a/url.wav',\n  },\n  {\n    name: 'Fake sample B',\n "
  },
  {
    "path": "src/assets/js/webaudio-controls.js",
    "chars": 67972,
    "preview": "/* *\n *\n *  WebAudio-Controls is based on\n *    webaudio-knob by Eiji Kitamura http://google.com/+agektmr\n *    webaudio"
  },
  {
    "path": "src/assets/js/webcomponents-lite.js",
    "chars": 85401,
    "preview": "(function(){/*\n\n Copyright (c) 2016 The Polymer Project Authors. All rights reserved.\n This code may only be used under "
  },
  {
    "path": "src/common/channels/channels.actions.js",
    "chars": 3751,
    "preview": "import { loadSample } from '../../services/sampleStore';\nimport { CHANNELS_CONSTANTS } from './channels.constants';\nimpo"
  },
  {
    "path": "src/common/channels/channels.constants.js",
    "chars": 563,
    "preview": "export const CHANNELS_CONSTANTS = {\n  ADD_CHANNEL: 'ADD_CHANNEL',\n  REMOVE_CHANNEL: 'REMOVE_CHANNEL',\n  SET_CHANNEL_SAMP"
  },
  {
    "path": "src/common/channels/channels.reducer.js",
    "chars": 3167,
    "preview": "import * as R from 'ramda';\nimport { CHANNELS_CONSTANTS } from './channels.constants';\nimport presets from '../../preset"
  },
  {
    "path": "src/common/channels/channels.reducer.test.js",
    "chars": 4583,
    "preview": "import { channelsInitialState, channelsReducer } from './channels.reducer';\nimport {\n  setChannelSample,\n  setChannelGai"
  },
  {
    "path": "src/common/channels/channels.selectors.js",
    "chars": 83,
    "preview": "import * as R from 'ramda';\n\nexport const channelsSelector = R.path(['channels']);\n"
  },
  {
    "path": "src/common/channels/index.js",
    "chars": 110,
    "preview": "export * from './channels.reducer';\nexport * from './channels.selectors';\nexport * from './channels.actions';\n"
  },
  {
    "path": "src/common/index.js",
    "chars": 223,
    "preview": "export * from './playbackSession';\nexport * from './channels';\nexport * from './tempo';\nexport * from './master';\nexport"
  },
  {
    "path": "src/common/master/index.js",
    "chars": 104,
    "preview": "export * from './master.reducer';\nexport * from './master.selectors';\nexport * from './master.actions';\n"
  },
  {
    "path": "src/common/master/master.actions.js",
    "chars": 296,
    "preview": "import { MASTER_CONSTANTS } from './master.constants';\n\nexport const setPattern = (patternIndex) => ({\n  type: MASTER_CO"
  },
  {
    "path": "src/common/master/master.constants.js",
    "chars": 115,
    "preview": "export const MASTER_CONSTANTS = {\n  SET_PATTERN: 'SET_PATTERN',\n  SET_SELECTED_CHANNEL: 'SET_SELECTED_CHANNEL',\n};\n"
  },
  {
    "path": "src/common/master/master.reducer.js",
    "chars": 574,
    "preview": "import { MASTER_CONSTANTS } from './master.constants';\nimport presets from '../../presets';\n\nexport const masterInitialS"
  },
  {
    "path": "src/common/master/master.reducer.test.js",
    "chars": 312,
    "preview": "import { masterInitialState, masterReducer } from './master.reducer';\nimport {\n  setPattern,\n} from './master.actions';\n"
  },
  {
    "path": "src/common/master/master.selectors.js",
    "chars": 170,
    "preview": "import * as R from 'ramda';\n\nexport const patternSelector = R.path(['master', 'pattern']);\n\nexport const selectedChannel"
  },
  {
    "path": "src/common/notes/index.js",
    "chars": 101,
    "preview": "export * from './notes.reducer';\nexport * from './notes.selectors';\nexport * from './notes.actions';\n"
  },
  {
    "path": "src/common/notes/notes.actions.js",
    "chars": 552,
    "preview": "import { NOTES_CONSTANTS } from './notes.constants';\n\nexport const initializeChannelNotes = (channelID) => ({\n  type: NO"
  },
  {
    "path": "src/common/notes/notes.constants.js",
    "chars": 184,
    "preview": "export const NOTES_CONSTANTS = {\n  INITIALIZE_CHANNEL: 'INITIALIZE_CHANNEL_NOTES',\n  REMOVE_CHANNEL: 'REMOVE_CHANNEL_NOT"
  },
  {
    "path": "src/common/notes/notes.reducer.js",
    "chars": 1535,
    "preview": "import { uuid } from '../../services/uuid';\nimport presets from '../../presets';\nimport { EMPTY_NOTE_ROW } from '../../p"
  },
  {
    "path": "src/common/notes/notes.reducer.test.js",
    "chars": 2080,
    "preview": "import { notesReducer } from './notes.reducer';\nimport {\n  toggleNote,\n  initializeChannelNotes,\n  removeChannelNotes,\n "
  },
  {
    "path": "src/common/notes/notes.selectors.js",
    "chars": 77,
    "preview": "import * as R from 'ramda';\n\nexport const notesSelector = R.path(['notes']);\n"
  },
  {
    "path": "src/common/playbackSession/index.js",
    "chars": 131,
    "preview": "export * from './playbackSession.actions';\nexport * from './playbackSession.reducer';\nexport * from './playbackSession.s"
  },
  {
    "path": "src/common/playbackSession/playbackSession.actions.js",
    "chars": 618,
    "preview": "import { PLAYBACK_SESSION_CONSTANTS } from './playbackSession.constants';\nimport { getAudioContext } from '../../service"
  },
  {
    "path": "src/common/playbackSession/playbackSession.constants.js",
    "chars": 153,
    "preview": "export const PLAYBACK_SESSION_CONSTANTS = {\n  START_PLAYBACK: 'START_PLAYBACK',\n  STOP_PLAYBACK: 'STOP_PLAYBACK',\n  SET_"
  },
  {
    "path": "src/common/playbackSession/playbackSession.reducer.js",
    "chars": 921,
    "preview": "import { PLAYBACK_SESSION_CONSTANTS } from './playbackSession.constants';\nimport { getAudioContext } from '../../service"
  },
  {
    "path": "src/common/playbackSession/playbackSession.reducer.test.js",
    "chars": 1363,
    "preview": "import {\n  playbackSessionInitialState,\n  playbackSessionReducer,\n} from './playbackSession.reducer';\nimport {\n  startPl"
  },
  {
    "path": "src/common/playbackSession/playbackSession.selectors.js",
    "chars": 175,
    "preview": "import * as R from 'ramda';\n\nexport const playingSelector = R.path(['playbackSession', 'playing']);\nexport const startTi"
  },
  {
    "path": "src/common/presets/index.js",
    "chars": 107,
    "preview": "export * from './presets.actions';\nexport * from './presets.reducer';\nexport * from './presets.selectors';\n"
  },
  {
    "path": "src/common/presets/presets.actions.js",
    "chars": 2101,
    "preview": "import { setBPM, setSwing } from '../tempo';\nimport { loadChannels } from '../channels';\nimport { setPattern, setSelecte"
  },
  {
    "path": "src/common/presets/presets.constants.js",
    "chars": 166,
    "preview": "export const PRESETS_CONSTANTS = {\n  SAVE_PRESET: 'SAVE_PRESET',\n  SAVE_PRESET_AS: 'SAVE_PRESET_AS',\n  DELETE_PRESET: 'D"
  },
  {
    "path": "src/common/presets/presets.reducer.js",
    "chars": 1177,
    "preview": "import { PRESETS_CONSTANTS } from './presets.constants';\nimport defaultPresets from '../../presets';\n\nexport const prese"
  },
  {
    "path": "src/common/presets/presets.reducer.test.js",
    "chars": 1553,
    "preview": "import { presetsInitialState, presetsReducer } from './presets.reducer';\nimport {\n  setPreset,\n  savePreset,\n  savePrese"
  },
  {
    "path": "src/common/presets/presets.selectors.js",
    "chars": 639,
    "preview": "import * as R from 'ramda';\nimport { createSelector } from 'reselect';\nimport { channelsSelector } from '../channels';\ni"
  },
  {
    "path": "src/common/tempo/index.js",
    "chars": 101,
    "preview": "export * from './tempo.actions';\nexport * from './tempo.reducer';\nexport * from './tempo.selectors';\n"
  },
  {
    "path": "src/common/tempo/tempo.actions.js",
    "chars": 233,
    "preview": "import { TEMPO_CONSTANTS } from './tempo.constants';\n\nexport const setBPM = (val) => ({\n  type: TEMPO_CONSTANTS.SET_BPM,"
  },
  {
    "path": "src/common/tempo/tempo.constants.js",
    "chars": 84,
    "preview": "export const TEMPO_CONSTANTS = {\n  SET_BPM: 'SET_BPM',\n  SET_SWING: 'SET_SWING',\n};\n"
  },
  {
    "path": "src/common/tempo/tempo.reducer.js",
    "chars": 528,
    "preview": "import { TEMPO_CONSTANTS } from './tempo.constants';\nimport presets from '../../presets';\n\nexport const tempoInitialStat"
  },
  {
    "path": "src/common/tempo/tempo.reducer.test.js",
    "chars": 497,
    "preview": "import {\n  tempoInitialState,\n  tempoReducer,\n} from './tempo.reducer';\nimport { setBPM, setSwing } from './tempo.action"
  },
  {
    "path": "src/common/tempo/tempo.selectors.js",
    "chars": 139,
    "preview": "import * as R from 'ramda';\n\nexport const bpmSelector = R.path(['tempo', 'bpm']);\nexport const swingSelector = R.path(['"
  },
  {
    "path": "src/common/userSamples/index.js",
    "chars": 119,
    "preview": "export * from './userSamples.actions';\nexport * from './userSamples.reducer';\nexport * from './userSamples.selectors';\n"
  },
  {
    "path": "src/common/userSamples/userSamples.actions.js",
    "chars": 918,
    "preview": "import { saveToSampleStore } from '../../services/sampleStore';\nimport { USER_SAMPLES_CONSTANTS } from './userSamples.co"
  },
  {
    "path": "src/common/userSamples/userSamples.constants.js",
    "chars": 169,
    "preview": "export const USER_SAMPLES_CONSTANTS = {\n  ADD_USER_SAMPLE: 'ADD_USER_SAMPLE',\n  REMOVE_USER_SAMPLE: 'REMOVE_USER_SAMPLE'"
  },
  {
    "path": "src/common/userSamples/userSamples.reducer.js",
    "chars": 591,
    "preview": "import { USER_SAMPLES_CONSTANTS } from './userSamples.constants';\n\nexport const userSamplesInitialState = [];\n\nexport co"
  },
  {
    "path": "src/common/userSamples/userSamples.selectors.js",
    "chars": 89,
    "preview": "import * as R from 'ramda';\n\nexport const userSamplesSelector = R.path(['userSamples']);\n"
  },
  {
    "path": "src/common/window/index.js",
    "chars": 140,
    "preview": "export * from './window.actions';\nexport * from './window.reducer';\nexport * from './window.selectors';\nexport * from '."
  },
  {
    "path": "src/common/window/window.actions.js",
    "chars": 619,
    "preview": "import { WINDOW_CONSTANTS } from './window.constants';\n\nexport const setPresetPrompt = (isOpen) => ({\n  type: WINDOW_CON"
  },
  {
    "path": "src/common/window/window.constants.js",
    "chars": 447,
    "preview": "export const WINDOW_CONSTANTS = {\n  PRESET_PROMPT_OPEN: 'PRESET_PROMPT_OPEN',\n  SET_PRESET_NAME_FIELD: 'SET_PRESET_NAME_"
  },
  {
    "path": "src/common/window/window.reducer.js",
    "chars": 874,
    "preview": "import { WINDOW_CONSTANTS } from './window.constants';\n\nexport const windowInitialState = {\n  presetPromptOpen: false,\n "
  },
  {
    "path": "src/common/window/window.reducer.test.js",
    "chars": 1273,
    "preview": "import { windowInitialState, windowReducer } from './window.reducer';\nimport {\n  setPresetPrompt,\n  showFlashMessage,\n  "
  },
  {
    "path": "src/common/window/window.selectors.js",
    "chars": 341,
    "preview": "import * as R from 'ramda';\n\nexport const presetPromptOpenSelector = R.path(['window', 'presetPromptOpen']);\nexport cons"
  },
  {
    "path": "src/components/AddChannelButton/AddChannelButton.component.jsx",
    "chars": 505,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { HoverButton } from '../design-system';\n\nexport c"
  },
  {
    "path": "src/components/AddChannelButton/AddChannelButton.container.js",
    "chars": 349,
    "preview": "import { connect } from 'react-redux';\nimport { compose } from 'recompose';\nimport { AddChannelButtonComponent } from '."
  },
  {
    "path": "src/components/AddChannelButton/index.js",
    "chars": 46,
    "preview": "export * from './AddChannelButton.container';\n"
  },
  {
    "path": "src/components/App.jsx",
    "chars": 1264,
    "preview": "import React from 'react';\nimport { ThemeProvider } from 'styled-components';\nimport theme from '../styles/theme';\nimpor"
  },
  {
    "path": "src/components/BPMInput/BPMInput.component.jsx",
    "chars": 2631,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport theme from '../../styles/theme';\nimport {\n  Box,\n "
  },
  {
    "path": "src/components/BPMInput/BPMInput.container.js",
    "chars": 380,
    "preview": "import { connect } from 'react-redux';\nimport { compose } from 'recompose';\nimport { BPMInputComponent } from './BPMInpu"
  },
  {
    "path": "src/components/BPMInput/BPMInput.selectors.js",
    "chars": 182,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport { bpmSelector } from '../../common';\n\nexport const bpmInputS"
  },
  {
    "path": "src/components/BPMInput/index.js",
    "chars": 38,
    "preview": "export * from './BPMInput.container';\n"
  },
  {
    "path": "src/components/Branding.jsx",
    "chars": 581,
    "preview": "import React from 'react';\nimport styled from 'styled-components';\nimport theme from '../styles/theme';\nimport { Logo } "
  },
  {
    "path": "src/components/Channel/Channel.component.jsx",
    "chars": 2744,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport * as R from 'ramda';\nimport { Toggles } from '../T"
  },
  {
    "path": "src/components/Channel/Channel.container.js",
    "chars": 1122,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { ChannelComponent } fr"
  },
  {
    "path": "src/components/Channel/Channel.selectors.js",
    "chars": 360,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport {\n  channelsSelector,\n  notesSelector,\n  patternSelector,\n  "
  },
  {
    "path": "src/components/Channel/HitButton.component.jsx",
    "chars": 705,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { HoverButton } from '../design-system';\n\nexport c"
  },
  {
    "path": "src/components/Channel/RemoveButton.component.jsx",
    "chars": 1103,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { HoverButton } from '../design-system';\nimport th"
  },
  {
    "path": "src/components/Channel/index.js",
    "chars": 37,
    "preview": "export * from './Channel.container';\n"
  },
  {
    "path": "src/components/ChannelControls/ChannelControls.component.jsx",
    "chars": 2346,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  detuneSupported,\n} from '../../services/featur"
  },
  {
    "path": "src/components/ChannelControls/ChannelControls.container.js",
    "chars": 1348,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { ChannelControlsCompon"
  },
  {
    "path": "src/components/ChannelControls/ChannelControls.selectors.js",
    "chars": 562,
    "preview": "import { createStructuredSelector, createSelector } from 'reselect';\nimport { channelsSelector, selectedChannelSelector "
  },
  {
    "path": "src/components/ChannelControls/index.js",
    "chars": 45,
    "preview": "export * from './ChannelControls.container';\n"
  },
  {
    "path": "src/components/ChannelHeader/ChannelHeader.component.jsx",
    "chars": 886,
    "preview": "import React from 'react';\nimport { Box } from '../design-system';\nimport { ChannelHeaderLabel } from './ChannelHeaderLa"
  },
  {
    "path": "src/components/ChannelHeader/ChannelHeaderLabel.component.jsx",
    "chars": 636,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Box, Text } from '../design-system';\n\nconst Head"
  },
  {
    "path": "src/components/ChannelHeader/index.js",
    "chars": 43,
    "preview": "export * from './ChannelHeader.component';\n"
  },
  {
    "path": "src/components/ChannelList/ChannelList.component.jsx",
    "chars": 1236,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Sortable } from '@shopify/draggable';\nimport { B"
  },
  {
    "path": "src/components/ChannelList/ChannelList.container.js",
    "chars": 704,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { ChannelListComponent "
  },
  {
    "path": "src/components/ChannelList/ChannelList.selectors.js",
    "chars": 200,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport { channelsSelector } from '../../common';\n\nexport const chan"
  },
  {
    "path": "src/components/ChannelList/index.js",
    "chars": 41,
    "preview": "export * from './ChannelList.container';\n"
  },
  {
    "path": "src/components/FancyButton.component.jsx",
    "chars": 373,
    "preview": "import { variant } from 'styled-system';\nimport { Button } from './design-system';\n\nconst fancyButtonStyle = variant({\n "
  },
  {
    "path": "src/components/FlashMessage/FlashMessage.component.jsx",
    "chars": 3565,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport * as animol from 'animol';\nimport { FLASH_MESSAGES"
  },
  {
    "path": "src/components/FlashMessage/FlashMessage.container.js",
    "chars": 633,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { FlashMessageComponent"
  },
  {
    "path": "src/components/FlashMessage/FlashMessage.selectors.js",
    "chars": 298,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport { flashMessageKeySelector, flashMessageVisibleSelector } fro"
  },
  {
    "path": "src/components/FlashMessage/index.js",
    "chars": 42,
    "preview": "export * from './FlashMessage.container';\n"
  },
  {
    "path": "src/components/GithubLink.component.jsx",
    "chars": 601,
    "preview": "import React from 'react';\nimport {\n  Image,\n  HoverLink,\n  Text,\n  Box,\n} from './design-system';\nimport octocat from '"
  },
  {
    "path": "src/components/InfoKnob.component.jsx",
    "chars": 771,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Knob } from './Knob.component';\nimport { Control"
  },
  {
    "path": "src/components/InstallButton.jsx",
    "chars": 981,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { connect } from 'react-redux';\nimport { HoverButt"
  },
  {
    "path": "src/components/Knob.component.jsx",
    "chars": 951,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\n// import '../assets/js/webcomponents-lite';\nimport knobI"
  },
  {
    "path": "src/components/LabelBox.jsx",
    "chars": 1085,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport theme from '../styles/theme';\nimport { Box, Text }"
  },
  {
    "path": "src/components/Logo.component.jsx",
    "chars": 4440,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport theme from '../styles/theme';\n\nexport const Logo ="
  },
  {
    "path": "src/components/Marker/Marker.component.jsx",
    "chars": 1463,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Box } from '../design-system';\nimport { getCurre"
  },
  {
    "path": "src/components/Marker/Marker.container.js",
    "chars": 270,
    "preview": "import { connect } from 'react-redux';\nimport { compose } from 'recompose';\nimport { MarkerComponent } from './Marker.co"
  },
  {
    "path": "src/components/Marker/Marker.selectors.js",
    "chars": 283,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport {\n  bpmSelector,\n  startTimeSelector,\n  playingSelector,\n} f"
  },
  {
    "path": "src/components/Marker/index.js",
    "chars": 36,
    "preview": "export * from './Marker.container';\n"
  },
  {
    "path": "src/components/MasterControls/MasterControls.component.jsx",
    "chars": 828,
    "preview": "import React from 'react';\nimport { Box } from '../design-system';\nimport { PlayButton } from '../PlayButton';\nimport { "
  },
  {
    "path": "src/components/MasterControls/index.js",
    "chars": 44,
    "preview": "export * from './MasterControls.component';\n"
  },
  {
    "path": "src/components/Modal.component.jsx",
    "chars": 489,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Box } from './design-system';\n\nexport const Moda"
  },
  {
    "path": "src/components/MuteSolo/MuteSolo.component.jsx",
    "chars": 896,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Box, Button } from '../design-system';\n\nconst MS"
  },
  {
    "path": "src/components/MuteSolo/MuteSolo.container.js",
    "chars": 768,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { MuteSoloComponent } f"
  },
  {
    "path": "src/components/MuteSolo/index.js",
    "chars": 38,
    "preview": "export * from './MuteSolo.container';\n"
  },
  {
    "path": "src/components/PatternSelector/PatternSelector.component.jsx",
    "chars": 1154,
    "preview": "import React from 'react';\nimport * as R from 'ramda';\nimport PropTypes from 'prop-types';\nimport { LabelBox } from '../"
  },
  {
    "path": "src/components/PatternSelector/PatternSelector.container.js",
    "chars": 646,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { PatternSelectorCompon"
  },
  {
    "path": "src/components/PatternSelector/PatternSelector.selectors.js",
    "chars": 201,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport { patternSelector } from '../../common';\n\nexport const patte"
  },
  {
    "path": "src/components/PatternSelector/index.js",
    "chars": 45,
    "preview": "export * from './PatternSelector.container';\n"
  },
  {
    "path": "src/components/PlayButton/PlayButton.component.jsx",
    "chars": 1705,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { FancyButton } from '../FancyButton.component';\ni"
  },
  {
    "path": "src/components/PlayButton/PlayButton.container.js",
    "chars": 456,
    "preview": "import { connect } from 'react-redux';\nimport { compose } from 'recompose';\nimport { PlayButtonComponent } from './PlayB"
  },
  {
    "path": "src/components/PlayButton/PlayButton.selectors.js",
    "chars": 196,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport { playingSelector } from '../../common';\n\nexport const playB"
  },
  {
    "path": "src/components/PlayButton/index.js",
    "chars": 40,
    "preview": "export * from './PlayButton.container';\n"
  },
  {
    "path": "src/components/PresetDeleted.component.jsx",
    "chars": 681,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  Box,\n  Text,\n  HoverButton,\n} from './design-s"
  },
  {
    "path": "src/components/PresetSaved.component.jsx",
    "chars": 675,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  Box,\n  Text,\n  HoverButton,\n} from './design-s"
  },
  {
    "path": "src/components/PresetSelector/PresetSelector.component.jsx",
    "chars": 3473,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Select from 'react-select';\nimport * as R from 'ra"
  },
  {
    "path": "src/components/PresetSelector/PresetSelector.container.js",
    "chars": 1468,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withProps, withHandlers } from 'recompose';\nimport { PresetSele"
  },
  {
    "path": "src/components/PresetSelector/PresetSelector.selectors.js",
    "chars": 1110,
    "preview": "import { createStructuredSelector, createSelector } from 'reselect';\nimport * as R from 'ramda';\nimport {\n  presetSelect"
  },
  {
    "path": "src/components/PresetSelector/index.js",
    "chars": 44,
    "preview": "export * from './PresetSelector.container';\n"
  },
  {
    "path": "src/components/SampleLoadError.component.jsx",
    "chars": 704,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  Box,\n  Text,\n  HoverButton,\n} from './design-s"
  },
  {
    "path": "src/components/SampleSelect/SampleSelect.component.jsx",
    "chars": 3416,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport Select from 'react-select';\nimport { Box, ControlL"
  },
  {
    "path": "src/components/SampleSelect/SampleSelect.container.js",
    "chars": 903,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { SampleSelectComponent"
  },
  {
    "path": "src/components/SampleSelect/SampleSelect.selectors.js",
    "chars": 424,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport {\n  channelsSelector,\n  notesSelector,\n  patternSelector,\n  "
  },
  {
    "path": "src/components/SampleSelect/index.js",
    "chars": 42,
    "preview": "export * from './SampleSelect.container';\n"
  },
  {
    "path": "src/components/SavePresetModal/SavePresetModal.component.jsx",
    "chars": 3007,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport {\n  TextInput,\n  Text,\n  Button,\n  HoverButton,\n  "
  },
  {
    "path": "src/components/SavePresetModal/SavePresetModal.container.js",
    "chars": 1876,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers, withState } from 'recompose';\nimport { SavePreset"
  },
  {
    "path": "src/components/SavePresetModal/SavePresetModal.selectors.js",
    "chars": 352,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport {\n  presetPromptOpenSelector,\n  currentStateSelector,\n  user"
  },
  {
    "path": "src/components/SavePresetModal/index.js",
    "chars": 45,
    "preview": "export * from './SavePresetModal.container';\n"
  },
  {
    "path": "src/components/SwingControl/SwingControl.component.jsx",
    "chars": 772,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Knob } from '../Knob.component';\nimport { Box, T"
  },
  {
    "path": "src/components/SwingControl/SwingControl.container.js",
    "chars": 601,
    "preview": "import { connect } from 'react-redux';\nimport { compose, withHandlers } from 'recompose';\nimport { SwingControlComponent"
  },
  {
    "path": "src/components/SwingControl/SwingControl.selectors.js",
    "chars": 192,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport { swingSelector } from '../../common';\n\nexport const swingCo"
  },
  {
    "path": "src/components/SwingControl/index.js",
    "chars": 42,
    "preview": "export * from './SwingControl.container';\n"
  },
  {
    "path": "src/components/Toggles/Toggle.component.jsx",
    "chars": 1513,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport styled from 'styled-components';\nimport * as ss fr"
  },
  {
    "path": "src/components/Toggles/ToggleGroup.component.jsx",
    "chars": 449,
    "preview": "import React from 'react';\nimport PropTypes from 'prop-types';\nimport { Box } from '../design-system';\n\nexport const Tog"
  },
  {
    "path": "src/components/Toggles/Toggles.component.jsx",
    "chars": 1537,
    "preview": "import React from 'react';\nimport * as R from 'ramda';\nimport PropTypes from 'prop-types';\nimport { Box } from '../desig"
  },
  {
    "path": "src/components/Toggles/Toggles.container.js",
    "chars": 381,
    "preview": "import { connect } from 'react-redux';\nimport { compose } from 'recompose';\nimport { TogglesComponent } from './Toggles."
  },
  {
    "path": "src/components/Toggles/Toggles.selectors.js",
    "chars": 278,
    "preview": "import { createStructuredSelector } from 'reselect';\nimport {\n  bpmSelector,\n  playingSelector,\n  patternSelector,\n} fro"
  },
  {
    "path": "src/components/Toggles/index.js",
    "chars": 73,
    "preview": "export * from './Toggles.container';\nexport * from './Toggle.component';\n"
  },
  {
    "path": "src/components/VolumeMeter.component.jsx",
    "chars": 1171,
    "preview": "import React, { useEffect, useRef } from 'react';\nimport { Box } from './design-system';\nimport { getVolume } from '../s"
  },
  {
    "path": "src/components/design-system/Box.js",
    "chars": 535,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nexport const Box = styled.div`\n  ${ss.colo"
  },
  {
    "path": "src/components/design-system/Button.js",
    "chars": 682,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nconst Button = styled.button`\n  ${ss.color"
  },
  {
    "path": "src/components/design-system/ControlLabel.js",
    "chars": 141,
    "preview": "import { Text } from './Text';\n\nexport const ControlLabel = Text.extend`\n  font-size: 0.7em;\n  text-transform: uppercase"
  },
  {
    "path": "src/components/design-system/Form.js",
    "chars": 449,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nexport const Form = styled.form`\n  ${ss.co"
  },
  {
    "path": "src/components/design-system/Heading.js",
    "chars": 198,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nexport const Heading = styled.h1`\n  ${ss.c"
  },
  {
    "path": "src/components/design-system/HoverButton.js",
    "chars": 570,
    "preview": "import { Button } from './Button';\n\nconst getColor = (theme, color) => theme.colors[color] || color;\n\nexport const Hover"
  },
  {
    "path": "src/components/design-system/HoverLink.js",
    "chars": 395,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nexport const HoverLink = styled.a`\n  ${ss."
  },
  {
    "path": "src/components/design-system/Image.js",
    "chars": 306,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nexport const Image = styled.img`\n  ${ss.co"
  },
  {
    "path": "src/components/design-system/Label.js",
    "chars": 352,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nconst Label = styled.label`\n  ${ss.color}\n"
  },
  {
    "path": "src/components/design-system/Line.js",
    "chars": 378,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nconst Line = styled.div`\n  ${ss.color}\n  $"
  },
  {
    "path": "src/components/design-system/Text.js",
    "chars": 528,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nconst Text = styled.span`\n  ${ss.color}\n  "
  },
  {
    "path": "src/components/design-system/TextInput.js",
    "chars": 360,
    "preview": "import styled from 'styled-components';\nimport * as ss from 'styled-system';\n\nconst TextInput = styled.input`\n  ${ss.col"
  },
  {
    "path": "src/components/design-system/index.js",
    "chars": 319,
    "preview": "export * from './Heading';\nexport * from './Box';\nexport * from './Button';\nexport * from './HoverButton';\nexport * from"
  },
  {
    "path": "src/components/index.js",
    "chars": 649,
    "preview": "export * from './design-system';\nexport * from './ChannelList';\nexport * from './Channel';\nexport * from './ChannelHeade"
  },
  {
    "path": "src/components/timedCallback.hoc.jsx",
    "chars": 329,
    "preview": "import React from 'react';\n\nexport const timedCallback = (callback, delay) => WrappedEl => class extends React.Component"
  },
  {
    "path": "src/index.html",
    "chars": 860,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <!-- Global site tag (gtag.js) - Google Analytics -->\n    <script async sr"
  },
  {
    "path": "src/index.jsx",
    "chars": 1635,
    "preview": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport { PersistGat"
  },
  {
    "path": "src/presets/707.js",
    "chars": 14228,
    "preview": "import { samples } from '../samples.config';\n\nexport default {\n  name: '707',\n  bpm: 133,\n  swing: 0.2,\n  channels: [\n  "
  },
  {
    "path": "src/presets/808.js",
    "chars": 17277,
    "preview": "import { samples } from '../samples.config';\n\nexport default {\n  name: '808',\n  bpm: 105,\n  swing: 0,\n  channels: [\n    "
  },
  {
    "path": "src/presets/__mocks__/index.js",
    "chars": 378,
    "preview": "export default [\n  {\n    name: 'Roland 707',\n    bpm: 130,\n    channels: [\n      {\n        id: 'channel-id',\n        sam"
  },
  {
    "path": "src/presets/ace.js",
    "chars": 14338,
    "preview": "import { samples } from '../samples.config';\n\nexport default {\n  name: 'Ace Drum',\n  bpm: 140,\n  swing: 0.3,\n  channels:"
  },
  {
    "path": "src/presets/empty.js",
    "chars": 328,
    "preview": "import sampleList from '../samples.config';\n\nexport const EMPTY_NOTE_ROW = [[], [], [], [], [], [], [], []];\n\nexport def"
  },
  {
    "path": "src/presets/hip-hop.js",
    "chars": 15118,
    "preview": "import { samples } from '../samples.config';\n\nexport default {\n  name: 'Hip Hop',\n  bpm: 98,\n  swing: 0.4,\n  channels: ["
  },
  {
    "path": "src/presets/index.js",
    "chars": 256,
    "preview": "import empty from './empty';\nimport hipHop from './hip-hop';\nimport lDrum from './ldrum';\nimport sevenohseven from './70"
  },
  {
    "path": "src/presets/ldrum.js",
    "chars": 20924,
    "preview": "import { samples } from '../samples.config';\n\nexport default {\n  name: 'LDrum',\n  bpm: 124,\n  swing: 0.2,\n  channels: [\n"
  },
  {
    "path": "src/reducer.js",
    "chars": 488,
    "preview": "import { combineReducers } from 'redux';\nimport {\n  channelsReducer,\n  playbackSessionReducer,\n  tempoReducer,\n  masterR"
  },
  {
    "path": "src/samples.config.js",
    "chars": 5884,
    "preview": "import tr707Bd from './assets/drums/707/707-bd.mp3';\nimport tr707SdLow from './assets/drums/707/707-sd-low.mp3';\nimport "
  },
  {
    "path": "src/services/__mocks__/audioContext.js",
    "chars": 122,
    "preview": "export const getAudioContext = () => ({\n  currentTime: 1,\n});\n\nexport const playNote = () => new AudioBufferSourceNode()"
  },
  {
    "path": "src/services/__mocks__/audioRouter.js",
    "chars": 34,
    "preview": "export const playNote = () => {};\n"
  },
  {
    "path": "src/services/__mocks__/featureChecks.js",
    "chars": 37,
    "preview": "export const detuneSupported = true;\n"
  },
  {
    "path": "src/services/animations.js",
    "chars": 1283,
    "preview": "import { getCurrentBeat } from './audioContext';\nimport { swing } from './swing';\n\nconst draw = (store) => {\n  // Get so"
  },
  {
    "path": "src/services/audioAnalyzer.js",
    "chars": 314,
    "preview": "import { analyserNode } from './audioRouter';\n\nconst pcmData = new Float32Array(analyserNode.fftSize);\n\nexport function "
  },
  {
    "path": "src/services/audioContext.js",
    "chars": 510,
    "preview": "let audioCtx;\n\nexport const getAudioContext = () => {\n  if (typeof audioCtx === 'undefined') {\n    audioCtx = new (windo"
  },
  {
    "path": "src/services/audioContext.test.js",
    "chars": 1029,
    "preview": "import {\n  getCurrentBeat,\n} from './audioContext';\n\njest.mock('./featureChecks');\n\ndescribe('getCurrentBeat', () => {\n "
  },
  {
    "path": "src/services/audioEngine.config.js",
    "chars": 85,
    "preview": "export const LOOKAHEAD = 0.2; // seconds\nexport const INTERVAL = 50; // milliseconds\n"
  },
  {
    "path": "src/services/audioLoop.js",
    "chars": 1125,
    "preview": "import { getAudioContext, getCurrentBeat } from './audioContext';\nimport { updateChannelNodes } from './audioRouter';\nim"
  },
  {
    "path": "src/services/audioRouter.js",
    "chars": 3809,
    "preview": "import { detuneSupported, stereoPannerSupported } from './featureChecks';\nimport { getAudioContext } from './audioContex"
  },
  {
    "path": "src/services/audioScheduler.js",
    "chars": 2609,
    "preview": "import { LOOKAHEAD } from './audioEngine.config';\nimport { playNote } from './audioRouter';\nimport { sampleStore } from "
  },
  {
    "path": "src/services/audioScheduler.test.js",
    "chars": 1277,
    "preview": "import {\n  isBetween,\n  getScheduledNotes,\n} from './audioScheduler';\n\njest.mock('./featureChecks');\njest.mock('./audioC"
  },
  {
    "path": "src/services/database.js",
    "chars": 1217,
    "preview": "const DB_NAME = 'wds-1';\nconst DB_VERSION = 1;\nconst USER_SAMPLES = 'USER_SAMPLES';\n\nlet db;\n\nexport const initializeDB "
  },
  {
    "path": "src/services/featureChecks.js",
    "chars": 281,
    "preview": "const audioCtx = new (window.AudioContext || window.webkitAudioContext)();\nconst source = audioCtx.createBufferSource();"
  },
  {
    "path": "src/services/fileUtils.js",
    "chars": 713,
    "preview": "import { getAudioContext } from './audioContext';\n\nexport const fetchFile = (url) => new Promise(\n  (resolve, reject) =>"
  },
  {
    "path": "src/services/pwaInstall.js",
    "chars": 492,
    "preview": "import { setCanInstall } from '../common';\n\nlet deferredPrompt;\n\nexport const initializePwaInstall = (store) => {\n  wind"
  },
  {
    "path": "src/services/reverb.js",
    "chars": 345,
    "preview": "import { fetchFile, decodeFile, decodeAudio } from './fileUtils';\n\nconst impulseResponses = {};\n\nexport const loadImpuls"
  },
  {
    "path": "src/services/sampleStore.js",
    "chars": 925,
    "preview": "import { fetchFile, decodeFile, decodeAudio } from './fileUtils';\nimport { saveToDB, getFromDB } from './database';\n\nexp"
  },
  {
    "path": "src/services/swing.js",
    "chars": 419,
    "preview": "export const swing = (beatTime, swingAmount) => {\n  const SWING_TIMING = 0.5; // eight note cycles\n  const MAX_SWING = 0"
  },
  {
    "path": "src/services/unmute.js",
    "chars": 156,
    "preview": "import silence from '../assets/silence.mp3';\n\nexport const unmute = () => {\n  var el = document.createElement('audio');\n"
  },
  {
    "path": "src/services/uuid.js",
    "chars": 59,
    "preview": "import uuidv4 from 'uuid/v4';\n\nexport const uuid = uuidv4;\n"
  },
  {
    "path": "src/store.js",
    "chars": 988,
    "preview": "import { createStore, applyMiddleware, compose } from 'redux';\nimport thunk from 'redux-thunk';\nimport { persistStore, p"
  },
  {
    "path": "src/styles/globalStyles.js",
    "chars": 1992,
    "preview": "import { injectGlobal } from 'styled-components';\nimport theme from './theme';\nimport jostMediumWoff2 from '../assets/fo"
  },
  {
    "path": "src/styles/theme.js",
    "chars": 1617,
    "preview": "const colors = {\n  nearWhite: '#F2F2F8',\n  lightGray: '#C0C3C7',\n  gray: '#909599',\n  steel: '#606469',\n  darkGray: '#40"
  },
  {
    "path": "vite.config.js",
    "chars": 158,
    "preview": "import { defineConfig } from 'vite';\nimport reactRefresh from '@vitejs/plugin-react-refresh';\n\nexport default defineConf"
  }
]

About this extraction

This page contains the full source code of the stufreen/web-drum-sequencer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 199 files (381.2 KB), approximately 125.4k tokens, and a symbol index with 331 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!