diff --git a/.flake8 b/.flake8 index 787941ef51..1033edee63 100644 --- a/.flake8 +++ b/.flake8 @@ -3,7 +3,8 @@ max-line-length = 88 # E203: whitespace before ‘,’, ‘;’, or ‘:’ # E501: line length # W503: line break after binary operator -ignore = E203, E501, W503 +ignore = E203, E501, W503, D, DAR +extend-select = B902, B903, B904 extend-exclude = *.pyc, .github, diff --git a/.github/workflows/build_and_push_image.yml b/.github/workflows/build_and_push_image.yml index cd161e2903..259104c7d3 100644 --- a/.github/workflows/build_and_push_image.yml +++ b/.github/workflows/build_and_push_image.yml @@ -24,7 +24,7 @@ jobs: if [ ${{ github.base_ref }} == 'main' ]; then branch='' else - branch="-""${{ github.base_ref }}" + branch=`"-""${{ github.base_ref }}" | awk '{print tolower($0)}'` fi narrative_version=`grep '\"version\":' src/config.json.templ | awk '{print $2}' | sed 's/"//g'` narrative_git_hash=`grep '\"git_commit_hash\":' src/config.json.templ | awk '{print $2}' | sed 's/"//g' | sed 's/,//'` diff --git a/.github/workflows/build_test_pr.yaml b/.github/workflows/build_test_pr.yaml index 66ef50dc88..b41cea17b8 100644 --- a/.github/workflows/build_test_pr.yaml +++ b/.github/workflows/build_test_pr.yaml @@ -2,8 +2,8 @@ name: Build Dev Image on: pull_request: - branches: - - develop + branches-ignore: + - main types: - opened - synchronize diff --git a/.github/workflows/build_truss_pr.yaml b/.github/workflows/build_truss_pr.yaml deleted file mode 100644 index dde123bd99..0000000000 --- a/.github/workflows/build_truss_pr.yaml +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Build Truss Branch Image -on: - pull_request: - branches: - - truss - types: - - opened - - synchronize - - ready_for_review - -jobs: - run_build_and_push: - uses: ./.github/workflows/build_and_push_image.yml - secrets: - GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }} - GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} - - run_unit_tests: - uses: ./.github/workflows/unit_test.yml - needs: run_build_and_push - secrets: - GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }} - GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} - - run_integration_tests: - uses: ./.github/workflows/integration_test.yml - needs: run_build_and_push - secrets: - GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }} - GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} - NARRATIVE_TEST_TOKEN: ${{ secrets.NARRATIVE_TEST_TOKEN }} diff --git a/.github/workflows/build_truss_push.yaml b/.github/workflows/build_truss_push.yaml deleted file mode 100644 index 6058821330..0000000000 --- a/.github/workflows/build_truss_push.yaml +++ /dev/null @@ -1,46 +0,0 @@ ---- -name: Build and push Truss image -on: - push: - branches: - - truss - -jobs: - docker_build: - if: github.event.pull_request.draft == false - runs-on: ubuntu-latest - steps: - - - name: Check out GitHub Repo - with: - ref: "${{ github.event.pull_request.head.sha }}" - uses: actions/checkout@v2 - - - name: Set up environment - run: | - echo "BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_ENV - echo "VCS_REF=$(echo "${{ github.event.pull_request.head.sha }}" | cut -c -7)" >> $GITHUB_ENV - - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Log in to the Container registry - uses: docker/login-action@v1 - with: - registry: ghcr.io - username: ${{ secrets.GHCR_USERNAME }} - password: ${{ secrets.GHCR_TOKEN }} - - - name: Build narrative image - uses: docker/build-push-action@v2 - with: - context: . - push: true - tags: ghcr.io/${{ github.repository }}-truss:latest - build-args: | - BUILD_DATE=${{ env.BUILD_DATE }} - VCS_REF=${{ env.VCS_REF }} - BRANCH=${{ github.head_ref }} diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index 83bae1e097..1476b884e0 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -30,7 +30,7 @@ jobs: if [ ${{ github.base_ref }} == 'main' ]; then branch='' else - branch="-""${{ github.base_ref }}" + branch=`"-""${{ github.base_ref }}" | awk '{print tolower($0)}'` fi narrative_version=`grep '\"version\":' src/config.json.templ | awk '{print $2}' | sed 's/"//g'` narrative_git_hash=`grep '\"git_commit_hash\":' src/config.json.templ | awk '{print $2}' | sed 's/"//g' | sed 's/,//'` diff --git a/.github/workflows/manual_build.yml b/.github/workflows/manual_build.yml new file mode 100644 index 0000000000..9fb9082fcc --- /dev/null +++ b/.github/workflows/manual_build.yml @@ -0,0 +1,23 @@ +name: Build and Tag Latest Image + +# Controls when the workflow will run +on: + # Manually triggers the workflow on the develop branch + workflow_dispatch: + inputs: + branch: + description: 'Branch to build the new image from' + required: true + default: 'develop' + type: choice + options: + - develop + - main + +jobs: + run_build_and_push: + runs-on: ubuntu-latest + steps: + - + name: say hello + run: echo "hello world" diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml index fd9c3c566a..c79bfebdda 100644 --- a/.github/workflows/unit_test.yml +++ b/.github/workflows/unit_test.yml @@ -28,7 +28,7 @@ jobs: if [ ${{ github.base_ref }} == 'main' ]; then branch='' else - branch="-""${{ github.base_ref }}" + branch=`"-""${{ github.base_ref }}" | awk '{print tolower($0)}'` fi narrative_version=`grep '\"version\":' src/config.json.templ | awk '{print $2}' | sed 's/"//g'` narrative_git_hash=`grep '\"git_commit_hash\":' src/config.json.templ | awk '{print $2}' | sed 's/"//g' | sed 's/,//'` diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6aefc7e1ee..f65dd8c24e 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -4,8 +4,74 @@ The Narrative Interface allows users to craft KBase Narratives using a combinati This is built on the Jupyter Notebook v6.0.2 (more notes will follow). +### Version 5.1.0 +- PTV-1783 - fixed issue where the previous object revert option was unavailable +- DATAUP-639 - fix problems with dynamic dropdown app cell input + - selected value wasn't being displayed properly after a page reload or cell refresh + - selected value wasn't being displayed in view-only version + - "Loading..." message wasn't displayed while fetching data from a service. + - Update the dynamic dropdown to support the `exact_match_on` field in app specs. + - Add a copy button to the dynamic dropdown - this will copy the most relevant text from the dropdown to the clipboard. + - For dropdowns with an `exact_match_on` field, this will copy the contents of that field (e.g. for those that present taxonomy ids for a species, this copies just the scientific name) + - For dropdowns that go against the FTP staging area, this copies the file name and path. + - For other dropdowns, this copies the formatted text +- DATAUP-751 - add link to staging area docs in the upload tour +- DATAUP-753 - alter the error text for Select input boxes in app cells to be a bit more generalized. +- DATAUP-756 - add a copy button for other, non-dynamic dropdowns. This copies the displayed text to the clipboard. + +Dependency Changes +- Javascript dependency updates + - @wdio/browserstack-service: 7.16.16 -> 7.19.7 + - @wdio/cli: 7.16.16 -> 7.19.6 + - @wdio/local-runner: 7.16.6 -> 7.19.3 + - @wdio/mocha-framework: 7.16.15 -> 7.20.0 + - @wdio/selenium-standalone-service: 7.16.16 -> 7.19.1 + - @wdio/spec-reporter: 7.16.14 -> 7.19.1 + - autoprefixer: 10.2.6 -> 10.4.5 + - commander: 9.0.0 -> 9.3.0 + - chromedriver: 100.0.0 -> 101.0.0 + - corejs-typeahead: 1.6.1 -> 1.3.1 + - datatables.net: 1.11.3 -> 1.12.1 + - datatables.net-bs 1.11.5 -> 1.12.1 + - datatables.net-buttons-bs: 1.4.2 -> 2.2.3 + - ejs: 3.1.6 -> 3.1.7 + - eslint: 8.14.0 -> 8.16.0 + - grunt: 1.4.1 -> 1.5.3 + - grunt-contrib-concat: 1.0.1 -> 2.1.0 + - handlebars: 4.0.5 -> 4.7.7 + - jasmine-core: 4.0.0 -> 4.1.0 + - jquery-nearest: 1.3.1 -> 1.4.0 + - jquery-ui: 1.12.1 -> 1.13.1 + - js-yaml: 3.3.1 -> 3.14.1 + - karma-jasmine: 4.0.1 -> 5.0.1 + - karma-jasmine-matchers: 4.0.2 -> 5.0.0 + - postcss-remove-comments: 5.0.1 -> 5.1.2 + - postcss-cli: 8.3.1 -> 9.1.0 + - postcss-scss: 3.0.5 -> 4.0.4 + - pure-uuid: 1.4.2 -> 1.6.2 + - sass: 1.34.1 -> 1.51.0 + - selenium-standalone: 8.0.9 -> 8.0.10 + - selenium-webdriver: 4.1.1 -> 4.1.2 + - spark-md5: 3.0.0 -> 3.0.2 + - underscore: 1.8.3 -> 1.13.3 + - webdriverio: 7.16.16 -> 7.19.7 + +- Python dependency updates + - beautifulsoup4: 4.8.1 -> 4.11.1 + - cryptography: 3.3.2 -> 36.0.2 + - html5lib: 1.0.1 -> 1.1 + - idna: 2.8 -> 3.3 + - jinja2: 3.1.1 -> 3.0.3 + - plotly: 5.6.0 -> 5.7.0 + - pygments: 2.11.2 -> 2.12.0 + - jupyter-console: 6.0.0 -> 6.4.3 + - jsonschema: 4.4.0 -> 3.2.0 + - pymongo: 4.1.0 -> 4.1.1 + - pyopenssl: 19.0.0 -> 22.0.0 + - setuptools: 62.0.0 -> 62.1.0 + ### Version 5.0.3 -- DATAUP-641 +- DATAUP-641 - Adds custom error messages when app cell dropdown menu inputs are incorrect in various different ways. - Adds custom error messages when app cell checkboxes are initialized with non binary data (should only happen with a bulk import cell from a spreadsheet file) - Adds custom error messages when app cell numeric inputs are initialized with non-numeric data. diff --git a/docs/deploy_narrative.md b/docs/deploy_narrative.md index 0f725d101f..ac1994e8b2 100644 --- a/docs/deploy_narrative.md +++ b/docs/deploy_narrative.md @@ -79,7 +79,7 @@ The [next](https://next.kbase.us), [appdev](https://appdev.kbase.us), and [produ ### Deploying Narrative-Refactor -The [narrative-refactor](https://narrative-refactor.kbase.us) image is automatically built against the "truss" branch of the repo and is called narrative-truss:pr### when still in a PR state or narrative-truss:latest after merge. The images can be found here: https://github.com/orgs/kbase/packages +The [narrative-refactor](https://narrative-refactor.kbase.us) image is automatically built against the "develop" branch of the repo and is called narrative-develop:pr### when still in a PR state or narrative-develop:latest after merge. The images can be found here: https://github.com/orgs/kbase/packages ### Deploying Narrative-Dev The [narrative-dev](https://narrative-dev.kbase.us) environment is meant for pre-release and iterative testing of new UI features and changes. As such, this isn't always tied to any particular branch, although it is most often set to deploy the production image. Contact a DevOps team member if there are any questions. @@ -117,7 +117,7 @@ Once a pull request is merged from `develop` to `main` a new _production_ image | Environment | Image URL | | ----------- | -------------------------------------------------------------- | | CI | ghcr.io/kbase/narrative-develop:latest | -| Narrative-refactor| ghcr.io/kbase/narrative-truss:latest | +| Narrative-refactor| ghcr.io/kbase/narrative-develop:latest | | Appdev | ghcr.io/kbase/narrative:appdev | | Next | ghcr.io/kbase/narrative:next | | Production | ghcr.io/kbase/narrative:prod | diff --git a/docs/design/job_architecture.md b/docs/design/job_architecture.md index 56dc5b660d..ae41d08abc 100644 --- a/docs/design/job_architecture.md +++ b/docs/design/job_architecture.md @@ -1,21 +1,59 @@ # Job Management Architecture -The Narrative job manager is based on a data flow that operates between the browser, the IPython Kernel behind the Narrative (also known as the narrative backend), and the KBase Execution Engine (EE2) behind that. Some frontend components access external resources directly, but job-related data flows between those three stops across a single channel from frontend and backend, and backend and EE2. -# Comm channels -Jupyter provides a "Comm" object that allows for custom messaging between the frontend and the kernel ([details and documentation here](https://jupyter-notebook.readthedocs.io/en/stable/comms.html)). This provides an interface for the frontend to directly request information from the kernel, and to listen to asynchronous responses. On the kernel-side, it allows one or more modules to register message handlers to process those requests out of the band of the usual kernel invocation. These are used to implement the Jupyter Notebook's ipywidgets, for example. +The Narrative job manager is based on a data flow that operates between the browser, the IPython Kernel behind the Narrative (also known as the narrative backend), and the [KBase Execution Engine](https://github.com/kbase/execution_engine2) (EE2) behind that. Some frontend components access external resources directly, but job-related data flows between those three stops across a single channel from frontend and backend, and backend and EE2. + +- [Job Management Architecture](#job-management-architecture) + - [Comm channels](#comm-channels) + - [Frontend Comm Channel](#frontend-comm-channel) + - [Backend JobComm module](#backend-jobcomm-module) + - [Messages](#messages) + - [Job communication vocabulary](#job-communication-vocabulary) + - [Messages from frontend to backend](#messages-from-frontend-to-backend) + - [`CANCEL`](#cancel) + - [`INFO`](#info) + - [`LOGS`](#logs) + - [`RETRY`](#retry) + - [`STATUS`](#status) + - [To be deprecated -- do not use](#to-be-deprecated----do-not-use) + - [`START_UPDATE`](#start_update) + - [`STOP_UPDATE`](#stop_update) + - [Receiving messages in the backend](#receiving-messages-in-the-backend) + - [Messages from backend to frontend](#messages-from-backend-to-frontend) + - [`ERROR`](#error) + - [`INFO` (response)](#info-response) + - [`LOGS` (response)](#logs-response) + - [`RETRY` (response)](#retry-response) + - [`RUN_STATUS`](#run_status) + - [`STATUS` (response)](#status-response) + - [Job output state](#job-output-state) + - [`STATUS_ALL`](#status_all) + - [Usage Examples](#usage-examples) + - [Job Management flow](#job-management-flow) + - [JobManager initialization and startup](#jobmanager-initialization-and-startup) + - [Running an app](#running-an-app) + - [App initialisation on reload](#app-initialisation-on-reload) + - [JobComm status lookup loop -- TO BE DEPRECATED](#jobcomm-status-lookup-loop----to-be-deprecated) + + +## Comm channels + +Jupyter provides a "Comm" object that allows for custom messaging between the frontend and the kernel ([details and documentation here](https://jupyter-notebook.readthedocs.io/en/stable/comms.html)) using WebSockets. This provides an interface for the frontend to directly request information from the kernel, and to listen to asynchronous responses. On the kernel (narrative backend) side, it allows one or more modules to register message handlers to process those requests out of the band of the usual kernel invocation. These are used to implement the Jupyter Notebook's ipywidgets, for example. The Narrative Interface uses one of these channels to manage job information. These are funneled through an interface on the frontend side and a matching one in the kernel. -## Frontend Comm Channel -On the frontend, there's a `jobCommChannel.js` module that uses the MonoBus system to communicate. Frontend modules use the bus system to send one of the following messages over the main channel, which then get transformed into a message that gets passed through a kernel comm object. +### Frontend Comm Channel -## Backend JobComm module +On the frontend, there's a `jobCommChannel.js` module that uses the frontend's monobus (`monobus.js`) system to communicate. Frontend modules use monobus to send messages bound for the backend over the main channel; the `jobCommChannel` module passes them to the backend over the websocket established on narrative start up. -The narrative backend uses the JobComm module to send and receive messages from the frontend. Its main job is translating incoming messages into requests to be fulfilled by the JobManager module, which in turn may contact external services such as the workspace or EE2 to fetch relevant data. The JobComm converts the results of the JobManager's actions into messages to be sent back over to the frontend. +### Backend JobComm module -## Job communication vocabulary +The narrative backend uses the JobComm module (`jobcomm.py`) to send and receive messages from the frontend. Its main job is translating incoming messages into requests to be fulfilled by the backend JobManager (`jobmanager.py`) module, which in turn may contact external services such as the workspace or EE2 to fetch relevant data. The JobComm converts the results of the JobManager's actions into messages to be sent back over to the frontend. -The front- and backend have a shared vocabulary of message types and parameters, loaded from the file `kbase-extension/static/kbase/config/job_config.json`. In the frontend, the message param and type names are stored in the JobCommMessages object exported by `jobCommChannel.js`: +## Messages + +### Job communication vocabulary + +The front- and backend have a shared vocabulary of message types and parameters, loaded from the file `kbase-extension/static/kbase/config/job_config.json`. In the frontend, the message param and type names are stored in the JobCommMessages object exported by `jobCommMessages.js`: ```js define(['common/jobCommMessages'], (jcm) => { @@ -25,248 +63,107 @@ define(['common/jobCommMessages'], (jcm) => { console.log("job ID parameter: " + jcm.PARAM.JOB_ID) ``` -# Frontend messages +## Messages from frontend to backend - Most of these take one or more inputs. These are listed below the command, where applicable. +Messages are sent from the frontend's `JobCommChannel` to the narrative backend, using a websocket established by one of the Jupyter notebook modules, `Jupyter.kernel.comm`. On the kernel side, a complementary comm channel is used. This is set up in the `biokbase.narrative.jobs.jobcomm.JobComm` class. On Narrative load, page reload, or kernel restart, the comm channel is initialized to handle any messages sent to the kernel. It uses the same controlled vocabulary of terms for message types and job parameters as the frontend. -## Bus requests -These messages are sent to the `JobCommChannel` on the front end, to get processed into messages sent to the kernel. The documentation will use the message type and parameter names used in the job config file (e.g. `STATUS` instead of `job_status`, `RETRY` instead of `retry_job`, `JOB_ID` instead of `job_id`, etc.) as the JS code will refer to those values using the names in the JobCommMessages object, rather than hardcoding the strings. +Most of these messages take one or more inputs. These are listed below the command, where applicable. +The documentation will use the message type and parameter names used in the job config file (e.g. [`STATUS`](#status) instead of `job_status`, [`RETRY`](#retry) instead of `retry_job`, `JOB_ID` instead of `job_id`, etc.) as [the JavaScript code](#usage-examples) will refer to those values using the names in the JobCommMessages object, rather than hardcoding the strings. -`STATUS` - gets the status for a job or an array of jobs. - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs OR - * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) +### `CANCEL` -`START_UPDATE` - request the status for a job or jobs, but start an update cycle so that it's continually requested. - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs OR - * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) +Request that the server cancel the running job(s). If the job ID supplied is a batch ID, EE2 will cancel the job and all its child jobs. -`STOP_UPDATE` - signal that the front end doesn't need any more updates for the specified job(s), so stop sending them for each loop cycle. Doesn't actually end the job, only requests for updates. +**Arguments** * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs OR - * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) + * `JOB_ID_LIST` - an array of job IDs -`INFO` - request information about the job(s), specifically app id, spec, input parameters and (if finished) outputs +### `INFO` + +Request information about the job(s), specifically app id, spec, input parameters and (if finished) outputs + +**Arguments** * `JOB_ID` - a string, the job id OR * `JOB_ID_LIST` - an array of job IDs OR * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) -`CANCEL` - request that the server cancel the running job(s) - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs +### `LOGS` -`RETRY` - request that the server rerun a job or set of jobs - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs +Request the job logs starting at some given line. Note that the `FIRST_LINE`, `NUM_LINES`, and `LATEST` arguments apply to all jobs in the `JOB_ID_LIST`. -`LOGS` - request the job logs starting at some given line. +**Arguments** * `JOB_ID` - a string, the job id OR * `JOB_ID_LIST` - an array of job IDs - * `first_line` - the first line (0-indexed) to request (optional) - * `num_lines` - the number of lines to request (will get back up to that many if there aren't more) (optional) - * `latest` - true if requesting just the latest set of logs (optional) - -### Usage Example -The comm channel is used through the main Bus object that's instantiated through the global `Runtime` object. That needs to be included in the `define` statement for all AMD modules. The bus is then used with its `emit` function (you have the bus *emit* a message to its listeners), and any inputs are passed along with it. - -Generally, this is used as follows (without much detail. For a readable real example, check out the `jobLogViewer.js` module): - -```Javascript -define( - ['common/runtime', ... other modules ...], - function(Runtime, ...others...) { - let runtime = Runtime.make(); - runtime.bus().emit('some-request', { - param: 'value' - }); - } -); -``` - -Some more specific examples: -```Javascript -define( - ['common/runtime', 'common/jobCommMessages'], - function(Runtime, jcm) { - const runtime = Runtime.make(); - - // request the first 10 job log lines: - runtime.bus().emit(jcm.MESSAGE_TYPE.LOGS, { - [jcm.PARAM.JOB_ID]: 'some_job_id', - first_line: 0, - num_lines: 10 - }); + * `FIRST_LINE` (optional; default 0) - return logs from this line number onwards. Line numbers are 0-indexed. + * `NUM_LINES` (optional) - the maximum number of lines to return; if not specified, there is no maximum. + * `LATEST` (optional; default false) - boolean; if true and `NUM_LINES` is set, return the latest `NUM_LINES` lines from the logs. If `FIRST_LINE` is also set, `LATEST` overrides the `FIRST_LINE` parameter. - // request the status of all jobs in a batch: - runtime.bus().emit(jcm.MESSAGE_TYPE.STATUS, { - [jcm.PARAM.BATCH_ID]: 'some_batch_id', - }); - } -); -``` - -## Bus responses -Messages from the kernel to the front end are received by the `JobCommChannel` module. This takes the responses, unpacks them, and turns them into a response message that is passed back over the bus to any frontend Javascript module that listens to them. The message types are described below, along with the content that gets sent, followed by an example of how to make use of them. - -### Cell-related - -`RUN_STATUS` - updates the run status of the job - this is part of the initial flow of starting a job through the AppManager. - * see `run_status` below for the message format. +### `RETRY` -### Job-related +Request that the server rerun a job or set of jobs -`INFO` - contains information about the current job. The format is described under `job_info` in the **Messages sent from the kernel to the browser** section below. +**Arguments** + * `JOB_ID` - a string, the job id OR + * `JOB_ID_LIST` - an array of job IDs -`LOGS` - sent with information about some job logs. The format is described under `job_logs` in the **Messages sent from the kernel to the browser** section below. +### `STATUS` -`RETRY` - sent in response to a retry request; contains the original job ID, the ID of the retry if the request was successful, or an error message, if it was not. +Get the status for a job or an array of jobs. -`STATUS` - contains the current job state - * `jobState` - object, describes the job state (see the **Data Structures** section below for the structure) - * `outputWidgetInfo` - object, contains the parameters to be sent to an output widget. This will be different for all widgets, depending on the App that invokes them. +**Arguments** + * `JOB_ID` - a string, the job id OR + * `JOB_ID_LIST` - an array of job IDs OR + * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) -`ERROR` - sent in response to an error that happened on job information lookup, or another error that happened while processing some other message to the JobManager. - * `raw_request` - object; the request that generated the error - * `source` - string; what triggered the error, e.g. an invalid request or an issue completing a request - * any other content that was supplied - this is frequently an error object, from which a name and error message, and potentially other information, are taken. +### To be deprecated -- do not use -### Usage example -As in the Bus requests section above, the front end response handling is done through the Runtime bus. The bus provides both an `on` and a `listen` function, examples will show how to use both. Generally, the `listen` function is more specific and binds the listener to a specific bus channel. These channels can invoke the jobId, or the cellId, to make sure that only information about specific jobs is listened for. +#### `START_UPDATE` -The `listen` function takes an object with three attributes as input - a channel (either the cellId or jobId), a key (with the type of message to listen for), and a handle, which is a function to process the message. This is probably the easiest way to handle messages. Usage would look like this: +Request the status for a job or jobs, but start an update cycle so that it's continually requested. -```Javascript -define( - ['common/runtime', 'common/jobCommMessages'], - function(Runtime, jcm) { - const runtime = Runtime.make(); +**Arguments** + * `JOB_ID` - a string, the job id OR + * `JOB_ID_LIST` - an array of job IDs OR + * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) - const listener = runtime.bus().listen({ - channel: { - [jcm.CHANNEL.JOB]: 'some_job_id' - }, - key: { - type: jcm.MESSAGE_TYPE.STATUS, - }, - handle: (message) => { - ...process the message... - } - }) - } -); -``` +#### `STOP_UPDATE` -The `on` function requires a constructed channel bus, premade and reusable for a given channel. So you would make a channel bus that would always receive messages for that channel, and instruct it on what to do when a message of a given type arrives. That looks like this: -```Javascript -define( - ['common/runtime', 'common/jobCommMessages'], - function(Runtime, jcm) { - const runtime = Runtime.make(); +Signal that the front end doesn't need any more updates for the specified job(s), so stop sending them for each loop cycle. Doesn't actually end the job, only requests for updates. -const cellBus = runtime.bus().makeChannelBus({ - name: { - cell: 'some_cell_id' - } - }); - const listenerId = cellBus.on(jcm.MESSAGE_TYPE.RUN_STATUS, (message) => { - // process the message... - }); - } -); -``` -Note that both of these create events that get bound to the DOM, and when the widget is removed, they should be cleaned up. This can be done by calling `bus.removeListener(id)` with the created `listenerId`. If you created a channel bus, then that bus should be used, otherwise the main runtime.bus() object should be used. +**Arguments** + * `JOB_ID` - a string, the job id OR + * `JOB_ID_LIST` - an array of job IDs OR + * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) -## Kernel Comm Channel -On the kernel side, a complementary comm channel is used. This is set up in the `biokbase.narrative.jobs.jobcomm.JobComm` class. On Narrative load, page reload, or kernel restart, this is initialized to handle any messages sent to the kernel. The same controlled vocabulary of terms is used for message types and job parameters as for the frontend. +## Receiving messages in the backend -Note that these are autogenerated by the frontend `JobCommChannel` object, using the `Jupyter.kernel.comm` package. +The messages listed above undergo minor modifications to be sent over the websocket to the backend. The message data structures that `JobComm` receives in the kernel has the following format: -The actual message that the JobComm sees in the kernel has this format: ``` { "msg_id": "some random string", "content": { "data": { "request_type": "a string", # present in all messages - ... other params, such as job ID, depending on message ... + ... other params (e.g. JOB_ID, BATCH_ID, FIRST_LINE, etc.) depending on message ... } } } ``` -All messages have a `request_type`, most specify a job or list of job IDs, and a few have some extra info. -## Messages sent to the kernel -These are organized by the `request_type` field, followed by the expected response message. Additional parameters and their formats are given as a list below the request name. The job params and message type terms are imported into the JobComm module as PARAM and MESSAGE_TYPE respectively, i.e. +All messages are assigned a `msg_id` by the Jupyter comm framework (KBase does not use this ID for anything); the message type is added as the `request_type` field, and merged with any other fields, such as `JOB_ID`, `JOB_ID_LIST`, etc. -```py -# in biokbase.narrative.jobs.jobcomm -(PARAM, MESSAGE_TYPE) = load_job_constants() +The python `JobComm` module uses the `request_type` field to trigger the appropriate method in the `JobManager`. -print(MESSAGE_TYPE["STATUS"]) # prints 'job_status' -print(PARAM["JOB_ID_LIST"]) # prints 'job_id_list' -``` -For simplicity below, it is assumed that constants have been created from the key/value pairs in MESSAGE_TYPE and PARAM. +## Messages from backend to frontend -An example of a job status message sent from the frontend to the kernel: -```json -{ - "msg_id": "some string", - "content": { - "data": { - "request_type": "job_status", - "job_id": "a_job_id", - } - } -} -``` -Messages expected by the narrative backend: +These messages are sent by the python `JobComm` module and received by the `JobCommChannel` on the browser side, then parsed and distributed to frontend components over the bus system. Like other kernel messages sent by the Jupyter notebook, they have a `msg_type` field, and a `content` field containing data meant for the frontend to use. They have a rough structure like this: -`STATUS` - request job status - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs OR - * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) - -`STATUS_ALL` - request the status of all jobs registered in the job manager - -`START_UPDATE` - request updating job(s) during the update thread, responds with `STATUS` - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs OR - * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) - -`STOP_UPDATE` - request halting update for job(s) during the update thread, responds with `STATUS` - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs OR - * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) - -`INFO` - request general information about job(s) - * `JOB_ID` - a string, the job id OR - * `JOB_ID_LIST` - an array of job IDs OR - * `BATCH_ID` - a batch parent (make the request for all jobs in the batch) - -`LOGS` - request job log information -* `JOB_ID` - string OR -* `JOB_ID_LIST` - array of strings -* `first_line` - int >= 0, ignored if `latest` is `true` -* `num_lines` - int > 0 -* `latest` - boolean, `true` if requesting just the latest logs - -`CANCEL` - cancel a job or list of jobs; responds with `STATUS` -* `JOB_ID` - string OR -* `JOB_ID_LIST` - array of strings - -`RETRY` - retry a job or list of jobs, responds with `RETRY` -* `JOB_ID` - string OR -* `JOB_ID_LIST` - array of strings - -## Messages sent from the kernel to the browser -These are all caught by the `JobCommChannel` on the browser side, then parsed and sent as the bus messages described above. Like other kernel messages, they have a `msg_type` field, and a `content` field containing data meant for the frontend to use. They have a rough structure like this: - -```json +```js { "data": { "msg_type": "some_message", @@ -277,134 +174,66 @@ These are all caught by the `JobCommChannel` on the browser side, then parsed an } } ``` +Although the backend message types are included in the controlled vocabulary, the content keys are not, as there are too many to make it worthwhile capturing them. -For example: -```json -{ - "msg_id": "some_string", - "data": { - "msg_type": "job_status", - "content": { - "example_job_id": { - "jobState": { - "job_id": "example_job_id", - "status": "running", - ... other state keys ... - }, - "outputWidgetInfo": {} - } - } - } -} -``` +The full set of messages sent by the backend are described below. The name (`msg_type`) is given, followed by the keys given in the `content` block. -These are described below. The name (`msg_type`) is given, followed by the keys given in the `content` block. +The backend bundles together multiple messages of the same type in an object indexed by key (usually job or cell ID). In nearly all cases, the frontend then separates out the data and sends it out on individual channels for each job, batch job, or cell. The exception to this is `ERROR` messages; if the error contains data pertaining to the original request, the request parameters (`JOB_ID`, `BATCH_ID`, etc.) can be used to route the message to specific frontend components. Otherwise, the JobCommChannel emits the message in the browser console to assist in debugging. -By design, these should only be seen by the `JobCommChannel` instance, then sent into bus messages that get sent on specific channels. That information is also given in each block. +### `ERROR` -The backend bundles together multiple messages of the same type in an object indexed by key (usually job or cell ID). In nearly all cases, the frontend then separates out the data and sends it out on individual channels for each job or cell. +A general job comm error message, capturing exceptions that get thrown by the kernel. The frontend uses the `request` data to distribute error messages on the appropriate job or cell channels. -### `ERROR` -A general job comm error, capturing most errors that get thrown by the kernel +Error messages contain the following information: + * `name` - the exception type name + * `message` - the exception message + * `source` - what triggered the error; this may be the request type, or a string or null in the case of errors from the backend job lookup loop. Note that the lookup loop is to be deprecated. + * `request` - the frontend request that triggered that error, or a string or null in the case of errors from the backend job lookup loop. -**content** (this varies, but usually includes the below) - * `raw_request` - the original request message that wound up in an error - * `source` - request type or method that triggered the error -Error messages usually also contain data about the error itself: - * `name` - the error type - * `message` - description of the issue -**bus** `ERROR` +### `INFO` (response) -### `INFO` -Includes information about the running job +Includes information about the running job. The frontend splits out messages and distributes them by job or batch ID. -**content** -Dictionary with key(s) job ID and value dictionaries with the following structure: +Job metadata, keyed by job ID, with the following structure: * `app_id` - string, the app id (format = `module_name/app_name`) * `app_name` - string, the human-readable app name * `job_id` - string, the job id - * `job_params` - the unstructured set of parameters sent to the execution engine + * `job_params` - array of job parameters sent to the execution engine * `batch_id` - id of batch container job -i.e. -```json -{ - "job_id_1": { - "app_id": ..., - "app_name": ..., - "job_id": "job_id_1", - "job_params": ..., - "batch_id": "some_batch_id", - }, - "job_id_2": { ...contents... } -} -``` - -In case of error, the response has the keys: +In case of error, the response has instead the keys: * `job_id` * `error` - brief message explaining the issue -**bus** -The frontend splits out the job info and distributes it out by job ID. - -### `STATUS` -The current job state. This one is probably most common. - -**content** -Dictionary with key(s) job ID and value dictionaries with the following structure: - * `jobState` - see **Data Structures** below for details (it's big and shouldn't be repeated all over this document). Regarding error states: non-existent jobs have the status `does_not_exist`, and when the job state cannot be retrieved from EE2 the status `ee2_error` is used - * `outputWidgetInfo` - the parameters to send to output widgets, only available for a completed job - Sample response JSON: -```json +```js { "job_id_1": { - "jobState": { - "job_id": "job_id_1", - "status": "running", - ... - }, - "outputWidgetInfo": null, // only available for completed jobs + "app_id": "MyFaveApp/Best_App_in_the_World", + "app_name": "An Overrated App", + "job_id": "job_id_1", + "job_params": [{"param_1": "value_1", "param_2": "value_2"}], + "batch_id": "some_batch_id", }, - "job_id_2": { ...contents... } -} -``` - -In case of error, the response has the keys: - * `job_id` - * `error` - brief message explaining the issue - -**bus** -Job status data is split out into individual jobs by the frontend and distributed. - - -### `STATUS_ALL` -The set of all job states for all running jobs, or at least the set that should be updated (those that are complete and not requested by the front end are not included - if a job is sitting in an error or finished state, it doesn't need ot have its app cell updated) - -**content** - all of the below are included, but the top-level keys are all job id strings, e.g.: -```json -{ - "job_id_1": { ...contents... }, - "job_id_2": { ...contents... } + "error_id_1": { + "job_id": "error_id_1", + "error": "Something went terribly wrong." + } } ``` - * `jobState` - the job state (see the **Data Structures** section below for details - * `outputWidgetInfo` - the parameters to send to output widgets, only available for a completed job -**bus** - see `STATUS` +### `LOGS` (response) -### `LOGS` -Includes log statement information for a given job. +Logs for a job or set of jobs. The frontend distributes these by job or batch ID. See the frontend [`LOGS`](#logs) message for the parameters of an incoming `LOGS` request. -**content** -Dictionary with key(s) job ID and value dictionaries with the following structure: +Job logs, keyed by job ID, with the following structure: * `job_id` - string, the job id - * `latest` - boolean, `true` if this is just the latest set of logs + * `latest` - boolean; if returning a limited number of lines, whether these are the latest lines or not. See [`LOGS`](#logs) for details. * `first` - int, the index of first line included in the set * `max_lines` - int, the total log lines available in the server - * `lines` - list of log line objects, each one has the following keys: + * `lines` - list of log line objects, each with the following structure: * `line` - string, the log line * `is_error` - 0 or 1, if 1 then the line is an "error" as reported by the server @@ -414,114 +243,288 @@ In case of error, the response has the keys: The most common log error encountered is that logs are not found -- this can occur if the job has not yet started running or the job was terminated whilst it was still in the job queue. -**bus** `LOGS` -Log data is split out into individual jobs and sent to `job_id` (see above) +### `RETRY` (response) +Response to a request to retry one or more jobs. If the request was successful, includes the new job state; otherwise, contains an error message. -### `RETRY` -Sent when one or more jobs are retried +Retry data indexed by the ID of the job being retried. For each job retried, the following data is returned: + * `job_id` - string, ID of the job that was retried (the retry parent) + * `job` - object, the job state in the format used by the [`STATUS`](#status-response) + * `retry_id` - string, ID of the new job + * `retry` - string, the job state object of the new job that was launched in the format used by the [`STATUS`](#status-response) + +In case of error, the response has instead the keys: + * `job_id` + * `error` - brief message explaining the issue -**content** -Dictionary with key(s) original job ID and value dictionaries with the following structure: -```json +Sample response JSON: +```js { "job_id_1": { "job_id": "job_id_1", - "job": {"jobState": {"job_id": "job_id_1", "status": status, ...} ...}, + "job": {"jobState": {"job_id": "job_id_1", "status": "error"}, "job_id": "job_id_1", "outputWidgetState": null}, "retry_id": "retry_id_1", - "retry": {"jobState": {"job_id": "retry_id_1", "status": status, ...} ...} + "retry": {"jobState": {"job_id": "retry_id_1", "status": "queued"} "job_id": "retry_id_1", "outputWidgetState": null}, }, "job_id_2": { "job_id": "job_id_2", - "job": {"jobState": {"job_id": "job_id_2", "status": status, ...} ...}, - "error": "..." + "job": {"jobState": {"job_id": "job_id_2", "status": "terminated", "job_id": "job_id_2", "outputWidgetState": null}, + "error": "Cannot retry a batch parent job" // from EE2 }, - ... - job_id_x: { - "job": {"jobState": {"job_id": "job_id_x", "status": "does_not_exist"}}, + "error_id_1": { + "job_id": "error_id_1", "error": "does_not_exist" } } ``` -Where the dict values corresponding to "job" or "retry" are the same data structures as for `job_status` -Outer keys: - * `job_id` - string, ID of the job that was retried (the retry parent) - * `job` - string, the job state object of that job - * `retry_id` - string, ID of the new job - * `retry` - string, the job state object of the new job that was launched - -In case of error, the response has the keys: - * `job_id` - * `error` - brief message explaining the issue - -**bus** `RETRY` - -Retry data is split out into individual jobs and sent to `job_id` - ### `RUN_STATUS` -Sent during the job startup process. There are a few of these containing various startup status, including errors (if they happen). -**content** +Sent during the job startup process. There are two basic message types: one for successful job launch with the ID(s) of the job(s) launched, and the other for errors during job launch. Unlike other message types, `RUN_STATUS` messages are not bundled, so each message is sent unchanged to the relevant cell. + All cases: - * `event` - string, what's the run status - * `event_at` - string, timestamp + * `event` - string; see below for the values + * `event_at` - string, UTC timestamp in the format `YYYY-MM-DD HH:MM:SS.mmmmmmZ` * `cell_id` - the app cell id (used for routing) * `run_id` - the run id of the app (autogenerated by the cell) -(if error) - * `event` - string, "error", - * `event_at` - string, timestamp +Successful job launch, single job: + * `event`: "launched_job" + * `job_id` - if the job was launched successfully + +Successful job launch, batch job: + * `event`: "launched_job_batch" + * `batch_id` - ID of the batch parent job + * `child_job_ids` - IDs of the child jobs + +Error when attempting to launch a job: + * `event`: "error" * `error_message` - string, the error * `error_type` - string, the type of Exception that was raised. * `error_stacktrace` - string, a stacktrace - * `error_code` - int, an error code + * `error_code` - int, an [error code from EE2](https://github.com/kbase/execution_engine2) * `error_source` - string, the "source" of the error (generally "appmanager") -(if ok) - * `job_id` - if the job was launched successfully -**bus** `RUN_STATUS` sent unchanged to `cell_id` +### `STATUS` (response) +The current job state. The frontend splits out messages and distributes them by job or batch ID. + +Bundled job status information for one or more jobs, keyed by job ID, with the following structure: + * `job_id` + * `jobState` - see [Job output state](#job-output-state) below for the detailed structure + * `outputWidgetInfo` - the parameters to send to output widgets, generated from the app specifications and job output. This is only available for completed jobs and is set to null otherwise. + +In case of error, the response has instead the keys: + * `job_id` + * `error` - brief message explaining the issue + +Sample response JSON: +```js +{ + "job_id_1": { + "job_id": "job_id_1", + "jobState": { + "job_id": "job_id_1", + "status": "running", + "created": 123456789, + }, + "outputWidgetInfo": null, // only available for completed jobs + }, + "job_id_2": { + "job_id": "job_id_2", + "error": "Cannot find job with ID job_id_2" + }, +} +``` + +#### Job output state + +As sent to browser, includes cell info and run info. The structure below indicates the type of data in each field. + +```js +{ + "job_id": string, + "outputWidgetInfo": object if job completed successfully; otherwise null + "jobState": { + "job_id": string, + "status": string, + "batch_id": str or null, + "batch_job": bool, + "child_jobs": array of job IDs, + "retry_ids": array of job IDs, + "retry_parent": str, + "created": epoch ms, + "queued": optional - epoch ms, + "finished": optional - epoch ms, + "updated": epoch ms, + "terminated_code": optional - int, + "error": { // optional + "code": int, + "name": string, + "message": string, (should be for the user to read), + "error": string, (likely a stacktrace) + }, + "run_id": string, + "cell_id": string, + "tag": string (release, beta, dev), + "error_code": optional - int, + "errormsg": optional - string, + } +} +``` + + +### `STATUS_ALL` + +The set of all job states for all running jobs, or at least the set that should be updated (those that are complete and not requested by the front end are not included - if a job is sitting in an error or finished state, it doesn't need to be updated). + +As [`STATUS`](#status-response) + + +## Usage Examples + +The comm channel is used through the main Bus object that's instantiated through the global `Runtime` object. That needs to be included in the `define` statement for all JavaScript modules. The bus is then used with its `emit` function (you have the bus *emit* a message to its listeners), and any inputs are passed along with it. + +Generally, this is used as follows (without much detail. For a readable real example, check out the `jobLogViewer.js` module): + +```Javascript +define( + ['common/runtime', ... other modules ...], + function(Runtime, ...others...) { + let runtime = Runtime.make(); + runtime.bus().emit('some-request', { + param: 'value' + }); + } +); +``` + +Some more specific examples: +```Javascript +define( + ['common/runtime', 'common/jobCommMessages'], + function(Runtime, jcm) { + const runtime = Runtime.make(); + + // request the first 10 job log lines: + runtime.bus().emit(jcm.MESSAGE_TYPE.LOGS, { + [jcm.PARAM.JOB_ID]: 'some_job_id', + [jcm.PARAM.FIRST_LINE]: 0, + [jcm.PARAM.NUM_LINES]: 10 + }); + + // request the status of all jobs in a batch: + runtime.bus().emit(jcm.MESSAGE_TYPE.STATUS, { + [jcm.PARAM.BATCH_ID]: 'some_batch_id', + }); + } +); +``` + +The front end response handling is done through the Runtime bus. The bus provides both an `on` and a `listen` function; examples will show how to use both. Generally, the `listen` function is more specific and binds the listener to a specific bus channel. These channels can invoke the jobId, or the cellId, to make sure that only information about specific jobs is listened for. + +The `listen` function takes an object with three attributes as input - a channel (either the cellId or jobId), a key (with the type of message to listen for), and a handle, which is a function to process the message. This is probably the easiest way to handle messages. Usage would look like this: + +```Javascript +define( + ['common/runtime', 'common/jobCommMessages'], + function(Runtime, jcm) { + const runtime = Runtime.make(); + + const listener = runtime.bus().listen({ + channel: { + [jcm.CHANNEL.JOB]: 'some_job_id' + }, + key: { + type: jcm.MESSAGE_TYPE.STATUS, + }, + handle: (message) => { + // process the message... + } + }) + } +); +``` + +The `on` function requires a constructed channel bus, premade and reusable for a given channel. So you would make a channel bus that would always receive messages for that channel, and instruct it on what to do when a message of a given type arrives. That looks like this: + +```Javascript +define( + ['common/runtime', 'common/jobCommMessages'], + function(Runtime, jcm) { + const runtime = Runtime.make(); + +const cellBus = runtime.bus().makeChannelBus({ + name: { + cell: 'some_cell_id' + } + }); + const listenerId = cellBus.on(jcm.MESSAGE_TYPE.RUN_STATUS, (message) => { + // process the message... + }); + } +); +``` + +Note that both of these create events that get bound to the DOM, and when the widget is removed, they should be cleaned up. This can be done by calling `bus.removeListener(id)` with the created `listenerId`. If you created a channel bus, then that bus should be used, otherwise the main `runtime.bus()` object should be used. + + +## Job Management flow + +### JobManager initialization and startup -## Job Management flow on backend (in IPython kernel, biokbase.narrative.jobs package) -These steps define the process of creating a new app running job. -1. User clicks "Run" on App Cell in browser. - * Cell provides app_id, cell_id, run_id, and parameters. - * Invokes biokbase.narrative.appmanager.AppManager.run_app. -2. `AppManager.run_app` validates the following bits of information before passing them on to EE2: - * App (based on id, version, and spec). - * Parameters (based on the app spec). -3. `AppManager.run_app` preparation and start: - * Convert app params from user-readable to machine-understandable (via the spec input_mapping). - * Fetch cell id, run id, workspace id, user token. - * Create an agent token on behalf of the user. This effectively makes a new authentication token that has a two-week lifetime, separate from the current login token. For example, if the user's current login token has a remaining lifespan of 1 hour, then the new job will be able to continue long past that. - * Submit all of the above to `NarrativeJobService.run_job`. -4. Get response from `NarrativeJobService.run_job` - * Combine with info from step 3, create `biokbase.narrative.jobs.job.Job` object. - * submit new `Job` to `biokbase.narrative.jobs.jobmanager.JobManager` singleton object. -5. `AppManager` tells the `JobComm` channel to (1) fetch the new job status and push it to the browser, and (2) start the job lookup loop for the newly created job. (calls `AppManager.register_new_job`) - -## JobManager initialization and startup. These steps take place whenever the user loads a narrative, or when the kernel is restarted. This ensures that the JobManager in the kernel is kept up-to-date on Job status. -1. User starts kernel (opens a Narrative, or clicks Kernel -> Restart) -2. `jobCommChannel.js` (front end widget) executes the following kernel call: + +* User starts kernel (opens a Narrative, or clicks Kernel -> Restart) +* `jobCommChannel.js` (front end widget) gets the IDs of the cells in the current narrative and then executes the following kernel call, using the gathered cell IDs as the `cell_list` parameter: ```py JobManager().initialize_jobs() -JobComm().start_update_loop +JobComm().start_job_status_loop(cell_list=cell_list, init_jobs=True) ``` -3. `JobManager` does: - * Get current user and workspace id. - * `ExecutionEngine2.check_workspace_jobs` with the workspace id - gets the set of jobs in that workspace, and builds them into `Job` objects. -4. `JobComm` does: +* The `JobManager` runs `check_workspace_jobs` on EE2 with the current workspace ID to fetch the list of jobs associated with the workspace. This is filtered to include only those in `cell_list`, and then `Job` objects are built from the data. +* The `JobComm`: * Starts the lookup loop thread. * On the first pass, this looks up status of all jobs and pushes them forward to the browser. * If any jobs are in a terminal state, they'll stopped being looked up automatically. If all jobs are terminated, then the loop thread itself stops. -## JobComm status lookup loop. -1. Calls `JobComm._lookup_job_status_loop`, which in turn calls `JobComm.lookup_all_job_states`. This gets forwarded to `JobManager.lookup_all_job_states`, and the results pushed to the browser as a comm channel message. -2. Internal to `JobManager.lookup_all_job_states`, the following steps happen: + +### Running an app + +These steps define the process by which jobs are created by running an app. + +* User clicks "Run" on app or batch cell in the browser. + * Cell provides app_id, cell_id, run_id, and parameters. + * Invokes `biokbase.narrative.appmanager.AppManager.run_app` or `run_app_batch`. +* `AppManager.run_app` validates the following bits of information before passing them on to EE2: + * App specifications (validated against the [Narrative Method Store](https://github.com/kbase/narrative_method_store)) + * Parameters (based on the app spec). +* `AppManager.run_app` preparation and start: + * Convert app params from user-readable to machine-understandable (via the spec input_mapping). + * Fetch cell id, run id, workspace id, user token. + * Create an agent token on behalf of the user. This effectively makes a new authentication token with a limited lifetime, separate from the current login token. Having a separate auth token for the job allows it to continue executing even if the user's current login token expires. + * Submit all of the above to the Execution Engine (EE2) endpoint `run_job` or `run_job_batch`. +* Get response from EE2 +* Send a `RUN_STATUS` message to the browser, giving the results of the job submission; this will either contain a job ID or list of job IDs, if the submission was successful, or an error if not. +* Assuming the submission was successful, the job IDs are combined with info from the job submission to create `biokbase.narrative.jobs.job.Job` objects, and stored in the `biokbase.narrative.jobs.jobmanager.JobManager` singleton object. +* On the frontend, the cell receiving the `RUN_STATUS` message will send `STATUS` requests to the backend periodically (configurable; set in the JavaScript `JobManager` module) to track the progress of the job. Other message types (`LOGS`, `CANCEL`, `RETRY`, etc.) are sent as needed. + * Batch cells have an update mechanism that triggers a `STATUS` request a short period after receiving the last update from the backend. + * App cells also use the [job lookup loop](#jobcomm-status-lookup-loop----to-be-deprecated), backend code that sends periodic job updates, to keep up to date with job status. + + +### App initialisation on reload + +These steps are taken when an app with a running (or previously-run) job starts up. +* Job ID(s) are retrieved from the app meta data +* If the job was not in a terminal state when it was saved, the app requests `STATUS` from the backend. For batch jobs, if jobs were retried but the narrative was not saved afterwards, the job retry data will be sent in the status update. +* Job request and response flow follows the pattern above. + + +#### JobComm status lookup loop -- TO BE DEPRECATED + +* Calls `JobComm._lookup_job_status_loop`, which in turn calls `JobComm.lookup_all_job_states`. This gets forwarded to `JobManager.lookup_all_job_states`, and the results pushed to the browser as a comm channel message. +* Internal to `JobManager.lookup_all_job_states`, the following steps happen: * Build a list of job ids to lookup - those that are flagged for lookup. * Call `_construct_job_status_set` * Call `_get_all_job_states` @@ -530,108 +533,6 @@ JobComm().start_update_loop * Calls `NarrativeJobService.check_jobs` on everything that's not finalized. * Injects `run_id` and `cell_id` into states * Returns dict of states. -3. Sends result to browser over comm channel -4. Since this runs in the background on the kernel-side, it removes any need for the browser to constantly poll. - -## Data Structures -### Job state -#### EE2 State -In kernel, as retrieved from EE2.check_job -(described by example) -```json -{ - "user": "wjriehl", - "authstrat": "kbaseworkspace", - "wsid": 46214, - "status": "queued", - "updated": 1583863267977, - "queued": 1583863267977, - "scheduler_type": "condor", - "scheduler_id": "14221", - "job_input": { - "wsid": 46214, - "method": "simpleapp.simple_add", - "params": [ - { - "workspace_name": "wjriehl:narrative_1580237536246", - "base_number": 5 - } - ], - "service_ver": "f5a7586776c31b05ae3cc6923c2d46c25990d20a", - "app_id": "simpleapp/example_method", - "source_ws_objects": [], - "parent_job_id": "None", - "requirements": { - "clientgroup": "njs", - "cpu": 4, - "memory": 23000, - "disk": 100 - }, - "narrative_cell_info": { - "run_id": "d7558838-a712-42d3-9511-c4b95f3651fe", - "token_id": "e80f4f81-b7bb-4483-a92b-b1e0200f8a20", - "tag": "beta", - "cell_id": "c04c19bd-20ce-41be-b793-50f84de8f60b" - } - }, - "job_id": "5e67d5e395d1f00a7cf4ea21", - "created": 1583863267000, - "batch_id": null, - "batch_job": false, - "child_jobs": [], - "retry_ids": [], - "retry_parent": null -} -``` -#### BE Output State -As sent to browser, includes cell info and run info -``` -{ - outputWidgetInfo: (if not finished, None, else...) job.get_viewer_params result - jobState: { - job_id: string, - status: string, - created: epoch ms, - updated: epoch ms, - queued: optional - epoch ms, - finished: optional - epoch ms, - terminated_code: optional - int, - tag: string (release, beta, dev), - parent_job_id: optional - string or null, - run_id: string, - cell_id: string, - errormsg: optional - string, - error (optional): { - code: int, - name: string, - message: string (should be for the user to read), - error: string, (likely a stacktrace) - }, - error_code: optional - int - created: 1583863267000, - batch_id: str, - batch_job: bool, - child_jobs: array, - retry_ids: array, - retry_parent: str - } -} -``` +* Sends result to browser over comm channel -When an error occurs while preparing the job state, the output states will have the formats -```json -{ - "job_id_0": { - "jobState": {"job_id": "job_id_0", "status": "does_not_exist"} - }, - "job_id_1": { - "jobState": { - "job_id": "job_id_1", - "status": "ee2_error", - "updated": 1234567890, // the current epoch time - ... // cached job data - } - }, - ... -} -``` +Since this runs in the background on the kernel-side, it removes any need for the browser to constantly poll. diff --git a/kbase-extension/scss/partials/_appInput.scss b/kbase-extension/scss/partials/_appInput.scss index 85b547fe71..1eddd06994 100644 --- a/kbase-extension/scss/partials/_appInput.scss +++ b/kbase-extension/scss/partials/_appInput.scss @@ -38,4 +38,57 @@ } } } + + // .kb-appInput__dynDropdown + &__dynDropdown { + // .kb-appInput__dynDropdown_display + &_display { + display: block; + + &__filepath { + word-wrap: break-word; + } + + &__indent { + margin-left: 0.1rem; + } + } + } + + // .kb-appInput__sequence + &__sequence { + // .kb-appInput__sequence__button_container + &__button_container { + padding: 0; + height: 100%; + } + + // .kb-appInput__sequence__row + &__row { + width: 100%; + padding: 2px; + } + + // .kb-appInput__sequence__empty + &__empty { + font-style: italic; + color: use-color('grey'); + } + } + + // .kb-appInput__struct + &__struct { + // .kb-appInput__struct__field + &__field { + border: 0; + padding: 0; + } + + // .kb-appInput__struct__subcontrols + &__subcontrols { + border-left: 5px solid silver; + padding: 2px; + margin: 6px + } + } } diff --git a/kbase-extension/scss/partials/_bulkImportCell.scss b/kbase-extension/scss/partials/_bulkImportCell.scss index 0f4e7ee41f..0cffdee042 100644 --- a/kbase-extension/scss/partials/_bulkImportCell.scss +++ b/kbase-extension/scss/partials/_bulkImportCell.scss @@ -56,6 +56,17 @@ $panel-separator-color: use_color('mid-blue'); display: flex; } + // kb-bulk-import-configure__button--generate-template + &__button--generate-template { + @extend %kbase-button; + + @include button-variant(use_color('primary'), use-color('primary-lightest'), transparent); + + position: absolute; + right: 15px; // panel-body padding + margin: 1rem 0; + } + // kb-bulk-import-configure__message &__message { padding: 0.5rem; @@ -63,9 +74,7 @@ $panel-separator-color: use_color('mid-blue'); color: use-color('ink'); // kb-bulk-import-configure__message_container - &_container { - - } + &_container {} // kb-bulk-import-configure__message--error &--error { @@ -121,8 +130,26 @@ $panel-separator-color: use_color('mid-blue'); } // kb-field-cell__input_control - &__input_control select { - margin-left: 0; + &__input_control { + + // kb-field-cell__input_control select + & select { + margin-left: 0; + } + + // kb-field-cell__input_control select2-selection--single + & .select2-selection--single { + border-radius: 2px; + height: inherit; + + & .select2-selection__rendered { + line-height: 30px; + } + } + + & .select2-dropdown { + border-radius: 2px; + } } // kb-field-cell__cell_label diff --git a/kbase-extension/scss/partials/_filePath.scss b/kbase-extension/scss/partials/_filePath.scss index 571f218360..62024e5ed4 100644 --- a/kbase-extension/scss/partials/_filePath.scss +++ b/kbase-extension/scss/partials/_filePath.scss @@ -73,5 +73,6 @@ &__params { margin-left: 0.5rem; + width: 100%; } } diff --git a/kbase-extension/scss/partials/_infoTab.scss b/kbase-extension/scss/partials/_infoTab.scss index 643fd8dd78..ce90388069 100644 --- a/kbase-extension/scss/partials/_infoTab.scss +++ b/kbase-extension/scss/partials/_infoTab.scss @@ -30,13 +30,25 @@ &__link--docs { @include base-text-with-margins; } + // .kb-info-tab__list--params + &__list--params { + padding-left: 2rem; + } // .kb-info-tab__list_title--params &__list_title--params { @include font-h5; margin: 1rem 0; } -} + // .kb-info-tab__param--id + &__param--id { + @include fixed-width; + padding: .25rem 0.5rem; + white-space: nowrap; + border-radius: .25rem; + background-color: use-color("info-light"); -ul.kb-info-tab__list--params { - padding-left: 2rem; + + .kb-info-tab__param--ui-name { + margin-left: 0.5rem; + } + } } diff --git a/kbase-extension/static/buildTools/loadAppWidgets.js b/kbase-extension/static/buildTools/loadAppWidgets.js index 1a6cfa16cd..b2077ffa56 100644 --- a/kbase-extension/static/buildTools/loadAppWidgets.js +++ b/kbase-extension/static/buildTools/loadAppWidgets.js @@ -5,7 +5,6 @@ define([ 'widgets/appWidgets2/fieldWidgetCompact', 'widgets/appWidgets2/fieldWidgetMicro', 'widgets/appWidgets2/inputUtils', - 'widgets/appWidgets2/parameterSpec', 'widgets/appWidgets2/paramResolver', 'widgets/appWidgets2/validation', 'widgets/appWidgets2/display/multiIntDisplay', @@ -40,11 +39,9 @@ define([ 'widgets/appWidgets2/subdataMethods/manager', 'widgets/appWidgets2/subdataMethods/sampleProperty', 'widgets/appWidgets2/subdataMethods/samplePropertyHistogram', - 'widgets/appWidgets2/validators/customSubdata', 'widgets/appWidgets2/validators/resolver', 'widgets/appWidgets2/validators/sequence', 'widgets/appWidgets2/validators/struct', - 'widgets/appWidgets2/validators/subdata', 'widgets/appWidgets2/validators/workspaceObjectName', 'widgets/appWidgets2/validators/workspaceObjectRef', 'widgets/appWidgets2/view/autocompleteView', diff --git a/kbase-extension/static/kbase/config/job_config.json b/kbase-extension/static/kbase/config/job_config.json index bc8f7b4d74..2274aea9e4 100644 --- a/kbase-extension/static/kbase/config/job_config.json +++ b/kbase-extension/static/kbase/config/job_config.json @@ -4,7 +4,11 @@ "CELL_ID": "cell_id", "CELL_ID_LIST": "cell_id_list", "JOB_ID": "job_id", - "JOB_ID_LIST": "job_id_list" + "JOB_ID_LIST": "job_id_list", + "FIRST_LINE": "first_line", + "LATEST": "latest", + "NUM_LINES": "num_lines", + "TS": "ts" }, "message_types": { "CANCEL": "cancel_job", diff --git a/kbase-extension/static/kbase/config/staging_upload.json b/kbase-extension/static/kbase/config/staging_upload.json index b4bcef6fa8..354a633f17 100644 --- a/kbase-extension/static/kbase/config/staging_upload.json +++ b/kbase-extension/static/kbase/config/staging_upload.json @@ -48,6 +48,10 @@ "id": "sample_set", "name": "Sample Set" }, + { + "id": "import_specification", + "name": "Import Specification" + }, { "id": "decompress", "name": "Decompress/Unpack" @@ -65,6 +69,7 @@ "web_upload": { "app_id": "kb_uploadmethods/upload_web_file" }, + "import_specification": { }, "test_fastq_reads": { "app_id": "NarrativeTest/example_reads_upload", "app_input_param": "fastq_fwd_staging_file_name", diff --git a/kbase-extension/static/kbase/css/all_concat.css b/kbase-extension/static/kbase/css/all_concat.css index 0e532ab7e5..52ebfc4991 100644 --- a/kbase-extension/static/kbase/css/all_concat.css +++ b/kbase-extension/static/kbase/css/all_concat.css @@ -1 +1 @@ -@charset "UTF-8";@font-face{font-family:Glyphicons Halflings;src:url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot);src:url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2) format("woff2"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff) format("woff"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf) format("truetype"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg")}@font-face{font-family:kbase-icons;font-style:normal;font-weight:400;src:url(../fonts/kbase-icons.eot);src:url(../fonts/kbase-icons.eot?#iefix) format("embedded-opentype"),url(../fonts/kbase-icons.woff) format("woff"),url(../fonts/kbase-icons.ttf) format("truetype"),url(../fonts/kbase-icons.svg#kbase-icons) format("svg")}@font-face{font-family:Oxygen;font-style:normal;font-weight:400;src:url(../fonts/Oxygen-webfont.eot);src:url(../fonts/Oxygen-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-webfont.woff) format("woff"),url(../fonts/Oxygen-webfont.ttf) format("truetype"),url(../fonts/Oxygen-webfont.svg#OxygenRegular) format("svg")}@font-face{font-family:Oxygen;font-style:normal;font-weight:700;src:url(../fonts/Oxygen-Bold-webfont.eot);src:url(../fonts/Oxygen-Bold-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-Bold-webfont.woff) format("woff"),url(../fonts/Oxygen-Bold-webfont.ttf) format("truetype"),url(../fonts/Oxygen-Bold-webfont.svg#OxygenBold) format("svg")}@font-face{font-family:Oxygen;font-style:italic;font-weight:400;src:url(../fonts/Oxygen-Italic-webfont.eot);src:url(../fonts/Oxygen-Italic-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-Italic-webfont.woff) format("woff"),url(../fonts/Oxygen-Italic-webfont.ttf) format("truetype"),url(../fonts/Oxygen-Italic-webfont.svg#OxygenItalic) format("svg")}@font-face{font-family:Oxygen;font-style:italic;font-weight:700;src:url(../fonts/Oxygen-BoldItalic-webfont.eot);src:url(../fonts/Oxygen-BoldItalic-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-BoldItalic-webfont.woff) format("woff"),url(../fonts/Oxygen-BoldItalic-webfont.ttf) format("truetype"),url(../fonts/Oxygen-BoldItalic-webfont.svg#OxygenBoldItalic) format("svg")}@font-face{font-family:OxygenMono;font-style:normal;font-weight:400;src:url(../fonts/OxygenMono-Regular-webfont.eot);src:url(../fonts/OxygenMono-Regular-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/OxygenMono-Regular-webfont.woff) format("woff"),url(../fonts/OxygenMono-Regular-webfont.ttf) format("truetype"),url(../fonts/OxygenMono-Regular-webfont.svg#OxygenMonoRegular) format("svg")}@font-face{font-family:OxygenRegular;font-style:normal;font-weight:400;src:url(../fonts/Oxygen-webfont.eot);src:url(../fonts/Oxygen-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-webfont.woff) format("woff"),url(../fonts/Oxygen-webfont.ttf) format("truetype"),url(../fonts/Oxygen-webfont.svg#OxygenRegular) format("svg")}@font-face{font-family:OxygenBold;font-style:normal;font-weight:400;src:url(../fonts/Oxygen-Bold-webfont.eot);src:url(../fonts/Oxygen-Bold-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-Bold-webfont.woff) format("woff"),url(../fonts/Oxygen-Bold-webfont.ttf) format("truetype"),url(../fonts/Oxygen-Bold-webfont.svg#OxygenBold) format("svg")}@font-face{font-family:RobotoBlack;font-style:normal;font-weight:400;src:url(../fonts/Roboto-Black-webfont.eot);src:url(../fonts/Roboto-Black-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Roboto-Black-webfont.woff) format("woff"),url(../fonts/Roboto-Black-webfont.ttf) format("truetype"),url(../fonts/Roboto-Black-webfont.svg#RobotoBlack) format("svg")}#ipython-main-app{position:relative}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#337ab7;color:#fff}.select2-container--default .select2-results__option--highlighted[aria-selected] span{color:#fff!important}#site{overflow:visible}#notebook>.end_space{height:0;min-height:0}@media (min-width:1200px){#notebook-container{width:auto}}@media (min-width:992px){#notebook-container{width:auto}}@media (min-width:768px){#notebook-container{width:auto}}.celltoolbar{background:none;border:0;border-left:1px solid transparent;height:auto;padding-bottom:2px;padding-top:0}div.input_area{border:1px solid #cecece;border-radius:0;padding-top:4px}div.output_subarea{max-width:inherit}div.text_cell_input{border:1px solid #cecece;border-radius:0}div.cell{border:1px solid #ded5cb;border-left-width:5px;border-radius:0;margin:8px 0;padding:0}div.cell.selected{background:none;border:1px solid #4bb856;border-left-width:5px;box-shadow:0 1px 2px #aaa,0 5px 5px #aaa;margin-left:0;padding-left:0;transition:box-shadow .2s ease-in-out}div.cell.selected:before{background:none}div.cell.selected.kb-error{border:1px solid #d9534f;border-left-width:5px}div.cell.opened{padding-top:0}div#notebook{padding:0}.edit_mode div.cell.selected{background:none;border-left:5px solid #66bb6a;padding-left:0}#notebook_name{color:#006698}#notebook_name:hover{background-color:#e0e0e0;cursor:pointer}#notebook-container{bottom:0;box-shadow:none;left:380px;min-width:460px;overflow:auto;position:fixed;right:0;top:70px;width:auto}#notebook-container:after{content:"";display:block;height:100px}.btn-toolbar{margin-left:0;padding-left:0}.kb-narr-side-panel .btn-group .btn{font-size:16px;padding:3px 4px}.btn-subtle{color:#888;margin:0}.btn-subtle .fa,.btn-subtle .fa:before{color:#888}.notebook_app{background-color:#fff;overflow-y:hidden}.notebook_app .btn.active{box-shadow:none}.notebook_app .inner_cell{overflow:visible}.notebook_app .celltoolbar>.button_container{flex:0 auto}.notebook_app .celltoolbar>.button_container:first-child{flex:auto}.notebook_app .celltoolbar_container{border-bottom:1px solid silver}.notebook_app .prompt{color:silver;padding-top:0;width:75px}.notebook_app .cell.selected div.text_cell_render,.notebook_app .cell.unselected div.text_cell_render{border:1px solid transparent}.notebook_app .buttons .dropdown-menu{height:auto!important;overflow:visible!important}.notebook_app .btn.disabled .fa{color:silver}.text_cell.kb-cell .rendered_html table{border:1px solid #ddd}.text_cell.kb-cell .rendered_html ul{margin:0}.text_cell.opened.rendered.kb-cell .rendered_html{border:0;padding:0}.text_cell.opened.rendered.selected.kb-cell .rendered_html{border-left:1px solid #4bb856}.text_cell.opened.rendered.selected.kb-cell.kb-error .rendered_html{border-left:1px solid #d9534f}.text_cell.opened.rendered.kb-cell{padding-bottom:0}.rendered_html td,.rendered_html th,.rendered_html tr{text-align:inherit}.rendered_html table{table-layout:inherit}.cell.selected .prompt .method-icon{color:#673ab7}.cell.selected .prompt .app-icon{color:#009688}.cell.selected .prompt .app-output-icon,.cell.selected .prompt .data-viewer-icon,.cell.selected .prompt .markdown-icon,.cell.selected .prompt .method-output-icon{color:#000}.cell.selected .prompt .error-icon{color:red}.cell.selected .btn-default{color:#000}.cell>.inner_cell>.ctb_hideshow{display:block}.cell.unselected .btn-default{color:#ded5cb}.cell.unselected .app-icon,.cell.unselected .method-icon{color:silver}.kb-btn-icon{display:inline-block;padding:4px}.kb-btn-icon .fa{opacity:.5}.kb-btn-icon:hover .fa{opacity:1}p{margin-bottom:1rem}.prompt{display:none!important}div.run_this_cell{display:none;width:0}div.code_cell div.input_prompt{min-width:0}.panel-title{font:normal 700 18px/30px Oxygen,Arial,sans-serif}[data-toggle=collapse]{cursor:pointer}[data-toggle=collapse]:before{color:silver;content:"\f078";display:inline-block;font:normal 400 90%/1 FontAwesome;margin-left:0;margin-right:.2em;text-align:center;vertical-align:baseline;width:1.2em}[data-toggle=collapse].collapsed:before{content:"\f054";margin-left:.1em;margin-right:.1em}[data-toggle=vertical-collapse-after]{cursor:pointer}[data-toggle=vertical-collapse-after]:after{content:" \f0d8";display:inline-block;font:normal 400 130%/1 FontAwesome;text-align:right;vertical-align:baseline;width:1em}.vertical_collapse--open [data-toggle=vertical-collapse-after]:after{content:" \f0d7"}body{background-color:#fff;color:#171412;font:1.4em Oxygen,Arial,sans-serif}h1{color:#232323;font:400 1.75em/2em RobotoBlack,Arial,sans-serif}h1,h2{letter-spacing:0}h2{color:#898989;font:normal 400 1.5em/1.75em RobotoBlack,Arial,sans-serif}h3{font:normal 400 1.15em/1.25em RobotoBlack,Arial,sans-serif;letter-spacing:0}h4{font:italic 400 1.15em/1.25em Oxygen,Arial,sans-serif;letter-spacing:.07em}b,strong{font-family:Oxygen,Arial,sans-serif;font-weight:700}b i,em,em strong,i,i b,strong em{font-family:Oxygen,Arial,sans-serif;font-style:italic}b i,em strong,i b,strong em{font-weight:700}a{color:#037ac0;text-decoration:none}a:hover,a:visited{color:#2a6496}a:hover{text-decoration:underline}code,pre{font-style:normal}.kb-ga-seq,code,pre{font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.kb-ga-seq{word-wrap:break-word;max-height:100px;max-width:300px;overflow-y:auto}.ui-front{z-index:1000}.whiteout-pane{background-color:#fff;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:1001}#kb-narr-name{font:normal 700 18px/1.2 Oxygen,Arial,sans-serif;overflow:hidden;padding-bottom:7px;text-overflow:ellipsis;white-space:nowrap}#kb-narr-name:hover{text-overflow:inherit;white-space:normal}#save_widget{padding:0}#kb-narr-creator,#save_widget{font-family:Oxygen,Arial,sans-serif;font-weight:700}.kb-narr-namestamp{border-left:2px solid #cecece;display:block;flex:2;margin:5px auto 0;min-width:0;padding-left:20px}.kb-narr-namestamp__error_container{font-size:200%;line-height:1.5}.ui-draggable.kb-data-inflight{background-color:#feffd6!important;border:2px solid gray;border-radius:4px;display:block;z-index:1000}.ui-draggable.kb-data-inflight.-over{background-color:#effceb!important;border-color:green}.kb-data-list-drag-target{border:2px dashed orange;border-radius:4px;display:block;height:40px;padding:6px;text-align:center;transition:all .25s ease}.kb-data-list-drag-target.-drag-active{background-color:#feffd6}.kb-data-list-drag-target.-drag-hover{background-color:#effceb;border-color:green;height:90px;transition:all .25s ease}#kb-notify-area{float:left;position:relative}.kb-navbar-buttons{border-right:2px solid #cecece;display:inline-block;margin-right:15px;padding-right:15px}header[role=banner]{background-color:#fff;border-bottom:1px solid #cecece;position:absolute;top:0;width:100%;z-index:999}nav[role=navigation] ul{margin:1.2em 0 .5em;padding-left:0}nav[role=navigation] ul li{display:inline;margin:0 .5em;vertical-align:middle}nav[role=navigation] ul li a{background-color:#5c9531;border:1px solid #5c9531;border-radius:8px;box-shadow:inset 0 3px 8px rgba(0,0,0,.125);color:#fff;font:normal 700 1.2em Oxygen,Arial,sans-serif;padding:7px 1em;text-decoration:none}input#search_terms{background-image:url(../images/search.png);background-position:100%;background-repeat:no-repeat;background-size:22px;border-color:#5c9531;border-radius:0 4px 4px 0;display:inline;font-size:1em;left:-.5em;margin-top:-3px;padding:.4em 1em;position:relative}span#searchspan{display:inline-block;width:50%}@media screen and (max-width:1170px){span#searchspan{width:50%}}@media screen and (max-width:980px){span#searchspan{width:40%}}@media screen and (max-width:768px){span#searchspan{width:30%}}@media screen and (max-width:590px){span#searchspan{width:60%}}.navbar-kbase{background-color:#fff;border-bottom:5px solid #cecece!important;box-shadow:0 1px 10px rgba(0,0,0,.1);padding:8px}.navbar-kbase a:hover{cursor:pointer}.kb-nav-btn{background-color:#fff;border:0;box-shadow:0 0 3px #cecece;font-size:24px;margin:0 5px 0 0;min-width:50px;padding:1px 7px;text-shadow:none!important}.kb-nav-btn>div{color:#6a6158!important}.kb-nav-btn .kb-nav-btn-txt{font-size:13px;margin-top:-5px}.navbar-right .fa:before{color:#2196f3}.kb-navbar-container{display:flex;justify-content:space-between}#kb-nav-menu{box-shadow:none}.kb-nav-menu__container{display:inline-block}.navbar-right .kb-nav-btn:hover{background-color:#f5f5f5}.kb-nav-btn-upgrade{background-color:#4bb856!important;display:none}.kb-nav-btn-upgrade .fa:before,.kb-nav-btn-upgrade>div{color:#fff!important}.kb-nav-btn-upgrade:hover{background-color:#43a047!important}.kb-nav-btn-upgrade.warning{background-color:#f44336!important}.kb-nav-btn-upgrade.warning:hover{background-color:#dc3c31!important}.kb-nav-menu-icon{display:inline-block;margin-right:5px;text-align:center;vertical-align:middle;width:20px}.kb-nav-menu-icon .fa{font-size:150%}#kb-ipy-menu{border-radius:4px!important;margin-right:0}#signin-button .btn{border:0}.btn-xs .glyphicon-user{padding:14px 5px}.narrative-menu-container{background-color:#fff;border-bottom:1px solid #ababab;margin-left:auto;margin-top:-10px;padding-bottom:30px;padding-top:10px;position:fixed;width:100%;z-index:499}p.clear{clear:both;height:0}body>#header{box-sizing:border-box;display:block}p#site-title{background:url(../images/kbase_logo.png) no-repeat;background-size:46px;float:left;height:46px;margin:5px;text-indent:-9999px;width:46px}#login-info{font-size:1.2em;margin:5px;position:absolute;right:0;top:7px}#login-widget button{margin-left:5px}.search-box{border-collapse:separate;display:inline;margin:-11px 0;padding:10px 1px;position:relative;width:200px}#search-box-name{border:0;border-radius:4px;padding:6px 0}#search-box-name:first-child{border-bottom-right-radius:0;border-right:0;border-top-right-radius:0}#search-box-name:last-child{border-bottom-left-radius:0;border-top-left-radius:0}#search-input{margin:-11px 0}#search-select{margin:-11px 0;width:150px}#search-area{color:#686868;font:normal 400 18px Oxygen,Arial,sans-serif;margin:0 5px;padding:11px;position:relative}#search-area input{padding:11px}#workspace{bottom:42px;overflow:auto;position:fixed;top:173px;width:878px}#bottom-tabs{background-color:#fff;border-top:1px solid #aaa;bottom:0;clear:left;margin:0 auto;position:fixed;width:1170px}#bottom-tabs p a{background-color:#fff;border:1px solid #018841;font-size:14px;padding:14px 20px}#left-column{border-right:5px solid #cecece;bottom:0;position:fixed;top:70px;width:380px}.kb-side-overlay-container{background:#fff;border:1px solid #cecece;max-height:calc(100% - 73px);overflow-y:auto;position:fixed;width:730px;z-index:1030}.kb-side-overlay-header{background-color:#2196f3;color:#fff;font-size:16px;padding:6px;width:100%}.kb-side-overlay-close{color:#fff;cursor:pointer;font-size:13px;font-weight:700}.kb-side-overlay-close:hover{color:orange}.kb-side-panel{height:100%;overflow-y:hidden}#kb-side-toggle-in{background-color:#2196f3;border-bottom:6px solid #cecece;border-right:6px solid #cecece;color:#cce5f3;cursor:pointer;display:none;font-size:16px;font-weight:700;padding:12px 6px;position:fixed;text-align:center;top:70px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:22px;z-index:1}#kb-side-toggle-in:hover{color:#fff}.kb-side-toggle{background-color:#2196f3;border-bottom:6px solid #2196f3;border-top:6px solid #2196f3;color:#cce5f3;cursor:pointer;display:inline-block;font-size:16px;font-weight:700;padding:6px;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kb-side-toggle:hover{color:#fff}.kb-side-header{background-color:#2196f3;border-bottom:6px solid #2196f3;border-top:6px solid #2196f3;color:#cce5f3;cursor:pointer;display:inline-block;font-size:16px;font-weight:700;padding:6px;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kb-side-header.active,.kb-side-header:hover{border-bottom:6px solid #10ce34}.kb-side-header.active{color:#fff;cursor:auto}.kb-overlay-active{background-color:gray;border-bottom:6px solid gray;border-top:6px solid gray}.kb-side-separator{border-bottom:5px solid #cecece}.kb-side-tab{display:none}.kb-side-tab.active{display:inherit}.kb-narr-side-panel-set,.kb-side-tab{height:100%}.kb-narr-side-panel-set:last-child{height:50%}.kb-overlay-dimmer{background-color:#000;bottom:0;opacity:.5;position:fixed;right:0;z-index:10}#data-header{background-color:#099;color:#fff;font-weight:700;padding:10px 0}#data-title{text-align:center}#data-add-btn{font-size:.8em;padding:0;position:absolute;right:7px}#data-add-btn:hover{color:#000}#data-tab-nav{background-color:#0bb;border-bottom:1px solid #aaa;padding-top:10px;width:100%}#data-tab-nav ul{bottom:0;padding-bottom:0;top:50px}#data-tab-nav ul li{background-color:#ddd;border:1px solid #000;display:inline;padding:4px 10px}#data-tab-nav ul li a{color:#000}#data-tab-nav ul li a:hover{color:#a00;text-decoration:none}#data-tab-nav ul li.selected{background-color:#fff}#data-view-panel{border:1px solid #aaa;height:150px;overflow-y:auto;padding:10px}#data-pane{border-bottom:1px solid #aaa;height:69%;margin-top:1px;overflow:auto}#data-pane p{margin:0}#data-pane p span{border:1px solid #fff;color:#fff;display:block;margin:0;padding:2px 10px;text-align:center;width:123px}#data-pane p span.tab1{background:linear-gradient(#6a6158,#bbb);color:#fff;float:right}#data-pane p span.tab2{background:linear-gradient(#ded5cb,#9d9389)}#function-pane{height:30%;margin-top:1px;overflow:auto}.left-pane{font-size:14px;position:relative}#kb-function-panel .kb-function-body{height:100%;max-height:100%}h3.pane-title{background-color:#e0e0e0;border:1px solid silver;font-size:16px;margin:0;padding:3px 5px;position:relative}#add-link{font-size:.8em;position:absolute;right:7px;top:4px}ul.pane-list{margin:0;padding:2px}ul.pane-list li{list-style:none;margin-left:5px;padding:1px}.kb-method-list-logo{background-color:#607d8b;border:0 solid #555;color:#fff;cursor:pointer;display:inline-block;font-size:24px;font-weight:700;height:40px;padding-top:8px;text-align:center;text-shadow:-1px 0 #777,0 1px #777,1px 0 #777,0 -1px #777;width:40px}.kb-method-list-logo:hover{border-width:5px;padding-top:3px}.kb-method-list-more-div{color:#777;font-size:13px;margin:2px;text-align:justify}.kb-method-list-more-div>div:last-child{text-align:right}.kb-method-search-clear{border:1px solid #cecece;border-left:0;cursor:pointer}li.function a{color:#508232;text-decoration:none}li.function a:visited{color:#508232}li.dataset a{text-decoration:none}li.dataset a,li.dataset a:visited{color:#825032}.dialog-box{padding:20px}.dialog-box ul li{border-bottom:1px solid #aaa;font-size:1.2em;padding:50px 5px}.dialog-box ul li:first-child{padding-top:20px}.dialog-box ul li:last-child{border-bottom:0}fieldset{border:0;margin:0 0 15px}fieldset label{font-size:1em;font-weight:700;margin:0 0 3px}fieldset input[type=password],fieldset input[type=text],fieldset select{width:200px}div.dataset-cell,div.function-cell{border:1px solid #ded5cb;margin:3px auto;padding:7px 17px;width:90%}div.texttools p,div.tools p{margin:0}div.textarea{border:0;display:none;height:auto;min-height:1.2em;padding:0;width:650px}div.metadata{display:block;float:left;height:100px;padding:0 10px;width:200px}div.social{display:none;float:right;padding:0 10px;width:80px}img.dataset-cell{margin:3px auto;padding:0}.function-cell{background-image:url(../images/gears.png);background-position:100%;background-repeat:no-repeat}.dataset-cell p,.function-cell p{font-size:.875em}.dataset-cell h2,.function-cell h2{font-size:1.1em;margin-bottom:0}.textcell{border:2px solid #fff;color:#111;font-size:1em;height:1em;margin:3px auto;padding:5px 17px;width:90%}.textcell:hover{border:2px dotted #ded5cb}p.textcuepara{color:#ded5cb;display:none;height:1em;margin:0;padding:0}.texttools{display:none}.texttools img{vertical-align:middle}.tools{display:none;height:1em;margin-left:10px;margin-top:.5em}.tools a{border:1px solid #018841;font-size:13px;padding:2px 4px}#narrative-header .tools{display:block;left:350px;position:relative;top:-2em;width:30em}img.remove{float:right}.ui-state-highlight{background-color:#fbfaed}p span.notification{background-color:#f33;border-radius:1em;color:#fff;padding:4px 8px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{border-radius:0 6px 6px;left:100%;margin-left:-1px;margin-top:-6px;top:0}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu>a:after{border-color:transparent transparent transparent #ded5cb;border-style:solid;border-width:5px 0 5px 5px;content:" ";display:block;float:right;height:0;margin-right:-10px;margin-top:5px;width:0}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{border-radius:6px 0 6px 6px;left:-100%;margin-left:10px}#maintoolbar{background-color:#f9f9f9!important;background-image:none!important;border:0!important;box-shadow:none;min-height:0;position:relative;top:5px}#maintoolbar-container{margin-left:10px}#menubar{background-color:#f9f9f9;border-bottom:2px solid #ddd;padding-bottom:5px;position:absolute;top:3px;width:100%}#menubar .navbar .container{padding-left:0;padding-right:0}.navbar{background-color:#f8f8f8;background-image:none;min-height:0}#menubar .navbar-nav>li>a{padding-bottom:7px;padding-top:10px}.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning,.panel-default>.panel-heading{background-image:none}#menus{padding-left:0}#menubar .navbar{margin-bottom:5px;width:100%}div#notebook_panel{box-shadow:none}.version-stamp a{color:#037ac0!important}.creator-stamp,.version-stamp a{padding-right:320px;text-align:right}.creator-stamp{color:#006698;font:normal 700 120% Oxygen,Arial,sans-serif;height:1em}.panel{margin-bottom:0}#kb-jobs-panel{margin-bottom:5px}.kb-narr-side-panel{height:100%;margin-bottom:5px}.kb-narr-side-panel .kb-title{color:#03517d;font:normal 700 19px Oxygen,Arial,sans-serif;padding:10px 5px;text-transform:uppercase}.kb-narr-side-panel .btn{border:0}.kbujs-table-container{height:auto}.kbujs-timestamp{color:#0066b9;cursor:pointer}.kbujs-error-cell{color:#c7254e;font-weight:700}.kbujs-error:hover{cursor:pointer}.kbujs-loading-modal{font-size:16px;font-weight:700;text-align:center}.kbujs-refresh-btn{position:absolute;right:5px}.kbujs-jobs-table{margin-left:auto!important;margin-right:auto!important}.kbujs-loading{height:100%;text-align:center;vertical-align:middle}.kbujs-delete-job{cursor:pointer}.kbujs-error-traceback{float:left;max-height:250px;max-width:516px;overflow-x:scroll;overflow-y:scroll;white-space:nowrap}.kb-line{background-color:#d3d3d3;position:absolute}.nav-tabs .glyphicon-remove{color:#aaa;margin:0 0 0 3px}.nav-tabs .glyphicon-remove:hover{color:#6a6158;cursor:hand;cursor:pointer}.paging_full_numbers{height:22px;line-height:22px}.paging_full_numbers a:active{outline:none}.paging_full_numbers a:hover{text-decoration:none}.paging_full_numbers a.paginate_active{background-color:#99b3ff}.paging_full_numbers a.paginate_active,.paging_full_numbers a.paginate_button{border:1px solid #aaa;border-radius:5px;color:#333!important;cursor:pointer;margin:0 3px;padding:2px 5px}.paging_full_numbers a.paginate_button{background-color:#ddd}.paging_full_numbers a.paginate_button:hover{background-color:#ded5cb;text-decoration:none!important}.kb-function-header{background-color:#b6e9f8;color:#0064b6;font-weight:700;margin-bottom:3px;padding:10px 0;text-align:center}.kb-narr-panel-body{height:100%;padding:3px}.kb-narr-panel-body>div{height:100%}.kb-narr-panel-body-wrapper{height:100%;overflow-y:auto}.kb-narr-panel-body-wrapper>div{height:100%}.kb-narr-panel-toggle{color:#888;cursor:pointer;margin-right:4px;margin-top:-4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kb-function-body{height:100%;width:100%}.kb-function-body .accordion .panel .panel-body{padding:0 0 0 5px}.kb-function-body ul{border:1px solid #ddd;list-style-type:none;margin:0;padding:0;width:100%}.kb-function-body li{padding:5px;text-align:left;width:100%}.kb-function-body li:nth-child(odd){background-color:#f2efeb;border-bottom:1px solid #ddd}.kb-function-body li:nth-child(2n){background-color:#fff;border-bottom:1px solid #ddd}.kb-function-body li:hover{background-color:#f4f5d6;cursor:pointer;text-decoration:underline}.kb-function-body a,.kb-function-body a:hover{text-decoration:none}.kb-function-error{background-color:#f2dede!important;border-color:#eed3d7!important;color:#b94a48}.kb-function-help{color:#56559e;cursor:pointer;float:right;font-size:19px;padding:0 3px}.kb-function-help:hover{color:#000}.kb-function-help-popup{cursor:pointer;left:300px;max-width:300px;position:absolute;top:0;z-index:99}.kb-function-help-popup h1{color:#3076a2;font-size:110%;margin:-10px 0 0;padding:0}.kb-function-help-popup h2{color:#9d9389;font-size:80%;font-style:italic;font-weight:100;margin:10px 0 -10px;padding-top:5px;text-align:right}.kb-function-help-popup .header{background-color:#fff;color:#3076a2;font-size:120%;font-weight:700;margin:0;padding:0}.kb-function-help-popup a{font-weight:700;text-decoration:underline}.kb-function-help-popup .version{color:#6a6158;font-size:80%}.kb-function-help-popup .body{margin-bottom:10px;margin-top:10px}#kb-function-help{cursor:pointer;left:300px;position:absolute;top:400px;width:250px;z-index:99}#kb-function-help h1{color:#3076a2;font-size:110%;margin:-10px 0 0;padding:0}#kb-function-help h2{color:#9d9389;font-size:80%;font-style:italic;font-weight:100;margin:10px 0 -10px;padding-top:5px;text-align:right}#kb-function-error-traceback{float:left;max-width:250px;overflow-x:scroll;white-space:nowrap}.kb-function-dim,.kb-function-dim .panel-heading{background-color:#f2efeb!important}.kb-function-cat-dim,.kb-function-cat-dim .panel-heading{background-color:#ddd!important;border-color:#ddd!important}.kb-function-toggle{color:#037ac0;cursor:pointer;font-style:italic}.kb-toolbar-open{border-bottom:1px solid #ded5cb;border-radius:0}.selected .kb-toolbar-open{background-color:#dff0d8;border-bottom:1px solid #4bb856;border-left:1px solid #4bb856}.unselected .kb-toolbar-open{background:none}.selected.kb-error .kb-toolbar-open{background-color:#f2dede;border-color:#d9534f}.kb-cell-run{opacity:1;z-index:auto}.kb-cell-run h1{color:#03517d;display:inline;font:normal 400 16px/1 Oxygen,Arial,sans-serif;margin:3px 13px 3px 3px;opacity:inherit}.kb-cell-run div.kb-func-desc{display:block;opacity:inherit}.kb-cell-run h2{color:#6a6158;font:normal 400 15px/1.5 Oxygen,Arial,sans-serif;margin:3px;opacity:inherit}.kb-cell-run form input[type=submit]{float:right;margin-top:5px;opacity:inherit}.kb-cell-run form .buttons{float:right;margin-top:5px}.kb-cell-run.running form{opacity:.6}.kb-cell-params table{border:0;margin-bottom:10px;margin-left:auto;margin-right:auto;opacity:inherit}.kb-cell-params table>tr,td{border:0;vertical-align:middle}.kb-cell-params tbody>tr>td,.kb-cell-params tbody>tr>th,.kb-cell-params tfoot>tr>td,.kb-cell-params tfoot>tr>th,.kb-cell-params thead>tr>td,.kb-cell-params thead>tr>th{padding:2px 4px}.kb-cell-params tr:hover td,.kb-cell-params tr:hover th{background:#f2efeb}.kb-cell-progress{display:none}.kb-cell-progress.running{display:block}.kb-cell-progressbar{height:20px;width:400px}.kb-out-desc{color:#03517d}.kb-err-desc,.kb-out-desc{display:inline;font:normal 400 16px/1 Oxygen,Arial,sans-serif;margin:3px;opacity:inherit}.kb-err-desc{color:#a94442}.kb-err-msg{font-size:80%!important}.kb-out-header{background-color:#ddd;padding:10px}.kb-func-timestamp{color:#555;font:13px Oxygen,Arial,sans-serif;margin-top:-3px;padding-right:1em}.unselected .kb-func-timestamp{color:silver}.kb-func-panel,.kb-func-panel>.panel-heading{border-color:#bce8f1;border-radius:1px}.kb-func-panel>.panel-heading{background-color:#d9edf7;color:#31708f;padding:5px 10px}.kb-func-panel .panel-body{font-family:Oxygen,Arial,sans-serif;padding:0 10px}.kb-func-panel>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.kb-func-panel>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.kb-cell-output .panel{border-radius:0}.kb-cell-output .nav>li>a,.kb-cell-output .panel-heading{padding:5px 10px}.kb-cell-output-content{overflow-x:auto;padding:5px}.rendered_html .kb-cell-output ul{margin:0 0 10px}.rendered_html :link{text-decoration:none}.kb-jobs-title{color:#185a85;font:normal 700 1.2em Oxygen,Arial,sans-serif}.kb-jobs-title .glyphicon-info-sign{font-size:.9em}.kb-jobs-info-table{margin:0 2px;width:95%}.kb-jobs-info-table th{color:#777;font-family:Oxygen,Arial,sans-serif;font-weight:700;max-width:30%;min-width:30%;padding-right:5px;vertical-align:top;width:30%}.kb-jobs-item{border-bottom:2px solid #ddd;margin-bottom:5px;padding-bottom:3px}.kb-jobs-error{background-color:#f2dede}.kb-jobs-error-btn{font-size:13px}.kb-jobs-item:last-child{border-bottom:0}.kb-jobs-error-modal{word-wrap:break-word;max-height:220px;overflow-x:hidden;overflow-y:auto;width:485px}.kb-method-parameter-panel{border-left:3px solid #fff}.kb-method-parameter-panel-hover{border-left:3px solid #428bca}.kb-method-parameter-row{border-radius:5px;margin:0;padding:5px}.kb-method-parameter-row-hover{background:#f9f9f9}.kb-method-parameter-row-error{background:#f2dede}.kb-method-parameter-error-mssg{color:#f44336;font-family:Oxygen,Arial,sans-serif;font-size:12px;font-weight:700;padding:5px;text-align:center}.kb-method-parameter-name{color:#777;font-family:Oxygen,Arial,sans-serif;font-weight:700;margin-top:3px;padding-left:0;padding-right:0;text-align:right;vertical-align:middle;white-space:normal}.kb-method-parameter-input{padding-left:10px;vertical-align:middle;white-space:nowrap}.kb-method-parameter-input input{font-weight:700}.kb-method-parameter-input>div{padding-right:20px}.kb-method-parameter-input .kb-method-parameter-accepted-glyph,.kb-method-parameter-input .kb-method-parameter-required-glyph{font-size:15px;margin-left:-15px}.kb-parameter-data-selection{font-weight:700}.kb-method-parameter-hint{color:#777;margin-top:3px;padding-left:7px;text-align:left}.kb-method-parameter-required-glyph{color:#f44336;margin-left:7px}.kb-method-parameter-accepted-glyph{color:#4bb856;margin-left:7px}.kb-method-parameter-info{margin-left:7px}.kb-method-advanced-options-controller-inactive,.kb-method-parameter-info,.kb-parameter-data-row-add,.kb-parameter-data-row-remove{color:#777}.kb-method-advanced-options-controller,.kb-method-advanced-options-controller-inactive{font:italic 700 13px/14px Oxygen,Arial,sans-serif;text-align:center}.kb-method-advanced-options-controller{color:#037ac0;cursor:pointer}.kb-method-advanced-options-controller:hover{color:#2a6496}.kb-method-footer{background-color:#f5f5f5;padding:10px;width:100%}.kb-method-subtitle{background-color:#f5f5f5;padding:3px 5px}.kb-app-panel{border-radius:0}.kb-app-error{background-color:#f2dede}.kb-app-step-container{margin-top:6px}.kb-app-panel>.panel-footer{border:0;border-radius:0}.kb-app-panel-description{color:#03517d;font:normal 400 16px/1 Oxygen,Arial,sans-serif}.kb-app-step-error-mssg{color:#a63232;font:11px/14px sans-serif;margin:10px;text-align:left}.kb-app-step-error-heading{color:#555;font:normal 700 17px/1 Oxygen,Arial,sans-serif;margin-top:20px;padding-left:5px;text-align:left}.kb-app-step-error-main-heading{color:#555;cursor:pointer;font:21px/1 Oxygen,Arial,sans-serif;margin-top:20px;padding-left:20px;text-align:left}.kb-app-step-error{border:3px solid #d14836;z-index:auto}.kb-app-step-running{border:3px solid #2196f3;z-index:auto}.kb-app-next{border-top:2px solid #cecece}.kb-app-next h3{color:#888;float:left;font:italic 400 .9em Oxygen,Arial,sans-serif;margin:0;padding:.5em 0 .25em}.kb-app-next-hide{float:right;margin-right:.5em}.kb-app-next-hide,.kb-app-next-unhide{color:#2196f3;font:.9em Oxygen,Arial,sans-serif;margin-top:.25em}.kb-app-next div{clear:both}@-webkit-keyframes pulse{0%{opacity:1}50%{opacity:.7}to{opacity:1}}@keyframes pulse{0%{opacity:1}50%{opacity:.7}to{opacity:1}}button.kb-app-run,button.kb-method-run{background-color:#2196f3;border:0;border-radius:1px;box-shadow:1px 1px 1px #ded5cb;color:#fff;font-size:13px;padding:10px 20px}button.kb-app-run:hover,button.kb-method-run:hover{background-color:#1e88e5}button.kb-app-run.kb-app-cancel{background-color:#f44336}button.kb-app-run.kb-app-cancel:hover{background-color:#e53935}.modal-body{max-height:100%}div[class=tooltip-inner]{max-width:400px;text-align:left;white-space:pre-wrap}.notebook_app .tooltip-inner{background-color:#1b69b6}.notebook_app .tooltip{z-index:2000!important}.notebook_app .tooltip.top .tooltip-arrow,.notebook_app .tooltip.top-left .tooltip-arrow,.notebook_app .tooltip.top-right .tooltip-arrow{border-top-color:#1b69b6}.notebook_app .tooltip.right .tooltip-arrow{border-right-color:#1b69b6}.notebook_app .tooltip.left .tooltip-arrow{border-left-color:#1b69b6}.notebook_app .tooltip.bottom .tooltip-arrow,.notebook_app .tooltip.bottom-left .tooltip-arrow,.notebook_app .tooltip.bottom-right .tooltip-arrow{border-bottom-color:#1b69b6}.kb-data-main-panel{height:100%;margin-bottom:5px;max-height:425px}#data-tabs{height:375px!important}.kb-ws-refresh-btn{position:absolute;right:5px}#kb-ws .form-control{margin:3px;width:85%}.kb-data-control{width:95%}.kb-data-table{max-height:265px;width:100%!important}.kb-data-table thead{max-width:100%;width:281px}.kb-data-table tbody tr{border-bottom:1px solid #dcdcdc}.kb-data-table tbody tr td{font-size:1em;max-height:16px;max-width:100px;padding:5px}.kb-data-table tbody tr td.highlighted,.kb-data-table tbody tr:hover{background-color:#f4f5d6;cursor:pointer}.kb-data-obj-name{display:inline-block;max-width:88%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-data-loading{height:100%;text-align:center}.kb-data-loading,.kb-data-loading img{vertical-align:middle}#kb-ws .dataTables_filter{display:none}button.kb-data-obj{float:right}.kb-data-obj-panel{background:linear-gradient(180deg,#00d2ff,#b2adcb);margin:10px;padding:0}.kb-data-obj-panel button.close{font-size:125%;margin:5px}.kb-data-obj-panel-info{background:hsla(0,0%,100%,.5);height:100%;padding:10px}.kb-data-obj-panel-graph{background:transparent;height:100%;padding:10px}.kb-data-obj-panel-graph table{background-color:hsla(0,0%,100%,.9);border:0;color:rgba(0,0,0,.8);width:100%}.kb-data-obj-panel-graph thead tr{background-color:#e6e6e6;color:#000}.kb-data-obj-panel-info dl{margin:0}.kb-data-obj-panel-info dl dt{clear:left;color:rgba(0,0,0,.5);float:left;text-align:right;width:90px}.kb-data-obj-panel-info dl dt:after{content:":"}.kb-data-obj-panel-info dl dd{margin:0 0 0 100px}.kb-data-obj-panel-verlist span{background-color:hsla(0,0%,100%,.5);border-radius:2px;color:rgba(0,0,0,.5);cursor:pointer;margin-left:3px;padding:0 5px}.kb-data-obj-panel-verlist span.selected{background-color:#2196f3;color:#fff;cursor:default}.kb-data-obj-graph-ref-to{margin-top:8px}.kb-primary-btn{background-color:#2196f3;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#fff;font:normal 400 14px Oxygen,Arial,sans-serif;margin:3px;padding:10px 20px}.kb-primary-btn:hover{background-color:#1e88e5}.kb-primary-btn[disabled]{background-color:#cce5f3;box-shadow:none;color:#fff}.kb-default-btn{background-color:#f5f5f5;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#555;font:normal 400 14px Oxygen,Arial,sans-serif;margin:3px;padding:10px 20px}.kb-default-btn:hover{background-color:#cecece}.kb-default-btn[disabled]{box-shadow:none;color:#aaa}.kb-btn-sm{font-size:13px;padding:5px 10px}.narrative-card-logo{display:flex;font-size:14px;margin-right:2px;width:50px}.narrative-card-row-main{align-items:center;display:flex;margin:0 2px;padding:0 4px;width:98%}.narrative-data-list-subcontent{padding-left:10px}.narrative-card-ellipsis{align-items:center;display:flex;justify-content:center;width:20px}.narrative-card-palette-icon{color:#888;left:15px;position:relative;top:-50px}.narrative-card-action-button-wrapper{height:50px;margin:0 10px;width:80px}.narrative-card-action-button{display:flex;height:80%;justify-content:center;padding:10px 0;width:calc(100% - 6px)}.narrative-card-action-button>span{margin-right:5px}.narrative-card-action-button-name{display:inline-block}.narrative-data-panel-btnToolbar{display:flex;justify-content:center}.narrative-data-panel-btnToolbar>span{color:#888}.kb-data-list-obj-row,.narrative-card-row{border-left:5px solid #fff;box-shadow:1px 1px 1px 1px #fff;color:#333;transition:all .1s ease}.kb-function-dim .kb-data-list-obj-row{border-left-color:#f2efeb}.kb-data-list-obj-row:hover,.narrative-card-row:hover{border-left:5px solid #4bb856;box-shadow:1px 1px 1px 1px #aaa}.palette{background:#f5f5f5!important}.kb-data-list-obj-row-selected{border-left:5px solid #4bb856;box-shadow:1px 1px 1px 1px #aaa}.kb-data-list-obj-row-main{margin:0;padding:0;width:100%}.kb-data-list-nav-buttons{border:0;box-shadow:none;font-size:18px;margin:0;padding:5px 8px;text-shadow:none!important}.kb-data-list-add-data-button{background-color:#4379b1;border:0;box-shadow:1px 1px 3px #aaa;text-align:center}#kb-add-code-cell,#kb-add-md-cell,.kb-data-list-add-data-button{border-radius:50%;color:#fff;cursor:pointer;height:40px;width:40px}#kb-add-code-cell,#kb-add-md-cell{background-color:#2196f3;bottom:15px;box-shadow:2px 2px 1px #cecece;opacity:.5;padding-top:5px;position:fixed;z-index:5}#kb-add-code-cell{padding-left:7px;right:75px}#kb-add-md-cell{margin-right:20px;padding-left:8px;right:10px}#kb-add-code-cell:hover,#kb-add-md-cell:hover,.kb-data-list-add-data-button:hover{background-color:#36618e;cursor:pointer;opacity:1}.kb-data-list-add-data-text-button{background-color:#4379b1;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#fff;font:normal 400 14px Oxygen,Arial,sans-serif;margin:3px;padding:10px 20px}.kb-data-list-add-data-text-button:hover{background-color:#36618e}.kb-data-list-btn{background-color:#2196f3;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#fff;font-size:13px;margin:5px;padding:5px 10px}.kb-data-list-btn:hover{background-color:#1e88e5}.kb-data-list-btn[disabled]{background-color:#cce5f3;box-shadow:none;color:#fff}.kb-data-list-cancel-btn{background-color:#f5f5f5;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#888;font-size:13px;margin:5px;padding:5px 10px}.kb-data-list-cancel-btn:hover{background-color:#cecece}.kb-data-list-row-hr{margin:2px auto;width:70%}.kb-data-list-info{border-bottom:1px solid #e0e0e0;min-height:60px;padding:6px 0;width:80%}.kb-data-list-name{color:#03517d;cursor:pointer;font:normal 700 15px Oxygen,Arial,sans-serif;margin:2px}.kb-data-list-name:hover{text-decoration:underline}.kb-data-list-version{color:#777;cursor:default;font-size:12px;font-style:italic;white-space:nowrap}.kb-data-list-date,.kb-data-list-type{color:#777;cursor:default;font-size:13px;margin:2px}.kb-data-list-date{white-space:nowrap}.kb-data-list-edit-by{color:#777;cursor:pointer;font-size:13px;margin:2px 2px 2px 0;white-space:nowrap}.kb-data-list-edit-by:hover{color:#444}.kb-data-list-narinfo{color:#777;font-size:13px;margin:2px 2px 2px 10px}.kb-data-list-narrative-error{color:#f44336;font-size:13px;margin:2px}.kb-data-list-narrative{color:#777;font-size:13px;margin:2px 2px 2px 10px}.kb-data-list-more{color:#777;font-size:11px;margin:0 0 0 15px;padding:0;white-space:nowrap}.kb-data-list-more-btn{border:0;box-shadow:none;font-size:12px;margin:0;padding:2px 4px;text-shadow:none!important}.kb-data-list-more-div{align-items:center;display:flex;flex-direction:column}.kb-data-list-more-div,.kb-data-list-more-div td,.kb-data-list-more-div th,.kb-data-list-more-div tr{color:#777;font-size:13px;margin:2px}.kb-data-list-more-div tr:hover{background-color:#f2efeb}.kb-data-list-more-div tr:nth-child(odd){background-color:#f5f5f5}.kb-data-list-more-div tr:hover:nth-child(odd){background-color:#f2efeb}.kb-data-list-more-div th{font-weight:700;text-align:right}.kb-data-list-more-div td{padding-left:8px;text-align:left;word-break:break-all}.kb-data-list-job-name:hover{text-decoration:none}.kb-data-list-box>.kb-data-list-box{margin-left:40px}.kb-data-list-ctl span.inviso{background-color:#fff;color:#fff;text-shadow:none}.kb-data-list-ctl[enabled]{background-color:#d3d3d3}.kbcb-browser-container{margin:0 auto}.kbcb-back-link{padding:.4em}.kbcb-ctr-toolbar{margin:.4em}.kbcb-main-panel-div{margin:0}.kbcb-loading-panel-div{margin:.1em;text-align:center;vertical-align:middle}.kbcb-app-card-link{text-decoration:none}.kbcb-app-card-list-container{overflow:auto;padding:0 .2em 1em}.kbcb-app-card-container{display:block;float:left;height:110px;margin:.4em;position:relative;width:300px}.kbcb-app-card{background:#f1f1f5;border-radius:2px;color:#6a6158;height:100%;overflow:hidden;text-align:center;vertical-align:middle;width:100%}.kbcb-app-card-header{max-height:90px;overflow:hidden;text-align:left}.kbcb-app-card-title-panel{padding:10px 5px 5px 10px}.kbcb-app-card-title{font-size:1.1em}.kbcb-app-card-authors,.kbcb-app-card-module{font-size:.8em}.kbcb-app-card-subtitle{font-size:.9em;overflow:hidden;padding:10px}.kbcb-app-card-footer{bottom:0;color:#888;font-size:.9em;left:0;margin:0 5px 5px;position:absolute;width:100%}.kbcb-app-card-logo{font-size:14px;margin:0;padding:0}.kbcb-star-default{color:#888}.kbcb-star-favorite{color:orange}.kbcb-star-default,.kbcb-star-favorite,.kbcb-star-nonfavorite{cursor:pointer}.kbcb-star-default:hover,.kbcb-star-nonfavorite:hover{color:red}.kbcb-star-favorite:hover{color:orange}.kbcb-run-count,.kbcb-star-count{display:inline-block;margin-left:.3em}.kbcb-info:hover{color:orange}.kbcb-hover{box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);transition:all .2s ease-in-out}.kbcb-hover:hover{box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23);cursor:pointer}.kbcb-app-page{background:#f1f1f5;border-radius:2px;color:#6a6158;text-align:center}.kbcb-app-page-header{text-align:left}.kbcb-app-page-title-panel{padding:10px 5px 5px 0}.kbcb-app-page-title{font-size:2em}.kbcb-app-page-module{font-size:1.2em}.kbcb-app-page-authors{font-size:1em;margin:.3em 0 0}.kbcb-app-page-subtitle{font-size:1.2em;padding:1.5em 2em 0}.kbcb-app-page-stats-bar{font-size:1.2em;padding:0 2em .8em 3em;width:100%}.kbcb-app-page-logo{margin:1em;padding:0;text-align:center}.kb-share-user-permissions-dropdown{border:0;box-shadow:none;height:auto;padding:2px;text-shadow:none!important;width:auto}.kb-share-select{width:200px}.kb-share-select .select2-selection__choice{background-color:#f5f5f5!important;width:100%!important}.kb-nar-manager-titles{color:#777;font:normal 700 19px Oxygen,Arial,sans-serif;margin:20px 10px 10px}.kb-import-content{display:block;margin:0;position:relative}.kb-import-content .btn-xs{border:0}.ftp-file-header{margin:1rem 0}.globus-link:hover{text-decoration:none}.kb-import-content .upload-options button{background:#fff;border:1px solid silver;border-radius:6px;box-sizing:border-box;color:#000;font:normal 400 14px/18px Oxygen,Arial,sans-serif;height:42px;margin:0 6px;text-align:center;width:140px}.kb-import-content .upload-options button:hover{background-color:#fafafa;border:1px solid #cfcfcf}.kb-import-content .upload-options button:focus{background-color:#f2f2f2}.kb-import-content .upload-options button:active{background-color:#e6e6e6}.kb-import-content .upload-options button:disabled{background-color:#fafafa;color:#929292}.kb-overlay-footer{bottom:0;height:50px;position:absolute;width:100%}.kb-overlay-footer .btn-default,.kb-overlay-footer .btn-primary{margin:15px 15px 0 0}.kb-import-filter,.kb-import-search{margin:10px 40px 10px 10px}.kb-import-item{margin:0 20px 0 5px;padding:20px 0 0}.kb-import-item:hover{background-color:#f8f8f8;box-shadow:0 0 2px #aaa}.kb-import-item hr{border:2px solid #eaeaea;margin-bottom:0;margin-top:15px;width:85%}.kb-import-item .kb-import-checkbox{font-size:1.5em;opacity:.4;padding:15px 20px}.kb-import-item .fa-check-square-o{opacity:1!important}.kb-import-info{display:inline-block;font-weight:400;margin:10px 20px 0 0}.kb-import-info span{color:#9d9389;font-size:.9em;font-weight:700}.kb-import-status{margin:20px}.kb-error-dialog strong{color:#006400}.kb-err-text{color:#000;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.kb-err-warn{color:#b22222;font-style:italic;margin-top:.5em}#kb-ro-btn{margin-right:20px}#kb-view-mode{cursor:pointer;display:inline-block;font-size:17px;margin:-15px 0 0 1em;padding:0}#kb-view-mode-narr div{color:#2196f3;display:inline-block;font:normal 700 16px Oxygen,Arial,sans-serif;margin-top:-3px;padding:3px;position:fixed;text-align:left;width:147px}#kb-view-mode-narr-hide{background-color:#2196f3;color:#cce5f3;cursor:pointer;display:block;float:left;font-size:16px;height:41px;padding-left:5px;width:15px}#kb-view-mode-narr-hide span{margin-top:10px}.navbar-right div.label-warning{font:normal 700 16px Oxygen,Arial,sans-serif}#popdiv{background-color:#fcfcfc;border:1px solid #ded5cb;font-size:12px;position:absolute;visibility:hidden;z-index:10000}#popdiv a.alt{border:0;display:inline;font:12px OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;padding-left:9px}.kb-loading-spinner{padding:1rem;text-align:center}.fa.fa-14-pt{font-size:19px}[data-icon]:before{content:attr(data-icon)}[class*=" icon-"]:before,[class^=icon-]:before,[data-icon]:before{font-family:kbase-icons!important;font-style:normal!important;font-variant:normal!important;font-weight:400!important;text-transform:none!important}.icon-compare:before{content:"a"}.icon-genome:before{content:"b"}.icon-metabolism:before{content:"c"}.icon-metagenome:before{content:"d"}.icon-reads:before{content:"e"}.icon-tree:before{content:"f"}.app-icon:hover{opacity:.9}.app-icon:hover,.nav>li>a:focus,.nav>li>a:hover{text-decoration:none}#kbase-search-box{width:300px}#signin-button{display:inline-block;padding:0 15px 0 0}.wrapper{margin-left:auto;margin-right:auto;width:95%}#core-model{overflow-x:auto}#logo{margin:2px 10px 0}table{font-size:14px!important}.media-info-modal{width:800px}#selected-workspace{margin:17px 14px 15px 0}.tab-view{margin:10px 0 0}.search-query{margin:0 0 5px;width:100%}.caret-up{border-color:currentcolor transparent #fff;border-style:dotted solid solid;border-width:0 4px 4px;content:"";display:inline-block;height:0;margin-left:2px;vertical-align:middle;width:0}.scroll-pane{height:200px;overflow-x:hidden;overflow-y:scroll}#select-box tr td{padding:6px}.selected-ws{background-color:#428bca;color:#fff}.selected-ws:hover{background-color:#428bca!important}.side-bar-switch{margin:0 0 10px}.side-bar-switch li{font-size:12px}.side-bar-switch li a{padding:5px 10px}.selected-obj-alert{margin-bottom:5px;padding-bottom:10px;padding-top:10px}.heatmap-view{overflow-x:scroll}.ws-selector{margin:10px 0 0}.ws-selector.btn-ws-settings{position:absolute;right:30px}.object-view{margin:10px 0 0}.select-ws .badge{margin:0 4px 0 0}.select-ws .btn-ws-settings{padding:0 5px}.modal-alert{margin:10px 15px 0;padding:8px 15px}.modal-cover{position:absolute;z-index:10}.modal-cover-table{display:table;height:100%;position:static;width:100%}.modal-cover-cell{display:table-cell;position:static;vertical-align:middle}.modal-cover-box{box-shadow:7px 7px 5px #888;display:inline-block;margin:10px;padding:5px 15px}.modal-cover-content{background:#fff;border:1px solid #6a6158;border-radius:3px;padding:5px}.obj-table .dataTables_length label{margin:7px 0 0}.dataTables_info{float:left;margin:0 10px 0 0}.dataTables_length{float:left}.ellipsis{max-width:170px}.ellipsis,.ws-descript{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ws-descript{max-width:400px}.ncheck{border:1px solid #ded5cb;height:15px;margin-left:auto;margin-right:auto;width:15px}.ncheck:hover{border:1px solid #444}.ncheck-btn{border:1px solid #888;height:15px;margin:4px 0 4px -1px;width:15px}.ncheck-btn:hover{border:1px solid #444}.ncheck-checked{background:url(../img/checkmark.png) no-repeat -5px -4px;background-image:-webkit-image-set(url(../img/checkmark.png) 1x,url(../img/checkmark_2x.png) 2x);background-image:image-set(url(../img/checkmark.png) 1x,url(../img/checkmark_2x.png) 2x)}.ncheck-minus{background:url(../img/checkmark-partial.png) no-repeat -5px -5px;background-image:-webkit-image-set(url(../img/checkmark-partial.png) 1x,url(../img/checkmark-partial_2x.png) 2x);background-image:image-set(url(../img/checkmark-partial.png) 1x,url(../img/checkmark-partial_2x.png) 2x)}.btn-select-all{height:34px}.btn-select-all,.type-filter{margin:0 20px 0 0}.btn-trash{margin:3px 20px 0 0}.btn-show-info .glyphicon{padding:0 0 4px}.open-obj{margin:7px 0 0 20px}#login-form{margin:70px 0 0}#narrative-nav,.recent-narratives,.recent-projects{margin:0;padding:0}.group-item-expander{background:#f2f2f2}.group-item-expander:hover{cursor:hand;cursor:pointer}.btn-new-narrative{margin:0 20px 0 0}.btn-delete-narrative{cursor:hand;cursor:pointer}.btn-delete-narrative:hover{opacity:.7}.navbar-fixed-top{z-index:500}.FixedHeader_Header{background:#fff;height:44px;margin:-6px 0 0}.narrative-sidebar li{list-style:none}@media (min-width:960px){.narrative-sidebar{position:fixed;width:20%}}.sidebar-header,.view-header{color:#898989;font-family:RobotoBlack,Arial,sans-serif;font-weight:400;letter-spacing:0}.sidebar-header{font-size:14px}.view-header{font-size:1.5em;line-height:1.75}.active .btn-narr{background-color:#bbe8f9;border:1px solid #428bca}.active .btn-narr,.btn-narr{padding-left:20px;padding-right:20px;text-align:left}.btn-narr{background-color:#f2f2f2;border:1px solid #dbdbdb;color:#6da8cf;font:14px RobotoBlack,Arial,sans-serif}.nav-sidebar{top:70px}.nav-sidebar li{font-family:RobotoBlack,Arial,sans-serif;list-style:none;margin-bottom:10px;text-align:left}.nav-sidebar>li>a{padding:7px 15px}.navbar-nav{color:#6da8cf;font-family:RobotoBlack,Arial,sans-serif}.navbar-nav>li>a:hover{background-color:#fff}.navbar-nav>li.active:hover,.navbar-nav>li.active>a{border-bottom:4px solid #428bca;box-sizing:border-box;color:#2a6496!important;height:50px}.navbar-nav>.active:hover{color:#2a6496}#wrap{height:auto;margin:0 auto -58px;min-height:100%;padding:0 0 80px}#footer{height:58px}#footer ul{text-align:center}#footer ul li{display:inline;padding:7px 5px 5px 1px}#footer ul li:after{color:#bbb;content:"•";font-size:10px;padding-left:10px}#footer ul li:last-child:after,#footer ul li:nth-last-child(2):after{content:""}#footer img{position:relative;top:-3px}#footer .disclaimer{background-color:#a94442;bottom:0;color:#fff;display:block;font-weight:700;position:fixed;text-align:center;width:100%}.KBSnode rect{fill:#fff;fill-opacity:.5;stroke:#3182bd;stroke-width:1.5px;cursor:pointer}.KBSnode text{font:80% sans-serif;pointer-events:none}.modal-body .dataTables_processing{background:#e8f9ff;border:1px solid #aaa;opacity:.8}.kb-editor{margin:0 10px}.kb-editor .tab-content{margin:5px 0 0}.kb-editor .controls{margin:5px 0}.kb-editor .controls .btn{margin:0 10px}.kb-editor .btn-primary{background-color:#337ab7!important;border-color:#2e6da4!important}.kb-editor .btn-danger{background-color:#d9534f!important;border-color:#d43f3a!important}.kb-editor .btn i{color:#fff}.kb-editor table{border:1px solid #bbb}.kb-editor-table{width:100%!important}.kb-editor-table>tbody>tr>td:first-child{width:1%}.kb-editor-table>tbody>tr>td:first-child .fa-square-o{color:#6a6158;font-size:1.4em}.kb-editor-table>tbody>tr>td:first-child:hover{cursor:pointer}.kb-editor-table>tbody>tr>td:first-child:hover .fa-square-o{color:#000}.kb-editor-table>tbody>tr.row-select .fa-square-o:before{color:#444;content:"\f046"}.kb-editor-table>tbody>tr>td.editable{position:relative}.kb-editor-table>tbody>tr>td.editable:hover:after{bottom:0;color:#888;content:"\f044";font-family:FontAwesome;position:absolute;right:2px}.kb-notify{background-color:#000;bottom:10px;color:#fff;opacity:.8;padding:15px;position:relative;width:300px}.kb-notify.kb-notify-success{color:#00cc09}.kb-method-cell select.form-control{margin:0}.twitter-typeahead{width:100%}.code_cell div.input_area{display:none}.code_cell div.input_area.-show{display:block}.text-silver{color:silver}.modal .modal-title{font:normal 700 18px/24px Oxygen,Arial,sans-serif}.modal.kb-modal-alert .modal-title{color:unset}.modal input[type=checkbox]{margin-top:1px}.kb-panel-batch,.kb-panel-bulk-params,.kb-panel-container,.kb-panel-light,.kb-panel-params,.kb-panel-results{border:0;box-shadow:none}.kb-panel-batch .panel-heading,.kb-panel-bulk-params .panel-heading,.kb-panel-container .panel-heading,.kb-panel-light .panel-heading,.kb-panel-params .panel-heading,.kb-panel-results .panel-heading{background-color:transparent;color:#6a6158;font-weight:700}.kb-panel-light{margin-bottom:10px}.kb-panel-light.panel-danger .panel-title{color:#a94442}.kb-panel-light.panel-success .panel-title{color:#3c763d}.kb-panel-light.panel-warning .panel-title{color:#8a6d3b}.kb-panel-light.panel-info .panel-title{color:blue}.kb-panel-light .panel-heading{border-bottom:0;padding-bottom:2px}.kb-panel-light .panel-body{padding:0}.kb-panel-batch .panel-heading,.kb-panel-bulk-params .panel-heading,.kb-panel-params .panel-heading,.kb-panel-results .panel-heading{border-bottom:0;margin:15px 15px 5px;padding:0}.kb-panel-batch .panel-body,.kb-panel-bulk-params .panel-body,.kb-panel-params .panel-body,.kb-panel-results .panel-body{border-bottom:0;margin:0 15px 5px;padding:0}.kb-panel-params .panel-body{margin:0 10px 15px}.panel-title-collapse-toggle{margin-left:-15px}.kb-panel-container .panel-heading{border-bottom:2px solid #ded5cb;padding-bottom:2px}.kb-cell-error .panel-heading{background-image:none;padding:5px 10px}.btn{box-shadow:none}.btn-toolbar.kb-btn-toolbar-cell-widget{background-color:#f2efeb;margin-bottom:20px;padding:6px}.dataTables_empty{padding:.8rem}.btn.kb-flat-btn{background-color:#fff;border:0;color:#6a6158;margin:0;text-shadow:none!important}.btn.kb-flat-btn .kb-nav-btn-txt{font-size:13px;margin-top:-5px}.btn.kb-flat-btn:active,.btn.kb-flat-btn:hover{background-color:#ded5cb}.kb-flat-btn-wrapper{box-shadow:none}.dz-clear-all__button,.kb-data-staging__button,.kb-file-path__button--add_row,.kb-file-path__button--delete,.kb-job-status__cell_action--cancel,.kb-job-status__cell_action--go-to-results,.kb-job-status__cell_action--retry,.kb-staging-table-body__button--decompress,.kb-staging-table-body__button--delete,.kb-staging-table-body__button--download,.kb-staging-table-body__button--folder,.kb-staging-table-import__button{border:1px solid transparent;border-radius:4px;cursor:pointer;display:inline-block;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:700;line-height:1.428571429;padding:.6rem 1.2rem;text-align:center;text-transform:uppercase;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap}.dz-clear-all__button:focus,.focus.dz-clear-all__button,.focus.kb-data-staging__button,.focus.kb-file-path__button--add_row,.focus.kb-file-path__button--delete,.focus.kb-job-status__cell_action--cancel,.focus.kb-job-status__cell_action--go-to-results,.focus.kb-job-status__cell_action--retry,.focus.kb-staging-table-body__button--decompress,.focus.kb-staging-table-body__button--delete,.focus.kb-staging-table-body__button--download,.focus.kb-staging-table-body__button--folder,.focus.kb-staging-table-import__button,.kb-data-staging__button:focus,.kb-file-path__button--add_row:focus,.kb-file-path__button--delete:focus,.kb-job-status__cell_action--cancel:focus,.kb-job-status__cell_action--go-to-results:focus,.kb-job-status__cell_action--retry:focus,.kb-staging-table-body__button--decompress:focus,.kb-staging-table-body__button--delete:focus,.kb-staging-table-body__button--download:focus,.kb-staging-table-body__button--folder:focus,.kb-staging-table-import__button:focus{outline:5px auto Highlight;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.dz-clear-all__button:focus,.dz-clear-all__button:hover,.focus.dz-clear-all__button,.focus.kb-data-staging__button,.focus.kb-file-path__button--add_row,.focus.kb-file-path__button--delete,.focus.kb-job-status__cell_action--cancel,.focus.kb-job-status__cell_action--go-to-results,.focus.kb-job-status__cell_action--retry,.focus.kb-staging-table-body__button--decompress,.focus.kb-staging-table-body__button--delete,.focus.kb-staging-table-body__button--download,.focus.kb-staging-table-body__button--folder,.focus.kb-staging-table-import__button,.kb-data-staging__button:focus,.kb-data-staging__button:hover,.kb-file-path__button--add_row:focus,.kb-file-path__button--add_row:hover,.kb-file-path__button--delete:focus,.kb-file-path__button--delete:hover,.kb-job-status__cell_action--cancel:focus,.kb-job-status__cell_action--cancel:hover,.kb-job-status__cell_action--go-to-results:focus,.kb-job-status__cell_action--go-to-results:hover,.kb-job-status__cell_action--retry:focus,.kb-job-status__cell_action--retry:hover,.kb-staging-table-body__button--decompress:focus,.kb-staging-table-body__button--decompress:hover,.kb-staging-table-body__button--delete:focus,.kb-staging-table-body__button--delete:hover,.kb-staging-table-body__button--download:focus,.kb-staging-table-body__button--download:hover,.kb-staging-table-body__button--folder:focus,.kb-staging-table-body__button--folder:hover,.kb-staging-table-import__button:focus,.kb-staging-table-import__button:hover{color:#026daa;text-decoration:none}.active.dz-clear-all__button,.active.kb-data-staging__button,.active.kb-file-path__button--add_row,.active.kb-file-path__button--delete,.active.kb-job-status__cell_action--cancel,.active.kb-job-status__cell_action--go-to-results,.active.kb-job-status__cell_action--retry,.active.kb-staging-table-body__button--decompress,.active.kb-staging-table-body__button--delete,.active.kb-staging-table-body__button--download,.active.kb-staging-table-body__button--folder,.active.kb-staging-table-import__button,.dz-clear-all__button:active,.kb-data-staging__button:active,.kb-file-path__button--add_row:active,.kb-file-path__button--delete:active,.kb-job-status__cell_action--cancel:active,.kb-job-status__cell_action--go-to-results:active,.kb-job-status__cell_action--retry:active,.kb-staging-table-body__button--decompress:active,.kb-staging-table-body__button--delete:active,.kb-staging-table-body__button--download:active,.kb-staging-table-body__button--folder:active,.kb-staging-table-import__button:active{background-image:none;box-shadow:inset 0 3px 5px rgba(0,0,0,.125);outline:0}.disabled.dz-clear-all__button,.disabled.kb-data-staging__button,.disabled.kb-file-path__button--add_row,.disabled.kb-file-path__button--delete,.disabled.kb-job-status__cell_action--cancel,.disabled.kb-job-status__cell_action--go-to-results,.disabled.kb-job-status__cell_action--retry,.disabled.kb-staging-table-body__button--decompress,.disabled.kb-staging-table-body__button--delete,.disabled.kb-staging-table-body__button--download,.disabled.kb-staging-table-body__button--folder,.disabled.kb-staging-table-import__button,[disabled].dz-clear-all__button,[disabled].kb-data-staging__button,[disabled].kb-file-path__button--add_row,[disabled].kb-file-path__button--delete,[disabled].kb-job-status__cell_action--cancel,[disabled].kb-job-status__cell_action--go-to-results,[disabled].kb-job-status__cell_action--retry,[disabled].kb-staging-table-body__button--decompress,[disabled].kb-staging-table-body__button--delete,[disabled].kb-staging-table-body__button--download,[disabled].kb-staging-table-body__button--folder,[disabled].kb-staging-table-import__button,fieldset[disabled] .dz-clear-all__button,fieldset[disabled] .kb-data-staging__button,fieldset[disabled] .kb-file-path__button--add_row,fieldset[disabled] .kb-file-path__button--delete,fieldset[disabled] .kb-job-status__cell_action--cancel,fieldset[disabled] .kb-job-status__cell_action--go-to-results,fieldset[disabled] .kb-job-status__cell_action--retry,fieldset[disabled] .kb-staging-table-body__button--decompress,fieldset[disabled] .kb-staging-table-body__button--delete,fieldset[disabled] .kb-staging-table-body__button--download,fieldset[disabled] .kb-staging-table-body__button--folder,fieldset[disabled] .kb-staging-table-import__button{box-shadow:none;cursor:not-allowed;opacity:.8}.kb-staging-table-body__button--decompress{border-radius:3px;line-height:1.5;padding:.5rem 1rem}.kbcb-tooltip{background-color:#222;color:#fff;opacity:.8;padding:.5em;position:absolute;visibility:hidden;z-index:9999999}.kbcb-widget .kbcb-axis line,.kbcb-widget .kbcb-axis path{fill:none;shape-rendering:crispEdges;stroke:#000}.kbcb-widget .kbcb-axis text{font:11px sans-serif}.kbcb-feature{fill:red;stroke:#000}.kbcb-operon{fill:lime}.kbcb-center{fill:blue}.kbcb-highlight{fill:#fff}.kbcb-buttons{margin-left:auto;margin-right:auto;width:70%}.kb-tour{background-color:#2196f3}.kb-tour.popover.top>.arrow:after{border-top-color:#2196f3}.kb-tour.popover.bottom>.arrow:after{border-bottom-color:#2196f3}.kb-tour.popover.right>.arrow:after{border-right-color:#2196f3}.kb-tour.popover.left>.arrow:after{border-left-color:#2196f3}.kb-tour>h3.popover-title{background-color:#2196f3;color:#fff;font:16px Oxygen,Arial,sans-serif}.kb-tour>.popover-content,.kb-tour>.popover-navigation{background-color:#f2efeb}.kb-tour>.close-btn{position:absolute;right:7px;top:7px}.batch-mode-col{overflow:auto;padding:5px 10px}.job-info{cursor:pointer}.job-info.job-selected{background-color:#f2efeb}.batch-mode-list{max-height:860px;overflow:auto}.batch-input-panel{max-height:300px;overflow:auto}.kb-advanced-view-cell .kb-panel-container[data-element=parameters-group]>div.panel-collapse>.panel-body{padding:0}.kb-error-dialog__body .tab-content{padding-top:1rem}.kb-error-dialog__err_message,.kb-error-dialog__err_preamble{margin:1rem 0}.kb-error-dialog__stacktrace_container{word-wrap:break-word;background-color:#f2efeb;border:0;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px;margin:0;max-height:50rem;overflow-wrap:break-word;overflow-y:auto;padding:1rem;word-break:break-word}.kb-app-cell__container{align-items:stretch;display:flex;font-family:Oxygen,Arial,sans-serif}.kb-app-cell__prompt{align-items:stretch;display:flex;flex-direction:column}.kb-app-cell__body{align-items:stretch;display:flex;flex:1;flex-direction:column;width:100%}.kb-app-cell__widget_container{display:block;width:100%}.kb-app-cell-tab-pane__container--jobStatus,.kb-app-cell-tab-pane__container--results{padding:1.5rem}.kb-app-cell .kb-app-warning{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-app-cell .kb-app-parameter-panel{border-left:3px solid #fff}.kb-app-cell .kb-app-parameter-panel-hover{border-left:3px solid #428bca}.kb-app-cell .kb-app-parameter-row{border-radius:5px;margin:0;padding:5px}.kb-app-cell .kb-app-parameter-row:hover{background-color:rgba(0,0,0,.03)}.kb-app-cell .kb-app-parameter-row-hover{background:#f9f9f9}.kb-app-cell .kb-app-parameter-row .message{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-app-cell .kb-app-parameter-row .message.-error{background:#f2dede;color:#f44336}.kb-app-cell .kb-app-parameter-name{color:#777;font-family:Oxygen,Arial,sans-serif;padding-left:0;padding-right:4px;text-align:left;vertical-align:bottom;white-space:normal}.kb-app-cell .kb-app-parameter-input{vertical-align:middle}.kb-app-cell .kb-app-parameter-input select.form-control{margin:0}.kb-app-cell .kb-app-parameter-input .kb-app-parameter-accepted-glyph,.kb-app-cell .kb-app-parameter-input .kb-app-parameter-required-glyph{font-size:15px;margin-left:0}.kb-app-cell .kb-app-parameter-required-glyph{color:#f44336}.kb-app-cell .kb-parameter-data-selection{font-weight:700}.kb-app-cell .kb-app-parameter-hint{color:#777;margin-top:3px;padding-left:7px;text-align:left}.kb-app-cell .kb-app-parameter-accepted-glyph{color:#4bb856}.kb-app-cell .kb-app-advanced-options-controller-inactive,.kb-app-cell .kb-app-parameter-info,.kb-app-cell .kb-parameter-data-row-add,.kb-app-cell .kb-parameter-data-row-remove{color:#777}.kb-app-cell .kb-app-advanced-options-controller,.kb-app-cell .kb-app-advanced-options-controller-inactive{font:italic 700 13px/14px Oxygen,Arial,sans-serif;text-align:center}.kb-app-cell .kb-app-advanced-options-controller{color:#037ac0;cursor:pointer}.kb-app-cell .kb-app-advanced-options-controller:hover{color:#2a6496}.kb-app-cell .kb-app-footer{background-color:#f5f5f5;padding:10px;width:100%}.kb-app-cell .kb-app-subtitle{background-color:#f5f5f5;padding:3px 5px}.kb-app-cell .advanced-parameter-showing{display:block}.kb-app-cell .advanced-parameter-hidden{display:none}.kb-app-cell [data-element=run-control-panel]{width:100%}.kb-app-cell [data-element=tab-pane]{border-top:2px solid #2196f3}.kb-app-cell [data-element=tab-pane]>div{padding:0}.kb-app-row-clip-btn-addon,.kb-app-row-close-btn-addon{background:transparent;border:0}.kb-app-row-clip-btn-addon{height:100%;padding:0 10px 0 0}.kb-app-row-clip-btn-addon:active:after{background-color:#fff;border:1px solid gray;border-radius:3px;content:"copied!";margin-top:-5px;padding:7px;position:absolute}.kb-input-group-wide{width:100%}.kb-input-row-flex{align-items:center;display:flex;flex-direction:row}.cell.selected .btn-default.kb-app-row-close-btn{color:gray}.kb-app-row-clip-btn,.kb-app-row-close-btn{background-color:transparent;border:0;color:gray;height:100%;margin-left:1px}.kb-app-parameter-right-error-bar{background:red;height:28px}.kb-app-field-feedback,.kb-input-group-addon{background:transparent;border:0}.kb-input-group-addon{padding:0 0 0 10px}.unselected .kb-app-cell{opacity:.5}.kb-elapsed-time{font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.kb-elapsed-time.-active{color:lime}.kb-app-cell-info-desc{border:1px solid #777;margin-right:10px;min-height:100px;padding:10px}.kb-app-cell-info{color:#777;font:16px Oxygen,Arial,sans-serif}.kb-app-cell-info .header{border-bottom:1px solid #777;margin-bottom:8px;padding:5px 0}.kb-app-cell-info .value{color:#000}.btn.batch-active{background-color:#f2efeb;border-color:#adadad;box-shadow:inset 0 3px 7px rgba(0,0,0,.125)}.btn.batch-active:hover{background-color:#ded5cb}.btn.kb-app-cell-btn{background-color:#fff;margin-bottom:4px}.btn.kb-app-cell-btn,.btn.kb-app-cell-btn.btn-primary{border:2px solid #2196f3;color:#2196f3}.btn.kb-app-cell-btn.btn-primary:hover{border-bottom:6px solid #2196f3;margin-bottom:0}.btn.kb-app-cell-btn.btn-primary.active,.btn.kb-app-cell-btn.btn-primary:active,.btn.kb-app-cell-btn.btn-primary:hover{background-color:#2196f3;color:#fff}.btn.kb-app-cell-btn.btn-primary.active{border:solid #2196f3;border-width:2px 2px 6px;margin-bottom:0}.btn.kb-app-cell-btn.btn-primary.active:hover{background-color:#ddd;border-bottom:2px solid #2196f3;color:#2196f3;margin-bottom:4px}.btn.kb-app-cell-btn.btn-danger{border:2px solid #d15241;color:#d15241}.btn.kb-app-cell-btn.btn-danger:hover{border-bottom:6px solid #d15241}.btn.kb-app-cell-btn.btn-danger.active,.btn.kb-app-cell-btn.btn-danger:hover{background-color:#d15241;color:#fff;margin-bottom:0}.btn.kb-app-cell-btn.btn-danger.active{border:solid #d15241;border-width:2px 2px 6px}.btn.kb-app-cell-btn.btn-danger.active:hover{background-color:#ddd;border-bottom:2px solid #d15241;color:#d15241;margin-bottom:4px}.btn.kb-app-cell-btn.disabled,.btn.kb-app-cell-btn.disabled:active,.btn.kb-app-cell-btn.disabled:hover{background-color:#fff;border:2px solid #888;color:#888;margin-bottom:4px}.kb-app-status-ok{color:#4bb856}.kb-app-status-warning{color:orange}.kb-app-status-danger,.kb-app-status-error{color:#d15241}.kb-app-status-default{color:#2196f3}.parameter-panel .info-panel{background:transparent;padding-top:4px}.tt-input,.tt-query{box-shadow:inset 0 1px 1px rgba(0,0,0,.075);width:100%}.tt-hint{color:#999}.tt-menu{background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:4px;box-shadow:0 5px 10px rgba(0,0,0,.2);margin-top:4px;padding:4px 0;width:100%}.tt-suggestion{line-height:24px;padding:3px 20px}.tt-suggestion.tt-cursor,.tt-suggestion:hover{background-color:#0097cf;color:#fff}.tt-suggestion p{margin:0}.tt-header{font-size:75%;font-style:italic;padding-left:5px}.kb-app-results-tab{max-width:inherit;overflow-x:auto}.kb-editor-cell .kb-app-warning{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-editor-cell .kb-app-parameter-panel{border-left:3px solid #fff}.kb-editor-cell .kb-app-parameter-panel-hover{border-left:3px solid #428bca}.kb-editor-cell .kb-app-parameter-row{margin:0}.kb-editor-cell .kb-app-parameter-row-hover{background:#f9f9f9}.kb-editor-cell .kb-app-parameter-row .message{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-editor-cell .kb-app-parameter-row .message.-error{background:#f2dede;color:#f44336}.kb-editor-cell .kb-app-parameter-name{color:#777;font-family:Oxygen,Arial,sans-serif;padding-left:0;padding-right:4px;text-align:left;vertical-align:bottom;white-space:normal}.kb-editor-cell .kb-app-parameter-input{vertical-align:middle}.kb-editor-cell .kb-app-parameter-input select.form-control{margin:0}.kb-editor-cell .kb-app-parameter-input .kb-app-parameter-accepted-glyph,.kb-editor-cell .kb-app-parameter-input .kb-app-parameter-required-glyph{font-size:15px;margin-left:0}.kb-editor-cell .kb-app-parameter-required-glyph{color:#f44336}.kb-editor-cell .kb-parameter-data-selection{font-weight:700}.kb-editor-cell .kb-app-parameter-hint{color:#777;margin-top:3px;padding-left:7px;text-align:left}.kb-editor-cell .kb-app-parameter-accepted-glyph{color:#4bb856}.kb-editor-cell .kb-app-advanced-options-controller-inactive,.kb-editor-cell .kb-app-parameter-info,.kb-editor-cell .kb-parameter-data-row-add,.kb-editor-cell .kb-parameter-data-row-remove{color:#777}.kb-editor-cell .kb-app-advanced-options-controller,.kb-editor-cell .kb-app-advanced-options-controller-inactive{font:italic 700 13px/14px Oxygen,Arial,sans-serif;text-align:center}.kb-editor-cell .kb-app-advanced-options-controller{color:#037ac0;cursor:pointer}.kb-editor-cell .kb-app-advanced-options-controller:hover{color:#2a6496}.kb-editor-cell .kb-app-footer{background-color:#f5f5f5;padding:10px;width:100%}.kb-editor-cell .kb-app-subtitle{background-color:#f5f5f5;padding:3px 5px}.kb-editor-cell .advanced-parameter-showing{display:block}.kb-editor-cell .advanced-parameter-hidden{display:none}.kb-editor-cell [data-element=run-control-panel]{width:100%}.kb-editor-cell [data-element=tab-pane]{border-top:2px solid #2196f3}.kb-editor-cell [data-element=tab-pane]>div{padding:4px}.kb-editor-cell [data-element=tab-pane]>div:empty{padding:0}.kb-editor-cell .btn-primary.kb-btn-action.-rerun{color:#2196f3}.kb-editor-cell .btn-primary.kb-btn-action.-run{color:#4bb856}.kb-editor-cell .btn-danger.kb-btn-action.-cancel,.kb-editor-cell .btn-danger.kb-btn-action.-reset{color:#d15241}.unselected .kb-editor-cell{opacity:.5}.kb-editor-cell-info-desc{border:1px solid #777;margin-right:10px;min-height:100px;padding:10px}.kb-editor-cell-info{color:#777;font:16px Oxygen,Arial,sans-serif}.kb-editor-cell-info .header{border-bottom:1px solid #777;margin-bottom:8px;padding:5px 0}.kb-editor-cell-info .value{color:#000}.btn.kb-editor-cell-btn{background-color:#fff;margin-bottom:4px}.btn.kb-editor-cell-btn,.btn.kb-editor-cell-btn.btn-primary{border:2px solid #2196f3;color:#2196f3}.btn.kb-editor-cell-btn.btn-primary:hover{border-bottom:6px solid #2196f3;margin-bottom:0}.btn.kb-editor-cell-btn.btn-primary.active,.btn.kb-editor-cell-btn.btn-primary:active,.btn.kb-editor-cell-btn.btn-primary:hover{background-color:#2196f3;color:#fff}.btn.kb-editor-cell-btn.btn-primary.active{border:solid #2196f3;border-width:2px 2px 6px;margin-bottom:0}.btn.kb-editor-cell-btn.btn-primary.active:hover{background-color:#ddd;border-bottom:2px solid #2196f3;color:#2196f3;margin-bottom:4px}.btn.kb-editor-cell-btn.btn-danger{border:2px solid #d15241;color:#d15241}.btn.kb-editor-cell-btn.btn-danger:hover{background-color:#d15241;border-bottom:6px solid #d15241;color:#fff;margin-bottom:0}.btn.kb-editor-cell-btn.btn-danger.active{background-color:#d15241;border:solid #d15241;border-width:2px 2px 6px;color:#fff;margin-bottom:0}.btn.kb-editor-cell-btn.btn-danger.active:hover{background-color:#ddd;border-bottom:2px solid #d15241;color:#d15241;margin-bottom:4px}.btn.kb-editor-cell-btn.disabled,.btn.kb-editor-cell-btn.disabled:active,.btn.kb-editor-cell-btn.disabled:hover{border:2px solid #888;color:#888;margin-bottom:4px}.kb-appInput__checkbox_container{display:flex}.kb-appInput__checkbox_error{display:flex;margin-left:1rem;width:100%}.kb-appInput__checkbox_error_container{background-color:#f9dadb;border:1px solid #eda7aa;color:#171412;padding:.5em}.kb-appInput__checkbox_error_container__title{color:#d2232a;margin-right:.5rem}.kb-appInput__checkbox_error__close_button{background:none;border:0;margin-left:auto}.kb-appInput__checkbox_error__close_button:hover{background:none}.kb-app-params__message--advanced-hidden{font-style:italic;margin-left:6px}.kb-app-params__toggle--advanced-errors{background-color:#f9dadb;color:#171412;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429}.kb-app-params__toggle--advanced-errors--icon{color:#d2232a}.kb-app-params__fields--parameters-hidden{display:none}.kb-bulk-import__layout_container{align-items:stretch;display:flex}.kb-bulk-import__prompt{align-items:stretch;display:flex;flex-direction:column}.kb-bulk-import__body{align-items:stretch;display:flex;flex:1;flex-direction:column;width:100%}.kb-bulk-import__tab_pane{align-content:stretch;align-items:stretch;border-top:2px solid #2196f3;display:flex;flex-direction:row}.kb-bulk-import__tab_pane_widget{width:100%}.kb-bulk-import-configure__container,.kb-bulk-import-info__container{display:flex}.kb-bulk-import-configure__message,.kb-bulk-import-info__message{border:1px solid silver;color:#171412;padding:.5rem}.kb-bulk-import-configure__message--error,.kb-bulk-import-info__message--error{background-color:#f9dadb;border-color:#eda7aa}.kb-bulk-import-configure__message--error-title,.kb-bulk-import-info__message--error-title{color:#d2232a;margin-right:.5rem;text-transform:capitalize}.kb-bulk-import-configure__message--warning,.kb-bulk-import-info__message--warning{background-color:#ffefac;border-color:#fddd49}.kb-bulk-import-configure__message--warning-title,.kb-bulk-import-info__message--warning-title{color:#8f7700;margin-right:.5rem;text-transform:capitalize}.kb-bulk-import-configure__panel--filetype,.kb-bulk-import-info__panel--filetype{background-color:#f2efeb;width:24rem}.kb-bulk-import-configure__panel--configure,.kb-bulk-import-configure__panel--info,.kb-bulk-import-info__panel--configure,.kb-bulk-import-info__panel--info{flex:1}.kb-field-widget__error_message--parameters{border:1px solid #d2232a}.kb-field-cell__param_container{margin:3px}.kb-field-cell__input_control select{margin-left:0}.kb-field-cell__cell_label{margin-bottom:0;padding-top:8px}.kb-field-cell__error_message,.kb-field-cell__error_message .form-control{border-color:#d2232a;color:#d2232a}.kb-field-cell__error_message .select2-selection{border-color:#d2232a}.kb-field-cell__error_message .select2-container--default .select2-selection--single .select2-selection__placeholder,.kb-field-cell__error_message .select2-container--default .select2-selection--single .select2-selection__rendered{color:#d2232a}.kb-field-cell__message_panel,.kb-field-cell__message_panel__duplicate{border:1px solid silver;padding:.5em}.kb-field-cell__message_panel__duplicate__error,.kb-field-cell__message_panel__error{background-color:#f9dadb;border-color:#eda7aa;color:#171412}.kb-field-cell__message_panel__duplicate__error__title,.kb-field-cell__message_panel__error__title{color:#d2232a}.kb-field-cell__message_panel__duplicate__warning,.kb-field-cell__message_panel__warning{background-color:#ffefac;border-color:#fddd49;color:#171412}.kb-field-cell__message_panel__duplicate__warning__title,.kb-field-cell__message_panel__warning__title{color:#8f7700}.kb-result-tab__container{max-height:70rem;overflow-y:auto;padding:1.5rem}.kb-job-status-tab__container{padding:1.5rem}.kb-cell-toolbar__button{border:0}.kb-cell-toolbar__container{align-items:flex-start;display:flex;height:56px;justify-content:space-between}.kb-cell-toolbar__app_icon{flex:none;font-size:14px;height:56px;line-height:56px;margin-right:4px;padding:0;text-align:center;width:56px}.kb-cell-toolbar__title-container{flex:1 1 10rem;overflow:hidden;text-overflow:ellipsis}.cell.unselected .kb-cell-toolbar__title-container{opacity:.5}.kb-cell-toolbar__title{color:#03517d;font:normal 700 18px/20px Oxygen,Arial,sans-serif;margin-top:8px}.kb-cell-toolbar__subtitle,.kb-cell-toolbar__title{height:20px;min-width:0;overflow:hidden;text-overflow:ellipsis}.kb-cell-toolbar__subtitle{color:#6a6158;font:normal 400 14px/20px Oxygen,Arial,sans-serif}.kb-cell-toolbar__buttons-container{float:right;min-width:2rem;white-space:nowrap}.cell.unselected .kb-cell-toolbar__buttons-container{opacity:.2}.kb-cell-toolbar__icon--info{color:#65798c}.kb-cell-toolbar__icon--minus{color:#f78e1e}.kb-cell-toolbar__icon--outdated{border:0;color:#f78e1e;margin:0 5px;padding:0;vertical-align:top}.kb-cell-toolbar__icon--plus,.kb-cell-toolbar__icon--table,.kb-cell-toolbar__icon--terminal{color:#000}.kb-cell-toolbar__icon--times{color:#d12329}.kb-cell-toolbar__dropdown_item{border:0;text-align:left;width:100%}.kb-cell-toolbar__dropdown_item_icon{display:inline-block;margin-right:4px;width:25px}.kb-data-staging__breadcrumbs{margin:1rem 0 1.5rem}.kb-data-staging__breadcrumb_link{cursor:pointer}.kb-data-staging__container{height:604px;overflow-y:auto;padding:10px}.kb-data-staging__button{background-color:#dfeef6;border-color:transparent;color:#026daa;letter-spacing:.7px;margin-left:1rem;position:relative;top:-3px}.kb-data-staging__button.focus,.kb-data-staging__button:focus,.kb-data-staging__button:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-data-staging__button.active,.kb-data-staging__button:active,.open>.kb-data-staging__button.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-data-staging__button.active.focus,.kb-data-staging__button.active:focus,.kb-data-staging__button.active:hover,.kb-data-staging__button:active.focus,.kb-data-staging__button:active:focus,.kb-data-staging__button:active:hover,.open>.kb-data-staging__button.dropdown-toggle.focus,.open>.kb-data-staging__button.dropdown-toggle:focus,.open>.kb-data-staging__button.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-data-staging__button.disabled.focus,.kb-data-staging__button.disabled:focus,.kb-data-staging__button.disabled:hover,.kb-data-staging__button[disabled].focus,.kb-data-staging__button[disabled]:focus,.kb-data-staging__button[disabled]:hover,fieldset[disabled] .kb-data-staging__button.focus,fieldset[disabled] .kb-data-staging__button:focus,fieldset[disabled] .kb-data-staging__button:hover{background-color:#dfeef6;border-color:transparent}.kb-data-staging__button .badge{background-color:#026daa;color:#dfeef6}.kb-data-staging__title{font:normal 700 24px/30px Oxygen,Arial,sans-serif}.dz-clear-all__button{background-color:#dfeef6;border-color:transparent;color:#026daa}.dz-clear-all__button.focus,.dz-clear-all__button:focus,.dz-clear-all__button:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.dz-clear-all__button.active,.dz-clear-all__button:active,.open>.dz-clear-all__button.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.dz-clear-all__button.active.focus,.dz-clear-all__button.active:focus,.dz-clear-all__button.active:hover,.dz-clear-all__button:active.focus,.dz-clear-all__button:active:focus,.dz-clear-all__button:active:hover,.open>.dz-clear-all__button.dropdown-toggle.focus,.open>.dz-clear-all__button.dropdown-toggle:focus,.open>.dz-clear-all__button.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.dz-clear-all__button.disabled.focus,.dz-clear-all__button.disabled:focus,.dz-clear-all__button.disabled:hover,.dz-clear-all__button[disabled].focus,.dz-clear-all__button[disabled]:focus,.dz-clear-all__button[disabled]:hover,fieldset[disabled] .dz-clear-all__button.focus,fieldset[disabled] .dz-clear-all__button:focus,fieldset[disabled] .dz-clear-all__button:hover{background-color:#dfeef6;border-color:transparent}.dz-clear-all__button .badge{background-color:#026daa;color:#dfeef6}.dz-file{border:1px solid #f2efeb;font:16px Oxygen,Arial,sans-serif;margin:2px 0;padding:5px 0;width:100%}.dz-file__progress__bar{margin-bottom:inherit;margin-left:5px}.dz-file__upload-progress{display:inline}.dz-file__row{align-items:center;display:flex}.dz-file__name{line-height:20px;white-space:nowrap}.dz-file__msg,.dz-file__name{overflow:hidden;text-overflow:ellipsis}.dz-file__msg{font-size:14px}.dz-file__msg__success{color:#4baf4f;display:none}.dz-file__status{align-items:center;display:none;font-weight:700}.dz-file__status__icon{margin:0 4px 0 8px}.dz-file__status__success{color:#4baf4f}.dz-file__status__error{color:#df0002}.kb-dropzone{border:2px dashed #2196f3!important;margin-bottom:5px;max-height:150px;overflow-y:auto}.kb-dropzone-progress__header{border-bottom:1px solid #f2efeb;display:none;margin-bottom:5px}.kb-dropzone .dz-message{color:#000;font:normal 400 24px/28px Oxygen,Arial,sans-serif;margin:2em 4.5em;mix-blend-mode:normal;text-align:center}.kb-dropzone__message--upload{font-family:Oxygen,Arial,sans-serif;font-weight:700}.kb-error-display__container{padding:1.5rem}.kb-error-display__container.kb-log__error_container{padding:0}.kb-error-display__detail_title,.kb-error-display__stacktrace_title,.kb-error-display__summary{font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin-top:1rem}.kb-app-cell-tab-pane__container--error .kb-error-display__summary{margin-top:0}.kb-error-display__stacktrace_code{word-wrap:break-word;background-color:#f2efeb;border:0;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px;margin:0;max-height:50rem;overflow-wrap:break-word;overflow-y:auto;padding:1rem;word-break:break-word}.kb-error-display__advice_list{list-style:none;padding-left:0}.access-error__container,.generic-error__container{margin:2rem;text-align:center}.access-error__heading,.generic-error__heading{font-size:200%;font-weight:700;line-height:1.5}.access-error__text,.generic-error__text{font-size:150%;line-height:2}.access-request-form__container{margin-top:2rem}.access-request-progress__container{display:none;margin-top:1rem}.access-request-result{font-size:125%;margin-top:2rem}.error-dialog__body{margin:1rem}.kb-file-path__list{counter-reset:fpw-item;list-style-position:outside;list-style-type:none;max-height:60rem;overflow-y:auto;padding:0}.kb-file-path__list_item{align-items:center;display:flex;font:normal 400 14px/18px Oxygen,Arial,sans-serif;padding:0 1.5rem .5rem}.kb-file-path__list_item:nth-child(2n){background-color:#f2efeb}.kb-file-path__list_item:before{content:counter(fpw-item) " ";counter-increment:fpw-item;font-weight:700;padding-right:.5rem;padding-top:20px;vertical-align:middle}.kb-file-path__param_container{display:flex;flex:1;flex-wrap:wrap}.kb-file-path__param_container .input-group .select2-container{display:table;table-layout:fixed}.kb-file-path__row_cell--file-path_id{flex:1;min-width:30rem;padding:4px}.kb-file-path__button--delete{background-color:#dfeef6;border-color:transparent;color:#026daa;margin-top:2rem}.kb-file-path__button--delete.focus,.kb-file-path__button--delete:focus,.kb-file-path__button--delete:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-file-path__button--delete.active,.kb-file-path__button--delete:active,.open>.kb-file-path__button--delete.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-file-path__button--delete.active.focus,.kb-file-path__button--delete.active:focus,.kb-file-path__button--delete.active:hover,.kb-file-path__button--delete:active.focus,.kb-file-path__button--delete:active:focus,.kb-file-path__button--delete:active:hover,.open>.kb-file-path__button--delete.dropdown-toggle.focus,.open>.kb-file-path__button--delete.dropdown-toggle:focus,.open>.kb-file-path__button--delete.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-file-path__button--delete.disabled.focus,.kb-file-path__button--delete.disabled:focus,.kb-file-path__button--delete.disabled:hover,.kb-file-path__button--delete[disabled].focus,.kb-file-path__button--delete[disabled]:focus,.kb-file-path__button--delete[disabled]:hover,fieldset[disabled] .kb-file-path__button--delete.focus,fieldset[disabled] .kb-file-path__button--delete:focus,fieldset[disabled] .kb-file-path__button--delete:hover{background-color:#dfeef6;border-color:transparent}.kb-file-path__button--delete .badge{background-color:#026daa;color:#dfeef6}.kb-file-path__button--add_row{background-color:#dfeef6;border-color:transparent;color:#026daa;margin:1rem}.kb-file-path__button--add_row.focus,.kb-file-path__button--add_row:focus,.kb-file-path__button--add_row:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-file-path__button--add_row.active,.kb-file-path__button--add_row:active,.open>.kb-file-path__button--add_row.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-file-path__button--add_row.active.focus,.kb-file-path__button--add_row.active:focus,.kb-file-path__button--add_row.active:hover,.kb-file-path__button--add_row:active.focus,.kb-file-path__button--add_row:active:focus,.kb-file-path__button--add_row:active:hover,.open>.kb-file-path__button--add_row.dropdown-toggle.focus,.open>.kb-file-path__button--add_row.dropdown-toggle:focus,.open>.kb-file-path__button--add_row.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-file-path__button--add_row.disabled.focus,.kb-file-path__button--add_row.disabled:focus,.kb-file-path__button--add_row.disabled:hover,.kb-file-path__button--add_row[disabled].focus,.kb-file-path__button--add_row[disabled]:focus,.kb-file-path__button--add_row[disabled]:hover,fieldset[disabled] .kb-file-path__button--add_row.focus,fieldset[disabled] .kb-file-path__button--add_row:focus,fieldset[disabled] .kb-file-path__button--add_row:hover{background-color:#dfeef6;border-color:transparent}.kb-file-path__button--add_row .badge{background-color:#026daa;color:#dfeef6}.kb-file-path__button_icon--add_row{margin-right:.5rem}.kb-file-path__params{margin-left:.5rem}.kb-filetype-panel__filetype_button,.kb-filetype-panel__filetype_button--selected,.kb-filetype-panel__filetype_button:hover:not(.kb-filetype-panel__filetype_button--selected){background-color:inherit;border:solid silver;border-width:1px 0 0;display:flex;flex-direction:row;padding:8px;text-align:left;width:100%}.kb-filetype-panel__header{border-bottom:1px solid silver;font:normal 700 18px/30px Oxygen,Arial,sans-serif;padding:8px}.kb-filetype-panel__header_icon{color:#000;padding:8px 6px 8px 8px}.kb-filetype-panel__filetype_button{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429}.kb-filetype-panel__filetype_button:hover:not(.kb-filetype-panel__filetype_button--selected){background-color:#ded5cb;cursor:pointer}.kb-filetype-panel__filetype_button--selected{background-color:#fff;box-shadow:0 3px 2px -2px #6a6158}.kb-filetype-panel__filetype_button--selected+.kb-bulk-import__filetype-panel__filetype_button{box-shadow:inset 0 3px 2px -2px #6a6158}.kb-filetype-panel__filetype_icon{padding:2px 8px 0;text-align:center;width:3rem}.kb-filetype-panel__filetype_icon--complete{color:#5e9732}.kb-filetype-panel__filetype_icon--incomplete{color:#d2232a}.kb-filetype-panel__filetype_icon--warning{color:#b99902}.kb-filetype-panel__filetype_label{flex:1}.kb-fsm__key{margin-left:3px}.kb-fsm__value{background-color:#6a6158;color:#fff;margin:0 3px;padding:2px}.kb-info-tab__container{padding:1.5rem}.kb-info-tab__title{line-height:30px}.kb-info-tab__name{font:normal 700 18px/30px Oxygen,Arial,sans-serif}.kb-info-tab__version{padding:0 1rem}.kb-info-tab__tag{padding:.5rem;vertical-align:middle}.kb-info-tab__authors,.kb-info-tab__description,.kb-info-tab__link--docs,.kb-info-tab__list--params{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429;margin:1rem 0}.kb-info-tab__list_title--params{font:normal 700 16px/24px Oxygen,Arial,sans-serif;margin:1rem 0}ul.kb-info-tab__list--params{padding-left:2rem}.kb-job-action__dropdown_header{font-weight:700;text-transform:uppercase}.kb-job-action__dropdown-menu{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;line-height:2.5;padding:0}.kb-job-action__dropdown-menu-item-link--cancel,.kb-job-action__dropdown-menu-item-link--retry{background:#fff;border:0;border-bottom:1px solid rgba(0,0,0,.15);font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;line-height:2.5;text-align:left;width:100%}.kb-job-action__dropdown-menu-item-link--cancel:disabled,.kb-job-action__dropdown-menu-item-link--retry:disabled{color:#6a6158;cursor:not-allowed}.kb-job-action__dropdown-menu-item-link--cancel:active:disabled,.kb-job-action__dropdown-menu-item-link--cancel:hover:disabled,.kb-job-action__dropdown-menu-item-link--retry:active:disabled,.kb-job-action__dropdown-menu-item-link--retry:hover:disabled{background:#9d9389;color:#fff}.kb-job-action__dropdown-menu-item-link--retry{color:#026daa}.kb-job-action__dropdown-menu-item-link--retry:active,.kb-job-action__dropdown-menu-item-link--retry:hover{background:#026daa;color:#fff}.kb-job-action__dropdown-menu-item-link--cancel{color:#b6151c}.kb-job-action__dropdown-menu-item-link--cancel:active,.kb-job-action__dropdown-menu-item-link--cancel:hover{background:#d2232a;color:#fff}.kb-log__log_line_container,.kb-log__log_line_container--error{counter-reset:code-list-counter;list-style:none;margin:0;padding:0}.kb-log__line_text,.kb-log__line_text--error,.kb-log__log_line_container,.kb-log__log_line_container--error{font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px}.kb-log__line_text,.kb-log__line_text--error{counter-increment:code-list-counter;padding-left:5rem;position:relative;white-space:normal}.kb-log__container,.kb-log__dev_container{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px}.kb-log__dev_container{padding-bottom:2rem}.kb-log__controls{margin:2rem 0}.kb-log__content,.kb-log__content--expanded{background-color:#f2efeb;border:0;margin:0;overflow:scroll;padding:0;transition:height .5s}.kb-log__content{max-height:288px}.kb-log__content--expanded{max-height:720px}.kb-log__content p{margin:1rem}.kb-log__log_line_container--error{background-color:#f9dadb}.kb-log__line_text--error:before,.kb-log__line_text:before{content:counter(code-list-counter);left:1rem;position:absolute}.kb-log__line_text{background-color:#f2efeb;color:#171412}.kb-log__line_text--error{background-color:#f9dadb;color:#7c0e12}.kb-log__logs_title{font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin-top:1rem}.kb-log__spinner{border:0;line-height:1.428571429;margin:0;padding:.5rem 1rem}.kb-job-params__params_container,.kb-log__spinner{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400}.kb-job-params__params_container{line-height:24px}.kb-job-params__params_title{font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin-top:1rem}.kb-job-params__param_list{list-style-type:none;margin:1rem 0;padding:0}.kb-job-params__param_list,.kb-job-state-viewer__container{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px}.kb-job-state-viewer__job_status_detail_container div:first-of-type{font-weight:700}.kb-job-state-viewer__error_container.kb-error-display__container{padding:0}.kb-job-status{box-shadow:none}.kb-job-status__table{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429;padding:0;table-layout:fixed;width:100%}.kb-job-status__table.dataTable{border-collapse:collapse!important}.kb-job-status__table_body{border-bottom:2px solid #9d9389;border-top:2px solid #9d9389}.kb-job-status__table_body .kb-job-status__row,.kb-job-status__table_body tr.even,.kb-job-status__table_body tr.odd{border-bottom:1px solid #f2efeb}.kb-job-status__table__row--selected,.kb-job-status__table_body .kb-job-status__row:hover,.kb-job-status__table_body tr.even:hover,.kb-job-status__table_body tr.odd:hover{background:#f2efeb}.kb-job-status__table__row--selected:hover{background:#cce5f3}.kb-job-status__table_head_row{font-weight:700}.kb-job-status__table_head_row .sorting:after,.kb-job-status__table_head_row .sorting_asc:after,.kb-job-status__table_head_row .sorting_desc:after{bottom:0!important;display:inline-block!important;left:5px!important;position:relative!important}.kb-job-status__table_head_cell--action,.kb-job-status__table_head_cell--import-type,.kb-job-status__table_head_cell--output,.kb-job-status__table_head_cell--status{border:0;margin:0;padding:.8rem}.kb-job-status__table_footer{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px}.kb-job-status__cell--action,.kb-job-status__cell--import-type,.kb-job-status__cell--output,.kb-job-status__cell--status{border:0;margin:0;overflow:hidden;padding:.8rem;text-overflow:ellipsis}.kb-job-status__cell--status{text-transform:capitalize;width:10rem}.kb-job-status__cell--action{width:11rem}.kb-job-status__cell--import-type{width:18rem}.kb-job-status__cell_action--go-to-results,.kb-job-status__cell_action--retry{background-color:#dfeef6;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.focus,.kb-job-status__cell_action--go-to-results:focus,.kb-job-status__cell_action--go-to-results:hover,.kb-job-status__cell_action--retry.focus,.kb-job-status__cell_action--retry:focus,.kb-job-status__cell_action--retry:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.active,.kb-job-status__cell_action--go-to-results:active,.kb-job-status__cell_action--retry.active,.kb-job-status__cell_action--retry:active,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle,.open>.kb-job-status__cell_action--retry.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.active.focus,.kb-job-status__cell_action--go-to-results.active:focus,.kb-job-status__cell_action--go-to-results.active:hover,.kb-job-status__cell_action--go-to-results:active.focus,.kb-job-status__cell_action--go-to-results:active:focus,.kb-job-status__cell_action--go-to-results:active:hover,.kb-job-status__cell_action--retry.active.focus,.kb-job-status__cell_action--retry.active:focus,.kb-job-status__cell_action--retry.active:hover,.kb-job-status__cell_action--retry:active.focus,.kb-job-status__cell_action--retry:active:focus,.kb-job-status__cell_action--retry:active:hover,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle.focus,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle:focus,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle:hover,.open>.kb-job-status__cell_action--retry.dropdown-toggle.focus,.open>.kb-job-status__cell_action--retry.dropdown-toggle:focus,.open>.kb-job-status__cell_action--retry.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.disabled.focus,.kb-job-status__cell_action--go-to-results.disabled:focus,.kb-job-status__cell_action--go-to-results.disabled:hover,.kb-job-status__cell_action--go-to-results[disabled].focus,.kb-job-status__cell_action--go-to-results[disabled]:focus,.kb-job-status__cell_action--go-to-results[disabled]:hover,.kb-job-status__cell_action--retry.disabled.focus,.kb-job-status__cell_action--retry.disabled:focus,.kb-job-status__cell_action--retry.disabled:hover,.kb-job-status__cell_action--retry[disabled].focus,.kb-job-status__cell_action--retry[disabled]:focus,.kb-job-status__cell_action--retry[disabled]:hover,fieldset[disabled] .kb-job-status__cell_action--go-to-results.focus,fieldset[disabled] .kb-job-status__cell_action--go-to-results:focus,fieldset[disabled] .kb-job-status__cell_action--go-to-results:hover,fieldset[disabled] .kb-job-status__cell_action--retry.focus,fieldset[disabled] .kb-job-status__cell_action--retry:focus,fieldset[disabled] .kb-job-status__cell_action--retry:hover{background-color:#dfeef6;border-color:transparent}.kb-job-status__cell_action--go-to-results .badge,.kb-job-status__cell_action--retry .badge{background-color:#026daa;color:#dfeef6}.kb-job-status__cell_action--cancel{background-color:#f9dadb;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.focus,.kb-job-status__cell_action--cancel:focus,.kb-job-status__cell_action--cancel:hover{background-color:#f2aeb0;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.active,.kb-job-status__cell_action--cancel:active,.open>.kb-job-status__cell_action--cancel.dropdown-toggle{background-color:#f2aeb0;background-image:none;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.active.focus,.kb-job-status__cell_action--cancel.active:focus,.kb-job-status__cell_action--cancel.active:hover,.kb-job-status__cell_action--cancel:active.focus,.kb-job-status__cell_action--cancel:active:focus,.kb-job-status__cell_action--cancel:active:hover,.open>.kb-job-status__cell_action--cancel.dropdown-toggle.focus,.open>.kb-job-status__cell_action--cancel.dropdown-toggle:focus,.open>.kb-job-status__cell_action--cancel.dropdown-toggle:hover{background-color:#ed8f92;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.disabled.focus,.kb-job-status__cell_action--cancel.disabled:focus,.kb-job-status__cell_action--cancel.disabled:hover,.kb-job-status__cell_action--cancel[disabled].focus,.kb-job-status__cell_action--cancel[disabled]:focus,.kb-job-status__cell_action--cancel[disabled]:hover,fieldset[disabled] .kb-job-status__cell_action--cancel.focus,fieldset[disabled] .kb-job-status__cell_action--cancel:focus,fieldset[disabled] .kb-job-status__cell_action--cancel:hover{background-color:#f9dadb;border-color:transparent}.kb-job-status__cell_action--cancel .badge{background-color:#d2232a;color:#f9dadb}.kb-job-status__param_list{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;list-style-type:none;margin:1rem 0;padding:0}.kb-job-status__detail_container{background-color:#e7eff8;border-bottom:1px solid #f2efeb;padding:1rem}.kb-job-status__icon--action_warning{color:#d2232a;font-size:1.5em;padding:.5rem 1rem;vertical-align:middle}.kb-job-status__icon--created{color:#a1b9cf;margin:4px}.kb-job-status__summary--created{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--created{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--estimating{color:#a1b9cf;margin:4px}.kb-job-status__summary--estimating{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--estimating{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--queued{color:#a1b9cf;margin:4px}.kb-job-status__summary--queued{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--queued{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--running{color:#a1b9cf;margin:4px}.kb-job-status__summary--running{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--running{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--completed{color:#0a6258;margin:4px}.kb-job-status__summary--completed{color:#0a6258;font-weight:700}.kb-job-status__cell_summary--completed{color:#0a6258;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--terminated{color:#b99902;margin:4px}.kb-job-status__summary--terminated{color:#b99902;font-weight:700}.kb-job-status__cell_summary--terminated{color:#b99902;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--error{color:#d2232a;margin:4px}.kb-job-status__summary--error{color:#d2232a;font-weight:700}.kb-job-status__cell_summary--error{color:#d2232a;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--does_not_exist{color:#d2232a;margin:4px}.kb-job-status__summary--does_not_exist{color:#d2232a;font-weight:700}.kb-job-status__cell_summary--does_not_exist{color:#d2232a;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--ee2_error{color:#b99902;margin:4px}.kb-job-status__summary--ee2_error{color:#b99902;font-weight:700}.kb-job-status__cell_summary--ee2_error{color:#b99902;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-icon__container--image{display:block}.kb-icon__container--data,.kb-icon__container--data-stack{cursor:pointer}.kb-icon__container--app,.kb-icon__container--app-toolbar,.kb-icon__container--data,.kb-icon__container--generic,.kb-icon__container--generic-toolbar,.kb-icon__container--type,.kb-icon__container--type-toolbar{font-size:2em}.kb-icon__container--data-stack{font-size:1.7em}.kb-icon__icon_background--app,.kb-icon__icon_background--app-toolbar{color:#66489d}.kb-icon__icon_background--generic,.kb-icon__icon_background--generic-toolbar{color:silver}.kb-icon__icon_background--type,.kb-icon__icon_background--type-toolbar{color:#000}.kb-icon__img--image{margin:3px;max-height:50px;max-width:50px}.kb-icon__outline--l1{margin-left:1px;margin-top:1px}.kb-icon__stack--l1{margin-left:8px;margin-top:6px}.kb-icon__outline--l2{margin-left:9px;margin-top:7px}.kb-icon__stack--l2{margin-left:16px;margin-top:12px}.kb-icon__outline--l1,.kb-icon__outline--l2{color:#fff}.kb-data-list-logo{background-color:#607d8b;border:0 solid #555;border-radius:50%;color:#fff;display:inline-block;font-size:24px;font-weight:700;height:40px;padding-top:8px;text-align:center;text-shadow:-1px 0 #777,0 1px #777,1px 0 #777,0 -1px #777;width:40px}.kb-loading-blocker__text,.kb-loading-blocker__text--warning{font-size:16px;line-height:1.5;margin-left:30%;text-align:left;width:40%}.kb-loading-blocker__container{background-color:#fff;height:100%;left:0;position:absolute;top:0;width:100%;z-index:9999}.kb-loading-blocker__header{font-size:24px;font-weight:700;text-align:center}.kb-loading-blocker__text--warning{display:none;position:absolute}.kb-loading-blocker__image_container{padding-top:10%;text-align:center}.kb-narr-outline{padding:.5em .5em .5em .25em}.kb-narr-outline ul{list-style:none;padding:0;position:relative}.kb-narr-outline ul ul{padding-left:1.5em}.kb-narr-outline ul li:not(:last-of-type):before{border-left:2px solid #ded5cb;content:"";height:calc(100% + .25em);left:-.5em;position:absolute;top:0}.kb-narr-outline li{position:relative}.kb-narr-outline__item{align-items:center;cursor:pointer;display:flex;flex-flow:row nowrap;justify-content:left;left:0;padding:.1em .1em .3em;position:relative;top:0}.kb-narr-outline__item:before{background-color:transparent;border:1px solid transparent;border-radius:.333em;bottom:.2em;content:"";position:absolute;top:0;transition:background-color .1s linear,border .1s linear;width:100%;z-index:-1}.kb-narr-outline__item:after{border-bottom:2px solid #ded5cb;border-left:2px solid #ded5cb;bottom:calc(50% + 1px);content:"";height:calc(50% - .25em);left:-.5em;position:absolute;width:.5em}.kb-narr-outline__item-content{display:block;flex-grow:0;flex-shrink:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-narr-outline__item-icon{display:inline-block;transform:scale(.5);transform-origin:top left}.kb-narr-outline__item-icon-wrapper{border-radius:10px;display:block;flex-grow:0;flex-shrink:0;height:2em;margin-left:.1em;margin-right:.5em;max-width:2em;overflow:hidden}.kb-narr-outline__item--highlight:before{background-color:#f2efeb;border:1px solid #9d9389}.kb-narr-outline__item--highlight-selected:before{background-color:rgba(75,184,86,.15);border:1px solid #4bb856}.kb-narr-outline ul ul .kb-narr-outline__item:after{border-bottom:2px solid #ded5cb;border-left:2px solid #ded5cb;bottom:calc(50% + 1px);content:"";height:calc(50% - .25em);left:-.5em;position:absolute;width:.5em}.kb-rcp__layout_div{border-top:1px solid silver;display:flex;flex-direction:row;height:50px;position:relative}.kb-rcp__toolbar{flex:none;height:50px;line-height:50px}.kb-rcp__btn-toolbar{display:inline-block;line-height:50px;padding-right:.5rem;vertical-align:bottom}.kb-rcp__action-button{float:left;margin:6px;width:8rem}.kb-rcp__action-button-container{flex:none;height:50px;line-height:50px;overflow:hidden}.kb-rcp-status__container{flex:1 1 auto;font-size:14px;line-height:50px;margin:0 1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-rcp-status__fsm_display{background:#fff;display:inline-block;font:12px/1 Oxygen,Arial,sans-serif;margin-top:-30px;padding:6px 10px;position:absolute;top:0}.kb-rcp__tab-button{float:left;margin-left:.5rem}a.kb-rcp__tab-button--outdated{color:#ffd200;float:left;margin-left:.5rem;padding:6px 0 0}a.kb-rcp__tab-button--outdated:active,a.kb-rcp__tab-button--outdated:hover{color:#b99902}.kb-report-view__warning__count{margin:5px}.kb-report-view__warning__container{margin:0 5px 5px 10px;max-height:100px;overflow-y:auto}.kb-report-view__warning__text{margin:0 5px 5px 10px}.kb-report-view__summary{color:#544c45;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;height:auto;line-height:24px;max-height:500px;overflow:auto;white-space:pre-wrap;width:100%}.kb-report-view__download-iframe{display:none}.kb-report-view__download_button{cursor:pointer}.kb-report-view__report_iframe{display:block;height:auto;margin:0;padding:0;width:100%}.kb-report-view__report_button{margin:4px 4px 8px 0}.kb-output-widget__object_link{cursor:pointer}.kb-output-widget__table.dataTable{width:100%}.kb-report__container{margin:-1.5rem}.kb-report__item_container{border-bottom:1px solid #ded5cb;padding:0 1.5rem}.kb-report__item_toggle{color:#037ac0;font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin:0 -1rem;padding:.5rem 0}.kb-report__item_toggle:hover{color:#2a6496}.kb-select2-object-input__item,.kb-select2-taxonomy-ref__item{display:block;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;height:20px;line-height:1.428571429}.kb-select2-object-input__object{word-wrap:break-word;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429}.kb-select2-object-input__object_name{font-weight:700}.kb-select2-object-input__object_type{font-style:italic}.kb-select2-object-input__object_details{margin-left:1rem}.kb-select2-object-input__object_narrative,.kb-select2-object-input__object_type,.kb-select2-object-input__object_updated{display:block}.kb-staging-table{table-layout:fixed}.kb-staging-table .kb-staging-table-body td{vertical-align:middle}.kb-staging-table .kb-staging-table-header .sorting:before,.kb-staging-table .kb-staging-table-header .sorting_asc:before,.kb-staging-table .kb-staging-table-header .sorting_desc:before{content:"\e150";display:inline-block;font-family:Glyphicons Halflings;opacity:.2;position:relative;right:4px;top:1px}.kb-staging-table .kb-staging-table-header .sorting_asc:before{content:"\e155"}.kb-staging-table .kb-staging-table-header .sorting_desc:before{content:"\e156"}.kb-staging-table .kb-staging-table-header .sorting:after,.kb-staging-table .kb-staging-table-header .sorting_asc:after,.kb-staging-table .kb-staging-table-header .sorting_desc:after{display:none}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__checkbox{padding-right:0;width:2rem}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file{padding-right:0;width:4rem}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file.sorting:before,.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file.sorting_asc:before,.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file.sorting_desc:before{left:9px}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__age,.kb-staging-table .kb-staging-table-header .kb-staging-table-header__size{width:7rem}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__import{width:24rem}.kb-staging-table-body__cell--expander{text-align:center}.kb-staging-table-body__cell--import{text-align:right;white-space:nowrap}.kb-staging-table-body__button--decompress{background:transparent;border-radius:0;font-size:12px;line-height:12px;padding:.2rem}.kb-staging-table-body__button--download{background-color:#026daa;border-color:transparent;border-radius:0;color:#fff;font-size:12px;line-height:12px;margin-left:.5rem;padding:.5rem}.kb-staging-table-body__button--download.focus,.kb-staging-table-body__button--download:focus,.kb-staging-table-body__button--download:hover{background-color:#014d78;border-color:transparent;color:#fff}.kb-staging-table-body__button--download.active,.kb-staging-table-body__button--download:active,.open>.kb-staging-table-body__button--download.dropdown-toggle{background-color:#014d78;background-image:none;border-color:transparent;color:#fff}.kb-staging-table-body__button--download.active.focus,.kb-staging-table-body__button--download.active:focus,.kb-staging-table-body__button--download.active:hover,.kb-staging-table-body__button--download:active.focus,.kb-staging-table-body__button--download:active:focus,.kb-staging-table-body__button--download:active:hover,.open>.kb-staging-table-body__button--download.dropdown-toggle.focus,.open>.kb-staging-table-body__button--download.dropdown-toggle:focus,.open>.kb-staging-table-body__button--download.dropdown-toggle:hover{background-color:#013654;border-color:transparent;color:#fff}.kb-staging-table-body__button--download.disabled.focus,.kb-staging-table-body__button--download.disabled:focus,.kb-staging-table-body__button--download.disabled:hover,.kb-staging-table-body__button--download[disabled].focus,.kb-staging-table-body__button--download[disabled]:focus,.kb-staging-table-body__button--download[disabled]:hover,fieldset[disabled] .kb-staging-table-body__button--download.focus,fieldset[disabled] .kb-staging-table-body__button--download:focus,fieldset[disabled] .kb-staging-table-body__button--download:hover{background-color:#026daa;border-color:transparent}.kb-staging-table-body__button--download .badge{background-color:#fff;color:#026daa}.kb-staging-table-body__button--delete,.kb-staging-table-body__button--folder{background-color:transparent;border-color:transparent;border-radius:0;color:#026daa;font-size:18px;line-height:12px;padding:.5rem}.kb-staging-table-body__button--delete.focus,.kb-staging-table-body__button--delete:focus,.kb-staging-table-body__button--delete:hover,.kb-staging-table-body__button--folder.focus,.kb-staging-table-body__button--folder:focus,.kb-staging-table-body__button--folder:hover{background-color:transparent;border-color:transparent;color:#026daa}.kb-staging-table-body__button--delete.active,.kb-staging-table-body__button--delete:active,.kb-staging-table-body__button--folder.active,.kb-staging-table-body__button--folder:active,.open>.kb-staging-table-body__button--delete.dropdown-toggle,.open>.kb-staging-table-body__button--folder.dropdown-toggle{background-color:transparent;background-image:none;border-color:transparent;color:#026daa}.kb-staging-table-body__button--delete.active.focus,.kb-staging-table-body__button--delete.active:focus,.kb-staging-table-body__button--delete.active:hover,.kb-staging-table-body__button--delete:active.focus,.kb-staging-table-body__button--delete:active:focus,.kb-staging-table-body__button--delete:active:hover,.kb-staging-table-body__button--folder.active.focus,.kb-staging-table-body__button--folder.active:focus,.kb-staging-table-body__button--folder.active:hover,.kb-staging-table-body__button--folder:active.focus,.kb-staging-table-body__button--folder:active:focus,.kb-staging-table-body__button--folder:active:hover,.open>.kb-staging-table-body__button--delete.dropdown-toggle.focus,.open>.kb-staging-table-body__button--delete.dropdown-toggle:focus,.open>.kb-staging-table-body__button--delete.dropdown-toggle:hover,.open>.kb-staging-table-body__button--folder.dropdown-toggle.focus,.open>.kb-staging-table-body__button--folder.dropdown-toggle:focus,.open>.kb-staging-table-body__button--folder.dropdown-toggle:hover{background-color:transparent;border-color:transparent;color:#026daa}.kb-staging-table-body__button--delete.disabled.focus,.kb-staging-table-body__button--delete.disabled:focus,.kb-staging-table-body__button--delete.disabled:hover,.kb-staging-table-body__button--delete[disabled].focus,.kb-staging-table-body__button--delete[disabled]:focus,.kb-staging-table-body__button--delete[disabled]:hover,.kb-staging-table-body__button--folder.disabled.focus,.kb-staging-table-body__button--folder.disabled:focus,.kb-staging-table-body__button--folder.disabled:hover,.kb-staging-table-body__button--folder[disabled].focus,.kb-staging-table-body__button--folder[disabled]:focus,.kb-staging-table-body__button--folder[disabled]:hover,fieldset[disabled] .kb-staging-table-body__button--delete.focus,fieldset[disabled] .kb-staging-table-body__button--delete:focus,fieldset[disabled] .kb-staging-table-body__button--delete:hover,fieldset[disabled] .kb-staging-table-body__button--folder.focus,fieldset[disabled] .kb-staging-table-body__button--folder:focus,fieldset[disabled] .kb-staging-table-body__button--folder:hover{background-color:transparent;border-color:transparent}.kb-staging-table-body__button--delete .badge,.kb-staging-table-body__button--folder .badge{background-color:#026daa;color:transparent}.kb-staging-table-body__button--delete:active,.kb-staging-table-body__button--delete:hover,.kb-staging-table-body__button--folder:active,.kb-staging-table-body__button--folder:hover{color:#03517d}.kb-staging-table-body__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-staging-table-body__folder:hover{cursor:pointer;text-decoration:underline}.kb-staging-table-body__select_container{align-items:center;display:flex;justify-content:flex-end;text-align:left}.kb-staging-table-body .select2{margin:4px 0;width:19rem!important}.kb-staging-table-body .kb-staging-table-body__import-dropdown{align-items:center;background:#fff;border:1px solid #b6151c;border-radius:4px;box-sizing:border-box;display:flex;height:38px}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__rendered{color:#171412;flex:1 1 auto;font-size:14px;line-height:20px;padding:8px 20px 8px 8px}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__placeholder{color:#b6151c}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__arrow{margin-top:4px}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__arrow b{border-color:#b6151c transparent transparent}.kb-staging-table-body .kb-staging-table-body__import-dropdown.kb-staging-table-body__import-type-selected .select2-selection__arrow b,.kb-staging-table-body .kb-staging-table-body__import-dropdown:focus .select2-selection__arrow b{border-color:#9d9389 transparent transparent}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-container--focus .select2-selection__placeholder,.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-container--open .select2-selection__placeholder{color:#171412}.kb-staging-table-body .kb-staging-table-body__import-dropdown.kb-staging-table-body__import-type-selected,.kb-staging-table-body .select2-container--focus .kb-staging-table-body__import-dropdown,.kb-staging-table-body .select2-container--open .kb-staging-table-body__import-dropdown{border:1px solid silver}.kb-staging-table-file-metadata .tab-pane{margin:1rem}.kb-staging-table-file-metadata__def_list{display:flex;flex-wrap:wrap;margin:1rem;padding:0;width:100%}.kb-staging-table-file-metadata__term{font-weight:700;padding-top:.5rem;text-align:right;width:9rem}.kb-staging-table-file-metadata__def{margin-left:0;padding-left:1rem;padding-top:.5rem;width:calc(100% - 9rem)}.kb-staging-table-file-metadata__list{list-style-type:none}.kb-staging-table-file-metadata__file_lines{word-wrap:break-word;background-color:#f2efeb;border:0;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px;margin:0;max-height:50rem;max-height:200px;overflow-wrap:break-word;overflow-y:auto;overflow:scroll;padding:1rem;white-space:pre;word-break:break-word}.kb-staging-table__notice{background-color:#f2efeb;font:normal 700 16px/20px Oxygen,Arial,sans-serif;padding:1rem;text-align:center}.kb-staging-table-import__button{background-color:#026daa;border-color:transparent;border-radius:6px;bottom:-50px;color:#fff;font-size:14px;line-height:1.3333333;padding:1rem 1.5rem;position:absolute;right:10px;text-transform:none}.kb-staging-table-import__button.focus,.kb-staging-table-import__button:focus,.kb-staging-table-import__button:hover{background-color:#014d78;border-color:transparent;color:#fff}.kb-staging-table-import__button.active,.kb-staging-table-import__button:active,.open>.kb-staging-table-import__button.dropdown-toggle{background-color:#014d78;background-image:none;border-color:transparent;color:#fff}.kb-staging-table-import__button.active.focus,.kb-staging-table-import__button.active:focus,.kb-staging-table-import__button.active:hover,.kb-staging-table-import__button:active.focus,.kb-staging-table-import__button:active:focus,.kb-staging-table-import__button:active:hover,.open>.kb-staging-table-import__button.dropdown-toggle.focus,.open>.kb-staging-table-import__button.dropdown-toggle:focus,.open>.kb-staging-table-import__button.dropdown-toggle:hover{background-color:#013654;border-color:transparent;color:#fff}.kb-staging-table-import__button.disabled.focus,.kb-staging-table-import__button.disabled:focus,.kb-staging-table-import__button.disabled:hover,.kb-staging-table-import__button[disabled].focus,.kb-staging-table-import__button[disabled]:focus,.kb-staging-table-import__button[disabled]:hover,fieldset[disabled] .kb-staging-table-import__button.focus,fieldset[disabled] .kb-staging-table-import__button:focus,fieldset[disabled] .kb-staging-table-import__button:hover{background-color:#026daa;border-color:transparent}.kb-staging-table-import__button .badge{background-color:#fff;color:#026daa}.kb-staging-table-import__button[disabled]{background-color:#a1b9cf;cursor:not-allowed;opacity:1}.kb-staging-table-import__button[disabled]:active,.kb-staging-table-import__button[disabled]:focus,.kb-staging-table-import__button[disabled]:hover{background-color:#a1b9cf}.kb-staging-table-import__button[disabled]:focus{outline:none}.kb-staging-table-import__tooltip.tooltip{background:#fff;border-radius:4px;box-shadow:2px 4px 6px rgba(0,0,0,.15)}.kb-staging-table-import__tooltip.tooltip .tooltip-inner{align-items:center;background:#fff;color:#000;display:flex;font:normal 400 14px/16px Oxygen,Arial,sans-serif;height:6rem;width:20rem}.kb-ui__button_label,.kb-ui__icon{vertical-align:middle}.kb-ui__text--na{color:#f78e1e;font-style:italic}.kb-user-menu__menu{display:inline-block}.kb-user-menu__menu_caret.caret{margin-left:5px}.kb-user-menu__icon--gravatar{width:40px}.kb-user-menu__icon--signout.fa,.kb-user-menu__icon--user.fa{font-size:150%;margin-right:10px}.kb-user-menu__block--name{display:inline-block}.kb-user-menu__block--displayName,.kb-user-menu__block--userName{display:block}.kb-user-menu__block--displayName{font-style:italic}.kb-user-menu__block--signout-icon,.kb-user-menu__block--user-icon{display:inline-block;width:34px}.kb-user-menu__block--user-icon{vertical-align:top} \ No newline at end of file +@charset "UTF-8";@font-face{font-family:Glyphicons Halflings;src:url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot);src:url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2) format("woff2"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff) format("woff"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf) format("truetype"),url(../../ext_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg")}@font-face{font-family:kbase-icons;font-style:normal;font-weight:400;src:url(../fonts/kbase-icons.eot);src:url(../fonts/kbase-icons.eot?#iefix) format("embedded-opentype"),url(../fonts/kbase-icons.woff) format("woff"),url(../fonts/kbase-icons.ttf) format("truetype"),url(../fonts/kbase-icons.svg#kbase-icons) format("svg")}@font-face{font-family:Oxygen;font-style:normal;font-weight:400;src:url(../fonts/Oxygen-webfont.eot);src:url(../fonts/Oxygen-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-webfont.woff) format("woff"),url(../fonts/Oxygen-webfont.ttf) format("truetype"),url(../fonts/Oxygen-webfont.svg#OxygenRegular) format("svg")}@font-face{font-family:Oxygen;font-style:normal;font-weight:700;src:url(../fonts/Oxygen-Bold-webfont.eot);src:url(../fonts/Oxygen-Bold-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-Bold-webfont.woff) format("woff"),url(../fonts/Oxygen-Bold-webfont.ttf) format("truetype"),url(../fonts/Oxygen-Bold-webfont.svg#OxygenBold) format("svg")}@font-face{font-family:Oxygen;font-style:italic;font-weight:400;src:url(../fonts/Oxygen-Italic-webfont.eot);src:url(../fonts/Oxygen-Italic-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-Italic-webfont.woff) format("woff"),url(../fonts/Oxygen-Italic-webfont.ttf) format("truetype"),url(../fonts/Oxygen-Italic-webfont.svg#OxygenItalic) format("svg")}@font-face{font-family:Oxygen;font-style:italic;font-weight:700;src:url(../fonts/Oxygen-BoldItalic-webfont.eot);src:url(../fonts/Oxygen-BoldItalic-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-BoldItalic-webfont.woff) format("woff"),url(../fonts/Oxygen-BoldItalic-webfont.ttf) format("truetype"),url(../fonts/Oxygen-BoldItalic-webfont.svg#OxygenBoldItalic) format("svg")}@font-face{font-family:OxygenMono;font-style:normal;font-weight:400;src:url(../fonts/OxygenMono-Regular-webfont.eot);src:url(../fonts/OxygenMono-Regular-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/OxygenMono-Regular-webfont.woff) format("woff"),url(../fonts/OxygenMono-Regular-webfont.ttf) format("truetype"),url(../fonts/OxygenMono-Regular-webfont.svg#OxygenMonoRegular) format("svg")}@font-face{font-family:OxygenRegular;font-style:normal;font-weight:400;src:url(../fonts/Oxygen-webfont.eot);src:url(../fonts/Oxygen-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-webfont.woff) format("woff"),url(../fonts/Oxygen-webfont.ttf) format("truetype"),url(../fonts/Oxygen-webfont.svg#OxygenRegular) format("svg")}@font-face{font-family:OxygenBold;font-style:normal;font-weight:400;src:url(../fonts/Oxygen-Bold-webfont.eot);src:url(../fonts/Oxygen-Bold-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Oxygen-Bold-webfont.woff) format("woff"),url(../fonts/Oxygen-Bold-webfont.ttf) format("truetype"),url(../fonts/Oxygen-Bold-webfont.svg#OxygenBold) format("svg")}@font-face{font-family:RobotoBlack;font-style:normal;font-weight:400;src:url(../fonts/Roboto-Black-webfont.eot);src:url(../fonts/Roboto-Black-webfont.eot?#iefix) format("embedded-opentype"),url(../fonts/Roboto-Black-webfont.woff) format("woff"),url(../fonts/Roboto-Black-webfont.ttf) format("truetype"),url(../fonts/Roboto-Black-webfont.svg#RobotoBlack) format("svg")}#ipython-main-app{position:relative}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#337ab7;color:#fff}.select2-container--default .select2-results__option--highlighted[aria-selected] span{color:#fff!important}#site{overflow:visible}#notebook>.end_space{height:0;min-height:0}@media (min-width:1200px){#notebook-container{width:auto}}@media (min-width:992px){#notebook-container{width:auto}}@media (min-width:768px){#notebook-container{width:auto}}.celltoolbar{background:none;border:0;border-left:1px solid transparent;height:auto;padding-bottom:2px;padding-top:0}div.input_area{border:1px solid #cecece;border-radius:0;padding-top:4px}div.output_subarea{max-width:inherit}div.text_cell_input{border:1px solid #cecece;border-radius:0}div.cell{border:1px solid #ded5cb;border-left-width:5px;border-radius:0;margin:8px 0;padding:0}div.cell.selected{background:none;border:1px solid #4bb856;border-left-width:5px;box-shadow:0 1px 2px #aaa,0 5px 5px #aaa;margin-left:0;padding-left:0;transition:box-shadow .2s ease-in-out}div.cell.selected:before{background:none}div.cell.selected.kb-error{border:1px solid #d9534f;border-left-width:5px}div.cell.opened{padding-top:0}div#notebook{padding:0}.edit_mode div.cell.selected{background:none;border-left:5px solid #66bb6a;padding-left:0}#notebook_name{color:#006698}#notebook_name:hover{background-color:#e0e0e0;cursor:pointer}#notebook-container{bottom:0;box-shadow:none;left:380px;min-width:460px;overflow:auto;position:fixed;right:0;top:70px;width:auto}#notebook-container:after{content:"";display:block;height:100px}.btn-toolbar{margin-left:0;padding-left:0}.kb-narr-side-panel .btn-group .btn{font-size:16px;padding:3px 4px}.btn-subtle{color:#888;margin:0}.btn-subtle .fa,.btn-subtle .fa:before{color:#888}.notebook_app{background-color:#fff;overflow-y:hidden}.notebook_app .btn.active{box-shadow:none}.notebook_app .inner_cell{overflow:visible}.notebook_app .celltoolbar>.button_container{flex:0 auto}.notebook_app .celltoolbar>.button_container:first-child{flex:auto}.notebook_app .celltoolbar_container{border-bottom:1px solid silver}.notebook_app .prompt{color:silver;padding-top:0;width:75px}.notebook_app .cell.selected div.text_cell_render,.notebook_app .cell.unselected div.text_cell_render{border:1px solid transparent}.notebook_app .buttons .dropdown-menu{height:auto!important;overflow:visible!important}.notebook_app .btn.disabled .fa{color:silver}.text_cell.kb-cell .rendered_html table{border:1px solid #ddd}.text_cell.kb-cell .rendered_html ul{margin:0}.text_cell.opened.rendered.kb-cell .rendered_html{border:0;padding:0}.text_cell.opened.rendered.selected.kb-cell .rendered_html{border-left:1px solid #4bb856}.text_cell.opened.rendered.selected.kb-cell.kb-error .rendered_html{border-left:1px solid #d9534f}.text_cell.opened.rendered.kb-cell{padding-bottom:0}.rendered_html td,.rendered_html th,.rendered_html tr{text-align:inherit}.rendered_html table{table-layout:inherit}.cell.selected .prompt .method-icon{color:#673ab7}.cell.selected .prompt .app-icon{color:#009688}.cell.selected .prompt .app-output-icon,.cell.selected .prompt .data-viewer-icon,.cell.selected .prompt .markdown-icon,.cell.selected .prompt .method-output-icon{color:#000}.cell.selected .prompt .error-icon{color:red}.cell.selected .btn-default{color:#000}.cell>.inner_cell>.ctb_hideshow{display:block}.cell.unselected .btn-default{color:#ded5cb}.cell.unselected .app-icon,.cell.unselected .method-icon{color:silver}.kb-btn-icon{display:inline-block;padding:4px}.kb-btn-icon .fa{opacity:.5}.kb-btn-icon:hover .fa{opacity:1}p{margin-bottom:1rem}.prompt{display:none!important}div.run_this_cell{display:none;width:0}div.code_cell div.input_prompt{min-width:0}.panel-title{font:normal 700 18px/30px Oxygen,Arial,sans-serif}[data-toggle=collapse]{cursor:pointer}[data-toggle=collapse]:before{color:silver;content:"\f078";display:inline-block;font:normal 400 90%/1 FontAwesome;margin-left:0;margin-right:.2em;text-align:center;vertical-align:baseline;width:1.2em}[data-toggle=collapse].collapsed:before{content:"\f054";margin-left:.1em;margin-right:.1em}[data-toggle=vertical-collapse-after]{cursor:pointer}[data-toggle=vertical-collapse-after]:after{content:" \f0d8";display:inline-block;font:normal 400 130%/1 FontAwesome;text-align:right;vertical-align:baseline;width:1em}.vertical_collapse--open [data-toggle=vertical-collapse-after]:after{content:" \f0d7"}body{background-color:#fff;color:#171412;font:1.4em Oxygen,Arial,sans-serif}h1{color:#232323;font:400 1.75em/2em RobotoBlack,Arial,sans-serif}h1,h2{letter-spacing:0}h2{color:#898989;font:normal 400 1.5em/1.75em RobotoBlack,Arial,sans-serif}h3{font:normal 400 1.15em/1.25em RobotoBlack,Arial,sans-serif;letter-spacing:0}h4{font:italic 400 1.15em/1.25em Oxygen,Arial,sans-serif;letter-spacing:.07em}b,strong{font-family:Oxygen,Arial,sans-serif;font-weight:700}b i,em,em strong,i,i b,strong em{font-family:Oxygen,Arial,sans-serif;font-style:italic}b i,em strong,i b,strong em{font-weight:700}a{color:#037ac0;text-decoration:none}a:hover,a:visited{color:#2a6496}a:hover{text-decoration:underline}code,pre{font-style:normal}.kb-ga-seq,code,pre{font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.kb-ga-seq{word-wrap:break-word;max-height:100px;max-width:300px;overflow-y:auto}.ui-front{z-index:1000}.whiteout-pane{background-color:#fff;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:1001}#kb-narr-name{font:normal 700 18px/1.2 Oxygen,Arial,sans-serif;overflow:hidden;padding-bottom:7px;text-overflow:ellipsis;white-space:nowrap}#kb-narr-name:hover{text-overflow:inherit;white-space:normal}#save_widget{padding:0}#kb-narr-creator,#save_widget{font-family:Oxygen,Arial,sans-serif;font-weight:700}.kb-narr-namestamp{border-left:2px solid #cecece;display:block;flex:2;margin:5px auto 0;min-width:0;padding-left:20px}.kb-narr-namestamp__error_container{font-size:200%;line-height:1.5}.ui-draggable.kb-data-inflight{background-color:#feffd6!important;border:2px solid grey;border-radius:4px;display:block;z-index:1000}.ui-draggable.kb-data-inflight.-over{background-color:#effceb!important;border-color:green}.kb-data-list-drag-target{border:2px dashed orange;border-radius:4px;display:block;height:40px;padding:6px;text-align:center;transition:all .25s ease}.kb-data-list-drag-target.-drag-active{background-color:#feffd6}.kb-data-list-drag-target.-drag-hover{background-color:#effceb;border-color:green;height:90px;transition:all .25s ease}#kb-notify-area{float:left;position:relative}.kb-navbar-buttons{border-right:2px solid #cecece;display:inline-block;margin-right:15px;padding-right:15px}header[role=banner]{background-color:#fff;border-bottom:1px solid #cecece;position:absolute;top:0;width:100%;z-index:999}nav[role=navigation] ul{margin:1.2em 0 .5em;padding-left:0}nav[role=navigation] ul li{display:inline;margin:0 .5em;vertical-align:middle}nav[role=navigation] ul li a{background-color:#5c9531;border:1px solid #5c9531;border-radius:8px;box-shadow:inset 0 3px 8px rgba(0,0,0,.125);color:#fff;font:normal 700 1.2em Oxygen,Arial,sans-serif;padding:7px 1em;text-decoration:none}input#search_terms{background-image:url(../images/search.png);background-position:100%;background-repeat:no-repeat;background-size:22px;border-color:#5c9531;border-radius:0 4px 4px 0;display:inline;font-size:1em;left:-.5em;margin-top:-3px;padding:.4em 1em;position:relative}span#searchspan{display:inline-block;width:50%}@media screen and (max-width:1170px){span#searchspan{width:50%}}@media screen and (max-width:980px){span#searchspan{width:40%}}@media screen and (max-width:768px){span#searchspan{width:30%}}@media screen and (max-width:590px){span#searchspan{width:60%}}.navbar-kbase{background-color:#fff;border-bottom:5px solid #cecece!important;box-shadow:0 1px 10px rgba(0,0,0,.1);padding:8px}.navbar-kbase a:hover{cursor:pointer}.kb-nav-btn{background-color:#fff;border:0;box-shadow:0 0 3px #cecece;font-size:24px;margin:0 5px 0 0;min-width:50px;padding:1px 7px;text-shadow:none!important}.kb-nav-btn>div{color:#6a6158!important}.kb-nav-btn .kb-nav-btn-txt{font-size:13px;margin-top:-5px}.navbar-right .fa:before{color:#2196f3}.kb-navbar-container{display:flex;justify-content:space-between}#kb-nav-menu{box-shadow:none}.kb-nav-menu__container{display:inline-block}.navbar-right .kb-nav-btn:hover{background-color:#f5f5f5}.kb-nav-btn-upgrade{background-color:#4bb856!important;display:none}.kb-nav-btn-upgrade .fa:before,.kb-nav-btn-upgrade>div{color:#fff!important}.kb-nav-btn-upgrade:hover{background-color:#43a047!important}.kb-nav-btn-upgrade.warning{background-color:#f44336!important}.kb-nav-btn-upgrade.warning:hover{background-color:#dc3c31!important}.kb-nav-menu-icon{display:inline-block;margin-right:5px;text-align:center;vertical-align:middle;width:20px}.kb-nav-menu-icon .fa{font-size:150%}#kb-ipy-menu{border-radius:4px!important;margin-right:0}#signin-button .btn{border:0}.btn-xs .glyphicon-user{padding:14px 5px}.narrative-menu-container{background-color:#fff;border-bottom:1px solid #ababab;margin-left:auto;margin-top:-10px;padding-bottom:30px;padding-top:10px;position:fixed;width:100%;z-index:499}p.clear{clear:both;height:0}body>#header{box-sizing:border-box;display:block}p#site-title{background:url(../images/kbase_logo.png) no-repeat;background-size:46px;float:left;height:46px;margin:5px;text-indent:-9999px;width:46px}#login-info{font-size:1.2em;margin:5px;position:absolute;right:0;top:7px}#login-widget button{margin-left:5px}.search-box{border-collapse:separate;display:inline;margin:-11px 0;padding:10px 1px;position:relative;width:200px}#search-box-name{border:0;border-radius:4px;padding:6px 0}#search-box-name:first-child{border-bottom-right-radius:0;border-right:0;border-top-right-radius:0}#search-box-name:last-child{border-bottom-left-radius:0;border-top-left-radius:0}#search-input{margin:-11px 0}#search-select{margin:-11px 0;width:150px}#search-area{color:#686868;font:normal 400 18px Oxygen,Arial,sans-serif;margin:0 5px;padding:11px;position:relative}#search-area input{padding:11px}#workspace{bottom:42px;overflow:auto;position:fixed;top:173px;width:878px}#bottom-tabs{background-color:#fff;border-top:1px solid #aaa;bottom:0;clear:left;margin:0 auto;position:fixed;width:1170px}#bottom-tabs p a{background-color:#fff;border:1px solid #018841;font-size:14px;padding:14px 20px}#left-column{border-right:5px solid #cecece;bottom:0;position:fixed;top:70px;width:380px}.kb-side-overlay-container{background:#fff;border:1px solid #cecece;max-height:calc(100% - 73px);overflow-y:auto;position:fixed;width:730px;z-index:1030}.kb-side-overlay-header{background-color:#2196f3;color:#fff;font-size:16px;padding:6px;width:100%}.kb-side-overlay-close{color:#fff;cursor:pointer;font-size:13px;font-weight:700}.kb-side-overlay-close:hover{color:orange}.kb-side-panel{height:100%;overflow-y:hidden}#kb-side-toggle-in{background-color:#2196f3;border-bottom:6px solid #cecece;border-right:6px solid #cecece;color:#cce5f3;cursor:pointer;display:none;font-size:16px;font-weight:700;padding:12px 6px;position:fixed;text-align:center;top:70px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:22px;z-index:1}#kb-side-toggle-in:hover{color:#fff}.kb-side-toggle{background-color:#2196f3;border-bottom:6px solid #2196f3;border-top:6px solid #2196f3;color:#cce5f3;cursor:pointer;display:inline-block;font-size:16px;font-weight:700;padding:6px;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kb-side-toggle:hover{color:#fff}.kb-side-header{background-color:#2196f3;border-bottom:6px solid #2196f3;border-top:6px solid #2196f3;color:#cce5f3;cursor:pointer;display:inline-block;font-size:16px;font-weight:700;padding:6px;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kb-side-header.active,.kb-side-header:hover{border-bottom:6px solid #10ce34}.kb-side-header.active{color:#fff;cursor:auto}.kb-overlay-active{background-color:grey;border-bottom:6px solid grey;border-top:6px solid grey}.kb-side-separator{border-bottom:5px solid #cecece}.kb-side-tab{display:none}.kb-side-tab.active{display:inherit}.kb-narr-side-panel-set,.kb-side-tab{height:100%}.kb-narr-side-panel-set:last-child{height:50%}.kb-overlay-dimmer{background-color:#000;bottom:0;opacity:.5;position:fixed;right:0;z-index:10}#data-header{background-color:#099;color:#fff;font-weight:700;padding:10px 0}#data-title{text-align:center}#data-add-btn{font-size:.8em;padding:0;position:absolute;right:7px}#data-add-btn:hover{color:#000}#data-tab-nav{background-color:#0bb;border-bottom:1px solid #aaa;padding-top:10px;width:100%}#data-tab-nav ul{bottom:0;padding-bottom:0;top:50px}#data-tab-nav ul li{background-color:#ddd;border:1px solid #000;display:inline;padding:4px 10px}#data-tab-nav ul li a{color:#000}#data-tab-nav ul li a:hover{color:#a00;text-decoration:none}#data-tab-nav ul li.selected{background-color:#fff}#data-view-panel{border:1px solid #aaa;height:150px;overflow-y:auto;padding:10px}#data-pane{border-bottom:1px solid #aaa;height:69%;margin-top:1px;overflow:auto}#data-pane p{margin:0}#data-pane p span{border:1px solid #fff;color:#fff;display:block;margin:0;padding:2px 10px;text-align:center;width:123px}#data-pane p span.tab1{background:linear-gradient(#6a6158,#bbb);color:#fff;float:right}#data-pane p span.tab2{background:linear-gradient(#ded5cb,#9d9389)}#function-pane{height:30%;margin-top:1px;overflow:auto}.left-pane{font-size:14px;position:relative}#kb-function-panel .kb-function-body{height:100%;max-height:100%}h3.pane-title{background-color:#e0e0e0;border:1px solid silver;font-size:16px;margin:0;padding:3px 5px;position:relative}#add-link{font-size:.8em;position:absolute;right:7px;top:4px}ul.pane-list{margin:0;padding:2px}ul.pane-list li{list-style:none;margin-left:5px;padding:1px}.kb-method-list-logo{background-color:#607d8b;border:0 solid #555;color:#fff;cursor:pointer;display:inline-block;font-size:24px;font-weight:700;height:40px;padding-top:8px;text-align:center;text-shadow:-1px 0 #777,0 1px #777,1px 0 #777,0 -1px #777;width:40px}.kb-method-list-logo:hover{border-width:5px;padding-top:3px}.kb-method-list-more-div{color:#777;font-size:13px;margin:2px;text-align:justify}.kb-method-list-more-div>div:last-child{text-align:right}.kb-method-search-clear{border:1px solid #cecece;border-left:0;cursor:pointer}li.function a{color:#508232;text-decoration:none}li.function a:visited{color:#508232}li.dataset a{text-decoration:none}li.dataset a,li.dataset a:visited{color:#825032}.dialog-box{padding:20px}.dialog-box ul li{border-bottom:1px solid #aaa;font-size:1.2em;padding:50px 5px}.dialog-box ul li:first-child{padding-top:20px}.dialog-box ul li:last-child{border-bottom:0}fieldset{border:0;margin:0 0 15px}fieldset label{font-size:1em;font-weight:700;margin:0 0 3px}fieldset input[type=password],fieldset input[type=text],fieldset select{width:200px}div.dataset-cell,div.function-cell{border:1px solid #ded5cb;margin:3px auto;padding:7px 17px;width:90%}div.texttools p,div.tools p{margin:0}div.textarea{border:0;display:none;height:auto;min-height:1.2em;padding:0;width:650px}div.metadata{display:block;float:left;height:100px;padding:0 10px;width:200px}div.social{display:none;float:right;padding:0 10px;width:80px}img.dataset-cell{margin:3px auto;padding:0}.function-cell{background-image:url(../images/gears.png);background-position:100%;background-repeat:no-repeat}.dataset-cell p,.function-cell p{font-size:.875em}.dataset-cell h2,.function-cell h2{font-size:1.1em;margin-bottom:0}.textcell{border:2px solid #fff;color:#111;font-size:1em;height:1em;margin:3px auto;padding:5px 17px;width:90%}.textcell:hover{border:2px dotted #ded5cb}p.textcuepara{color:#ded5cb;display:none;height:1em;margin:0;padding:0}.texttools{display:none}.texttools img{vertical-align:middle}.tools{display:none;height:1em;margin-left:10px;margin-top:.5em}.tools a{border:1px solid #018841;font-size:13px;padding:2px 4px}#narrative-header .tools{display:block;left:350px;position:relative;top:-2em;width:30em}img.remove{float:right}.ui-state-highlight{background-color:#fbfaed}p span.notification{background-color:#f33;border-radius:1em;color:#fff;padding:4px 8px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{border-radius:0 6px 6px;left:100%;margin-left:-1px;margin-top:-6px;top:0}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu>a:after{border-color:transparent transparent transparent #ded5cb;border-style:solid;border-width:5px 0 5px 5px;content:" ";display:block;float:right;height:0;margin-right:-10px;margin-top:5px;width:0}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{border-radius:6px 0 6px 6px;left:-100%;margin-left:10px}#maintoolbar{background-color:#f9f9f9!important;background-image:none!important;border:0!important;box-shadow:none;min-height:0;position:relative;top:5px}#maintoolbar-container{margin-left:10px}#menubar{background-color:#f9f9f9;border-bottom:2px solid #ddd;padding-bottom:5px;position:absolute;top:3px;width:100%}#menubar .navbar .container{padding-left:0;padding-right:0}.navbar{background-color:#f8f8f8;background-image:none;min-height:0}#menubar .navbar-nav>li>a{padding-bottom:7px;padding-top:10px}.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning,.panel-default>.panel-heading{background-image:none}#menus{padding-left:0}#menubar .navbar{margin-bottom:5px;width:100%}div#notebook_panel{box-shadow:none}.version-stamp a{color:#037ac0!important}.creator-stamp,.version-stamp a{padding-right:320px;text-align:right}.creator-stamp{color:#006698;font:normal 700 120% Oxygen,Arial,sans-serif;height:1em}.panel{margin-bottom:0}#kb-jobs-panel{margin-bottom:5px}.kb-narr-side-panel{height:100%;margin-bottom:5px}.kb-narr-side-panel .kb-title{color:#03517d;font:normal 700 19px Oxygen,Arial,sans-serif;padding:10px 5px;text-transform:uppercase}.kb-narr-side-panel .btn{border:0}.kbujs-table-container{height:auto}.kbujs-timestamp{color:#0066b9;cursor:pointer}.kbujs-error-cell{color:#c7254e;font-weight:700}.kbujs-error:hover{cursor:pointer}.kbujs-loading-modal{font-size:16px;font-weight:700;text-align:center}.kbujs-refresh-btn{position:absolute;right:5px}.kbujs-jobs-table{margin-left:auto!important;margin-right:auto!important}.kbujs-loading{height:100%;text-align:center;vertical-align:middle}.kbujs-delete-job{cursor:pointer}.kbujs-error-traceback{float:left;max-height:250px;max-width:516px;overflow-x:scroll;overflow-y:scroll;white-space:nowrap}.kb-line{background-color:#d3d3d3;position:absolute}.nav-tabs .glyphicon-remove{color:#aaa;margin:0 0 0 3px}.nav-tabs .glyphicon-remove:hover{color:#6a6158;cursor:hand;cursor:pointer}.paging_full_numbers{height:22px;line-height:22px}.paging_full_numbers a:active{outline:none}.paging_full_numbers a:hover{text-decoration:none}.paging_full_numbers a.paginate_active{background-color:#99b3ff}.paging_full_numbers a.paginate_active,.paging_full_numbers a.paginate_button{border:1px solid #aaa;border-radius:5px;color:#333!important;cursor:pointer;margin:0 3px;padding:2px 5px}.paging_full_numbers a.paginate_button{background-color:#ddd}.paging_full_numbers a.paginate_button:hover{background-color:#ded5cb;text-decoration:none!important}.kb-function-header{background-color:#b6e9f8;color:#0064b6;font-weight:700;margin-bottom:3px;padding:10px 0;text-align:center}.kb-narr-panel-body{height:100%;padding:3px}.kb-narr-panel-body>div{height:100%}.kb-narr-panel-body-wrapper{height:100%;overflow-y:auto}.kb-narr-panel-body-wrapper>div{height:100%}.kb-narr-panel-toggle{color:#888;cursor:pointer;margin-right:4px;margin-top:-4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.kb-function-body{height:100%;width:100%}.kb-function-body .accordion .panel .panel-body{padding:0 0 0 5px}.kb-function-body ul{border:1px solid #ddd;list-style-type:none;margin:0;padding:0;width:100%}.kb-function-body li{padding:5px;text-align:left;width:100%}.kb-function-body li:nth-child(odd){background-color:#f2efeb;border-bottom:1px solid #ddd}.kb-function-body li:nth-child(2n){background-color:#fff;border-bottom:1px solid #ddd}.kb-function-body li:hover{background-color:#f4f5d6;cursor:pointer;text-decoration:underline}.kb-function-body a,.kb-function-body a:hover{text-decoration:none}.kb-function-error{background-color:#f2dede!important;border-color:#eed3d7!important;color:#b94a48}.kb-function-help{color:#56559e;cursor:pointer;float:right;font-size:19px;padding:0 3px}.kb-function-help:hover{color:#000}.kb-function-help-popup{cursor:pointer;left:300px;max-width:300px;position:absolute;top:0;z-index:99}.kb-function-help-popup h1{color:#3076a2;font-size:110%;margin:-10px 0 0;padding:0}.kb-function-help-popup h2{color:#9d9389;font-size:80%;font-style:italic;font-weight:100;margin:10px 0 -10px;padding-top:5px;text-align:right}.kb-function-help-popup .header{background-color:#fff;color:#3076a2;font-size:120%;font-weight:700;margin:0;padding:0}.kb-function-help-popup a{font-weight:700;text-decoration:underline}.kb-function-help-popup .version{color:#6a6158;font-size:80%}.kb-function-help-popup .body{margin-bottom:10px;margin-top:10px}#kb-function-help{cursor:pointer;left:300px;position:absolute;top:400px;width:250px;z-index:99}#kb-function-help h1{color:#3076a2;font-size:110%;margin:-10px 0 0;padding:0}#kb-function-help h2{color:#9d9389;font-size:80%;font-style:italic;font-weight:100;margin:10px 0 -10px;padding-top:5px;text-align:right}#kb-function-error-traceback{float:left;max-width:250px;overflow-x:scroll;white-space:nowrap}.kb-function-dim,.kb-function-dim .panel-heading{background-color:#f2efeb!important}.kb-function-cat-dim,.kb-function-cat-dim .panel-heading{background-color:#ddd!important;border-color:#ddd!important}.kb-function-toggle{color:#037ac0;cursor:pointer;font-style:italic}.kb-toolbar-open{border-bottom:1px solid #ded5cb;border-radius:0}.selected .kb-toolbar-open{background-color:#dff0d8;border-bottom:1px solid #4bb856;border-left:1px solid #4bb856}.unselected .kb-toolbar-open{background:none}.selected.kb-error .kb-toolbar-open{background-color:#f2dede;border-color:#d9534f}.kb-cell-run{opacity:1;z-index:auto}.kb-cell-run h1{color:#03517d;display:inline;font:normal 400 16px/1 Oxygen,Arial,sans-serif;margin:3px 13px 3px 3px;opacity:inherit}.kb-cell-run div.kb-func-desc{display:block;opacity:inherit}.kb-cell-run h2{color:#6a6158;font:normal 400 15px/1.5 Oxygen,Arial,sans-serif;margin:3px;opacity:inherit}.kb-cell-run form input[type=submit]{float:right;margin-top:5px;opacity:inherit}.kb-cell-run form .buttons{float:right;margin-top:5px}.kb-cell-run.running form{opacity:.6}.kb-cell-params table{border:0;margin-bottom:10px;margin-left:auto;margin-right:auto;opacity:inherit}.kb-cell-params table>tr,td{border:0;vertical-align:middle}.kb-cell-params tbody>tr>td,.kb-cell-params tbody>tr>th,.kb-cell-params tfoot>tr>td,.kb-cell-params tfoot>tr>th,.kb-cell-params thead>tr>td,.kb-cell-params thead>tr>th{padding:2px 4px}.kb-cell-params tr:hover td,.kb-cell-params tr:hover th{background:#f2efeb}.kb-cell-progress{display:none}.kb-cell-progress.running{display:block}.kb-cell-progressbar{height:20px;width:400px}.kb-out-desc{color:#03517d}.kb-err-desc,.kb-out-desc{display:inline;font:normal 400 16px/1 Oxygen,Arial,sans-serif;margin:3px;opacity:inherit}.kb-err-desc{color:#a94442}.kb-err-msg{font-size:80%!important}.kb-out-header{background-color:#ddd;padding:10px}.kb-func-timestamp{color:#555;font:13px Oxygen,Arial,sans-serif;margin-top:-3px;padding-right:1em}.unselected .kb-func-timestamp{color:silver}.kb-func-panel,.kb-func-panel>.panel-heading{border-color:#bce8f1;border-radius:1px}.kb-func-panel>.panel-heading{background-color:#d9edf7;color:#31708f;padding:5px 10px}.kb-func-panel .panel-body{font-family:Oxygen,Arial,sans-serif;padding:0 10px}.kb-func-panel>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.kb-func-panel>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.kb-cell-output .panel{border-radius:0}.kb-cell-output .nav>li>a,.kb-cell-output .panel-heading{padding:5px 10px}.kb-cell-output-content{overflow-x:auto;padding:5px}.rendered_html .kb-cell-output ul{margin:0 0 10px}.rendered_html :link{text-decoration:none}.kb-jobs-title{color:#185a85;font:normal 700 1.2em Oxygen,Arial,sans-serif}.kb-jobs-title .glyphicon-info-sign{font-size:.9em}.kb-jobs-info-table{margin:0 2px;width:95%}.kb-jobs-info-table th{color:#777;font-family:Oxygen,Arial,sans-serif;font-weight:700;max-width:30%;min-width:30%;padding-right:5px;vertical-align:top;width:30%}.kb-jobs-item{border-bottom:2px solid #ddd;margin-bottom:5px;padding-bottom:3px}.kb-jobs-error{background-color:#f2dede}.kb-jobs-error-btn{font-size:13px}.kb-jobs-item:last-child{border-bottom:0}.kb-jobs-error-modal{word-wrap:break-word;max-height:220px;overflow-x:hidden;overflow-y:auto;width:485px}.kb-method-parameter-panel{border-left:3px solid #fff}.kb-method-parameter-panel-hover{border-left:3px solid #428bca}.kb-method-parameter-row{border-radius:5px;margin:0;padding:5px}.kb-method-parameter-row-hover{background:#f9f9f9}.kb-method-parameter-row-error{background:#f2dede}.kb-method-parameter-error-mssg{color:#f44336;font-family:Oxygen,Arial,sans-serif;font-size:12px;font-weight:700;padding:5px;text-align:center}.kb-method-parameter-name{color:#777;font-family:Oxygen,Arial,sans-serif;font-weight:700;margin-top:3px;padding-left:0;padding-right:0;text-align:right;vertical-align:middle;white-space:normal}.kb-method-parameter-input{padding-left:10px;vertical-align:middle;white-space:nowrap}.kb-method-parameter-input input{font-weight:700}.kb-method-parameter-input>div{padding-right:20px}.kb-method-parameter-input .kb-method-parameter-accepted-glyph,.kb-method-parameter-input .kb-method-parameter-required-glyph{font-size:15px;margin-left:-15px}.kb-parameter-data-selection{font-weight:700}.kb-method-parameter-hint{color:#777;margin-top:3px;padding-left:7px;text-align:left}.kb-method-parameter-required-glyph{color:#f44336;margin-left:7px}.kb-method-parameter-accepted-glyph{color:#4bb856;margin-left:7px}.kb-method-parameter-info{margin-left:7px}.kb-method-advanced-options-controller-inactive,.kb-method-parameter-info,.kb-parameter-data-row-add,.kb-parameter-data-row-remove{color:#777}.kb-method-advanced-options-controller,.kb-method-advanced-options-controller-inactive{font:italic 700 13px/14px Oxygen,Arial,sans-serif;text-align:center}.kb-method-advanced-options-controller{color:#037ac0;cursor:pointer}.kb-method-advanced-options-controller:hover{color:#2a6496}.kb-method-footer{background-color:#f5f5f5;padding:10px;width:100%}.kb-method-subtitle{background-color:#f5f5f5;padding:3px 5px}.kb-app-panel{border-radius:0}.kb-app-error{background-color:#f2dede}.kb-app-step-container{margin-top:6px}.kb-app-panel>.panel-footer{border:0;border-radius:0}.kb-app-panel-description{color:#03517d;font:normal 400 16px/1 Oxygen,Arial,sans-serif}.kb-app-step-error-mssg{color:#a63232;font:11px/14px sans-serif;margin:10px;text-align:left}.kb-app-step-error-heading{color:#555;font:normal 700 17px/1 Oxygen,Arial,sans-serif;margin-top:20px;padding-left:5px;text-align:left}.kb-app-step-error-main-heading{color:#555;cursor:pointer;font:21px/1 Oxygen,Arial,sans-serif;margin-top:20px;padding-left:20px;text-align:left}.kb-app-step-error{border:3px solid #d14836;z-index:auto}.kb-app-step-running{border:3px solid #2196f3;z-index:auto}.kb-app-next{border-top:2px solid #cecece}.kb-app-next h3{color:#888;float:left;font:italic 400 .9em Oxygen,Arial,sans-serif;margin:0;padding:.5em 0 .25em}.kb-app-next-hide{float:right;margin-right:.5em}.kb-app-next-hide,.kb-app-next-unhide{color:#2196f3;font:.9em Oxygen,Arial,sans-serif;margin-top:.25em}.kb-app-next div{clear:both}@-webkit-keyframes pulse{0%{opacity:1}50%{opacity:.7}to{opacity:1}}@keyframes pulse{0%{opacity:1}50%{opacity:.7}to{opacity:1}}button.kb-app-run,button.kb-method-run{background-color:#2196f3;border:0;border-radius:1px;box-shadow:1px 1px 1px #ded5cb;color:#fff;font-size:13px;padding:10px 20px}button.kb-app-run:hover,button.kb-method-run:hover{background-color:#1e88e5}button.kb-app-run.kb-app-cancel{background-color:#f44336}button.kb-app-run.kb-app-cancel:hover{background-color:#e53935}.modal-body{max-height:100%}div[class=tooltip-inner]{max-width:400px;text-align:left;white-space:pre-wrap}.notebook_app .tooltip-inner{background-color:#1b69b6}.notebook_app .tooltip{z-index:2000!important}.notebook_app .tooltip.top .tooltip-arrow,.notebook_app .tooltip.top-left .tooltip-arrow,.notebook_app .tooltip.top-right .tooltip-arrow{border-top-color:#1b69b6}.notebook_app .tooltip.right .tooltip-arrow{border-right-color:#1b69b6}.notebook_app .tooltip.left .tooltip-arrow{border-left-color:#1b69b6}.notebook_app .tooltip.bottom .tooltip-arrow,.notebook_app .tooltip.bottom-left .tooltip-arrow,.notebook_app .tooltip.bottom-right .tooltip-arrow{border-bottom-color:#1b69b6}.kb-data-main-panel{height:100%;margin-bottom:5px;max-height:425px}#data-tabs{height:375px!important}.kb-ws-refresh-btn{position:absolute;right:5px}#kb-ws .form-control{margin:3px;width:85%}.kb-data-control{width:95%}.kb-data-table{max-height:265px;width:100%!important}.kb-data-table thead{max-width:100%;width:281px}.kb-data-table tbody tr{border-bottom:1px solid #dcdcdc}.kb-data-table tbody tr td{font-size:1em;max-height:16px;max-width:100px;padding:5px}.kb-data-table tbody tr td.highlighted,.kb-data-table tbody tr:hover{background-color:#f4f5d6;cursor:pointer}.kb-data-obj-name{display:inline-block;max-width:88%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-data-loading{height:100%;text-align:center}.kb-data-loading,.kb-data-loading img{vertical-align:middle}#kb-ws .dataTables_filter{display:none}button.kb-data-obj{float:right}.kb-data-obj-panel{background:linear-gradient(180deg,#00d2ff,#b2adcb);margin:10px;padding:0}.kb-data-obj-panel button.close{font-size:125%;margin:5px}.kb-data-obj-panel-info{background:hsla(0,0%,100%,.5);height:100%;padding:10px}.kb-data-obj-panel-graph{background:transparent;height:100%;padding:10px}.kb-data-obj-panel-graph table{background-color:hsla(0,0%,100%,.9);border:0;color:rgba(0,0,0,.8);width:100%}.kb-data-obj-panel-graph thead tr{background-color:#e6e6e6;color:#000}.kb-data-obj-panel-info dl{margin:0}.kb-data-obj-panel-info dl dt{clear:left;color:rgba(0,0,0,.5);float:left;text-align:right;width:90px}.kb-data-obj-panel-info dl dt:after{content:":"}.kb-data-obj-panel-info dl dd{margin:0 0 0 100px}.kb-data-obj-panel-verlist span{background-color:hsla(0,0%,100%,.5);border-radius:2px;color:rgba(0,0,0,.5);cursor:pointer;margin-left:3px;padding:0 5px}.kb-data-obj-panel-verlist span.selected{background-color:#2196f3;color:#fff;cursor:default}.kb-data-obj-graph-ref-to{margin-top:8px}.kb-primary-btn{background-color:#2196f3;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#fff;font:normal 400 14px Oxygen,Arial,sans-serif;margin:3px;padding:10px 20px}.kb-primary-btn:hover{background-color:#1e88e5}.kb-primary-btn[disabled]{background-color:#cce5f3;box-shadow:none;color:#fff}.kb-default-btn{background-color:#f5f5f5;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#555;font:normal 400 14px Oxygen,Arial,sans-serif;margin:3px;padding:10px 20px}.kb-default-btn:hover{background-color:#cecece}.kb-default-btn[disabled]{box-shadow:none;color:#aaa}.kb-btn-sm{font-size:13px;padding:5px 10px}.narrative-card-logo{display:flex;font-size:14px;margin-right:2px;width:50px}.narrative-card-row-main{align-items:center;display:flex;margin:0 2px;padding:0 4px;width:98%}.narrative-data-list-subcontent{padding-left:10px}.narrative-card-ellipsis{align-items:center;display:flex;justify-content:center;width:20px}.narrative-card-palette-icon{color:#888;left:15px;position:relative;top:-50px}.narrative-card-action-button-wrapper{height:50px;margin:0 10px;width:80px}.narrative-card-action-button{display:flex;height:80%;justify-content:center;padding:10px 0;width:calc(100% - 6px)}.narrative-card-action-button>span{margin-right:5px}.narrative-card-action-button-name{display:inline-block}.narrative-data-panel-btnToolbar{display:flex;justify-content:center}.narrative-data-panel-btnToolbar>span{color:#888}.kb-data-list-obj-row,.narrative-card-row{border-left:5px solid #fff;box-shadow:1px 1px 1px 1px #fff;color:#333;transition:all .1s ease}.kb-function-dim .kb-data-list-obj-row{border-left-color:#f2efeb}.kb-data-list-obj-row:hover,.narrative-card-row:hover{border-left:5px solid #4bb856;box-shadow:1px 1px 1px 1px #aaa}.palette{background:#f5f5f5!important}.kb-data-list-obj-row-selected{border-left:5px solid #4bb856;box-shadow:1px 1px 1px 1px #aaa}.kb-data-list-obj-row-main{margin:0;padding:0;width:100%}.kb-data-list-nav-buttons{border:0;box-shadow:none;font-size:18px;margin:0;padding:5px 8px;text-shadow:none!important}.kb-data-list-add-data-button{background-color:#4379b1;border:0;box-shadow:1px 1px 3px #aaa;text-align:center}#kb-add-code-cell,#kb-add-md-cell,.kb-data-list-add-data-button{border-radius:50%;color:#fff;cursor:pointer;height:40px;width:40px}#kb-add-code-cell,#kb-add-md-cell{background-color:#2196f3;bottom:15px;box-shadow:2px 2px 1px #cecece;opacity:.5;padding-top:5px;position:fixed;z-index:5}#kb-add-code-cell{padding-left:7px;right:75px}#kb-add-md-cell{margin-right:20px;padding-left:8px;right:10px}#kb-add-code-cell:hover,#kb-add-md-cell:hover,.kb-data-list-add-data-button:hover{background-color:#36618e;cursor:pointer;opacity:1}.kb-data-list-add-data-text-button{background-color:#4379b1;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#fff;font:normal 400 14px Oxygen,Arial,sans-serif;margin:3px;padding:10px 20px}.kb-data-list-add-data-text-button:hover{background-color:#36618e}.kb-data-list-btn{background-color:#2196f3;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#fff;font-size:13px;margin:5px;padding:5px 10px}.kb-data-list-btn:hover{background-color:#1e88e5}.kb-data-list-btn[disabled]{background-color:#cce5f3;box-shadow:none;color:#fff}.kb-data-list-cancel-btn{background-color:#f5f5f5;border:0;border-radius:1px;box-shadow:1px 1px 3px #aaa;color:#888;font-size:13px;margin:5px;padding:5px 10px}.kb-data-list-cancel-btn:hover{background-color:#cecece}.kb-data-list-row-hr{margin:2px auto;width:70%}.kb-data-list-info{border-bottom:1px solid #e0e0e0;min-height:60px;padding:6px 0;width:80%}.kb-data-list-name{color:#03517d;cursor:pointer;font:normal 700 15px Oxygen,Arial,sans-serif;margin:2px}.kb-data-list-name:hover{text-decoration:underline}.kb-data-list-version{color:#777;cursor:default;font-size:12px;font-style:italic;white-space:nowrap}.kb-data-list-date,.kb-data-list-type{color:#777;cursor:default;font-size:13px;margin:2px}.kb-data-list-date{white-space:nowrap}.kb-data-list-edit-by{color:#777;cursor:pointer;font-size:13px;margin:2px 2px 2px 0;white-space:nowrap}.kb-data-list-edit-by:hover{color:#444}.kb-data-list-narinfo{color:#777;font-size:13px;margin:2px 2px 2px 10px}.kb-data-list-narrative-error{color:#f44336;font-size:13px;margin:2px}.kb-data-list-narrative{color:#777;font-size:13px;margin:2px 2px 2px 10px}.kb-data-list-more{color:#777;font-size:11px;margin:0 0 0 15px;padding:0;white-space:nowrap}.kb-data-list-more-btn{border:0;box-shadow:none;font-size:12px;margin:0;padding:2px 4px;text-shadow:none!important}.kb-data-list-more-div{align-items:center;display:flex;flex-direction:column}.kb-data-list-more-div,.kb-data-list-more-div td,.kb-data-list-more-div th,.kb-data-list-more-div tr{color:#777;font-size:13px;margin:2px}.kb-data-list-more-div tr:hover{background-color:#f2efeb}.kb-data-list-more-div tr:nth-child(odd){background-color:#f5f5f5}.kb-data-list-more-div tr:hover:nth-child(odd){background-color:#f2efeb}.kb-data-list-more-div th{font-weight:700;text-align:right}.kb-data-list-more-div td{padding-left:8px;text-align:left;word-break:break-all}.kb-data-list-job-name:hover{text-decoration:none}.kb-data-list-box>.kb-data-list-box{margin-left:40px}.kb-data-list-ctl span.inviso{background-color:#fff;color:#fff;text-shadow:none}.kb-data-list-ctl[enabled]{background-color:#d3d3d3}.kbcb-browser-container{margin:0 auto}.kbcb-back-link{padding:.4em}.kbcb-ctr-toolbar{margin:.4em}.kbcb-main-panel-div{margin:0}.kbcb-loading-panel-div{margin:.1em;text-align:center;vertical-align:middle}.kbcb-app-card-link{text-decoration:none}.kbcb-app-card-list-container{overflow:auto;padding:0 .2em 1em}.kbcb-app-card-container{display:block;float:left;height:110px;margin:.4em;position:relative;width:300px}.kbcb-app-card{background:#f1f1f5;border-radius:2px;color:#6a6158;height:100%;overflow:hidden;text-align:center;vertical-align:middle;width:100%}.kbcb-app-card-header{max-height:90px;overflow:hidden;text-align:left}.kbcb-app-card-title-panel{padding:10px 5px 5px 10px}.kbcb-app-card-title{font-size:1.1em}.kbcb-app-card-authors,.kbcb-app-card-module{font-size:.8em}.kbcb-app-card-subtitle{font-size:.9em;overflow:hidden;padding:10px}.kbcb-app-card-footer{bottom:0;color:#888;font-size:.9em;left:0;margin:0 5px 5px;position:absolute;width:100%}.kbcb-app-card-logo{font-size:14px;margin:0;padding:0}.kbcb-star-default{color:#888}.kbcb-star-favorite{color:orange}.kbcb-star-default,.kbcb-star-favorite,.kbcb-star-nonfavorite{cursor:pointer}.kbcb-star-default:hover,.kbcb-star-nonfavorite:hover{color:red}.kbcb-star-favorite:hover{color:orange}.kbcb-run-count,.kbcb-star-count{display:inline-block;margin-left:.3em}.kbcb-info:hover{color:orange}.kbcb-hover{box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);transition:all .2s ease-in-out}.kbcb-hover:hover{box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23);cursor:pointer}.kbcb-app-page{background:#f1f1f5;border-radius:2px;color:#6a6158;text-align:center}.kbcb-app-page-header{text-align:left}.kbcb-app-page-title-panel{padding:10px 5px 5px 0}.kbcb-app-page-title{font-size:2em}.kbcb-app-page-module{font-size:1.2em}.kbcb-app-page-authors{font-size:1em;margin:.3em 0 0}.kbcb-app-page-subtitle{font-size:1.2em;padding:1.5em 2em 0}.kbcb-app-page-stats-bar{font-size:1.2em;padding:0 2em .8em 3em;width:100%}.kbcb-app-page-logo{margin:1em;padding:0;text-align:center}.kb-share-user-permissions-dropdown{border:0;box-shadow:none;height:auto;padding:2px;text-shadow:none!important;width:auto}.kb-share-select{width:200px}.kb-share-select .select2-selection__choice{background-color:#f5f5f5!important;width:100%!important}.kb-nar-manager-titles{color:#777;font:normal 700 19px Oxygen,Arial,sans-serif;margin:20px 10px 10px}.kb-import-content{display:block;margin:0;position:relative}.kb-import-content .btn-xs{border:0}.ftp-file-header{margin:1rem 0}.globus-link:hover{text-decoration:none}.kb-import-content .upload-options button{background:#fff;border:1px solid silver;border-radius:6px;box-sizing:border-box;color:#000;font:normal 400 14px/18px Oxygen,Arial,sans-serif;height:42px;margin:0 6px;text-align:center;width:140px}.kb-import-content .upload-options button:hover{background-color:#fafafa;border:1px solid #cfcfcf}.kb-import-content .upload-options button:focus{background-color:#f2f2f2}.kb-import-content .upload-options button:active{background-color:#e6e6e6}.kb-import-content .upload-options button:disabled{background-color:#fafafa;color:#929292}.kb-overlay-footer{bottom:0;height:50px;position:absolute;width:100%}.kb-overlay-footer .btn-default,.kb-overlay-footer .btn-primary{margin:15px 15px 0 0}.kb-import-filter,.kb-import-search{margin:10px 40px 10px 10px}.kb-import-item{margin:0 20px 0 5px;padding:20px 0 0}.kb-import-item:hover{background-color:#f8f8f8;box-shadow:0 0 2px #aaa}.kb-import-item hr{border:2px solid #eaeaea;margin-bottom:0;margin-top:15px;width:85%}.kb-import-item .kb-import-checkbox{font-size:1.5em;opacity:.4;padding:15px 20px}.kb-import-item .fa-check-square-o{opacity:1!important}.kb-import-info{display:inline-block;font-weight:400;margin:10px 20px 0 0}.kb-import-info span{color:#9d9389;font-size:.9em;font-weight:700}.kb-import-status{margin:20px}.kb-error-dialog strong{color:#006400}.kb-err-text{color:#000;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.kb-err-warn{color:#b22222;font-style:italic;margin-top:.5em}#kb-ro-btn{margin-right:20px}#kb-view-mode{cursor:pointer;display:inline-block;font-size:17px;margin:-15px 0 0 1em;padding:0}#kb-view-mode-narr div{color:#2196f3;display:inline-block;font:normal 700 16px Oxygen,Arial,sans-serif;margin-top:-3px;padding:3px;position:fixed;text-align:left;width:147px}#kb-view-mode-narr-hide{background-color:#2196f3;color:#cce5f3;cursor:pointer;display:block;float:left;font-size:16px;height:41px;padding-left:5px;width:15px}#kb-view-mode-narr-hide span{margin-top:10px}.navbar-right div.label-warning{font:normal 700 16px Oxygen,Arial,sans-serif}#popdiv{background-color:#fcfcfc;border:1px solid #ded5cb;font-size:12px;position:absolute;visibility:hidden;z-index:10000}#popdiv a.alt{border:0;display:inline;font:12px OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;padding-left:9px}.kb-loading-spinner{padding:1rem;text-align:center}.fa.fa-14-pt{font-size:19px}[data-icon]:before{content:attr(data-icon)}[class*=" icon-"]:before,[class^=icon-]:before,[data-icon]:before{font-family:kbase-icons!important;font-style:normal!important;font-variant:normal!important;font-weight:400!important;text-transform:none!important}.icon-compare:before{content:"a"}.icon-genome:before{content:"b"}.icon-metabolism:before{content:"c"}.icon-metagenome:before{content:"d"}.icon-reads:before{content:"e"}.icon-tree:before{content:"f"}.app-icon:hover{opacity:.9}.app-icon:hover,.nav>li>a:focus,.nav>li>a:hover{text-decoration:none}#kbase-search-box{width:300px}#signin-button{display:inline-block;padding:0 15px 0 0}.wrapper{margin-left:auto;margin-right:auto;width:95%}#core-model{overflow-x:auto}#logo{margin:2px 10px 0}table{font-size:14px!important}.media-info-modal{width:800px}#selected-workspace{margin:17px 14px 15px 0}.tab-view{margin:10px 0 0}.search-query{margin:0 0 5px;width:100%}.caret-up{border-color:currentcolor transparent #fff;border-style:dotted solid solid;border-width:0 4px 4px;content:"";display:inline-block;height:0;margin-left:2px;vertical-align:middle;width:0}.scroll-pane{height:200px;overflow-x:hidden;overflow-y:scroll}#select-box tr td{padding:6px}.selected-ws{background-color:#428bca;color:#fff}.selected-ws:hover{background-color:#428bca!important}.side-bar-switch{margin:0 0 10px}.side-bar-switch li{font-size:12px}.side-bar-switch li a{padding:5px 10px}.selected-obj-alert{margin-bottom:5px;padding-bottom:10px;padding-top:10px}.heatmap-view{overflow-x:scroll}.ws-selector{margin:10px 0 0}.ws-selector.btn-ws-settings{position:absolute;right:30px}.object-view{margin:10px 0 0}.select-ws .badge{margin:0 4px 0 0}.select-ws .btn-ws-settings{padding:0 5px}.modal-alert{margin:10px 15px 0;padding:8px 15px}.modal-cover{position:absolute;z-index:10}.modal-cover-table{display:table;height:100%;position:static;width:100%}.modal-cover-cell{display:table-cell;position:static;vertical-align:middle}.modal-cover-box{box-shadow:7px 7px 5px #888;display:inline-block;margin:10px;padding:5px 15px}.modal-cover-content{background:#fff;border:1px solid #6a6158;border-radius:3px;padding:5px}.obj-table .dataTables_length label{margin:7px 0 0}.dataTables_info{float:left;margin:0 10px 0 0}.dataTables_length{float:left}.ellipsis{max-width:170px}.ellipsis,.ws-descript{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ws-descript{max-width:400px}.ncheck{border:1px solid #ded5cb;height:15px;margin-left:auto;margin-right:auto;width:15px}.ncheck:hover{border:1px solid #444}.ncheck-btn{border:1px solid #888;height:15px;margin:4px 0 4px -1px;width:15px}.ncheck-btn:hover{border:1px solid #444}.ncheck-checked{background:url(../img/checkmark.png) no-repeat -5px -4px;background-image:-webkit-image-set(url(../img/checkmark.png) 1x,url(../img/checkmark_2x.png) 2x);background-image:image-set(url(../img/checkmark.png) 1x,url(../img/checkmark_2x.png) 2x)}.ncheck-minus{background:url(../img/checkmark-partial.png) no-repeat -5px -5px;background-image:-webkit-image-set(url(../img/checkmark-partial.png) 1x,url(../img/checkmark-partial_2x.png) 2x);background-image:image-set(url(../img/checkmark-partial.png) 1x,url(../img/checkmark-partial_2x.png) 2x)}.btn-select-all{height:34px}.btn-select-all,.type-filter{margin:0 20px 0 0}.btn-trash{margin:3px 20px 0 0}.btn-show-info .glyphicon{padding:0 0 4px}.open-obj{margin:7px 0 0 20px}#login-form{margin:70px 0 0}#narrative-nav,.recent-narratives,.recent-projects{margin:0;padding:0}.group-item-expander{background:#f2f2f2}.group-item-expander:hover{cursor:hand;cursor:pointer}.btn-new-narrative{margin:0 20px 0 0}.btn-delete-narrative{cursor:hand;cursor:pointer}.btn-delete-narrative:hover{opacity:.7}.navbar-fixed-top{z-index:500}.FixedHeader_Header{background:#fff;height:44px;margin:-6px 0 0}.narrative-sidebar li{list-style:none}@media (min-width:960px){.narrative-sidebar{position:fixed;width:20%}}.sidebar-header,.view-header{color:#898989;font-family:RobotoBlack,Arial,sans-serif;font-weight:400;letter-spacing:0}.sidebar-header{font-size:14px}.view-header{font-size:1.5em;line-height:1.75}.active .btn-narr{background-color:#bbe8f9;border:1px solid #428bca}.active .btn-narr,.btn-narr{padding-left:20px;padding-right:20px;text-align:left}.btn-narr{background-color:#f2f2f2;border:1px solid #dbdbdb;color:#6da8cf;font:14px RobotoBlack,Arial,sans-serif}.nav-sidebar{top:70px}.nav-sidebar li{font-family:RobotoBlack,Arial,sans-serif;list-style:none;margin-bottom:10px;text-align:left}.nav-sidebar>li>a{padding:7px 15px}.navbar-nav{color:#6da8cf;font-family:RobotoBlack,Arial,sans-serif}.navbar-nav>li>a:hover{background-color:#fff}.navbar-nav>li.active:hover,.navbar-nav>li.active>a{border-bottom:4px solid #428bca;box-sizing:border-box;color:#2a6496!important;height:50px}.navbar-nav>.active:hover{color:#2a6496}#wrap{height:auto;margin:0 auto -58px;min-height:100%;padding:0 0 80px}#footer{height:58px}#footer ul{text-align:center}#footer ul li{display:inline;padding:7px 5px 5px 1px}#footer ul li:after{color:#bbb;content:"•";font-size:10px;padding-left:10px}#footer ul li:last-child:after,#footer ul li:nth-last-child(2):after{content:""}#footer img{position:relative;top:-3px}#footer .disclaimer{background-color:#a94442;bottom:0;color:#fff;display:block;font-weight:700;position:fixed;text-align:center;width:100%}.KBSnode rect{fill:#fff;fill-opacity:.5;stroke:#3182bd;stroke-width:1.5px;cursor:pointer}.KBSnode text{font:80% sans-serif;pointer-events:none}.modal-body .dataTables_processing{background:#e8f9ff;border:1px solid #aaa;opacity:.8}.kb-editor{margin:0 10px}.kb-editor .tab-content{margin:5px 0 0}.kb-editor .controls{margin:5px 0}.kb-editor .controls .btn{margin:0 10px}.kb-editor .btn-primary{background-color:#337ab7!important;border-color:#2e6da4!important}.kb-editor .btn-danger{background-color:#d9534f!important;border-color:#d43f3a!important}.kb-editor .btn i{color:#fff}.kb-editor table{border:1px solid #bbb}.kb-editor-table{width:100%!important}.kb-editor-table>tbody>tr>td:first-child{width:1%}.kb-editor-table>tbody>tr>td:first-child .fa-square-o{color:#6a6158;font-size:1.4em}.kb-editor-table>tbody>tr>td:first-child:hover{cursor:pointer}.kb-editor-table>tbody>tr>td:first-child:hover .fa-square-o{color:#000}.kb-editor-table>tbody>tr.row-select .fa-square-o:before{color:#444;content:"\f046"}.kb-editor-table>tbody>tr>td.editable{position:relative}.kb-editor-table>tbody>tr>td.editable:hover:after{bottom:0;color:#888;content:"\f044";font-family:FontAwesome;position:absolute;right:2px}.kb-notify{background-color:#000;bottom:10px;color:#fff;opacity:.8;padding:15px;position:relative;width:300px}.kb-notify.kb-notify-success{color:#00cc09}.kb-method-cell select.form-control{margin:0}.twitter-typeahead{width:100%}.code_cell div.input_area{display:none}.code_cell div.input_area.-show{display:block}.text-silver{color:silver}.modal .modal-title{font:normal 700 18px/24px Oxygen,Arial,sans-serif}.modal.kb-modal-alert .modal-title{color:unset}.modal input[type=checkbox]{margin-top:1px}.kb-panel-batch,.kb-panel-bulk-params,.kb-panel-container,.kb-panel-light,.kb-panel-params,.kb-panel-results{border:0;box-shadow:none}.kb-panel-batch .panel-heading,.kb-panel-bulk-params .panel-heading,.kb-panel-container .panel-heading,.kb-panel-light .panel-heading,.kb-panel-params .panel-heading,.kb-panel-results .panel-heading{background-color:transparent;color:#6a6158;font-weight:700}.kb-panel-light{margin-bottom:10px}.kb-panel-light.panel-danger .panel-title{color:#a94442}.kb-panel-light.panel-success .panel-title{color:#3c763d}.kb-panel-light.panel-warning .panel-title{color:#8a6d3b}.kb-panel-light.panel-info .panel-title{color:#00f}.kb-panel-light .panel-heading{border-bottom:0;padding-bottom:2px}.kb-panel-light .panel-body{padding:0}.kb-panel-batch .panel-heading,.kb-panel-bulk-params .panel-heading,.kb-panel-params .panel-heading,.kb-panel-results .panel-heading{border-bottom:0;margin:15px 15px 5px;padding:0}.kb-panel-batch .panel-body,.kb-panel-bulk-params .panel-body,.kb-panel-params .panel-body,.kb-panel-results .panel-body{border-bottom:0;margin:0 15px 5px;padding:0}.kb-panel-params .panel-body{margin:0 10px 15px}.panel-title-collapse-toggle{margin-left:-15px}.kb-panel-container .panel-heading{border-bottom:2px solid #ded5cb;padding-bottom:2px}.kb-cell-error .panel-heading{background-image:none;padding:5px 10px}.btn{box-shadow:none}.btn-toolbar.kb-btn-toolbar-cell-widget{background-color:#f2efeb;margin-bottom:20px;padding:6px}.dataTables_empty{padding:.8rem}.btn.kb-flat-btn{background-color:#fff;border:0;color:#6a6158;margin:0;text-shadow:none!important}.btn.kb-flat-btn .kb-nav-btn-txt{font-size:13px;margin-top:-5px}.btn.kb-flat-btn:active,.btn.kb-flat-btn:hover{background-color:#ded5cb}.kb-flat-btn-wrapper{box-shadow:none}.dz-clear-all__button,.kb-bulk-import-configure__button--generate-template,.kb-bulk-import-info__button--generate-template,.kb-data-staging__button,.kb-file-path__button--add_row,.kb-file-path__button--delete,.kb-job-status__cell_action--cancel,.kb-job-status__cell_action--go-to-results,.kb-job-status__cell_action--retry,.kb-staging-table-body__button--decompress,.kb-staging-table-body__button--delete,.kb-staging-table-body__button--download,.kb-staging-table-body__button--folder,.kb-staging-table-import__button{border:1px solid transparent;border-radius:4px;cursor:pointer;display:inline-block;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:700;line-height:1.428571429;padding:.6rem 1.2rem;text-align:center;text-transform:uppercase;touch-action:manipulation;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;white-space:nowrap}.dz-clear-all__button:focus,.focus.dz-clear-all__button,.focus.kb-bulk-import-configure__button--generate-template,.focus.kb-bulk-import-info__button--generate-template,.focus.kb-data-staging__button,.focus.kb-file-path__button--add_row,.focus.kb-file-path__button--delete,.focus.kb-job-status__cell_action--cancel,.focus.kb-job-status__cell_action--go-to-results,.focus.kb-job-status__cell_action--retry,.focus.kb-staging-table-body__button--decompress,.focus.kb-staging-table-body__button--delete,.focus.kb-staging-table-body__button--download,.focus.kb-staging-table-body__button--folder,.focus.kb-staging-table-import__button,.kb-bulk-import-configure__button--generate-template:focus,.kb-bulk-import-info__button--generate-template:focus,.kb-data-staging__button:focus,.kb-file-path__button--add_row:focus,.kb-file-path__button--delete:focus,.kb-job-status__cell_action--cancel:focus,.kb-job-status__cell_action--go-to-results:focus,.kb-job-status__cell_action--retry:focus,.kb-staging-table-body__button--decompress:focus,.kb-staging-table-body__button--delete:focus,.kb-staging-table-body__button--download:focus,.kb-staging-table-body__button--folder:focus,.kb-staging-table-import__button:focus{outline:5px auto Highlight;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.dz-clear-all__button:focus,.dz-clear-all__button:hover,.focus.dz-clear-all__button,.focus.kb-bulk-import-configure__button--generate-template,.focus.kb-bulk-import-info__button--generate-template,.focus.kb-data-staging__button,.focus.kb-file-path__button--add_row,.focus.kb-file-path__button--delete,.focus.kb-job-status__cell_action--cancel,.focus.kb-job-status__cell_action--go-to-results,.focus.kb-job-status__cell_action--retry,.focus.kb-staging-table-body__button--decompress,.focus.kb-staging-table-body__button--delete,.focus.kb-staging-table-body__button--download,.focus.kb-staging-table-body__button--folder,.focus.kb-staging-table-import__button,.kb-bulk-import-configure__button--generate-template:focus,.kb-bulk-import-configure__button--generate-template:hover,.kb-bulk-import-info__button--generate-template:focus,.kb-bulk-import-info__button--generate-template:hover,.kb-data-staging__button:focus,.kb-data-staging__button:hover,.kb-file-path__button--add_row:focus,.kb-file-path__button--add_row:hover,.kb-file-path__button--delete:focus,.kb-file-path__button--delete:hover,.kb-job-status__cell_action--cancel:focus,.kb-job-status__cell_action--cancel:hover,.kb-job-status__cell_action--go-to-results:focus,.kb-job-status__cell_action--go-to-results:hover,.kb-job-status__cell_action--retry:focus,.kb-job-status__cell_action--retry:hover,.kb-staging-table-body__button--decompress:focus,.kb-staging-table-body__button--decompress:hover,.kb-staging-table-body__button--delete:focus,.kb-staging-table-body__button--delete:hover,.kb-staging-table-body__button--download:focus,.kb-staging-table-body__button--download:hover,.kb-staging-table-body__button--folder:focus,.kb-staging-table-body__button--folder:hover,.kb-staging-table-import__button:focus,.kb-staging-table-import__button:hover{color:#026daa;text-decoration:none}.active.dz-clear-all__button,.active.kb-bulk-import-configure__button--generate-template,.active.kb-bulk-import-info__button--generate-template,.active.kb-data-staging__button,.active.kb-file-path__button--add_row,.active.kb-file-path__button--delete,.active.kb-job-status__cell_action--cancel,.active.kb-job-status__cell_action--go-to-results,.active.kb-job-status__cell_action--retry,.active.kb-staging-table-body__button--decompress,.active.kb-staging-table-body__button--delete,.active.kb-staging-table-body__button--download,.active.kb-staging-table-body__button--folder,.active.kb-staging-table-import__button,.dz-clear-all__button:active,.kb-bulk-import-configure__button--generate-template:active,.kb-bulk-import-info__button--generate-template:active,.kb-data-staging__button:active,.kb-file-path__button--add_row:active,.kb-file-path__button--delete:active,.kb-job-status__cell_action--cancel:active,.kb-job-status__cell_action--go-to-results:active,.kb-job-status__cell_action--retry:active,.kb-staging-table-body__button--decompress:active,.kb-staging-table-body__button--delete:active,.kb-staging-table-body__button--download:active,.kb-staging-table-body__button--folder:active,.kb-staging-table-import__button:active{background-image:none;box-shadow:inset 0 3px 5px rgba(0,0,0,.125);outline:0}.disabled.dz-clear-all__button,.disabled.kb-bulk-import-configure__button--generate-template,.disabled.kb-bulk-import-info__button--generate-template,.disabled.kb-data-staging__button,.disabled.kb-file-path__button--add_row,.disabled.kb-file-path__button--delete,.disabled.kb-job-status__cell_action--cancel,.disabled.kb-job-status__cell_action--go-to-results,.disabled.kb-job-status__cell_action--retry,.disabled.kb-staging-table-body__button--decompress,.disabled.kb-staging-table-body__button--delete,.disabled.kb-staging-table-body__button--download,.disabled.kb-staging-table-body__button--folder,.disabled.kb-staging-table-import__button,[disabled].dz-clear-all__button,[disabled].kb-bulk-import-configure__button--generate-template,[disabled].kb-bulk-import-info__button--generate-template,[disabled].kb-data-staging__button,[disabled].kb-file-path__button--add_row,[disabled].kb-file-path__button--delete,[disabled].kb-job-status__cell_action--cancel,[disabled].kb-job-status__cell_action--go-to-results,[disabled].kb-job-status__cell_action--retry,[disabled].kb-staging-table-body__button--decompress,[disabled].kb-staging-table-body__button--delete,[disabled].kb-staging-table-body__button--download,[disabled].kb-staging-table-body__button--folder,[disabled].kb-staging-table-import__button,fieldset[disabled] .dz-clear-all__button,fieldset[disabled] .kb-bulk-import-configure__button--generate-template,fieldset[disabled] .kb-bulk-import-info__button--generate-template,fieldset[disabled] .kb-data-staging__button,fieldset[disabled] .kb-file-path__button--add_row,fieldset[disabled] .kb-file-path__button--delete,fieldset[disabled] .kb-job-status__cell_action--cancel,fieldset[disabled] .kb-job-status__cell_action--go-to-results,fieldset[disabled] .kb-job-status__cell_action--retry,fieldset[disabled] .kb-staging-table-body__button--decompress,fieldset[disabled] .kb-staging-table-body__button--delete,fieldset[disabled] .kb-staging-table-body__button--download,fieldset[disabled] .kb-staging-table-body__button--folder,fieldset[disabled] .kb-staging-table-import__button{box-shadow:none;cursor:not-allowed;opacity:.8}.kb-staging-table-body__button--decompress{border-radius:3px;line-height:1.5;padding:.5rem 1rem}.kbcb-tooltip{background-color:#222;color:#fff;opacity:.8;padding:.5em;position:absolute;visibility:hidden;z-index:9999999}.kbcb-widget .kbcb-axis line,.kbcb-widget .kbcb-axis path{fill:none;shape-rendering:crispEdges;stroke:#000}.kbcb-widget .kbcb-axis text{font:11px sans-serif}.kbcb-feature{fill:red;stroke:#000}.kbcb-operon{fill:#0f0}.kbcb-center{fill:#00f}.kbcb-highlight{fill:#fff}.kbcb-buttons{margin-left:auto;margin-right:auto;width:70%}.kb-tour{background-color:#2196f3}.kb-tour.popover.top>.arrow:after{border-top-color:#2196f3}.kb-tour.popover.bottom>.arrow:after{border-bottom-color:#2196f3}.kb-tour.popover.right>.arrow:after{border-right-color:#2196f3}.kb-tour.popover.left>.arrow:after{border-left-color:#2196f3}.kb-tour>h3.popover-title{background-color:#2196f3;color:#fff;font:16px Oxygen,Arial,sans-serif}.kb-tour>.popover-content,.kb-tour>.popover-navigation{background-color:#f2efeb}.kb-tour>.close-btn{position:absolute;right:7px;top:7px}.batch-mode-col{overflow:auto;padding:5px 10px}.job-info{cursor:pointer}.job-info.job-selected{background-color:#f2efeb}.batch-mode-list{max-height:860px;overflow:auto}.batch-input-panel{max-height:300px;overflow:auto}.kb-advanced-view-cell .kb-panel-container[data-element=parameters-group]>div.panel-collapse>.panel-body{padding:0}.kb-error-dialog__body .tab-content{padding-top:1rem}.kb-error-dialog__err_message,.kb-error-dialog__err_preamble{margin:1rem 0}.kb-error-dialog__stacktrace_container{word-wrap:break-word;background-color:#f2efeb;border:0;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px;margin:0;max-height:50rem;overflow-wrap:break-word;overflow-y:auto;padding:1rem;word-break:break-word}.kb-app-cell__container{align-items:stretch;display:flex;font-family:Oxygen,Arial,sans-serif}.kb-app-cell__prompt{align-items:stretch;display:flex;flex-direction:column}.kb-app-cell__body{align-items:stretch;display:flex;flex:1;flex-direction:column;width:100%}.kb-app-cell__widget_container{display:block;width:100%}.kb-app-cell-tab-pane__container--jobStatus,.kb-app-cell-tab-pane__container--results{padding:1.5rem}.kb-app-cell .kb-app-warning{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-app-cell .kb-app-parameter-panel{border-left:3px solid #fff}.kb-app-cell .kb-app-parameter-panel-hover{border-left:3px solid #428bca}.kb-app-cell .kb-app-parameter-row{border-radius:5px;margin:0;padding:5px}.kb-app-cell .kb-app-parameter-row:hover{background-color:rgba(0,0,0,.03)}.kb-app-cell .kb-app-parameter-row-hover{background:#f9f9f9}.kb-app-cell .kb-app-parameter-row .message{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-app-cell .kb-app-parameter-row .message.-error{background:#f2dede;color:#f44336}.kb-app-cell .kb-app-parameter-name{color:#777;font-family:Oxygen,Arial,sans-serif;padding-left:0;padding-right:4px;text-align:left;vertical-align:bottom;white-space:normal}.kb-app-cell .kb-app-parameter-input{vertical-align:middle}.kb-app-cell .kb-app-parameter-input select.form-control{margin:0}.kb-app-cell .kb-app-parameter-input .kb-app-parameter-accepted-glyph,.kb-app-cell .kb-app-parameter-input .kb-app-parameter-required-glyph{font-size:15px;margin-left:0}.kb-app-cell .kb-app-parameter-required-glyph{color:#f44336}.kb-app-cell .kb-parameter-data-selection{font-weight:700}.kb-app-cell .kb-app-parameter-hint{color:#777;margin-top:3px;padding-left:7px;text-align:left}.kb-app-cell .kb-app-parameter-accepted-glyph{color:#4bb856}.kb-app-cell .kb-app-advanced-options-controller-inactive,.kb-app-cell .kb-app-parameter-info,.kb-app-cell .kb-parameter-data-row-add,.kb-app-cell .kb-parameter-data-row-remove{color:#777}.kb-app-cell .kb-app-advanced-options-controller,.kb-app-cell .kb-app-advanced-options-controller-inactive{font:italic 700 13px/14px Oxygen,Arial,sans-serif;text-align:center}.kb-app-cell .kb-app-advanced-options-controller{color:#037ac0;cursor:pointer}.kb-app-cell .kb-app-advanced-options-controller:hover{color:#2a6496}.kb-app-cell .kb-app-footer{background-color:#f5f5f5;padding:10px;width:100%}.kb-app-cell .kb-app-subtitle{background-color:#f5f5f5;padding:3px 5px}.kb-app-cell .advanced-parameter-showing{display:block}.kb-app-cell .advanced-parameter-hidden{display:none}.kb-app-cell [data-element=run-control-panel]{width:100%}.kb-app-cell [data-element=tab-pane]{border-top:2px solid #2196f3}.kb-app-cell [data-element=tab-pane]>div{padding:0}.kb-app-row-clip-btn-addon,.kb-app-row-close-btn-addon{background:transparent;border:0}.kb-app-row-clip-btn-addon{height:100%;padding:0 10px 0 0}.kb-app-row-clip-btn-addon:active:after{background-color:#fff;border:1px solid grey;border-radius:3px;content:"copied!";margin-top:-5px;padding:7px;position:absolute}.kb-input-group-wide{width:100%}.kb-input-row-flex{align-items:center;display:flex;flex-direction:row}.cell.selected .btn-default.kb-app-row-close-btn{color:grey}.kb-app-row-clip-btn,.kb-app-row-close-btn{background-color:transparent;border:0;color:grey;height:100%;margin-left:1px}.kb-app-parameter-right-error-bar{background:red;height:28px}.kb-app-field-feedback,.kb-input-group-addon{background:transparent;border:0}.kb-input-group-addon{padding:0 0 0 10px}.unselected .kb-app-cell{opacity:.5}.kb-elapsed-time{font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.kb-elapsed-time.-active{color:#0f0}.kb-app-cell-info-desc{border:1px solid #777;margin-right:10px;min-height:100px;padding:10px}.kb-app-cell-info{color:#777;font:16px Oxygen,Arial,sans-serif}.kb-app-cell-info .header{border-bottom:1px solid #777;margin-bottom:8px;padding:5px 0}.kb-app-cell-info .value{color:#000}.btn.batch-active{background-color:#f2efeb;border-color:#adadad;box-shadow:inset 0 3px 7px rgba(0,0,0,.125)}.btn.batch-active:hover{background-color:#ded5cb}.btn.kb-app-cell-btn{background-color:#fff;margin-bottom:4px}.btn.kb-app-cell-btn,.btn.kb-app-cell-btn.btn-primary{border:2px solid #2196f3;color:#2196f3}.btn.kb-app-cell-btn.btn-primary:hover{border-bottom:6px solid #2196f3;margin-bottom:0}.btn.kb-app-cell-btn.btn-primary.active,.btn.kb-app-cell-btn.btn-primary:active,.btn.kb-app-cell-btn.btn-primary:hover{background-color:#2196f3;color:#fff}.btn.kb-app-cell-btn.btn-primary.active{border:solid #2196f3;border-width:2px 2px 6px;margin-bottom:0}.btn.kb-app-cell-btn.btn-primary.active:hover{background-color:#ddd;border-bottom:2px solid #2196f3;color:#2196f3;margin-bottom:4px}.btn.kb-app-cell-btn.btn-danger{border:2px solid #d15241;color:#d15241}.btn.kb-app-cell-btn.btn-danger:hover{border-bottom:6px solid #d15241}.btn.kb-app-cell-btn.btn-danger.active,.btn.kb-app-cell-btn.btn-danger:hover{background-color:#d15241;color:#fff;margin-bottom:0}.btn.kb-app-cell-btn.btn-danger.active{border:solid #d15241;border-width:2px 2px 6px}.btn.kb-app-cell-btn.btn-danger.active:hover{background-color:#ddd;border-bottom:2px solid #d15241;color:#d15241;margin-bottom:4px}.btn.kb-app-cell-btn.disabled,.btn.kb-app-cell-btn.disabled:active,.btn.kb-app-cell-btn.disabled:hover{background-color:#fff;border:2px solid #888;color:#888;margin-bottom:4px}.kb-app-status-ok{color:#4bb856}.kb-app-status-warning{color:orange}.kb-app-status-danger,.kb-app-status-error{color:#d15241}.kb-app-status-default{color:#2196f3}.parameter-panel .info-panel{background:transparent;padding-top:4px}.tt-input,.tt-query{box-shadow:inset 0 1px 1px rgba(0,0,0,.075);width:100%}.tt-hint{color:#999}.tt-menu{background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:4px;box-shadow:0 5px 10px rgba(0,0,0,.2);margin-top:4px;padding:4px 0;width:100%}.tt-suggestion{line-height:24px;padding:3px 20px}.tt-suggestion.tt-cursor,.tt-suggestion:hover{background-color:#0097cf;color:#fff}.tt-suggestion p{margin:0}.tt-header{font-size:75%;font-style:italic;padding-left:5px}.kb-app-results-tab{max-width:inherit;overflow-x:auto}.kb-editor-cell .kb-app-warning{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-editor-cell .kb-app-parameter-panel{border-left:3px solid #fff}.kb-editor-cell .kb-app-parameter-panel-hover{border-left:3px solid #428bca}.kb-editor-cell .kb-app-parameter-row{margin:0}.kb-editor-cell .kb-app-parameter-row-hover{background:#f9f9f9}.kb-editor-cell .kb-app-parameter-row .message{font-family:Oxygen,Arial,sans-serif;text-align:center}.kb-editor-cell .kb-app-parameter-row .message.-error{background:#f2dede;color:#f44336}.kb-editor-cell .kb-app-parameter-name{color:#777;font-family:Oxygen,Arial,sans-serif;padding-left:0;padding-right:4px;text-align:left;vertical-align:bottom;white-space:normal}.kb-editor-cell .kb-app-parameter-input{vertical-align:middle}.kb-editor-cell .kb-app-parameter-input select.form-control{margin:0}.kb-editor-cell .kb-app-parameter-input .kb-app-parameter-accepted-glyph,.kb-editor-cell .kb-app-parameter-input .kb-app-parameter-required-glyph{font-size:15px;margin-left:0}.kb-editor-cell .kb-app-parameter-required-glyph{color:#f44336}.kb-editor-cell .kb-parameter-data-selection{font-weight:700}.kb-editor-cell .kb-app-parameter-hint{color:#777;margin-top:3px;padding-left:7px;text-align:left}.kb-editor-cell .kb-app-parameter-accepted-glyph{color:#4bb856}.kb-editor-cell .kb-app-advanced-options-controller-inactive,.kb-editor-cell .kb-app-parameter-info,.kb-editor-cell .kb-parameter-data-row-add,.kb-editor-cell .kb-parameter-data-row-remove{color:#777}.kb-editor-cell .kb-app-advanced-options-controller,.kb-editor-cell .kb-app-advanced-options-controller-inactive{font:italic 700 13px/14px Oxygen,Arial,sans-serif;text-align:center}.kb-editor-cell .kb-app-advanced-options-controller{color:#037ac0;cursor:pointer}.kb-editor-cell .kb-app-advanced-options-controller:hover{color:#2a6496}.kb-editor-cell .kb-app-footer{background-color:#f5f5f5;padding:10px;width:100%}.kb-editor-cell .kb-app-subtitle{background-color:#f5f5f5;padding:3px 5px}.kb-editor-cell .advanced-parameter-showing{display:block}.kb-editor-cell .advanced-parameter-hidden{display:none}.kb-editor-cell [data-element=run-control-panel]{width:100%}.kb-editor-cell [data-element=tab-pane]{border-top:2px solid #2196f3}.kb-editor-cell [data-element=tab-pane]>div{padding:4px}.kb-editor-cell [data-element=tab-pane]>div:empty{padding:0}.kb-editor-cell .btn-primary.kb-btn-action.-rerun{color:#2196f3}.kb-editor-cell .btn-primary.kb-btn-action.-run{color:#4bb856}.kb-editor-cell .btn-danger.kb-btn-action.-cancel,.kb-editor-cell .btn-danger.kb-btn-action.-reset{color:#d15241}.unselected .kb-editor-cell{opacity:.5}.kb-editor-cell-info-desc{border:1px solid #777;margin-right:10px;min-height:100px;padding:10px}.kb-editor-cell-info{color:#777;font:16px Oxygen,Arial,sans-serif}.kb-editor-cell-info .header{border-bottom:1px solid #777;margin-bottom:8px;padding:5px 0}.kb-editor-cell-info .value{color:#000}.btn.kb-editor-cell-btn{background-color:#fff;margin-bottom:4px}.btn.kb-editor-cell-btn,.btn.kb-editor-cell-btn.btn-primary{border:2px solid #2196f3;color:#2196f3}.btn.kb-editor-cell-btn.btn-primary:hover{border-bottom:6px solid #2196f3;margin-bottom:0}.btn.kb-editor-cell-btn.btn-primary.active,.btn.kb-editor-cell-btn.btn-primary:active,.btn.kb-editor-cell-btn.btn-primary:hover{background-color:#2196f3;color:#fff}.btn.kb-editor-cell-btn.btn-primary.active{border:solid #2196f3;border-width:2px 2px 6px;margin-bottom:0}.btn.kb-editor-cell-btn.btn-primary.active:hover{background-color:#ddd;border-bottom:2px solid #2196f3;color:#2196f3;margin-bottom:4px}.btn.kb-editor-cell-btn.btn-danger{border:2px solid #d15241;color:#d15241}.btn.kb-editor-cell-btn.btn-danger:hover{background-color:#d15241;border-bottom:6px solid #d15241;color:#fff;margin-bottom:0}.btn.kb-editor-cell-btn.btn-danger.active{background-color:#d15241;border:solid #d15241;border-width:2px 2px 6px;color:#fff;margin-bottom:0}.btn.kb-editor-cell-btn.btn-danger.active:hover{background-color:#ddd;border-bottom:2px solid #d15241;color:#d15241;margin-bottom:4px}.btn.kb-editor-cell-btn.disabled,.btn.kb-editor-cell-btn.disabled:active,.btn.kb-editor-cell-btn.disabled:hover{border:2px solid #888;color:#888;margin-bottom:4px}.kb-appInput__checkbox_container{display:flex}.kb-appInput__checkbox_error{display:flex;margin-left:1rem;width:100%}.kb-appInput__checkbox_error_container{background-color:#f9dadb;border:1px solid #eda7aa;color:#171412;padding:.5em}.kb-appInput__checkbox_error_container__title{color:#d2232a;margin-right:.5rem}.kb-appInput__checkbox_error__close_button{background:none;border:0;margin-left:auto}.kb-appInput__checkbox_error__close_button:hover{background:none}.kb-appInput__dynDropdown_display{display:block}.kb-appInput__dynDropdown_display__filepath{word-wrap:break-word}.kb-appInput__dynDropdown_display__indent{margin-left:.1rem}.kb-appInput__sequence__button_container{height:100%;padding:0}.kb-appInput__sequence__row{padding:2px;width:100%}.kb-appInput__sequence__empty{color:#9d9389;font-style:italic}.kb-appInput__struct__field{border:0;padding:0}.kb-appInput__struct__subcontrols{border-left:5px solid silver;margin:6px;padding:2px}.kb-app-params__message--advanced-hidden{font-style:italic;margin-left:6px}.kb-app-params__toggle--advanced-errors{background-color:#f9dadb;color:#171412;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429}.kb-app-params__toggle--advanced-errors--icon{color:#d2232a}.kb-app-params__fields--parameters-hidden{display:none}.kb-bulk-import__layout_container{align-items:stretch;display:flex}.kb-bulk-import__prompt{align-items:stretch;display:flex;flex-direction:column}.kb-bulk-import__body{align-items:stretch;display:flex;flex:1;flex-direction:column;width:100%}.kb-bulk-import__tab_pane{align-content:stretch;align-items:stretch;border-top:2px solid #2196f3;display:flex;flex-direction:row}.kb-bulk-import__tab_pane_widget{width:100%}.kb-bulk-import-configure__container,.kb-bulk-import-info__container{display:flex}.kb-bulk-import-configure__button--generate-template,.kb-bulk-import-info__button--generate-template{background-color:#dfeef6;border-color:transparent;color:#026daa;margin:1rem 0;position:absolute;right:15px}.kb-bulk-import-configure__button--generate-template.focus,.kb-bulk-import-configure__button--generate-template:focus,.kb-bulk-import-configure__button--generate-template:hover,.kb-bulk-import-info__button--generate-template.focus,.kb-bulk-import-info__button--generate-template:focus,.kb-bulk-import-info__button--generate-template:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-bulk-import-configure__button--generate-template.active,.kb-bulk-import-configure__button--generate-template:active,.kb-bulk-import-info__button--generate-template.active,.kb-bulk-import-info__button--generate-template:active,.open>.kb-bulk-import-configure__button--generate-template.dropdown-toggle,.open>.kb-bulk-import-info__button--generate-template.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-bulk-import-configure__button--generate-template.active.focus,.kb-bulk-import-configure__button--generate-template.active:focus,.kb-bulk-import-configure__button--generate-template.active:hover,.kb-bulk-import-configure__button--generate-template:active.focus,.kb-bulk-import-configure__button--generate-template:active:focus,.kb-bulk-import-configure__button--generate-template:active:hover,.kb-bulk-import-info__button--generate-template.active.focus,.kb-bulk-import-info__button--generate-template.active:focus,.kb-bulk-import-info__button--generate-template.active:hover,.kb-bulk-import-info__button--generate-template:active.focus,.kb-bulk-import-info__button--generate-template:active:focus,.kb-bulk-import-info__button--generate-template:active:hover,.open>.kb-bulk-import-configure__button--generate-template.dropdown-toggle.focus,.open>.kb-bulk-import-configure__button--generate-template.dropdown-toggle:focus,.open>.kb-bulk-import-configure__button--generate-template.dropdown-toggle:hover,.open>.kb-bulk-import-info__button--generate-template.dropdown-toggle.focus,.open>.kb-bulk-import-info__button--generate-template.dropdown-toggle:focus,.open>.kb-bulk-import-info__button--generate-template.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-bulk-import-configure__button--generate-template.disabled.focus,.kb-bulk-import-configure__button--generate-template.disabled:focus,.kb-bulk-import-configure__button--generate-template.disabled:hover,.kb-bulk-import-configure__button--generate-template[disabled].focus,.kb-bulk-import-configure__button--generate-template[disabled]:focus,.kb-bulk-import-configure__button--generate-template[disabled]:hover,.kb-bulk-import-info__button--generate-template.disabled.focus,.kb-bulk-import-info__button--generate-template.disabled:focus,.kb-bulk-import-info__button--generate-template.disabled:hover,.kb-bulk-import-info__button--generate-template[disabled].focus,.kb-bulk-import-info__button--generate-template[disabled]:focus,.kb-bulk-import-info__button--generate-template[disabled]:hover,fieldset[disabled] .kb-bulk-import-configure__button--generate-template.focus,fieldset[disabled] .kb-bulk-import-configure__button--generate-template:focus,fieldset[disabled] .kb-bulk-import-configure__button--generate-template:hover,fieldset[disabled] .kb-bulk-import-info__button--generate-template.focus,fieldset[disabled] .kb-bulk-import-info__button--generate-template:focus,fieldset[disabled] .kb-bulk-import-info__button--generate-template:hover{background-color:#dfeef6;border-color:transparent}.kb-bulk-import-configure__button--generate-template .badge,.kb-bulk-import-info__button--generate-template .badge{background-color:#026daa;color:#dfeef6}.kb-bulk-import-configure__message,.kb-bulk-import-info__message{border:1px solid silver;color:#171412;padding:.5rem}.kb-bulk-import-configure__message--error,.kb-bulk-import-info__message--error{background-color:#f9dadb;border-color:#eda7aa}.kb-bulk-import-configure__message--error-title,.kb-bulk-import-info__message--error-title{color:#d2232a;margin-right:.5rem;text-transform:capitalize}.kb-bulk-import-configure__message--warning,.kb-bulk-import-info__message--warning{background-color:#ffefac;border-color:#fddd49}.kb-bulk-import-configure__message--warning-title,.kb-bulk-import-info__message--warning-title{color:#8f7700;margin-right:.5rem;text-transform:capitalize}.kb-bulk-import-configure__panel--filetype,.kb-bulk-import-info__panel--filetype{background-color:#f2efeb;width:24rem}.kb-bulk-import-configure__panel--configure,.kb-bulk-import-configure__panel--info,.kb-bulk-import-info__panel--configure,.kb-bulk-import-info__panel--info{flex:1}.kb-field-widget__error_message--parameters{border:1px solid #d2232a}.kb-field-cell__param_container{margin:3px}.kb-field-cell__input_control select{margin-left:0}.kb-field-cell__input_control .select2-selection--single{border-radius:2px;height:inherit}.kb-field-cell__input_control .select2-selection--single .select2-selection__rendered{line-height:30px}.kb-field-cell__input_control .select2-dropdown{border-radius:2px}.kb-field-cell__cell_label{margin-bottom:0;padding-top:8px}.kb-field-cell__error_message,.kb-field-cell__error_message .form-control{border-color:#d2232a;color:#d2232a}.kb-field-cell__error_message .select2-selection{border-color:#d2232a}.kb-field-cell__error_message .select2-container--default .select2-selection--single .select2-selection__placeholder,.kb-field-cell__error_message .select2-container--default .select2-selection--single .select2-selection__rendered{color:#d2232a}.kb-field-cell__message_panel,.kb-field-cell__message_panel__duplicate{border:1px solid silver;padding:.5em}.kb-field-cell__message_panel__duplicate__error,.kb-field-cell__message_panel__error{background-color:#f9dadb;border-color:#eda7aa;color:#171412}.kb-field-cell__message_panel__duplicate__error__title,.kb-field-cell__message_panel__error__title{color:#d2232a}.kb-field-cell__message_panel__duplicate__warning,.kb-field-cell__message_panel__warning{background-color:#ffefac;border-color:#fddd49;color:#171412}.kb-field-cell__message_panel__duplicate__warning__title,.kb-field-cell__message_panel__warning__title{color:#8f7700}.kb-result-tab__container{max-height:70rem;overflow-y:auto;padding:1.5rem}.kb-job-status-tab__container{padding:1.5rem}.kb-cell-toolbar__button{border:0}.kb-cell-toolbar__container{align-items:flex-start;display:flex;height:56px;justify-content:space-between}.kb-cell-toolbar__app_icon{flex:none;font-size:14px;height:56px;line-height:56px;margin-right:4px;padding:0;text-align:center;width:56px}.kb-cell-toolbar__title-container{flex:1 1 10rem;overflow:hidden;text-overflow:ellipsis}.cell.unselected .kb-cell-toolbar__title-container{opacity:.5}.kb-cell-toolbar__title{color:#03517d;font:normal 700 18px/20px Oxygen,Arial,sans-serif;margin-top:8px}.kb-cell-toolbar__subtitle,.kb-cell-toolbar__title{height:20px;min-width:0;overflow:hidden;text-overflow:ellipsis}.kb-cell-toolbar__subtitle{color:#6a6158;font:normal 400 14px/20px Oxygen,Arial,sans-serif}.kb-cell-toolbar__buttons-container{float:right;min-width:2rem;white-space:nowrap}.cell.unselected .kb-cell-toolbar__buttons-container{opacity:.2}.kb-cell-toolbar__icon--info{color:#65798c}.kb-cell-toolbar__icon--minus{color:#f78e1e}.kb-cell-toolbar__icon--outdated{border:0;color:#f78e1e;margin:0 5px;padding:0;vertical-align:top}.kb-cell-toolbar__icon--plus,.kb-cell-toolbar__icon--table,.kb-cell-toolbar__icon--terminal{color:#000}.kb-cell-toolbar__icon--times{color:#d12329}.kb-cell-toolbar__dropdown_item{border:0;text-align:left;width:100%}.kb-cell-toolbar__dropdown_item_icon{display:inline-block;margin-right:4px;width:25px}.kb-data-staging__breadcrumbs{margin:1rem 0 1.5rem}.kb-data-staging__breadcrumb_link{cursor:pointer}.kb-data-staging__container{height:604px;overflow-y:auto;padding:10px}.kb-data-staging__button{background-color:#dfeef6;border-color:transparent;color:#026daa;letter-spacing:.7px;margin-left:1rem;position:relative;top:-3px}.kb-data-staging__button.focus,.kb-data-staging__button:focus,.kb-data-staging__button:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-data-staging__button.active,.kb-data-staging__button:active,.open>.kb-data-staging__button.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-data-staging__button.active.focus,.kb-data-staging__button.active:focus,.kb-data-staging__button.active:hover,.kb-data-staging__button:active.focus,.kb-data-staging__button:active:focus,.kb-data-staging__button:active:hover,.open>.kb-data-staging__button.dropdown-toggle.focus,.open>.kb-data-staging__button.dropdown-toggle:focus,.open>.kb-data-staging__button.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-data-staging__button.disabled.focus,.kb-data-staging__button.disabled:focus,.kb-data-staging__button.disabled:hover,.kb-data-staging__button[disabled].focus,.kb-data-staging__button[disabled]:focus,.kb-data-staging__button[disabled]:hover,fieldset[disabled] .kb-data-staging__button.focus,fieldset[disabled] .kb-data-staging__button:focus,fieldset[disabled] .kb-data-staging__button:hover{background-color:#dfeef6;border-color:transparent}.kb-data-staging__button .badge{background-color:#026daa;color:#dfeef6}.kb-data-staging__title{font:normal 700 24px/30px Oxygen,Arial,sans-serif}.dz-clear-all__button{background-color:#dfeef6;border-color:transparent;color:#026daa}.dz-clear-all__button.focus,.dz-clear-all__button:focus,.dz-clear-all__button:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.dz-clear-all__button.active,.dz-clear-all__button:active,.open>.dz-clear-all__button.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.dz-clear-all__button.active.focus,.dz-clear-all__button.active:focus,.dz-clear-all__button.active:hover,.dz-clear-all__button:active.focus,.dz-clear-all__button:active:focus,.dz-clear-all__button:active:hover,.open>.dz-clear-all__button.dropdown-toggle.focus,.open>.dz-clear-all__button.dropdown-toggle:focus,.open>.dz-clear-all__button.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.dz-clear-all__button.disabled.focus,.dz-clear-all__button.disabled:focus,.dz-clear-all__button.disabled:hover,.dz-clear-all__button[disabled].focus,.dz-clear-all__button[disabled]:focus,.dz-clear-all__button[disabled]:hover,fieldset[disabled] .dz-clear-all__button.focus,fieldset[disabled] .dz-clear-all__button:focus,fieldset[disabled] .dz-clear-all__button:hover{background-color:#dfeef6;border-color:transparent}.dz-clear-all__button .badge{background-color:#026daa;color:#dfeef6}.dz-file{border:1px solid #f2efeb;font:16px Oxygen,Arial,sans-serif;margin:2px 0;padding:5px 0;width:100%}.dz-file__progress__bar{margin-bottom:inherit;margin-left:5px}.dz-file__upload-progress{display:inline}.dz-file__row{align-items:center;display:flex}.dz-file__name{line-height:20px;white-space:nowrap}.dz-file__msg,.dz-file__name{overflow:hidden;text-overflow:ellipsis}.dz-file__msg{font-size:14px}.dz-file__msg__success{color:#4baf4f;display:none}.dz-file__status{align-items:center;display:none;font-weight:700}.dz-file__status__icon{margin:0 4px 0 8px}.dz-file__status__success{color:#4baf4f}.dz-file__status__error{color:#df0002}.kb-dropzone{border:2px dashed #2196f3!important;margin-bottom:5px;max-height:150px;overflow-y:auto}.kb-dropzone-progress__header{border-bottom:1px solid #f2efeb;display:none;margin-bottom:5px}.kb-dropzone .dz-message{color:#000;font:normal 400 24px/28px Oxygen,Arial,sans-serif;margin:2em 4.5em;mix-blend-mode:normal;text-align:center}.kb-dropzone__message--upload{font-family:Oxygen,Arial,sans-serif;font-weight:700}.kb-error-display__container{padding:1.5rem}.kb-error-display__container.kb-log__error_container{padding:0}.kb-error-display__detail_title,.kb-error-display__stacktrace_title,.kb-error-display__summary{font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin-top:1rem}.kb-app-cell-tab-pane__container--error .kb-error-display__summary{margin-top:0}.kb-error-display__stacktrace_code{word-wrap:break-word;background-color:#f2efeb;border:0;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px;margin:0;max-height:50rem;overflow-wrap:break-word;overflow-y:auto;padding:1rem;word-break:break-word}.kb-error-display__advice_list{list-style:none;padding-left:0}.access-error__container,.generic-error__container{margin:2rem;text-align:center}.access-error__heading,.generic-error__heading{font-size:200%;font-weight:700;line-height:1.5}.access-error__text,.generic-error__text{font-size:150%;line-height:2}.access-request-form__container{margin-top:2rem}.access-request-progress__container{display:none;margin-top:1rem}.access-request-result{font-size:125%;margin-top:2rem}.error-dialog__body{margin:1rem}.kb-file-path__list{counter-reset:fpw-item;list-style-position:outside;list-style-type:none;max-height:60rem;overflow-y:auto;padding:0}.kb-file-path__list_item{align-items:center;display:flex;font:normal 400 14px/18px Oxygen,Arial,sans-serif;padding:0 1.5rem .5rem}.kb-file-path__list_item:nth-child(2n){background-color:#f2efeb}.kb-file-path__list_item:before{content:counter(fpw-item) " ";counter-increment:fpw-item;font-weight:700;padding-right:.5rem;padding-top:20px;vertical-align:middle}.kb-file-path__param_container{display:flex;flex:1;flex-wrap:wrap}.kb-file-path__param_container .input-group .select2-container{display:table;table-layout:fixed}.kb-file-path__row_cell--file-path_id{flex:1;min-width:30rem;padding:4px}.kb-file-path__button--delete{background-color:#dfeef6;border-color:transparent;color:#026daa;margin-top:2rem}.kb-file-path__button--delete.focus,.kb-file-path__button--delete:focus,.kb-file-path__button--delete:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-file-path__button--delete.active,.kb-file-path__button--delete:active,.open>.kb-file-path__button--delete.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-file-path__button--delete.active.focus,.kb-file-path__button--delete.active:focus,.kb-file-path__button--delete.active:hover,.kb-file-path__button--delete:active.focus,.kb-file-path__button--delete:active:focus,.kb-file-path__button--delete:active:hover,.open>.kb-file-path__button--delete.dropdown-toggle.focus,.open>.kb-file-path__button--delete.dropdown-toggle:focus,.open>.kb-file-path__button--delete.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-file-path__button--delete.disabled.focus,.kb-file-path__button--delete.disabled:focus,.kb-file-path__button--delete.disabled:hover,.kb-file-path__button--delete[disabled].focus,.kb-file-path__button--delete[disabled]:focus,.kb-file-path__button--delete[disabled]:hover,fieldset[disabled] .kb-file-path__button--delete.focus,fieldset[disabled] .kb-file-path__button--delete:focus,fieldset[disabled] .kb-file-path__button--delete:hover{background-color:#dfeef6;border-color:transparent}.kb-file-path__button--delete .badge{background-color:#026daa;color:#dfeef6}.kb-file-path__button--add_row{background-color:#dfeef6;border-color:transparent;color:#026daa;margin:1rem}.kb-file-path__button--add_row.focus,.kb-file-path__button--add_row:focus,.kb-file-path__button--add_row:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-file-path__button--add_row.active,.kb-file-path__button--add_row:active,.open>.kb-file-path__button--add_row.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-file-path__button--add_row.active.focus,.kb-file-path__button--add_row.active:focus,.kb-file-path__button--add_row.active:hover,.kb-file-path__button--add_row:active.focus,.kb-file-path__button--add_row:active:focus,.kb-file-path__button--add_row:active:hover,.open>.kb-file-path__button--add_row.dropdown-toggle.focus,.open>.kb-file-path__button--add_row.dropdown-toggle:focus,.open>.kb-file-path__button--add_row.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-file-path__button--add_row.disabled.focus,.kb-file-path__button--add_row.disabled:focus,.kb-file-path__button--add_row.disabled:hover,.kb-file-path__button--add_row[disabled].focus,.kb-file-path__button--add_row[disabled]:focus,.kb-file-path__button--add_row[disabled]:hover,fieldset[disabled] .kb-file-path__button--add_row.focus,fieldset[disabled] .kb-file-path__button--add_row:focus,fieldset[disabled] .kb-file-path__button--add_row:hover{background-color:#dfeef6;border-color:transparent}.kb-file-path__button--add_row .badge{background-color:#026daa;color:#dfeef6}.kb-file-path__button_icon--add_row{margin-right:.5rem}.kb-file-path__params{margin-left:.5rem;width:100%}.kb-filetype-panel__filetype_button,.kb-filetype-panel__filetype_button--selected,.kb-filetype-panel__filetype_button:hover:not(.kb-filetype-panel__filetype_button--selected){background-color:inherit;border:solid silver;border-width:1px 0 0;display:flex;flex-direction:row;padding:8px;text-align:left;width:100%}.kb-filetype-panel__header{border-bottom:1px solid silver;font:normal 700 18px/30px Oxygen,Arial,sans-serif;padding:8px}.kb-filetype-panel__header_icon{color:#000;padding:8px 6px 8px 8px}.kb-filetype-panel__filetype_button{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429}.kb-filetype-panel__filetype_button:hover:not(.kb-filetype-panel__filetype_button--selected){background-color:#ded5cb;cursor:pointer}.kb-filetype-panel__filetype_button--selected{background-color:#fff;box-shadow:0 3px 2px -2px #6a6158}.kb-filetype-panel__filetype_button--selected+.kb-bulk-import__filetype-panel__filetype_button{box-shadow:inset 0 3px 2px -2px #6a6158}.kb-filetype-panel__filetype_icon{padding:2px 8px 0;text-align:center;width:3rem}.kb-filetype-panel__filetype_icon--complete{color:#5e9732}.kb-filetype-panel__filetype_icon--incomplete{color:#d2232a}.kb-filetype-panel__filetype_icon--warning{color:#b99902}.kb-filetype-panel__filetype_label{flex:1}.kb-fsm__key{margin-left:3px}.kb-fsm__value{background-color:#6a6158;color:#fff;margin:0 3px;padding:2px}.kb-info-tab__container{padding:1.5rem}.kb-info-tab__title{line-height:30px}.kb-info-tab__name{font:normal 700 18px/30px Oxygen,Arial,sans-serif}.kb-info-tab__version{padding:0 1rem}.kb-info-tab__tag{padding:.5rem;vertical-align:middle}.kb-info-tab__authors,.kb-info-tab__description,.kb-info-tab__link--docs,.kb-info-tab__list--params{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429;margin:1rem 0}.kb-info-tab__list--params{padding-left:2rem}.kb-info-tab__list_title--params{font:normal 700 16px/24px Oxygen,Arial,sans-serif;margin:1rem 0}.kb-info-tab__param--id{background-color:#d3e2f2;border-radius:.25rem;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px;padding:.25rem .5rem;white-space:nowrap}.kb-info-tab__param--id+.kb-info-tab__param--ui-name{margin-left:.5rem}.kb-job-action__dropdown_header{font-weight:700;text-transform:uppercase}.kb-job-action__dropdown-menu{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;line-height:2.5;padding:0}.kb-job-action__dropdown-menu-item-link--cancel,.kb-job-action__dropdown-menu-item-link--retry{background:#fff;border:0;border-bottom:1px solid rgba(0,0,0,.15);font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;line-height:2.5;text-align:left;width:100%}.kb-job-action__dropdown-menu-item-link--cancel:disabled,.kb-job-action__dropdown-menu-item-link--retry:disabled{color:#6a6158;cursor:not-allowed}.kb-job-action__dropdown-menu-item-link--cancel:active:disabled,.kb-job-action__dropdown-menu-item-link--cancel:hover:disabled,.kb-job-action__dropdown-menu-item-link--retry:active:disabled,.kb-job-action__dropdown-menu-item-link--retry:hover:disabled{background:#9d9389;color:#fff}.kb-job-action__dropdown-menu-item-link--retry{color:#026daa}.kb-job-action__dropdown-menu-item-link--retry:active,.kb-job-action__dropdown-menu-item-link--retry:hover{background:#026daa;color:#fff}.kb-job-action__dropdown-menu-item-link--cancel{color:#b6151c}.kb-job-action__dropdown-menu-item-link--cancel:active,.kb-job-action__dropdown-menu-item-link--cancel:hover{background:#d2232a;color:#fff}.kb-log__log_line_container,.kb-log__log_line_container--error{counter-reset:code-list-counter;list-style:none;margin:0;padding:0}.kb-log__line_text,.kb-log__line_text--error,.kb-log__log_line_container,.kb-log__log_line_container--error{font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px}.kb-log__line_text,.kb-log__line_text--error{counter-increment:code-list-counter;padding-left:5rem;position:relative;white-space:normal}.kb-log__container,.kb-log__dev_container{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px}.kb-log__dev_container{padding-bottom:2rem}.kb-log__controls{margin:2rem 0}.kb-log__content,.kb-log__content--expanded{background-color:#f2efeb;border:0;margin:0;overflow:scroll;padding:0;transition:height .5s}.kb-log__content{max-height:288px}.kb-log__content--expanded{max-height:720px}.kb-log__content p{margin:1rem}.kb-log__log_line_container--error{background-color:#f9dadb}.kb-log__line_text--error:before,.kb-log__line_text:before{content:counter(code-list-counter);left:1rem;position:absolute}.kb-log__line_text{background-color:#f2efeb;color:#171412}.kb-log__line_text--error{background-color:#f9dadb;color:#7c0e12}.kb-log__logs_title{font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin-top:1rem}.kb-log__spinner{border:0;line-height:1.428571429;margin:0;padding:.5rem 1rem}.kb-job-params__params_container,.kb-log__spinner{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400}.kb-job-params__params_container{line-height:24px}.kb-job-params__params_title{font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin-top:1rem}.kb-job-params__param_list{list-style-type:none;margin:1rem 0;padding:0}.kb-job-params__param_list,.kb-job-state-viewer__container{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px}.kb-job-state-viewer__job_status_detail_container div:first-of-type{font-weight:700}.kb-job-state-viewer__error_container.kb-error-display__container{padding:0}.kb-job-status{box-shadow:none}.kb-job-status__table{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429;padding:0;table-layout:fixed;width:100%}.kb-job-status__table.dataTable{border-collapse:collapse!important}.kb-job-status__table_body{border-bottom:2px solid #9d9389;border-top:2px solid #9d9389}.kb-job-status__table_body .kb-job-status__row,.kb-job-status__table_body tr.even,.kb-job-status__table_body tr.odd{border-bottom:1px solid #f2efeb}.kb-job-status__table__row--selected,.kb-job-status__table_body .kb-job-status__row:hover,.kb-job-status__table_body tr.even:hover,.kb-job-status__table_body tr.odd:hover{background:#f2efeb}.kb-job-status__table__row--selected:hover{background:#cce5f3}.kb-job-status__table_head_row{font-weight:700}.kb-job-status__table_head_row .sorting:after,.kb-job-status__table_head_row .sorting_asc:after,.kb-job-status__table_head_row .sorting_desc:after{bottom:0!important;display:inline-block!important;left:5px!important;position:relative!important}.kb-job-status__table_head_cell--action,.kb-job-status__table_head_cell--import-type,.kb-job-status__table_head_cell--output,.kb-job-status__table_head_cell--status{border:0;margin:0;padding:.8rem}.kb-job-status__table_footer{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px}.kb-job-status__cell--action,.kb-job-status__cell--import-type,.kb-job-status__cell--output,.kb-job-status__cell--status{border:0;margin:0;overflow:hidden;padding:.8rem;text-overflow:ellipsis}.kb-job-status__cell--status{text-transform:capitalize;width:10rem}.kb-job-status__cell--action{width:11rem}.kb-job-status__cell--import-type{width:18rem}.kb-job-status__cell_action--go-to-results,.kb-job-status__cell_action--retry{background-color:#dfeef6;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.focus,.kb-job-status__cell_action--go-to-results:focus,.kb-job-status__cell_action--go-to-results:hover,.kb-job-status__cell_action--retry.focus,.kb-job-status__cell_action--retry:focus,.kb-job-status__cell_action--retry:hover{background-color:#b7d9eb;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.active,.kb-job-status__cell_action--go-to-results:active,.kb-job-status__cell_action--retry.active,.kb-job-status__cell_action--retry:active,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle,.open>.kb-job-status__cell_action--retry.dropdown-toggle{background-color:#b7d9eb;background-image:none;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.active.focus,.kb-job-status__cell_action--go-to-results.active:focus,.kb-job-status__cell_action--go-to-results.active:hover,.kb-job-status__cell_action--go-to-results:active.focus,.kb-job-status__cell_action--go-to-results:active:focus,.kb-job-status__cell_action--go-to-results:active:hover,.kb-job-status__cell_action--retry.active.focus,.kb-job-status__cell_action--retry.active:focus,.kb-job-status__cell_action--retry.active:hover,.kb-job-status__cell_action--retry:active.focus,.kb-job-status__cell_action--retry:active:focus,.kb-job-status__cell_action--retry:active:hover,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle.focus,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle:focus,.open>.kb-job-status__cell_action--go-to-results.dropdown-toggle:hover,.open>.kb-job-status__cell_action--retry.dropdown-toggle.focus,.open>.kb-job-status__cell_action--retry.dropdown-toggle:focus,.open>.kb-job-status__cell_action--retry.dropdown-toggle:hover{background-color:#9bcae3;border-color:transparent;color:#026daa}.kb-job-status__cell_action--go-to-results.disabled.focus,.kb-job-status__cell_action--go-to-results.disabled:focus,.kb-job-status__cell_action--go-to-results.disabled:hover,.kb-job-status__cell_action--go-to-results[disabled].focus,.kb-job-status__cell_action--go-to-results[disabled]:focus,.kb-job-status__cell_action--go-to-results[disabled]:hover,.kb-job-status__cell_action--retry.disabled.focus,.kb-job-status__cell_action--retry.disabled:focus,.kb-job-status__cell_action--retry.disabled:hover,.kb-job-status__cell_action--retry[disabled].focus,.kb-job-status__cell_action--retry[disabled]:focus,.kb-job-status__cell_action--retry[disabled]:hover,fieldset[disabled] .kb-job-status__cell_action--go-to-results.focus,fieldset[disabled] .kb-job-status__cell_action--go-to-results:focus,fieldset[disabled] .kb-job-status__cell_action--go-to-results:hover,fieldset[disabled] .kb-job-status__cell_action--retry.focus,fieldset[disabled] .kb-job-status__cell_action--retry:focus,fieldset[disabled] .kb-job-status__cell_action--retry:hover{background-color:#dfeef6;border-color:transparent}.kb-job-status__cell_action--go-to-results .badge,.kb-job-status__cell_action--retry .badge{background-color:#026daa;color:#dfeef6}.kb-job-status__cell_action--cancel{background-color:#f9dadb;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.focus,.kb-job-status__cell_action--cancel:focus,.kb-job-status__cell_action--cancel:hover{background-color:#f2aeb0;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.active,.kb-job-status__cell_action--cancel:active,.open>.kb-job-status__cell_action--cancel.dropdown-toggle{background-color:#f2aeb0;background-image:none;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.active.focus,.kb-job-status__cell_action--cancel.active:focus,.kb-job-status__cell_action--cancel.active:hover,.kb-job-status__cell_action--cancel:active.focus,.kb-job-status__cell_action--cancel:active:focus,.kb-job-status__cell_action--cancel:active:hover,.open>.kb-job-status__cell_action--cancel.dropdown-toggle.focus,.open>.kb-job-status__cell_action--cancel.dropdown-toggle:focus,.open>.kb-job-status__cell_action--cancel.dropdown-toggle:hover{background-color:#ed8f92;border-color:transparent;color:#d2232a}.kb-job-status__cell_action--cancel.disabled.focus,.kb-job-status__cell_action--cancel.disabled:focus,.kb-job-status__cell_action--cancel.disabled:hover,.kb-job-status__cell_action--cancel[disabled].focus,.kb-job-status__cell_action--cancel[disabled]:focus,.kb-job-status__cell_action--cancel[disabled]:hover,fieldset[disabled] .kb-job-status__cell_action--cancel.focus,fieldset[disabled] .kb-job-status__cell_action--cancel:focus,fieldset[disabled] .kb-job-status__cell_action--cancel:hover{background-color:#f9dadb;border-color:transparent}.kb-job-status__cell_action--cancel .badge{background-color:#d2232a;color:#f9dadb}.kb-job-status__param_list{font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:24px;list-style-type:none;margin:1rem 0;padding:0}.kb-job-status__detail_container{background-color:#e7eff8;border-bottom:1px solid #f2efeb;padding:1rem}.kb-job-status__icon--action_warning{color:#d2232a;font-size:1.5em;padding:.5rem 1rem;vertical-align:middle}.kb-job-status__icon--created{color:#a1b9cf;margin:4px}.kb-job-status__summary--created{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--created{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--estimating{color:#a1b9cf;margin:4px}.kb-job-status__summary--estimating{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--estimating{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--queued{color:#a1b9cf;margin:4px}.kb-job-status__summary--queued{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--queued{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--running{color:#a1b9cf;margin:4px}.kb-job-status__summary--running{color:#a1b9cf;font-weight:700}.kb-job-status__cell_summary--running{color:#a1b9cf;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--completed{color:#0a6258;margin:4px}.kb-job-status__summary--completed{color:#0a6258;font-weight:700}.kb-job-status__cell_summary--completed{color:#0a6258;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--terminated{color:#b99902;margin:4px}.kb-job-status__summary--terminated{color:#b99902;font-weight:700}.kb-job-status__cell_summary--terminated{color:#b99902;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--error{color:#d2232a;margin:4px}.kb-job-status__summary--error{color:#d2232a;font-weight:700}.kb-job-status__cell_summary--error{color:#d2232a;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--does_not_exist{color:#d2232a;margin:4px}.kb-job-status__summary--does_not_exist{color:#d2232a;font-weight:700}.kb-job-status__cell_summary--does_not_exist{color:#d2232a;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-job-status__icon--ee2_error{color:#b99902;margin:4px}.kb-job-status__summary--ee2_error{color:#b99902;font-weight:700}.kb-job-status__cell_summary--ee2_error{color:#b99902;font-size:16px;font-weight:700;margin:0 .5rem;text-transform:capitalize}.kb-icon__container--image{display:block}.kb-icon__container--data,.kb-icon__container--data-stack{cursor:pointer}.kb-icon__container--app,.kb-icon__container--app-toolbar,.kb-icon__container--data,.kb-icon__container--generic,.kb-icon__container--generic-toolbar,.kb-icon__container--type,.kb-icon__container--type-toolbar{font-size:2em}.kb-icon__container--data-stack{font-size:1.7em}.kb-icon__icon_background--app,.kb-icon__icon_background--app-toolbar{color:#66489d}.kb-icon__icon_background--generic,.kb-icon__icon_background--generic-toolbar{color:silver}.kb-icon__icon_background--type,.kb-icon__icon_background--type-toolbar{color:#000}.kb-icon__img--image{margin:3px;max-height:50px;max-width:50px}.kb-icon__outline--l1{margin-left:1px;margin-top:1px}.kb-icon__stack--l1{margin-left:8px;margin-top:6px}.kb-icon__outline--l2{margin-left:9px;margin-top:7px}.kb-icon__stack--l2{margin-left:16px;margin-top:12px}.kb-icon__outline--l1,.kb-icon__outline--l2{color:#fff}.kb-data-list-logo{background-color:#607d8b;border:0 solid #555;border-radius:50%;color:#fff;display:inline-block;font-size:24px;font-weight:700;height:40px;padding-top:8px;text-align:center;text-shadow:-1px 0 #777,0 1px #777,1px 0 #777,0 -1px #777;width:40px}.kb-loading-blocker__text,.kb-loading-blocker__text--warning{font-size:16px;line-height:1.5;margin-left:30%;text-align:left;width:40%}.kb-loading-blocker__container{background-color:#fff;height:100%;left:0;position:absolute;top:0;width:100%;z-index:9999}.kb-loading-blocker__header{font-size:24px;font-weight:700;text-align:center}.kb-loading-blocker__text--warning{display:none;position:absolute}.kb-loading-blocker__image_container{padding-top:10%;text-align:center}.kb-narr-outline{padding:.5em .5em .5em .25em}.kb-narr-outline ul{list-style:none;padding:0;position:relative}.kb-narr-outline ul ul{padding-left:1.5em}.kb-narr-outline ul li:not(:last-of-type):before{border-left:2px solid #ded5cb;content:"";height:calc(100% + .25em);left:-.5em;position:absolute;top:0}.kb-narr-outline li{position:relative}.kb-narr-outline__item{align-items:center;cursor:pointer;display:flex;flex-flow:row nowrap;justify-content:left;left:0;padding:.1em .1em .3em;position:relative;top:0}.kb-narr-outline__item:before{background-color:transparent;border:1px solid transparent;border-radius:.333em;bottom:.2em;content:"";position:absolute;top:0;transition:background-color .1s linear,border .1s linear;width:100%;z-index:-1}.kb-narr-outline__item:after{border-bottom:2px solid #ded5cb;border-left:2px solid #ded5cb;bottom:calc(50% + 1px);content:"";height:calc(50% - .25em);left:-.5em;position:absolute;width:.5em}.kb-narr-outline__item-content{display:block;flex-grow:0;flex-shrink:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-narr-outline__item-icon{display:inline-block;transform:scale(.5);transform-origin:top left}.kb-narr-outline__item-icon-wrapper{border-radius:10px;display:block;flex-grow:0;flex-shrink:0;height:2em;margin-left:.1em;margin-right:.5em;max-width:2em;overflow:hidden}.kb-narr-outline__item--highlight:before{background-color:#f2efeb;border:1px solid #9d9389}.kb-narr-outline__item--highlight-selected:before{background-color:rgba(75,184,86,.15);border:1px solid #4bb856}.kb-narr-outline ul ul .kb-narr-outline__item:after{border-bottom:2px solid #ded5cb;border-left:2px solid #ded5cb;bottom:calc(50% + 1px);content:"";height:calc(50% - .25em);left:-.5em;position:absolute;width:.5em}.kb-rcp__layout_div{border-top:1px solid silver;display:flex;flex-direction:row;height:50px;position:relative}.kb-rcp__toolbar{flex:none;height:50px;line-height:50px}.kb-rcp__btn-toolbar{display:inline-block;line-height:50px;padding-right:.5rem;vertical-align:bottom}.kb-rcp__action-button{float:left;margin:6px;width:8rem}.kb-rcp__action-button-container{flex:none;height:50px;line-height:50px;overflow:hidden}.kb-rcp-status__container{flex:1 1 auto;font-size:14px;line-height:50px;margin:0 1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-rcp-status__fsm_display{background:#fff;display:inline-block;font:12px/1 Oxygen,Arial,sans-serif;margin-top:-30px;padding:6px 10px;position:absolute;top:0}.kb-rcp__tab-button{float:left;margin-left:.5rem}a.kb-rcp__tab-button--outdated{color:#ffd200;float:left;margin-left:.5rem;padding:6px 0 0}a.kb-rcp__tab-button--outdated:active,a.kb-rcp__tab-button--outdated:hover{color:#b99902}.kb-report-view__warning__count{margin:5px}.kb-report-view__warning__container{margin:0 5px 5px 10px;max-height:100px;overflow-y:auto}.kb-report-view__warning__text{margin:0 5px 5px 10px}.kb-report-view__summary{color:#544c45;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;height:auto;line-height:24px;max-height:500px;overflow:auto;white-space:pre-wrap;width:100%}.kb-report-view__download-iframe{display:none}.kb-report-view__download_button{cursor:pointer}.kb-report-view__report_iframe{display:block;height:auto;margin:0;padding:0;width:100%}.kb-report-view__report_button{margin:4px 4px 8px 0}.kb-output-widget__object_link{cursor:pointer}.kb-output-widget__table.dataTable{width:100%}.kb-report__container{margin:-1.5rem}.kb-report__item_container{border-bottom:1px solid #ded5cb;padding:0 1.5rem}.kb-report__item_toggle{color:#037ac0;font:normal 700 18px/30px Oxygen,Arial,sans-serif;margin:0 -1rem;padding:.5rem 0}.kb-report__item_toggle:hover{color:#2a6496}.kb-select2-object-input__item,.kb-select2-taxonomy-ref__item{display:block;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;height:20px;line-height:1.428571429}.kb-select2-object-input__object{word-wrap:break-word;font-family:Oxygen,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.428571429}.kb-select2-object-input__object_name{font-weight:700}.kb-select2-object-input__object_type{font-style:italic}.kb-select2-object-input__object_details{margin-left:1rem}.kb-select2-object-input__object_narrative,.kb-select2-object-input__object_type,.kb-select2-object-input__object_updated{display:block}.kb-staging-table{table-layout:fixed}.kb-staging-table .kb-staging-table-body td{vertical-align:middle}.kb-staging-table .kb-staging-table-header .sorting:before,.kb-staging-table .kb-staging-table-header .sorting_asc:before,.kb-staging-table .kb-staging-table-header .sorting_desc:before{content:"\e150";display:inline-block;font-family:Glyphicons Halflings;opacity:.2;position:relative;right:4px;top:1px}.kb-staging-table .kb-staging-table-header .sorting_asc:before{content:"\e155"}.kb-staging-table .kb-staging-table-header .sorting_desc:before{content:"\e156"}.kb-staging-table .kb-staging-table-header .sorting:after,.kb-staging-table .kb-staging-table-header .sorting_asc:after,.kb-staging-table .kb-staging-table-header .sorting_desc:after{display:none}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__checkbox{padding-right:0;width:2rem}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file{padding-right:0;width:4rem}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file.sorting:before,.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file.sorting_asc:before,.kb-staging-table .kb-staging-table-header .kb-staging-table-header__file.sorting_desc:before{left:9px}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__age,.kb-staging-table .kb-staging-table-header .kb-staging-table-header__size{width:7rem}.kb-staging-table .kb-staging-table-header .kb-staging-table-header__import{width:24rem}.kb-staging-table-body__cell--expander{text-align:center}.kb-staging-table-body__cell--import{text-align:right;white-space:nowrap}.kb-staging-table-body__button--decompress{background:transparent;border-radius:0;font-size:12px;line-height:12px;padding:.2rem}.kb-staging-table-body__button--download{background-color:#026daa;border-color:transparent;border-radius:0;color:#fff;font-size:12px;line-height:12px;margin-left:.5rem;padding:.5rem}.kb-staging-table-body__button--download.focus,.kb-staging-table-body__button--download:focus,.kb-staging-table-body__button--download:hover{background-color:#014d78;border-color:transparent;color:#fff}.kb-staging-table-body__button--download.active,.kb-staging-table-body__button--download:active,.open>.kb-staging-table-body__button--download.dropdown-toggle{background-color:#014d78;background-image:none;border-color:transparent;color:#fff}.kb-staging-table-body__button--download.active.focus,.kb-staging-table-body__button--download.active:focus,.kb-staging-table-body__button--download.active:hover,.kb-staging-table-body__button--download:active.focus,.kb-staging-table-body__button--download:active:focus,.kb-staging-table-body__button--download:active:hover,.open>.kb-staging-table-body__button--download.dropdown-toggle.focus,.open>.kb-staging-table-body__button--download.dropdown-toggle:focus,.open>.kb-staging-table-body__button--download.dropdown-toggle:hover{background-color:#013654;border-color:transparent;color:#fff}.kb-staging-table-body__button--download.disabled.focus,.kb-staging-table-body__button--download.disabled:focus,.kb-staging-table-body__button--download.disabled:hover,.kb-staging-table-body__button--download[disabled].focus,.kb-staging-table-body__button--download[disabled]:focus,.kb-staging-table-body__button--download[disabled]:hover,fieldset[disabled] .kb-staging-table-body__button--download.focus,fieldset[disabled] .kb-staging-table-body__button--download:focus,fieldset[disabled] .kb-staging-table-body__button--download:hover{background-color:#026daa;border-color:transparent}.kb-staging-table-body__button--download .badge{background-color:#fff;color:#026daa}.kb-staging-table-body__button--delete,.kb-staging-table-body__button--folder{background-color:transparent;border-color:transparent;border-radius:0;color:#026daa;font-size:18px;line-height:12px;padding:.5rem}.kb-staging-table-body__button--delete.focus,.kb-staging-table-body__button--delete:focus,.kb-staging-table-body__button--delete:hover,.kb-staging-table-body__button--folder.focus,.kb-staging-table-body__button--folder:focus,.kb-staging-table-body__button--folder:hover{background-color:transparent;border-color:transparent;color:#026daa}.kb-staging-table-body__button--delete.active,.kb-staging-table-body__button--delete:active,.kb-staging-table-body__button--folder.active,.kb-staging-table-body__button--folder:active,.open>.kb-staging-table-body__button--delete.dropdown-toggle,.open>.kb-staging-table-body__button--folder.dropdown-toggle{background-color:transparent;background-image:none;border-color:transparent;color:#026daa}.kb-staging-table-body__button--delete.active.focus,.kb-staging-table-body__button--delete.active:focus,.kb-staging-table-body__button--delete.active:hover,.kb-staging-table-body__button--delete:active.focus,.kb-staging-table-body__button--delete:active:focus,.kb-staging-table-body__button--delete:active:hover,.kb-staging-table-body__button--folder.active.focus,.kb-staging-table-body__button--folder.active:focus,.kb-staging-table-body__button--folder.active:hover,.kb-staging-table-body__button--folder:active.focus,.kb-staging-table-body__button--folder:active:focus,.kb-staging-table-body__button--folder:active:hover,.open>.kb-staging-table-body__button--delete.dropdown-toggle.focus,.open>.kb-staging-table-body__button--delete.dropdown-toggle:focus,.open>.kb-staging-table-body__button--delete.dropdown-toggle:hover,.open>.kb-staging-table-body__button--folder.dropdown-toggle.focus,.open>.kb-staging-table-body__button--folder.dropdown-toggle:focus,.open>.kb-staging-table-body__button--folder.dropdown-toggle:hover{background-color:transparent;border-color:transparent;color:#026daa}.kb-staging-table-body__button--delete.disabled.focus,.kb-staging-table-body__button--delete.disabled:focus,.kb-staging-table-body__button--delete.disabled:hover,.kb-staging-table-body__button--delete[disabled].focus,.kb-staging-table-body__button--delete[disabled]:focus,.kb-staging-table-body__button--delete[disabled]:hover,.kb-staging-table-body__button--folder.disabled.focus,.kb-staging-table-body__button--folder.disabled:focus,.kb-staging-table-body__button--folder.disabled:hover,.kb-staging-table-body__button--folder[disabled].focus,.kb-staging-table-body__button--folder[disabled]:focus,.kb-staging-table-body__button--folder[disabled]:hover,fieldset[disabled] .kb-staging-table-body__button--delete.focus,fieldset[disabled] .kb-staging-table-body__button--delete:focus,fieldset[disabled] .kb-staging-table-body__button--delete:hover,fieldset[disabled] .kb-staging-table-body__button--folder.focus,fieldset[disabled] .kb-staging-table-body__button--folder:focus,fieldset[disabled] .kb-staging-table-body__button--folder:hover{background-color:transparent;border-color:transparent}.kb-staging-table-body__button--delete .badge,.kb-staging-table-body__button--folder .badge{background-color:#026daa;color:transparent}.kb-staging-table-body__button--delete:active,.kb-staging-table-body__button--delete:hover,.kb-staging-table-body__button--folder:active,.kb-staging-table-body__button--folder:hover{color:#03517d}.kb-staging-table-body__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kb-staging-table-body__folder:hover{cursor:pointer;text-decoration:underline}.kb-staging-table-body__select_container{align-items:center;display:flex;justify-content:flex-end;text-align:left}.kb-staging-table-body .select2{margin:4px 0;width:19rem!important}.kb-staging-table-body .kb-staging-table-body__import-dropdown{align-items:center;background:#fff;border:1px solid #b6151c;border-radius:4px;box-sizing:border-box;display:flex;height:38px}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__rendered{color:#171412;flex:1 1 auto;font-size:14px;line-height:20px;padding:8px 20px 8px 8px}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__placeholder{color:#b6151c}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__arrow{margin-top:4px}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-selection__arrow b{border-color:#b6151c transparent transparent}.kb-staging-table-body .kb-staging-table-body__import-dropdown.kb-staging-table-body__import-type-selected .select2-selection__arrow b,.kb-staging-table-body .kb-staging-table-body__import-dropdown:focus .select2-selection__arrow b{border-color:#9d9389 transparent transparent}.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-container--focus .select2-selection__placeholder,.kb-staging-table-body .kb-staging-table-body__import-dropdown .select2-container--open .select2-selection__placeholder{color:#171412}.kb-staging-table-body .kb-staging-table-body__import-dropdown.kb-staging-table-body__import-type-selected,.kb-staging-table-body .select2-container--focus .kb-staging-table-body__import-dropdown,.kb-staging-table-body .select2-container--open .kb-staging-table-body__import-dropdown{border:1px solid silver}.kb-staging-table-file-metadata .tab-pane{margin:1rem}.kb-staging-table-file-metadata__def_list{display:flex;flex-wrap:wrap;margin:1rem;padding:0;width:100%}.kb-staging-table-file-metadata__term{font-weight:700;padding-top:.5rem;text-align:right;width:9rem}.kb-staging-table-file-metadata__def{margin-left:0;padding-left:1rem;padding-top:.5rem;width:calc(100% - 9rem)}.kb-staging-table-file-metadata__list{list-style-type:none}.kb-staging-table-file-metadata__file_lines{word-wrap:break-word;background-color:#f2efeb;border:0;font-family:OxygenMono,SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:14px;font-weight:400;line-height:24px;margin:0;max-height:50rem;max-height:200px;overflow-wrap:break-word;overflow-y:auto;overflow:scroll;padding:1rem;white-space:pre;word-break:break-word}.kb-staging-table__notice{background-color:#f2efeb;font:normal 700 16px/20px Oxygen,Arial,sans-serif;padding:1rem;text-align:center}.kb-staging-table-import__button{background-color:#026daa;border-color:transparent;border-radius:6px;bottom:-50px;color:#fff;font-size:14px;line-height:1.3333333;padding:1rem 1.5rem;position:absolute;right:10px;text-transform:none}.kb-staging-table-import__button.focus,.kb-staging-table-import__button:focus,.kb-staging-table-import__button:hover{background-color:#014d78;border-color:transparent;color:#fff}.kb-staging-table-import__button.active,.kb-staging-table-import__button:active,.open>.kb-staging-table-import__button.dropdown-toggle{background-color:#014d78;background-image:none;border-color:transparent;color:#fff}.kb-staging-table-import__button.active.focus,.kb-staging-table-import__button.active:focus,.kb-staging-table-import__button.active:hover,.kb-staging-table-import__button:active.focus,.kb-staging-table-import__button:active:focus,.kb-staging-table-import__button:active:hover,.open>.kb-staging-table-import__button.dropdown-toggle.focus,.open>.kb-staging-table-import__button.dropdown-toggle:focus,.open>.kb-staging-table-import__button.dropdown-toggle:hover{background-color:#013654;border-color:transparent;color:#fff}.kb-staging-table-import__button.disabled.focus,.kb-staging-table-import__button.disabled:focus,.kb-staging-table-import__button.disabled:hover,.kb-staging-table-import__button[disabled].focus,.kb-staging-table-import__button[disabled]:focus,.kb-staging-table-import__button[disabled]:hover,fieldset[disabled] .kb-staging-table-import__button.focus,fieldset[disabled] .kb-staging-table-import__button:focus,fieldset[disabled] .kb-staging-table-import__button:hover{background-color:#026daa;border-color:transparent}.kb-staging-table-import__button .badge{background-color:#fff;color:#026daa}.kb-staging-table-import__button[disabled]{background-color:#a1b9cf;cursor:not-allowed;opacity:1}.kb-staging-table-import__button[disabled]:active,.kb-staging-table-import__button[disabled]:focus,.kb-staging-table-import__button[disabled]:hover{background-color:#a1b9cf}.kb-staging-table-import__button[disabled]:focus{outline:none}.kb-staging-table-import__tooltip.tooltip{background:#fff;border-radius:4px;box-shadow:2px 4px 6px rgba(0,0,0,.15)}.kb-staging-table-import__tooltip.tooltip .tooltip-inner{align-items:center;background:#fff;color:#000;display:flex;font:normal 400 14px/16px Oxygen,Arial,sans-serif;height:6rem;width:20rem}.kb-ui__button_label,.kb-ui__icon{vertical-align:middle}.kb-ui__text--na{color:#f78e1e;font-style:italic}.kb-user-menu__menu{display:inline-block}.kb-user-menu__menu_caret.caret{margin-left:5px}.kb-user-menu__icon--gravatar{width:40px}.kb-user-menu__icon--signout.fa,.kb-user-menu__icon--user.fa{font-size:150%;margin-right:10px}.kb-user-menu__block--name{display:inline-block}.kb-user-menu__block--displayName,.kb-user-menu__block--userName{display:block}.kb-user-menu__block--displayName{font-style:italic}.kb-user-menu__block--signout-icon,.kb-user-menu__block--user-icon{display:inline-block;width:34px}.kb-user-menu__block--user-icon{vertical-align:top} \ No newline at end of file diff --git a/kbase-extension/static/kbase/css/all_concat.css.map b/kbase-extension/static/kbase/css/all_concat.css.map index 28c080ea9b..0eb14b2953 100644 --- a/kbase-extension/static/kbase/css/all_concat.css.map +++ b/kbase-extension/static/kbase/css/all_concat.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../../scss/modules/_colours.scss","../../../scss/modules/_fonts.scss","../../../scss/partials/_custom.scss","../../../scss/modules/_typography.scss","../../../scss/partials/_stylesheet.scss","../../../scss/modules/_variables.scss","../../../scss/partials/_narrative.scss","../../../scss/partials/_icons.scss","../../../scss/partials/_landingPages.scss","../../../scss/partials/_editor.scss","../../../scss/partials/_notify.scss","../../../scss/partials/_methodCell.scss","../../../scss/partials/_bootstrapHelper.scss","../../../scss/partials/_buttons.scss","../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins/_buttons.scss","../../../scss/partials/_contigBrowserStyles.scss","../../../scss/partials/_tour.scss","../../../scss/partials/_batchMode.scss","../../../scss/partials/_advancedViewCell.scss","../../../scss/partials/_errorDialog.scss","../../../scss/modules/_mixins.scss","../../../scss/partials/_appCell.scss","../../../scss/partials/_editorCell.scss","../../../scss/partials/_appInput.scss","../../../scss/partials/_appParams.scss","../../../scss/partials/_bulkImportCell.scss","../../../scss/partials/_cellToolbar.scss","../../../scss/partials/_dataStaging.scss","../../../scss/partials/_dropzoneDz.scss","../../../scss/partials/_errorDisplay.scss","../../../scss/partials/_filePath.scss","../../../scss/partials/_filetypePanel.scss","../../../scss/partials/_fsm.scss","../../../scss/partials/_infoTab.scss","../../../scss/partials/_jobAction.scss","../../../scss/partials/_jobLog.scss","../../../scss/partials/_jobStatus.scss","../../../scss/partials/_kb-icon.scss","../../../scss/partials/_loadingBlocker.scss","../../../scss/partials/_narrativeOutline.scss","../../../scss/partials/_rcp.scss","../../../scss/partials/_reportViewer.scss","../../../scss/partials/_select2.scss","../../../scss/partials/_stagingTable.scss","../../../scss/partials/_ui.scss","../../../scss/partials/_userMenu.scss"],"names":[],"mappings":";AAAA;ACEA;EACE;EACA;EACA,KACE;;AAOJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;ACtFF;AAAA;AAAA;;AAAA;AAAA;AAMA;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;AAEA;EACE;EACA;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;AAMA;;AAJA;EACE;;AAIF;EACE;EACA;;AAIJ;EACE;;AAIJ;AAAc;EACZ;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;AAEA;EACE;;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAEE;;AAIJ;EACE;EACA;;AAGF;EACE;;;AAIJ;AAII;EACE;;AAGF;EACE;;AAKF;EACE;EACA;;AAIA;EACE;;AAGF;EACE;;AAIJ;EACE;;;AAMJ;AAAA;AAAA;EAGE;;AAGF;EACE;;;AAOE;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;EAIE;;AAGF;EACE;;AAIJ;EACE;;AAIJ;EACE;;AAIA;EACE;;AAGF;AAAA;EAEE;;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;;AAMJ;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAMA;EACE;EACA;;;AAIA;EACE;;;AAIJ;EC3UE;;;AD+UF;AACA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;AACA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;;;AEjYF;EACE;EACA;EAGA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;EAEE,aC7BmB;ED8BnB;;;AAGF;EACE,aClCmB;EDmCnB;;;AAGF;EACE,aCvCmB;EDwCnB;;AAEA;EACE,aC3CiB;ED4CjB;;;AAIJ;EACE,aCjDmB;EDkDnB;;AAEA;EACE,aCrDiB;EDsDjB;;;AAIJ;EACE,aC3DmB;ED4DnB;;;AAGF;AAAA;AAAA;AAAA;EAIE;;;AAGF;EACE;EACA;;AAEA;EAEE;;AAGF;EACE;;;AAIJ;AAAA;EAEE,aCnFqB;EDoFrB;;;AE3FF;EACE,aDMqB;ECLrB;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAGF;AAAA;EAEE,aD1CmB;EC2CnB;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKN;AAAqB;EACnB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAkB;EAChB;EACA;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAAA;AAAA;AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;;AAIJ;AACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;AAAA;EAEE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AACE;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAe;EACb;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;;;AAMR;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;;AAMR;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;AAGE;EACE;EACA;;AAEA;AACE;EACA;;AAIJ;EACE;EACA;;AAEA;AACE;EACA;;;AAKN;AAEA;AAEA;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EAEE;;AAIJ;EACE;;;AAIJ;AAGE;EAEE;EACA;EACA;EACA;;AAKA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAKA;AAAA;EACE;;AAGF;AAAA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;;;AAKN;AAEA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;AAAqB;EACnB;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;AAGE;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAMR;AAEA;AAAA;AAAA;AAIA;AAAA;AAAA;AAIA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;;;AAKN;AAEA;AAEA;EACE;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;AAEA;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAKE;AAAA;EAEE;;AAKF;AAAA;EAEE;;AAKF;AAAA;EAEE;;AAKF;AAAA;EAEE;;;AAKN;AAEA;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE,aDrlDiB;ECslDjB;;AAIA;EACE;;AAGF;EACE;;;AAKN;AAEA;AASE;;AARA;EACE;;AAGF;EACE;;AAIF;EACE;;AAGF;EACE;EACA;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;EACE;EACA,aD1pDiB;EC2pDjB;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA,aD1tDmB;EC2tDnB;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA,aDruDmB;ECsuDnB;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;AACE;EACA;;AAGF;AAAA;EAEE;AAEA;EACA;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;AACE;EACA;;;AAGF;AAEA;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AAKF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKF;EACE;;AAEA;EACE;;;AAMR;AAAA;AAAA;AAIA;AAAA;AAAA;AAIA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;;;AAIA;EACE;;AAGF;EACE;;AAEA;EAGE;;AAGF;EACE;;AAGF;EACE;;AAGF;EAGE;;;AAKN;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAGF;AAAA;EAEE;EACA;;;AAKN;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAMA;AAEA;EACE;;;AAGF;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;AAEA;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAEA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;AAEA;EACE;;;AAGF;AAGE;EACE;AAEA;EACA;EACA;;AAGF;EACE;;;AAIJ;AAEA;AAEA;EACE;AAEA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;AAAA;EAEE;;;AAIJ;AAAA;EAEE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;AAEA;EACE;;;AAGF;EACE;EACA,aD56FqB;;;AC+6FvB;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;;AAIJ;EACE,SDh+F0B;ECi+F1B;;;AAIF;EACE;;;ACxgGF;EACE;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;ACnCF;EACE;EACA;;;AAIA;EAEE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAEA;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;AACE;EACA;;;AAIJ;EACE;;AAEA;EACE;;AAEA;EACE;;;AAKN;EACE;EACA;AAEA;EACA;;;AAGF;EACE;;;AAGF;AAEA;EACE;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAIA;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAEA;EACE;;;AAGF;AAAA;AAAA;EAGE;EACA;;;AAGF;EACE;AAEA;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;IACE;IACA;;;AAIJ;AAAA;EAEE;EACA,aH/TwB;EGgUxB;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE,aHnWsB;EGoWtB;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA,aHhXwB;;AGoXpB;EACE;;AAIA;AAAA;EAEE;EACA;EACA;EACA;;AAKN;EACE;;;AAKN;EACE;AAEA;EACA;EACA;AAEA;EACA;;;AAGF;AAEA;EACE;;AAEA;EACE;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EAEE;;AAKN;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AChdJ;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;;AAIJ;AAAA;AAAA;AAAA;AAKA;AAEA;AAEA;AAEA;AAAA;AAAA;AAIA;EACE;AAEA;;AAGE;EACE;AAEA;;AAEA;EACE;EACA;;AAGF;EACE;;AAEA;EACE;;AAKN;EACE;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA,aJxFgB;EIyFhB;EACA;;;AClGR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;ACVJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;;;ACZJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EACE;;;AAIA;EACE;;AAKF;EACE;;AAGF;EACE;;;AAKF;EAME;EACA;;AAEA;EACE;EACA;EACA;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AAcF;AAAA;AAAA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;AAAA;AAAA;EACE;EACA;EACA;;;AAKF;EACE;;;AAIJ;EACE;;;AAIA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAQF;EACE;EACA;EACA;;;AAGF;EACE;;;ACrIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EAEE;;;AAIJ;EAEE;;;AAGF;AAAA;;AAAA;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAgCA;ECDE;EACA,WT1C0B;ES2C1B,aTzC0B;ES0C1B,eTrB0B;EQuB1B;EACA;EACA;EACA,aR5DmB;EQ6DnB,aRjB+B;EQkB/B;EACA;EACA;EACA;EACA;EACA;;AAKE;EAEE;EACA;EACA;;AAIJ;EAGE,ORtC6B;EQuC7B;;AAGF;EAEE;EACA;EACA;;AAGF;EAGE;EACA,QR9C6B;EQ+C7B;;;AAUJ;ECzDE;EACA,WThB0B;ESiB1B,aThB0B;ESiB1B,eTtB0B;;;AUrC5B;AAEA;AAAA;AAAA;AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAKE;AAAA;EAEE;EACA;EACA;;AAGF;EACE;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;ACnEF;EACE;;AAGE;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAKF;EACE;EACA;EACA;;AAGF;AAAA;EAEE;;AAGF;EACE;EACA;EACA;;;ACpCN;EACE;EACA;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;ACpBF;EACE;;;ACCA;EACE;;AAMA;EAEE;;AAMF;EhBgBF,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EelB1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACZF;AAAA;AAAA;AAAA;AAME;EACE;EACA;EACA,ahBLiB;;AgBQnB;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EDEF,SfC0B;;AgBG1B;EACE,ahBnCiB;EgBoCjB;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE,ahB9DiB;EgB+DjB;;AAEA;EACE;EACA;;AAIJ;EACE;EACA,ahBzEiB;EgB0EjB;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAGF;AAAA;AAEE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;EAIE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;;AAKN;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE,ahBzOqB;;AgB2OrB;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;;AAAA;;AAAA;AAOE;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EAGE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;;;AAMR;AAEA;AAAA;AAAA;AAIA;AAEA;AAGE;EACE;;AAGF;EACE;;AAGF;EAEE;;AAGF;EACE;;;AAIJ;AAEA;AAEA;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EAEE;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AClcF;AAAA;AAAA;AAAA;AAME;EACE,ajBHiB;EiBIjB;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE,ajBxBiB;EiByBjB;;AAEA;EACE;EACA;;AAIJ;EACE;EACA,ajBnCiB;EiBoCjB;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAGF;AAAA;AAEE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;EAIE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAEA;EACE;;AAMJ;EACE;;AAGF;EACE;;AAKF;EAEE;;;AAKN;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;;AAAA;;AAAA;AAMA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EAGE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;;AAEA;EAEE;EACA;EACA;;;AC/PE;EACI;;AAIJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAMR;EACI;EACA;EACA;;AAEA;EACI;;;ACjClB;EJoCA;EACA;;AIhCA;ErBoDA,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EmBRxB;EACA;;AAGA;EACE;;AAMF;EACE;;;ACrBN;AAAA;AAAA;AAYE;EACE;EACA;;AAIF;EACE;EACA;EACA;;AAOF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAOA;EACE;;AAIF;EACE;EACA;EACA;;AAQA;EACE;EACA;;AAGA;EACE;EACA;EACA;;AAKJ;EACE;EACA;;AAGA;EACE;EACA;EACA;;AAON;EACE;EACA;;AAKF;EAEE;;;AAKN;EACE;;;AAKA;EACE;;AAIF;EACE;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;AAEA;EACE;EACA;;AAKF;EACE;;AAIA;AAAA;EAEE;;AAMN;EAEE;EACA;;AAGA;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;;AAON;EL1JA,SfC0B;EoB2JxB;EACA;;;AAKF;ELlKA,SfC0B;;;AqBhC1B;EACE;;AAIF;EACE;EACA;EACA,QAXgB;EAYhB;;AAIF;EACE;EACA;EACA,QAnBgB;EAoBhB,aApBgB;EAqBhB;EACA;EACA;EACA,OAxBgB;;AA4BlB;EACE;EACA;EACA;;AAGA;EACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIA;EACE;;AAKJ;AAgCE;AAAA;;AA9BA;EACE;;AAIF;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAKF;EAEE;;AAKF;EACE;;AAKJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;;AC1HJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;EACA;;AAKF;EbZA,Oae0B;Ebd1B,kBacgD;EbbhD,caa+E;EAE7E;EACA;EACA;EACA;;AbhBF;EAEE,OaSwB;EbRxB;EACA;;AAEF;EACE,OaIwB;EbHxB;EACA;;AAEF;EAGE,OaHwB;EbIxB;EACA;EACA;;AAEA;EAGE,OaXsB;EbYtB;EACA;;AAMF;EAGE,kBatB4C;EbuB5C,cavB2E;;Ab2B/E;EACE,Oa5B8C;Eb6B9C,kBa7BwB;;AAS1B;EACE;;;AC/BJ;EdME,OcHwB;EdIxB,kBcJ8C;EdK9C,ccL6E;;AdO7E;EAEE,OcTsB;EdUtB;EACA;;AAEF;EACE,OcdsB;EdetB;EACA;;AAEF;EAGE,OcrBsB;EdsBtB;EACA;EACA;;AAEA;EAGE,Oc7BoB;Ed8BpB;EACA;;AAMF;EAGE,kBcxC0C;EdyC1C,cczCyE;;Ad6C7E;EACE,Oc9C4C;Ed+C5C,kBc/CsB;;;AAG1B;EACE;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EAEE;EACA;;AAIF;EACE;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE,avBhGiB;EuBiGjB;;;ACnGF;ETgCA,SfC0B;;AwB7BxB;EACE;;AAIJ;E1BEA;E0BGE;;AAIA;EACE;;AAIJ;E1BQA,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EelB1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;ASiBA;EACE;EACA;;;AASA;AAAA;EACE;EACA;;AAKF;AAAA;EACE;EACA;EACA;;AAKF;AAAA;EACE;EACA;;;AAOJ;EACE;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;;AAIJ;EACE;;;AChFA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAKJ;EACE;EACA;EACA;;AAIF;EhB9CA,OgBiD0B;EhBhD1B,kBgBgDgD;EhB/ChD,cgB+C+E;EAE7E;;AhB/CF;EAEE,OgB2CwB;EhB1CxB;EACA;;AAEF;EACE,OgBsCwB;EhBrCxB;EACA;;AAEF;EAGE,OgB+BwB;EhB9BxB;EACA;EACA;;AAEA;EAGE,OgBuBsB;EhBtBtB;EACA;;AAMF;EAGE,kBgBY4C;EhBX5C,cgBW2E;;AhBP/E;EACE,OgBM8C;EhBL9C,kBgBKwB;;AAM1B;EhBvDA,OgB0D0B;EhBzD1B,kBgByDgD;EhBxDhD,cgBwD+E;EAE7E;;AhBxDF;EAEE,OgBoDwB;EhBnDxB;EACA;;AAEF;EACE,OgB+CwB;EhB9CxB;EACA;;AAEF;EAGE,OgBwCwB;EhBvCxB;EACA;EACA;;AAEA;EAGE,OgBgCsB;EhB/BtB;EACA;;AAMF;EAGE,kBgBqB4C;EhBpB5C,cgBoB2E;;AhBhB/E;EACE,OgBe8C;EhBd9C,kBgBcwB;;AAK1B;EACE;;AAGF;EACE;;;ACpEJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIA;E5BLA;E4BQE;EACA;;AAEA;EACE;EACA;;AAMF;E5B2BF,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;;A0BoBtB;EAGE,kBApCe;EAqCf;;AAIF;EAGE,kBA7CmB;EA8CnB;;AAGF;EACE;;AAKJ;EACE;EACA;EACA;;AAGA;EACE;;AAIF;EACE;;AAIF;EACE;;AAKJ;EACE;;;AChFJ;EACE;;AAGF;EACE;EACA;EACA;EACA;;;ACPF;EbgCA,SfC0B;;A4B7B1B;EACE;;AAGF;E9BGA;;A8BCA;EACE;;AAGF;EACE;EACA;;AAMF;E9BiCA,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EFkD1B;;A8BlCA;E9BhBA;E8BkBE;;;AAIJ;EACE;;;ACtCE;EACE;EACA;;AAIF;E/BgCF,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E6BXtB;EACA;;AAMI;E/BsBR,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E6BAhB;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKA;EACE;EACA;;AAKN;EACE;;AAEA;EAEE;EACA;;AAIJ;EACE;;AAEA;EAEE;EACA;;;ACzDd;EhC+BE,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;E8BjB1B,eALa;EAMb;EACA;EACA;;;AAGF;EhCsBE,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;E8BR1B,mBAda;EAeb;EACA;EACA;;;AAKA;EhCkBA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A8BI1B;EhCcA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E8BOxB;;AAGF;EACE;;AAIF;EfrBA;EACA;EACA;EeuBE;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAEF;EACE;;AAOF;EAGE;;AASF;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;;AAIJ;EhC5EA;EgC+EE;;AAGF;EhCpCA,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EeD1B;EACA;EACA;EeiFE;;;AAOA;EhClEF,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A8BwFxB;EhCjGF;EgCoGI;;AAIJ;EhC7EA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E8BkGxB;EACA;EACA;;;AAMF;EhCxFA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A8B+GxB;EACE;;AAIJ;EACE;;;ACzIJ;EACE;;AAEA;EjC+CA,aEhDmB;EFiDnB,WEtC0B;EFuC1B;EACA,aEtC0B;E+BTxB;EACA;EACA;;AAEA;EACE;;AAIF;EACE;EACA;;AAMA;AAAA;AAAA;EAGE;;AAEA;AAAA;AAAA;EACE;;AAMN;EACE;;AAEA;EACE;;AAMF;EACE;;AAEA;AAAA;AAAA;EAGE;EACA;EACA;EACA;;AAOA;EhBzCR;EACA;EACA;;AgBuCQ;EhBzCR;EACA;EACA;;AgBuCQ;EhBzCR;EACA;EACA;;AgBuCQ;EhBzCR;EACA;EACA;;AgB+CE;EjC/BF,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A+ByDtB;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAJF;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAJF;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAJF;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAKJ;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAOA;EtBnGJ,OsBuG8B;EtBtG9B,kBsBsGoD;EtBrGpD,csBqGmF;;AtBnGnF;EAEE,OsBiG4B;EtBhG5B;EACA;;AAEF;EACE,OsB4F4B;EtB3F5B;EACA;;AAEF;EAGE,OsBqF4B;EtBpF5B;EACA;EACA;;AAEA;EAGE,OsB6E0B;EtB5E1B;EACA;;AAMF;EAGE,kBsBkEgD;EtBjEhD,csBiE+E;;AtB7DnF;EACE,OsB4DkD;EtB3DlD,kBsB2D4B;;AAG1B;EtB1GJ,OsB6G8B;EtB5G9B,kBsB4GkD;EtB3GlD,csB2G+E;;AtBzG/E;EAEE,OsBuG4B;EtBtG5B;EACA;;AAEF;EACE,OsBkG4B;EtBjG5B;EACA;;AAEF;EAGE,OsB2F4B;EtB1F5B;EACA;EACA;;AAEA;EAGE,OsBmF0B;EtBlF1B;EACA;;AAMF;EAGE,kBsBwE8C;EtBvE9C,csBuE2E;;AtBnE/E;EACE,OsBkEgD;EtBjEhD,kBsBiE4B;;AAM9B;EjCjFA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E+BsGxB;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvJJ;AAME;AAAA;;AAJA;EACE;;AAKF;EAEE;;AAGF;EAOE;;AAGF;EACE;;AAOF;EAEE;;AAKF;EAEE;;AAKF;EAEE;;AAKF;EACE,QA/DS;EAgET,YA/DY;EAgEZ,WAhEY;;AAqEhB;EACE,aAnEa;EAoEb,YApEa;;AAuEf;EACE,aAzES;EA0ET,YA3EQ;;AA8EV;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EAEE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AC9GF;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAYA;EACE;EACA;EACA;EACA;EACA;;;AAKA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAQA;EAGE;EACA;;AAKJ;EACE;EACA;;;ACrDJ;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE,aAfY;EAgBZ;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE,eAtDY;EAuDZ,aAvDY;EAwDZ;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;EACE,eAxGgB;EAyGhB,aAzGgB;EA0GhB;EACA;EACA;EACA;EACA;EACA;;;AC3GA;EACE;EACA;EACA;EACA,QAPS;EAQT;;AAGF;EACE;EACA,QAbS;EAcT,aAdS;;AAiBX;EACE;EACA,aAnBS;EAoBT;EACA;;AAIF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;;AAKF;EpBbF;EACA;EACA;EoBcI;EACA;EACA,aA7CO;EA8CP;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EAEE;;;AC1EA;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAIJ;EtCgBA,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EoCFxB;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAMF;EACE;;AAGF;EACE;;;AAKF;EACE;;AAGF;EACE;EACA;;AAGF;EtCzDA;EsC2DE;EACA;EAEA;;AACA;EACE;;;AC1EF;EvCwDF,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EqCXtB;EACA,QrCasB;;AqCRxB;EvC+CF,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EqCFtB;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EAGE;;;AChCR;EACE;;AAEA;EACE;;AAMA;AAAA;AAAA;EAGE;EACA;EACA,atCLgB;EsCMhB;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;EAGE;;AAKA;EACE;EACA;;AAIF;EACE;EACA;;AAGA;EAGE;;AAMJ;EAEE;;AAIF;EACE;;AAQJ;EACE;;AAIF;EACE;EACA;;AAKA;E7B7BJ;EACA,W6B+B2C;E7B9B3C,a6B8BiD;E7B7BjD,e6B6BuD;EAEjD;;AAIF;E7BxFJ,O6B2F8B;E7B1F9B,kB6B0FkD;E7BzFlD,c6ByFwE;E7BzCxE;EACA,W6ByC2C;E7BxC3C,a6BwCiD;E7BvCjD,e6BuCuD;EAEjD;;A7B1FN;EAEE,O6BqF4B;E7BpF5B;EACA;;AAEF;EACE,O6BgF4B;E7B/E5B;EACA;;AAEF;EAGE,O6ByE4B;E7BxE5B;EACA;EACA;;AAEA;EAGE,O6BiE0B;E7BhE1B;EACA;;AAMF;EAGE,kB6BsD8C;E7BrD9C,c6BqDoE;;A7BjDxE;EACE,O6BgDgD;E7B/ChD,kB6B+C4B;;AAQ1B;E7BnGJ,O6BuG8B;E7BtG9B,kB6BsGoD;E7BrGpD,c6BqGiE;E7BrDjE;EACA,W6BqD2C;E7BpD3C,a6BoDiD;E7BnDjD,e6BmDuD;;A7BpGvD;EAEE,O6BiG4B;E7BhG5B;EACA;;AAEF;EACE,O6B4F4B;E7B3F5B;EACA;;AAEF;EAGE,O6BqF4B;E7BpF5B;EACA;EACA;;AAEA;EAGE,O6B6E0B;E7B5E1B;EACA;;AAMF;EAGE,kB6BkEgD;E7BjEhD,c6BiE6D;;A7B7DjE;EACE,O6B4DkD;E7B3DlD,kB6B2D4B;;AAGxB;EAEE;;AAMN;EvB5FF;EACA;EACA;;AuB+FE;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAOF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKE;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAKF;EACE;;AAEA;EACE;;AAOJ;EACE;;AAKJ;AAAA;EAEE;;AAIF;EACE;;AAIJ;AAAA;EAEE;;AAMF;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAIF;ExCrNF,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EelB1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EuB6OI;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAMA;E7BnQF,O6BsQ4B;E7BrQ5B,kB6BqQgD;E7BpQhD,c6BoQsE;E7BpNtE;EACA,WT1C0B;ES2C1B,aTb0B;ESc1B,eTpB0B;EsCwOtB;EACA;EACA;EACA;;A7BxQJ;EAEE,O6BgQ0B;E7B/P1B;EACA;;AAEF;EACE,O6B2P0B;E7B1P1B;EACA;;AAEF;EAGE,O6BoP0B;E7BnP1B;EACA;EACA;;AAEA;EAGE,O6B4OwB;E7B3OxB;EACA;;AAMF;EAGE,kB6BiO4C;E7BhO5C,c6BgOkE;;A7B5NtE;EACE,O6B2N8C;E7B1N9C,kB6B0N0B;;AAQxB;EACE;EACA;EACA;;AAEA;EAGE;;AAGF;EACE;;AAKN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AC9SN;EAEE;;AAGF;EACE;EACA;;;ACRF;EACE;;AAGA;EACE;;AAMF;EACE;;AAOA;EACE;EACA;;AAOJ;EACE;;AAIF;EAEE;;AAGF;EACE;;AAIF;EAEE;EACA;;AAGF;EACE","file":"all_concat.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../../scss/modules/_colours.scss","../../../scss/modules/_fonts.scss","../../../scss/partials/_custom.scss","../../../scss/modules/_typography.scss","../../../scss/partials/_stylesheet.scss","../../../scss/modules/_variables.scss","../../../scss/partials/_narrative.scss","../../../scss/partials/_icons.scss","../../../scss/partials/_landingPages.scss","../../../scss/partials/_editor.scss","../../../scss/partials/_notify.scss","../../../scss/partials/_methodCell.scss","../../../scss/partials/_bootstrapHelper.scss","../../../scss/partials/_buttons.scss","../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/mixins/_buttons.scss","../../../scss/partials/_contigBrowserStyles.scss","../../../scss/partials/_tour.scss","../../../scss/partials/_batchMode.scss","../../../scss/partials/_advancedViewCell.scss","../../../scss/partials/_errorDialog.scss","../../../scss/modules/_mixins.scss","../../../scss/partials/_appCell.scss","../../../scss/partials/_editorCell.scss","../../../scss/partials/_appInput.scss","../../../scss/partials/_appParams.scss","../../../scss/partials/_bulkImportCell.scss","../../../scss/partials/_cellToolbar.scss","../../../scss/partials/_dataStaging.scss","../../../scss/partials/_dropzoneDz.scss","../../../scss/partials/_errorDisplay.scss","../../../scss/partials/_filePath.scss","../../../scss/partials/_filetypePanel.scss","../../../scss/partials/_fsm.scss","../../../scss/partials/_infoTab.scss","../../../scss/partials/_jobAction.scss","../../../scss/partials/_jobLog.scss","../../../scss/partials/_jobStatus.scss","../../../scss/partials/_kb-icon.scss","../../../scss/partials/_loadingBlocker.scss","../../../scss/partials/_narrativeOutline.scss","../../../scss/partials/_rcp.scss","../../../scss/partials/_reportViewer.scss","../../../scss/partials/_select2.scss","../../../scss/partials/_stagingTable.scss","../../../scss/partials/_ui.scss","../../../scss/partials/_userMenu.scss"],"names":[],"mappings":";AAAA;ACEA;EACE;EACA;EACA,KACE;;AAOJ;EACE;EACA;EACA;EACA;EACA,KACE;;AAMJ;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;ACtFF;AAAA;AAAA;;AAAA;AAAA;AAMA;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;AAEA;EACE;EACA;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIA;EACE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;AAMA;;AAJA;EACE;;AAIF;EACE;EACA;;AAIJ;EACE;;AAIJ;AAAc;EACZ;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;AAEA;EACE;;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAEE;;AAIJ;EACE;EACA;;AAGF;EACE;;;AAIJ;AAII;EACE;;AAGF;EACE;;AAKF;EACE;EACA;;AAIA;EACE;;AAGF;EACE;;AAIJ;EACE;;;AAMJ;AAAA;AAAA;EAGE;;AAGF;EACE;;;AAOE;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;EAIE;;AAGF;EACE;;AAIJ;EACE;;AAIJ;EACE;;AAIA;EACE;;AAGF;AAAA;EAEE;;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EACE;;;AAMJ;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAMA;EACE;EACA;;;AAIA;EACE;;;AAIJ;EC3UE;;;AD+UF;AACA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;AACA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;;;AEjYF;EACE;EACA;EAGA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;EAEE,aC7BmB;ED8BnB;;;AAGF;EACE,aClCmB;EDmCnB;;;AAGF;EACE,aCvCmB;EDwCnB;;AAEA;EACE,aC3CiB;ED4CjB;;;AAIJ;EACE,aCjDmB;EDkDnB;;AAEA;EACE,aCrDiB;EDsDjB;;;AAIJ;EACE,aC3DmB;ED4DnB;;;AAGF;AAAA;AAAA;AAAA;EAIE;;;AAGF;EACE;EACA;;AAEA;EAEE;;AAGF;EACE;;;AAIJ;AAAA;EAEE,aCnFqB;EDoFrB;;;AE3FF;EACE,aDMqB;ECLrB;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAIA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAGF;AAAA;EAEE,aD1CmB;EC2CnB;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKN;AAAqB;EACnB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAkB;EAChB;EACA;;;AAGF;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;IACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAAA;AAAA;AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;;AAIJ;AACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;AAAA;EAEE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;;AAKN;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AACE;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAe;EACb;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;;AAIJ;EACE;;;AAMR;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;;AAMR;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;AAGE;EACE;EACA;;AAEA;AACE;EACA;;AAIJ;EACE;EACA;;AAEA;AACE;EACA;;;AAKN;AAEA;AAEA;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIA;EAEE;;AAIJ;EACE;;;AAIJ;AAGE;EAEE;EACA;EACA;EACA;;AAKA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAKA;AAAA;EACE;;AAGF;AAAA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAKA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAIA;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;;;AAKN;AAEA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;AAAqB;EACnB;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;AAAA;AAAA;AAIA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAKA;EACE;EACA;;AAGE;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAMR;AAEA;AAAA;AAAA;AAIA;AAAA;AAAA;AAIA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;;;AAKN;AAEA;AAEA;EACE;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;AAEA;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAIA;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAKE;AAAA;EAEE;;AAKF;AAAA;EAEE;;AAKF;AAAA;EAEE;;AAKF;AAAA;EAEE;;;AAKN;AAEA;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE,aDrlDiB;ECslDjB;;AAIA;EACE;;AAGF;EACE;;;AAKN;AAEA;AASE;;AARA;EACE;;AAGF;EACE;;AAIF;EACE;;AAGF;EACE;EACA;;;AAKF;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;EACE;EACA,aD1pDiB;EC2pDjB;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA,aD1tDmB;EC2tDnB;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA,aDruDmB;ECsuDnB;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;AACE;EACA;;AAGF;AAAA;EAEE;AAEA;EACA;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;AAAA;AAAA;AAAA;EAIE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;AAEA;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;;;AAGF;AACE;EACA;;;AAGF;AAEA;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AAKF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKF;EACE;;AAEA;EACE;;;AAMR;AAAA;AAAA;AAIA;AAAA;AAAA;AAIA;AAAA;AAAA;AAIA;EACE;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;;;AAIA;EACE;;AAGF;EACE;;AAEA;EAGE;;AAGF;EACE;;AAGF;EACE;;AAGF;EAGE;;;AAKN;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;AAEA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA;;AAGF;AAAA;EAEE;EACA;;;AAKN;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAMA;AAEA;EACE;;;AAGF;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;AAAA;AAAA;AAAA;AAKA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;AAEA;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAEA;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EAEE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;AAEA;EACE;;;AAGF;AAGE;EACE;AAEA;EACA;EACA;;AAGF;EACE;;;AAIJ;AAEA;AAEA;EACE;AAEA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAAA;EAGE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;EACA;;;AAIJ;AAEA;EACE;EACA;EACA;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AAEA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;AAAA;EAEE;;;AAIJ;AAAA;EAEE;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AAIJ;EACE;;;AAGF;AAEA;EACE;;;AAGF;EACE;EACA,aD56FqB;;;AC+6FvB;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;;;AAGF;AAEA;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;;AAIJ;EACE,SDh+F0B;ECi+F1B;;;AAIF;EACE;;;ACxgGF;EACE;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;ACnCF;EACE;EACA;;;AAIA;EAEE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAEA;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;AAEA;AACE;EACA;;;AAIJ;EACE;;AAEA;EACE;;AAEA;EACE;;;AAKN;EACE;EACA;AAEA;EACA;;;AAGF;EACE;;;AAGF;AAEA;EACE;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAIA;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAEA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAEA;EACE;;;AAGF;AAAA;AAAA;EAGE;EACA;;;AAGF;EACE;AAEA;;AAEA;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;AAEA;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;IACE;IACA;;;AAIJ;AAAA;EAEE;EACA,aH/TwB;EGgUxB;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;AAEA;EACE,aHnWsB;EGoWtB;EACA;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA,aHhXwB;;AGoXpB;EACE;;AAIA;AAAA;EAEE;EACA;EACA;EACA;;AAKN;EACE;;;AAKN;EACE;AAEA;EACA;EACA;AAEA;EACA;;;AAGF;AAEA;EACE;;AAEA;EACE;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EAEE;;AAKN;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAKF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;;AChdJ;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;AAGF;EACE;;AAEA;EACE;;AAGF;EACE;;AAEA;EACE;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;;AAIJ;AAAA;AAAA;AAAA;AAKA;AAEA;AAEA;AAEA;AAAA;AAAA;AAIA;EACE;AAEA;;AAGE;EACE;AAEA;;AAEA;EACE;EACA;;AAGF;EACE;;AAEA;EACE;;AAKN;EACE;EACA;;AAGF;EACE;;AAEA;EACE;EACA;EACA;EACA,aJxFgB;EIyFhB;EACA;;;AClGR;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;ACVJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;AAEA;EACE;;;ACZJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA;EACE;;;AAIA;EACE;;AAKF;EACE;;AAGF;EACE;;;AAKF;EAME;EACA;;AAEA;EACE;EACA;EACA;;;AAKN;EACE;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;;;AAcF;AAAA;AAAA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;AAAA;AAAA;EACE;EACA;EACA;;;AAKF;EACE;;;AAIJ;EACE;;;AAIA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAQF;EACE;EACA;EACA;;;AAGF;EACE;;;ACrIF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EAEE;;;AAIJ;EAEE;;;AAGF;AAAA;;AAAA;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAgCA;ECDE;EACA,WT1C0B;ES2C1B,aTzC0B;ES0C1B,eTrB0B;EQuB1B;EACA;EACA;EACA,aR5DmB;EQ6DnB,aRjB+B;EQkB/B;EACA;EACA;EACA;EACA;EACA;;AAKE;EAEE;EACA;EACA;;AAIJ;EAGE,ORtC6B;EQuC7B;;AAGF;EAEE;EACA;EACA;;AAGF;EAGE;EACA,QR9C6B;EQ+C7B;;;AAUJ;ECzDE;EACA,WThB0B;ESiB1B,aThB0B;ESiB1B,eTtB0B;;;AUrC5B;AAEA;AAAA;AAAA;AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAKE;AAAA;EAEE;EACA;EACA;;AAGF;EACE;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;AAAA;AAIA;EACE;EACA;EACA;;;ACnEF;EACE;;AAGE;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAKF;EACE;EACA;EACA;;AAGF;AAAA;EAEE;;AAGF;EACE;EACA;EACA;;;ACpCN;EACE;EACA;;;AAGF;EACE;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;;ACpBF;EACE;;;ACCA;EACE;;AAMA;EAEE;;AAMF;EhBgBF,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EelB1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;ACZF;AAAA;AAAA;AAAA;AAME;EACE;EACA;EACA,ahBLiB;;AgBQnB;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EDEF,SfC0B;;AgBG1B;EACE,ahBnCiB;EgBoCjB;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;;AAGF;EACE,ahB9DiB;EgB+DjB;;AAEA;EACE;EACA;;AAIJ;EACE;EACA,ahBzEiB;EgB0EjB;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAGF;AAAA;AAEE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;EAIE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;;AAKN;AAAA;EAEE;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;AAEA;EACE;;;AAGF;EACE,ahBzOqB;;AgB2OrB;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;;AAAA;;AAAA;AAOE;EACE;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EAGE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EACA;;;AAMR;AAEA;AAAA;AAAA;AAIA;AAEA;AAGE;EACE;;AAGF;EACE;;AAGF;EAEE;;AAGF;EACE;;;AAIJ;AAEA;AAEA;EACE;EACA;;;AAGF;AAAA;EAEE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;AAEA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EAEE;EACA;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AClcF;AAAA;AAAA;AAAA;AAME;EACE,ajBHiB;EiBIjB;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE,ajBxBiB;EiByBjB;;AAEA;EACE;EACA;;AAIJ;EACE;EACA,ajBnCiB;EiBoCjB;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAGF;AAAA;AAEE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAGF;AAAA;AAAA;AAAA;EAIE;;AAGF;AAAA;EAEE;EACA;;AAGF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;;AAEA;EACE;;AAMJ;EACE;;AAGF;EACE;;AAKF;EAEE;;;AAKN;EACE;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;;;AAIJ;;AAAA;;AAAA;AAMA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EAGE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAKN;EACE;EACA;EACA;;AAEA;EAEE;EACA;EACA;;;AC/PE;EACI;;AAIJ;EACI;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAMR;EACI;EACA;EACA;;AAEA;EACI;;AASZ;EACI;;AAEA;EACI;;AAGJ;EACI;;AAQR;EACI;EACA;;AAIJ;EACI;EACA;;AAIJ;EACI;EACA;;AAOJ;EACI;EACA;;AAIJ;EACI;EACA;EACA;;;ACxFV;EJoCA;EACA;;AIhCA;ErBoDA,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EmBRxB;EACA;;AAGA;EACE;;AAMF;EACE;;;ACrBN;AAAA;AAAA;AAYE;EACE;EACA;;AAIF;EACE;EACA;EACA;;AAOF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAOA;EACE;;AAIF;EXrDF,OWwD4B;EXvD5B,kBWuDkD;EXtDlD,cWsDiF;EAE7E;EACA;EACA;;AXxDJ;EAEE,OWkD0B;EXjD1B;EACA;;AAEF;EACE,OW6C0B;EX5C1B;EACA;;AAEF;EAGE,OWsC0B;EXrC1B;EACA;EACA;;AAEA;EAGE,OW8BwB;EX7BxB;EACA;;AAMF;EAGE,kBWmB8C;EXlB9C,cWkB6E;;AXdjF;EACE,OWagD;EXZhD,kBWY0B;;AAQ1B;EACE;EACA;EACA;;AAMA;EACE;EACA;;AAGA;EACE;EACA;EACA;;AAKJ;EACE;EACA;;AAGA;EACE;EACA;EACA;;AAON;EACE;EACA;;AAKF;EAEE;;;AAKN;EACE;;;AAKA;EACE;;AAOA;EACE;;AAIF;EACE;EACA;;AAEA;EACE;;AAIJ;EACE;;AAKJ;EACE;EACA;;AAIF;EACE;EACA;;AAEA;EACE;EACA;;AAKF;EACE;;AAIA;AAAA;EAEE;;AAMN;EAEE;EACA;;AAGA;EACE;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;;AAEA;EACE;;;AAON;ELrLA,SfC0B;EoBsLxB;EACA;;;AAKF;EL7LA,SfC0B;;;AqBhC1B;EACE;;AAIF;EACE;EACA;EACA,QAXgB;EAYhB;;AAIF;EACE;EACA;EACA,QAnBgB;EAoBhB,aApBgB;EAqBhB;EACA;EACA;EACA,OAxBgB;;AA4BlB;EACE;EACA;EACA;;AAGA;EACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIA;EACE;;AAKJ;AAgCE;AAAA;;AA9BA;EACE;;AAIF;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAKF;EAEE;;AAKF;EACE;;AAKJ;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;;;AC1HJ;EACE;;AAGF;EACE;;AAIF;EACE;EACA;EACA;;AAKF;EbZA,Oae0B;Ebd1B,kBacgD;EbbhD,caa+E;EAE7E;EACA;EACA;EACA;;AbhBF;EAEE,OaSwB;EbRxB;EACA;;AAEF;EACE,OaIwB;EbHxB;EACA;;AAEF;EAGE,OaHwB;EbIxB;EACA;EACA;;AAEA;EAGE,OaXsB;EbYtB;EACA;;AAMF;EAGE,kBatB4C;EbuB5C,cavB2E;;Ab2B/E;EACE,Oa5B8C;Eb6B9C,kBa7BwB;;AAS1B;EACE;;;AC/BJ;EdME,OcHwB;EdIxB,kBcJ8C;EdK9C,ccL6E;;AdO7E;EAEE,OcTsB;EdUtB;EACA;;AAEF;EACE,OcdsB;EdetB;EACA;;AAEF;EAGE,OcrBsB;EdsBtB;EACA;EACA;;AAEA;EAGE,Oc7BoB;Ed8BpB;EACA;;AAMF;EAGE,kBcxC0C;EdyC1C,cczCyE;;Ad6C7E;EACE,Oc9C4C;Ed+C5C,kBc/CsB;;;AAG1B;EACE;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;;AAIF;EACE;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;AAKF;EAEE;EACA;;AAIF;EACE;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;;AAIF;EACE;;AAIF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE,avBhGiB;EuBiGjB;;;ACnGF;ETgCA,SfC0B;;AwB7BxB;EACE;;AAIJ;E1BEA;E0BGE;;AAIA;EACE;;AAIJ;E1BQA,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EelB1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;ASiBA;EACE;EACA;;;AASA;AAAA;EACE;EACA;;AAKF;AAAA;EACE;EACA;EACA;;AAKF;AAAA;EACE;EACA;;;AAOJ;EACE;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;;AAIJ;EACE;;;AChFA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAKJ;EACE;EACA;EACA;;AAIF;EhB9CA,OgBiD0B;EhBhD1B,kBgBgDgD;EhB/ChD,cgB+C+E;EAE7E;;AhB/CF;EAEE,OgB2CwB;EhB1CxB;EACA;;AAEF;EACE,OgBsCwB;EhBrCxB;EACA;;AAEF;EAGE,OgB+BwB;EhB9BxB;EACA;EACA;;AAEA;EAGE,OgBuBsB;EhBtBtB;EACA;;AAMF;EAGE,kBgBY4C;EhBX5C,cgBW2E;;AhBP/E;EACE,OgBM8C;EhBL9C,kBgBKwB;;AAM1B;EhBvDA,OgB0D0B;EhBzD1B,kBgByDgD;EhBxDhD,cgBwD+E;EAE7E;;AhBxDF;EAEE,OgBoDwB;EhBnDxB;EACA;;AAEF;EACE,OgB+CwB;EhB9CxB;EACA;;AAEF;EAGE,OgBwCwB;EhBvCxB;EACA;EACA;;AAEA;EAGE,OgBgCsB;EhB/BtB;EACA;;AAMF;EAGE,kBgBqB4C;EhBpB5C,cgBoB2E;;AhBhB/E;EACE,OgBe8C;EhBd9C,kBgBcwB;;AAK1B;EACE;;AAGF;EACE;EACA;;;ACrEJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIA;E5BLA;E4BQE;EACA;;AAEA;EACE;EACA;;AAMF;E5B2BF,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;;A0BoBtB;EAGE,kBApCe;EAqCf;;AAIF;EAGE,kBA7CmB;EA8CnB;;AAGF;EACE;;AAKJ;EACE;EACA;EACA;;AAGA;EACE;;AAIF;EACE;;AAIF;EACE;;AAKJ;EACE;;;AChFJ;EACE;;AAGF;EACE;EACA;EACA;EACA;;;ACPF;EbgCA,SfC0B;;A4B7B1B;EACE;;AAGF;E9BGA;;A8BCA;EACE;;AAGF;EACE;EACA;;AAMF;E9BiCA,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EFkD1B;;A8BlCA;EACE;;AAGF;E9BpBA;E8BsBE;;AAGF;E9BTA,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;E4BsBxB;EACA;EACA;EACA;;AAEA;EACE;;;AChDF;EACE;EACA;;AAIF;E/BgCF,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E6BXtB;EACA;;AAMI;E/BsBR,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E6BAhB;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAKA;EACE;EACA;;AAKN;EACE;;AAEA;EAEE;EACA;;AAIJ;EACE;;AAEA;EAEE;EACA;;;ACzDd;EhC+BE,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;E8BjB1B,eALa;EAMb;EACA;EACA;;;AAGF;EhCsBE,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;E8BR1B,mBAda;EAeb;EACA;EACA;;;AAKA;EhCkBA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A8BI1B;EhCcA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E8BOxB;;AAGF;EACE;;AAIF;EfrBA;EACA;EACA;EeuBE;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAEF;EACE;;AAOF;EAGE;;AASF;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;;AAIJ;EhC5EA;EgC+EE;;AAGF;EhCpCA,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EeD1B;EACA;EACA;EeiFE;;;AAOA;EhClEF,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A8BwFxB;EhCjGF;EgCoGI;;AAIJ;EhC7EA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E8BkGxB;EACA;EACA;;;AAMF;EhCxFA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A8B+GxB;EACE;;AAIJ;EACE;;;ACzIJ;EACE;;AAEA;EjC+CA,aEhDmB;EFiDnB,WEtC0B;EFuC1B;EACA,aEtC0B;E+BTxB;EACA;EACA;;AAEA;EACE;;AAIF;EACE;EACA;;AAMA;AAAA;AAAA;EAGE;;AAEA;AAAA;AAAA;EACE;;AAMN;EACE;;AAEA;EACE;;AAMF;EACE;;AAEA;AAAA;AAAA;EAGE;EACA;EACA;EACA;;AAOA;EhBzCR;EACA;EACA;;AgBuCQ;EhBzCR;EACA;EACA;;AgBuCQ;EhBzCR;EACA;EACA;;AgBuCQ;EhBzCR;EACA;EACA;;AgB+CE;EjC/BF,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;;A+ByDtB;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAJF;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAJF;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAJF;EhBzDJ;EACA;EACA;EgB0DM;EACA;;AAKJ;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;AAOA;EtBnGJ,OsBuG8B;EtBtG9B,kBsBsGoD;EtBrGpD,csBqGmF;;AtBnGnF;EAEE,OsBiG4B;EtBhG5B;EACA;;AAEF;EACE,OsB4F4B;EtB3F5B;EACA;;AAEF;EAGE,OsBqF4B;EtBpF5B;EACA;EACA;;AAEA;EAGE,OsB6E0B;EtB5E1B;EACA;;AAMF;EAGE,kBsBkEgD;EtBjEhD,csBiE+E;;AtB7DnF;EACE,OsB4DkD;EtB3DlD,kBsB2D4B;;AAG1B;EtB1GJ,OsB6G8B;EtB5G9B,kBsB4GkD;EtB3GlD,csB2G+E;;AtBzG/E;EAEE,OsBuG4B;EtBtG5B;EACA;;AAEF;EACE,OsBkG4B;EtBjG5B;EACA;;AAEF;EAGE,OsB2F4B;EtB1F5B;EACA;EACA;;AAEA;EAGE,OsBmF0B;EtBlF1B;EACA;;AAMF;EAGE,kBsBwE8C;EtBvE9C,csBuE2E;;AtBnE/E;EACE,OsBkEgD;EtBjEhD,kBsBiE4B;;AAM9B;EjCjFA,aEpCmB;EFqCnB,WE1B0B;EF2B1B;EACA,aErB0B;E+BsGxB;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAKA;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAjBF;EACE;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;EACA;;;ACvJJ;AAME;AAAA;;AAJA;EACE;;AAKF;EAEE;;AAGF;EAOE;;AAGF;EACE;;AAOF;EAEE;;AAKF;EAEE;;AAKF;EAEE;;AAKF;EACE,QA/DS;EAgET,YA/DY;EAgEZ,WAhEY;;AAqEhB;EACE,aAnEa;EAoEb,YApEa;;AAuEf;EACE,aAzES;EA0ET,YA3EQ;;AA8EV;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EAEE;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AC9GF;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAYA;EACE;EACA;EACA;EACA;EACA;;;AAKA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAQA;EAGE;EACA;;AAKJ;EACE;EACA;;;ACrDJ;EACE;;AAEA;EACE;EACA;EACA;;AAEA;EACE;;AAGF;EACE,aAfY;EAgBZ;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE,eAtDY;EAuDZ,aAvDY;EAwDZ;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;EACE,eAxGgB;EAyGhB,aAzGgB;EA0GhB;EACA;EACA;EACA;EACA;EACA;;;AC3GA;EACE;EACA;EACA;EACA,QAPS;EAQT;;AAGF;EACE;EACA,QAbS;EAcT,aAdS;;AAiBX;EACE;EACA,aAnBS;EAoBT;EACA;;AAIF;EACE;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;;AAKF;EpBbF;EACA;EACA;EoBcI;EACA;EACA,aA7CO;EA8CP;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACE;EACA;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EAEE;;;AC1EA;EACE;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAIJ;EtCgBA,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EoCFxB;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAMF;EACE;;AAGF;EACE;;;AAKF;EACE;;AAGF;EACE;EACA;;AAGF;EtCzDA;EsC2DE;EACA;EAEA;;AACA;EACE;;;AC1EF;EvCwDF,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EqCXtB;EACA,QrCasB;;AqCRxB;EvC+CF,aEvDmB;EFwDnB,WE7C0B;EF8C1B;EACA,aE7C0B;EqCFtB;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EAGE;;;AChCR;EACE;;AAEA;EACE;;AAMA;AAAA;AAAA;EAGE;EACA;EACA,atCLgB;EsCMhB;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;AAAA;AAAA;EAGE;;AAKA;EACE;EACA;;AAIF;EACE;EACA;;AAGA;EAGE;;AAMJ;EAEE;;AAIF;EACE;;AAQJ;EACE;;AAIF;EACE;EACA;;AAKA;E7B7BJ;EACA,W6B+B2C;E7B9B3C,a6B8BiD;E7B7BjD,e6B6BuD;EAEjD;;AAIF;E7BxFJ,O6B2F8B;E7B1F9B,kB6B0FkD;E7BzFlD,c6ByFwE;E7BzCxE;EACA,W6ByC2C;E7BxC3C,a6BwCiD;E7BvCjD,e6BuCuD;EAEjD;;A7B1FN;EAEE,O6BqF4B;E7BpF5B;EACA;;AAEF;EACE,O6BgF4B;E7B/E5B;EACA;;AAEF;EAGE,O6ByE4B;E7BxE5B;EACA;EACA;;AAEA;EAGE,O6BiE0B;E7BhE1B;EACA;;AAMF;EAGE,kB6BsD8C;E7BrD9C,c6BqDoE;;A7BjDxE;EACE,O6BgDgD;E7B/ChD,kB6B+C4B;;AAQ1B;E7BnGJ,O6BuG8B;E7BtG9B,kB6BsGoD;E7BrGpD,c6BqGiE;E7BrDjE;EACA,W6BqD2C;E7BpD3C,a6BoDiD;E7BnDjD,e6BmDuD;;A7BpGvD;EAEE,O6BiG4B;E7BhG5B;EACA;;AAEF;EACE,O6B4F4B;E7B3F5B;EACA;;AAEF;EAGE,O6BqF4B;E7BpF5B;EACA;EACA;;AAEA;EAGE,O6B6E0B;E7B5E1B;EACA;;AAMF;EAGE,kB6BkEgD;E7BjEhD,c6BiE6D;;A7B7DjE;EACE,O6B4DkD;E7B3DlD,kB6B2D4B;;AAGxB;EAEE;;AAMN;EvB5FF;EACA;EACA;;AuB+FE;EACE;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAOF;EACE;EACA;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKE;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;;AAKF;EACE;;AAEA;EACE;;AAOJ;EACE;;AAKJ;AAAA;EAEE;;AAIF;EACE;;AAIJ;AAAA;EAEE;;AAMF;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AAIF;ExCrNF,aE1BqB;EF2BrB,WEnB0B;EFoB1B;EACA,aEd0B;EelB1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EuB6OI;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;;AAMA;E7BnQF,O6BsQ4B;E7BrQ5B,kB6BqQgD;E7BpQhD,c6BoQsE;E7BpNtE;EACA,WT1C0B;ES2C1B,aTb0B;ESc1B,eTpB0B;EsCwOtB;EACA;EACA;EACA;;A7BxQJ;EAEE,O6BgQ0B;E7B/P1B;EACA;;AAEF;EACE,O6B2P0B;E7B1P1B;EACA;;AAEF;EAGE,O6BoP0B;E7BnP1B;EACA;EACA;;AAEA;EAGE,O6B4OwB;E7B3OxB;EACA;;AAMF;EAGE,kB6BiO4C;E7BhO5C,c6BgOkE;;A7B5NtE;EACE,O6B2N8C;E7B1N9C,kB6B0N0B;;AAQxB;EACE;EACA;EACA;;AAEA;EAGE;;AAGF;EACE;;AAKN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AC9SN;EAEE;;AAGF;EACE;EACA;;;ACRF;EACE;;AAGA;EACE;;AAMF;EACE;;AAOA;EACE;EACA;;AAOJ;EACE;;AAIF;EAEE;;AAGF;EACE;;AAIF;EAEE;EACA;;AAGF;EACE","file":"all_concat.css"} \ No newline at end of file diff --git a/kbase-extension/static/kbase/js/api/RestAPIClient.js b/kbase-extension/static/kbase/js/api/RestAPIClient.js index 3c36228b53..559823a601 100644 --- a/kbase-extension/static/kbase/js/api/RestAPIClient.js +++ b/kbase-extension/static/kbase/js/api/RestAPIClient.js @@ -1,48 +1,48 @@ /* - This is an abstract class designed to wrapper up a RESTful API so it's encapsulated and abstracted away. - - Take a look at StagingServiceClient.js for ane example. Basically, just wrapper up a constructor to return - a RestAPIClient object with routes installed, e.g.: - - return function constructor(args) { - return new RestAPIClient({ - root : http://some.service.url - token : (your auth token) - routes : { - someRoute : { - method : get|post|delete|put|patch - path : "/path/to/route/${variable}/${other}?${query_string}" + This is an abstract class designed to wrapper up a RESTful API so it's encapsulated and abstracted away. + + Take a look at StagingServiceClient.js for ane example. Basically, just wrapper up a constructor to return + a RestAPIClient object with routes installed, e.g.: + + return function constructor(args) { + return new RestAPIClient({ + root : http://some.service.url + token : (your auth token) + routes : { + someRoute : { + method : get|post|delete|put|patch + path : "/path/to/route/${variable}/${other}?${query_string}" + } } + }) + }; + + Note that the path of the route *looks* like it's an ES6 template string - it's not, it's just future proofed to turn into one. + This'll create a new client object with a single route, "someRoute". Call it like this: + + $someClient.someRoute( + { + variable : 'first_thing_in_url", + other : "next_thing_in_url", + query_string: "some_query_in_this_case" } - }) - }; - - Note that the path of the route *looks* like it's an ES6 template string - it's not, it's just future proofed to turn into one. - This'll create a new client object with a single route, "someRoute". Call it like this: - - $someClient.someRoute( - { - variable : 'first_thing_in_url", - other : "next_thing_in_url", - query_string: "some_query_in_this_case" - } - ); - - The variables are arbitrary - it's whatever's named in the template string. Must match \w+. - - It returns a jQuery promise, with its .then and .fail method: - - $someClient.someRoute( { ... } ) - .then(function(data, status, xhr) { - // do interesting things - }) - .fail(function(xhr, textStatus, errorThrown) { - // report failure somehow - }); - - errata - it just uses jquery's ajax methods and promises, and we may want to upgrade that to bluebird. - It also returns the raw info on the successful request, with no parsing of json or nothing. It'd be handy to have - some sort of middleware in there. + ); + + The variables are arbitrary - it's whatever's named in the template string. Must match \w+. + + It returns a jQuery promise, with its .then and .fail method: + + $someClient.someRoute( { ... } ) + .then(function(data, status, xhr) { + // do interesting things + }) + .fail(function(xhr, textStatus, errorThrown) { + // report failure somehow + }); + + errata - it just uses jquery's ajax methods and promises, and we may want to upgrade that to bluebird. + It also returns the raw info on the successful request, with no parsing of json or nothing. It'd be handy to have + some sort of middleware in there. */ define(['jquery'], ($) => { @@ -58,14 +58,11 @@ define(['jquery'], ($) => { // gawd. What i wouldn't give for some ES6 syntax here. routeKeys.forEach((routeName) => { const route = args.routes[routeName]; - const routeArgs = route.path.match(/\${\w+}/g) || []; - if (routeArgs) { - for (let j = 0; j < routeArgs.length; j++) { - const remapped = routeArgs[j].match(/\w+/g)[0]; - routeArgs[j] = remapped; - } + for (let j = 0; j < routeArgs.length; j++) { + const remapped = routeArgs[j].match(/\w+/g)[0]; + routeArgs[j] = remapped; } this[routeName] = function (fArgs) { @@ -73,48 +70,61 @@ define(['jquery'], ($) => { fArgs = {}; } + const ajaxArgs = Object.assign( + {}, + { + token: this.token, + route, + }, + fArgs + ); + let path = route.path; + for (const element of routeArgs) { + const replacement = fArgs[element] !== undefined ? fArgs[element] : ''; + path = path.replace('${' + element + '}', replacement); + } - for (let i = 0; i < routeArgs.length; i++) { - const replacement = - fArgs[routeArgs[i]] !== undefined ? fArgs[routeArgs[i]] : ''; - path = path.replace('${' + routeArgs[i] + '}', replacement); + // add in the Auth header + if (!ajaxArgs.headers) { + ajaxArgs.headers = {}; } - const restURL = [this.root, path].join('/'); - - return this.ajax({ - route: route, - url: restURL, - token: this.token, - data: fArgs.data, - }); + ajaxArgs.headers.Authorization = this.token; + + ajaxArgs.url = [this.root, path].join('/'); + return this.ajax(ajaxArgs); }; }); - this.ajax = function ajax(args) { + /** + * AJAX query executed by each route created above + * + * @param {object} ajaxArgs arguments to pass to $.ajax, including: + * dataType {string} sets the 'Accept' header + * data {any} + * headers {object} object containing header names and values + * e.g. {'Content-Type': 'application/json', ...} + * @returns jQuery promise + */ + this.ajax = function ajax(ajaxArgs) { const deferred = $.Deferred(); + const promise = deferred.promise(); - const beforeSend = function (xhr) { - xhr.setRequestHeader('Authorization', args.token); - }; - - const xhr = $.ajax({ - url: args.url, - dataType: 'text', - type: args.route.method, + const xhrArgs = { + url: ajaxArgs.url, + dataType: ajaxArgs.dataType || 'text', + type: ajaxArgs.route.method, processData: false, - data: JSON.stringify(args.data), - beforeSend: beforeSend, - success: function (data, status, xhr) { + data: JSON.stringify(ajaxArgs.data), + headers: ajaxArgs.headers, + success: (data, status, xhr) => { deferred.resolve(data, status, xhr); }, - error: function (xhr, textStatus, errorThrown) { + error: (xhr, textStatus, errorThrown) => { deferred.reject(xhr, textStatus, errorThrown); }, - }); - - const promise = deferred.promise(); - promise.xhr = xhr; + }; + promise.xhr = $.ajax(xhrArgs); return promise; }; diff --git a/kbase-extension/static/kbase/js/api/StagingServiceClient.js b/kbase-extension/static/kbase/js/api/StagingServiceClient.js index 80606d78d9..1d9fbfe17a 100644 --- a/kbase-extension/static/kbase/js/api/StagingServiceClient.js +++ b/kbase-extension/static/kbase/js/api/StagingServiceClient.js @@ -22,6 +22,7 @@ define(['RestAPIClient'], (RestAPIClient) => { decompress: { method: 'patch', path: 'decompress/${path}' }, importer_mappings: { method: 'get', path: 'importer_mappings/?${file_list}' }, bulkSpecification: { method: 'get', path: 'bulk_specification/?files=${files}' }, + write_bulk_specification: { method: 'post', path: 'write_bulk_specification/' }, }, }); }; diff --git a/kbase-extension/static/kbase/js/common/cellComponents/fieldTableCellWidget.js b/kbase-extension/static/kbase/js/common/cellComponents/fieldTableCellWidget.js index 982d05d535..22f096184c 100644 --- a/kbase-extension/static/kbase/js/common/cellComponents/fieldTableCellWidget.js +++ b/kbase-extension/static/kbase/js/common/cellComponents/fieldTableCellWidget.js @@ -310,6 +310,7 @@ define([ bus, setDuplicateValue, clearDuplicateValue, + validateField, }; } diff --git a/kbase-extension/static/kbase/js/common/cellComponents/filePathWidget.js b/kbase-extension/static/kbase/js/common/cellComponents/filePathWidget.js index 79e842692d..f3e698414c 100644 --- a/kbase-extension/static/kbase/js/common/cellComponents/filePathWidget.js +++ b/kbase-extension/static/kbase/js/common/cellComponents/filePathWidget.js @@ -7,7 +7,8 @@ define([ 'common/cellComponents/fieldTableCellWidget', 'widgets/appWidgets2/paramResolver', 'common/runtime', -], (Promise, html, UI, Events, Props, FieldWidget, ParamResolver, Runtime) => { + 'util/appCellUtil', +], (Promise, html, UI, Events, Props, FieldWidget, ParamResolver, Runtime, Util) => { 'use strict'; const tag = html.tag, @@ -121,15 +122,15 @@ define([ bus = runtime.bus().makeChannelBus({ description: 'A file path widget', }); - let container, ui; + let container, ui, appSpec; - function makeFieldWidget(rowId, inputWidget, appSpec, parameterSpec, value) { + function makeFieldWidget(rowId, inputWidget, parameterSpec, value) { const fieldWidget = FieldWidget.make({ inputControlFactory: inputWidget, showHint: true, useRowHighight: true, initialValue: value, - appSpec, + appSpec: appSpec.getSpec(), parameterSpec, workspaceId, referenceType: 'name', @@ -143,6 +144,7 @@ define([ invalidValues: unavailableFiles, invalidError: 'file not found', disabledValues: getAllSelectedFiles(), + skipAutoValidate: true, }); /** @@ -174,9 +176,10 @@ define([ } else { paramsBus.emit('parameter-changed', { parameter: parameterSpec.id, - newValue: newValue, + newValue, + newDisplayValue: message.newDisplayValue, isError: message.isError, - rowId: rowId, + rowId, rowIndex: dataModel.rowIdToIndex[rowId], }); } @@ -456,13 +459,12 @@ define([ * Creates a new single file path widget for the parameter id with some initial value. * This returns a Promise that resolves into the new widget. * @param {string} rowId - the unique row id where this widget will live - * @param {object} appSpec - the entire app spec to pass along to the widget * @param {object} filePathParams - the object holding all file path param specs * @param {string} parameterId - the parameter id from the app spec * @param {any} parameterValue - the initial value of the parameter * @returns the created and started widget, linked to its parameterId in a tiny object */ - function createFilePathWidget(rowId, appSpec, filePathParams, parameterId, parameterValue) { + function createFilePathWidget(rowId, filePathParams, parameterId, parameterValue) { const spec = filePathParams.paramMap[parameterId]; let widget; let controlPromise; @@ -478,7 +480,7 @@ define([ } return controlPromise .then((inputWidget) => { - widget = makeFieldWidget(rowId, inputWidget, appSpec, spec, parameterValue); + widget = makeFieldWidget(rowId, inputWidget, spec, parameterValue); return widget.start({ node: container.querySelector('#' + filePathParams.view[spec.id].id), @@ -542,7 +544,6 @@ define([ * @returns a Promise that resolves when all widgets are created and saved. */ function makeFilePathRow(filePathRow, rowId, params) { - const appSpec = model.getItem('appSpec'); const filePathParams = makeFilePathsLayout(model.getItem('parameterSpecs')); const rowEvents = Events.make(); @@ -595,7 +596,6 @@ define([ filePathParams.layout.map(async (parameterId) => { return await createFilePathWidget( rowId, - appSpec, filePathParams, parameterId, params[parameterId] @@ -615,7 +615,7 @@ define([ * Update as changed, and propagate entire parameter list up to parent bus * @param {object} arg - has keys: * node - the containing DOM node - * appSpec - the appSpec for the app having its parameters portrayed here + * appSpec - the appSpec (the processed common/spec object) for the app having its parameters portrayed here * parameters - the parameter set with the layout order * @returns a promise that resolves when all file path rows are created from * the initial set of parameters @@ -629,7 +629,7 @@ define([ doAttach(); attachEvents(); model.setItem('parameterIds', paramIds); - model.setItem('appSpec', arg.appSpec); + appSpec = arg.appSpec; model.setItem('parameterValues', initialParams); // get the parameter specs in the right order. const parameterSpecs = []; @@ -661,6 +661,17 @@ define([ return addRow(paramRow); }) ) + .then(() => { + // At the end, we do a bulk validation job on all new file path widgets. + // Grab all widgets of each type, get their values, use the specs to get all other + // options / constraints. Feed this info into the validateArray command, then dole + // out individual validation results to each widget for rendering errors, etc. + if (!config.viewOnly) { + return doBulkValidation(); + } else { + return Promise.resolve(); + } + }) .then(() => { // once all rows are set up and we have the data model // disable all relevant files from each input widget. @@ -680,6 +691,58 @@ define([ }); } + /** + * + * @returns Promise that resolves into a whole bunch of validation objects + */ + function doBulkValidation() { + // transform values to { paramId: [values] } + const paramValueMap = paramIds.reduce((valueMap, paramId) => { + valueMap[paramId] = []; + return valueMap; + }, {}); + dataModel.rowOrder.forEach((row) => { + const rowData = dataModel.rows[row]; + paramIds.forEach((paramId) => paramValueMap[paramId].push(rowData.values[paramId])); + }); + + const validationOptions = Util.getFilePathValidationOptions( + model.getItem('fileParamIds'), + paramIds, + unavailableFiles, + { + invalidError: 'file not found', + }, + { + shouldNotExist: true, + nullToEmptyString: true, + } + ); + + return appSpec + .validateMultipleParamsArray(paramIds, paramValueMap, validationOptions) + .then((validations) => { + // send each validation to each widget + // if any are invalid for a parameter id, track it so we can send up + // the parameter bus + const invalidParamIds = new Set(); + Object.keys(validations).forEach((paramId) => { + validations[paramId].map((validation, index) => { + const rowId = dataModel.rowOrder[index]; + dataModel.rows[rowId].widgets[paramId].validateField(validation); + if (!validation.isValid) { + invalidParamIds.add(paramId); + } + }); + }); + invalidParamIds.forEach((paramId) => { + paramsBus.emit('invalid-param-value', { + parameter: paramId, + }); + }); + }); + } + /** * Gets all the selected files and tells all file input widgets to make those disabled. * So the user can only select one file from the list. diff --git a/kbase-extension/static/kbase/js/common/cellComponents/paramsWidget.js b/kbase-extension/static/kbase/js/common/cellComponents/paramsWidget.js index 53ab473d72..3e72890ed4 100644 --- a/kbase-extension/static/kbase/js/common/cellComponents/paramsWidget.js +++ b/kbase-extension/static/kbase/js/common/cellComponents/paramsWidget.js @@ -20,7 +20,7 @@ define([ function factory(config) { const viewOnly = config.viewOnly || false; - const { bus, workspaceId, paramIds, initialParams } = config; + const { bus, workspaceId, paramIds, initialParams, initialDisplay } = config; // key = param id, value = boolean, true if is in error const advancedParamErrors = {}; const runtime = Runtime.make(), @@ -78,12 +78,20 @@ define([ be cross-validated for uniqueness (optional) */ - function makeFieldWidget(inputWidget, appSpec, parameterSpec, value, closeParameters) { + function makeFieldWidget( + inputWidget, + appSpec, + parameterSpec, + value, + displayValue, + closeParameters + ) { const fieldWidget = FieldWidget.make({ inputControlFactory: inputWidget, showHint: true, useRowHighight: true, initialValue: value, + initialDisplayValue: displayValue, referenceType: 'name', paramsChannelName: bus.channelName, appSpec, @@ -100,6 +108,7 @@ define([ { parameter: parameterSpec.id, newValue: message.newValue, + newDisplayValue: message.newDisplayValue, isError: message.isError, }, { @@ -113,6 +122,7 @@ define([ bus.emit('parameter-changed', { parameter: parameterSpec.id, newValue: message.newValue, + newDisplayValue: message.newDisplayValue, isError: message.isError, }); }); @@ -305,7 +315,7 @@ define([ class: `${cssBaseClass}__toggle--advanced-message`, }), showAdvancedButton, - ].join() + ].join('') ); showHideAdvanced(); } @@ -463,7 +473,8 @@ define([ inputWidget, appSpec, paramSpec, - initialParams[paramSpec.id] + initialParams[paramSpec.id], + initialDisplay[paramSpec.id] ); widgets.push(widget); @@ -502,12 +513,11 @@ define([ places.parameterFields.innerHTML = filteredParams.content; - return Promise.all( - filteredParams.layout.map(async (parameterId) => { - await createParameterWidget(appSpec, filteredParams, parameterId); - }) - ).then(() => { - renderAdvanced(filteredParams.advancedIds); + const parameterPromises = filteredParams.layout.map((parameterId) => + createParameterWidget(appSpec, filteredParams, parameterId) + ); + return Promise.all(parameterPromises).then(() => { + renderAdvanced(); }); } @@ -548,7 +558,6 @@ define([ return renderParameters() .then(() => { - // do something after success attachEvents(); }) .catch((error) => { @@ -557,7 +566,7 @@ define([ } function stop() { - return Promise.try(() => { + return Promise.all(widgets.map((widget) => widget.stop())).then(() => { if (container) { container.innerHTML = ''; } diff --git a/kbase-extension/static/kbase/js/common/cellComponents/tabs/infoTab.js b/kbase-extension/static/kbase/js/common/cellComponents/tabs/infoTab.js index 5add106314..30b271edc9 100644 --- a/kbase-extension/static/kbase/js/common/cellComponents/tabs/infoTab.js +++ b/kbase-extension/static/kbase/js/common/cellComponents/tabs/infoTab.js @@ -42,7 +42,19 @@ define(['common/format', 'common/html', 'util/string'], (format, html, string) = { class: `${cssBaseClass}__list_item--params`, }, - span({}, param.ui_name) + (types ? ': ' + types : '') + span( + { + class: `${cssBaseClass}__param--id`, + }, + param.id + ) + + span( + { + class: `${cssBaseClass}__param--ui-name`, + }, + param.ui_name + ) + + (types ? ': ' + types : '') ); }); diff --git a/kbase-extension/static/kbase/js/common/dialogMessages.js b/kbase-extension/static/kbase/js/common/dialogMessages.js index 2770c267cc..1e58e4a639 100644 --- a/kbase-extension/static/kbase/js/common/dialogMessages.js +++ b/kbase-extension/static/kbase/js/common/dialogMessages.js @@ -42,20 +42,10 @@ define(['common/html', 'common/jobs', 'common/ui', 'util/string'], (html, Jobs, ]), }, appReset: { - // in case of general error - title: 'Reset app?', - body: div([ - p( - 'This action will clear any parameters, results, and logs, and re-enable the Configure tab for editing.' - ), - p('Reset the app and resume editing?'), - ]), - }, - appRerun: { title: 'Reset and resume editing?', body: div([ p( - 'This action will clear the results and re-enable the Configure tab for editing. You may then change inputs and run the app again.' + 'This action will clear any errors, results, or logs, and re-enable the Configure tab for editing. You may then change inputs and run the app again.' ), p( 'Any output you have already produced will be left intact in the Narrative and Data Panel' diff --git a/kbase-extension/static/kbase/js/common/errorDisplay.js b/kbase-extension/static/kbase/js/common/errorDisplay.js index 49c7de4b28..45a4ba9d05 100644 --- a/kbase-extension/static/kbase/js/common/errorDisplay.js +++ b/kbase-extension/static/kbase/js/common/errorDisplay.js @@ -23,17 +23,25 @@ define(['bluebird', 'common/html'], (Promise, html) => { */ function normaliseErrorObject(rawObject) { - if (rawObject.exec && rawObject.exec.jobState) { - rawObject = { jobState: rawObject.exec.jobState }; - } - let errorObject; - if (rawObject.jobState && (rawObject.jobState.error || rawObject.jobState.errormsg)) { - errorObject = convertJobError(rawObject.jobState); + if (rawObject.fatalError) { + errorObject = convertInternalError(rawObject.fatalError); } else if (rawObject.internalError) { errorObject = convertInternalError(rawObject.internalError); } else if (rawObject.appError) { errorObject = convertAppError(rawObject.appError); + } else if ( + rawObject.exec && + rawObject.exec.jobState && + (rawObject.exec.jobState.error || rawObject.exec.jobState.errormsg) + ) { + rawObject = { jobState: rawObject.exec.jobState }; + errorObject = convertJobError(rawObject.jobState); + } else if ( + rawObject.jobState && + (rawObject.jobState.error || rawObject.jobState.errormsg) + ) { + errorObject = convertJobError(rawObject.jobState); } if (!errorObject) { diff --git a/kbase-extension/static/kbase/js/common/iframe/messages.js b/kbase-extension/static/kbase/js/common/iframe/messages.js index 8c8c79bed3..60a2d61475 100644 --- a/kbase-extension/static/kbase/js/common/iframe/messages.js +++ b/kbase-extension/static/kbase/js/common/iframe/messages.js @@ -7,8 +7,8 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { let lastId = 0; //: number; const partners = {}; // Object; - const listeners = {}; //Object>; - const awaitingResponse = {}; //: Object; + const listeners = {}; // Object>; + const awaitingResponse = {}; // Object; function genId() { lastId += 1; @@ -30,7 +30,7 @@ define(['bluebird', 'uuid'], (Promise, Uuid) => { const message = event.data; let response; - if (!message.address && !message.address.to) { + if (!message.address || !message.address.to) { console.warn('Message without address.to - ignored (iframe)', message); return; } diff --git a/kbase-extension/static/kbase/js/common/jobManager.js b/kbase-extension/static/kbase/js/common/jobManager.js index e270f4d89c..89bd3e9d27 100644 --- a/kbase-extension/static/kbase/js/common/jobManager.js +++ b/kbase-extension/static/kbase/js/common/jobManager.js @@ -243,7 +243,7 @@ define([ if ( !this._isValidEvent(event) || !this.handlers[event] || - !Object.keys(this.handlers[event]) + !Object.keys(this.handlers[event]).length ) { return; } @@ -251,10 +251,14 @@ define([ Object.keys(this.handlers[event]) .sort() .forEach((handlerName) => { - try { - this.handlers[event][handlerName](ctx, ...args); - } catch (err) { - console.warn(`Error executing handler ${handlerName}:`, err); + // ensure the handler exists before trying to execute as it's possible + // for the handler to be removed by another process during iteration + if (this.handlers[event][handlerName]) { + try { + this.handlers[event][handlerName](ctx, ...args); + } catch (err) { + console.warn(`Error executing handler ${handlerName}:`, err); + } } }); } @@ -430,16 +434,21 @@ define([ this.looper = new Looper({ pollInterval: this.pollInterval }); } + // add the default job status handler this.addEventHandler(jcm.MESSAGE_TYPE.STATUS, { - // default job status handler [`__default_${jcm.MESSAGE_TYPE.STATUS}`]: self.handleJobStatus.bind(self), - - // set up a delayed request for job status, executed after this.pollInterval ms - jobStatusLooper: () => { - self.looper.scheduleRequest(self.requestJobStatus.bind(self)); - }, }); - this.bus.emit(jcm.MESSAGE_TYPE.STATUS, { [jcm.PARAM.JOB_ID]: job.job_id }); + + if (!Jobs.isTerminalStatus(job.status)) { + // if the job isn't terminal, add the job status request scheduler + this.addEventHandler(jcm.MESSAGE_TYPE.STATUS, { + // set up a delayed request for job status, executed after this.pollInterval ms + jobStatusLooper: () => { + self.looper.scheduleRequest(self.requestJobStatus.bind(self)); + }, + }); + this.bus.emit(jcm.MESSAGE_TYPE.STATUS, { [jcm.PARAM.JOB_ID]: job.job_id }); + } } /** @@ -463,8 +472,8 @@ define([ if (Jobs.isTerminalStatus(job.status)) { // no more updates. Remove the looping request handler - this.looper.clearRequest(); this.removeEventHandler(jcm.MESSAGE_TYPE.STATUS, 'jobStatusLooper'); + this.looper.clearRequest(); return; } @@ -481,11 +490,19 @@ define([ handleJobStatus(self, message) { const job = this.model.getItem('exec.jobState'); if (message[job.job_id]) { - const jobState = message[job.job_id].jobState; + const { outputWidgetInfo, jobState } = message[job.job_id]; + if (outputWidgetInfo) { + self.model.setItem('exec.outputWidgetInfo', outputWidgetInfo); + } if (_.isEqual(jobState, job)) { // no update required return; } + if (Jobs.isTerminalStatus(jobState.status)) { + // no more updates. Remove the looping request handler + this.removeEventHandler(jcm.MESSAGE_TYPE.STATUS, 'jobStatusLooper'); + this.looper.clearRequest(); + } // update the model self.updateModel(jobState); } @@ -504,6 +521,31 @@ define([ } return undefined; } + + /** + * Cancel a job in an app cell. + * + * This action is triggered by hitting the 'Cancel' button at the top left of the + * app cell + */ + cancelJob() { + const jobId = this.model.getItem('exec.jobState.job_id'); + if (jobId) { + this.bus.emit(jcm.MESSAGE_TYPE.CANCEL, { [jcm.PARAM.JOB_ID]: jobId }); + } + } + + /** + * Reset the job manager, removing all listeners and stored job data + */ + resetJobs() { + // remove all listeners and cancel any pending job requests + if (this.looper) { + this.looper.clearRequest(); + } + this.removeAllListeners(); + this.model.deleteItem('exec'); + } }; /** @@ -531,7 +573,7 @@ define([ const toAdd = {}; toAdd[`__default_${jcm.MESSAGE_TYPE[event]}`] = defaultHandlers[event]; this.addEventHandler(jcm.MESSAGE_TYPE[event], toAdd); - }, this); + }); } /** diff --git a/kbase-extension/static/kbase/js/common/jobStateViewer.js b/kbase-extension/static/kbase/js/common/jobStateViewer.js index e4e137463f..6b57203fba 100644 --- a/kbase-extension/static/kbase/js/common/jobStateViewer.js +++ b/kbase-extension/static/kbase/js/common/jobStateViewer.js @@ -101,9 +101,11 @@ define([ this.lastJobState = this.jobManager.getJob(this.jobId); this.renderJobState(this.lastJobState || { job_id: this.jobId }); - this.bus.emit(jcm.MESSAGE_TYPE.STATUS, { - [jcm.PARAM.JOB_ID]: this.jobId, - }); + if (!this.lastJobState || !this.lastJobState.status) { + this.bus.emit(jcm.MESSAGE_TYPE.STATUS, { + [jcm.PARAM.JOB_ID]: this.jobId, + }); + } }); } diff --git a/kbase-extension/static/kbase/js/common/jobs.js b/kbase-extension/static/kbase/js/common/jobs.js index 05f7f03623..0f30b06bfb 100644 --- a/kbase-extension/static/kbase/js/common/jobs.js +++ b/kbase-extension/static/kbase/js/common/jobs.js @@ -683,6 +683,21 @@ define([ return jobState; } + /** + * createJobStatusSummary + * This is designed for use in the appCell's `execMessage` element. + * + * @param {object} jobState object representing the current job state + * + * @returns {string} a single line summary of the current state + */ + function createJobStatusSummary(jobState) { + if (jobState && jobState.status === JOB.does_not_exist) { + return 'Job not found'; + } + return createJobStatusLines(jobState)[0]; + } + /** * createJobStatusLines * Record the current state of the job and its previous states, including time @@ -1078,6 +1093,7 @@ define([ createJobStatusFromFsm, createJobStatusFromBulkCellFsm, createJobStatusLines, + createJobStatusSummary, getCurrentJobCounts, getCurrentJobs, getFsmStateFromJobs, diff --git a/kbase-extension/static/kbase/js/common/parameterSpec.js b/kbase-extension/static/kbase/js/common/parameterSpec.js index 19a36685c5..68a2a82cef 100644 --- a/kbase-extension/static/kbase/js/common/parameterSpec.js +++ b/kbase-extension/static/kbase/js/common/parameterSpec.js @@ -43,10 +43,7 @@ define([], () => { } function isAdvanced() { - if (spec.advanced === 1) { - return true; - } - return false; + return spec.advanced === 1; } function dataType() { @@ -150,7 +147,7 @@ define([], () => { case 'float': return parseFloat(_defaultValue); case 'boolean': - return coerceToBoolean(_defaultValue); + return !!_defaultValue; case 'string': case 'workspaceObjectName': default: @@ -177,7 +174,7 @@ define([], () => { if (typeof value !== 'string') { return 0; } - switch (value.toLowerCase(value)) { + switch (value.toLowerCase()) { case 'true': case 't': case 'yes': @@ -237,13 +234,10 @@ define([], () => { if (value === undefined || value === null) { return true; } - if ( + return !!( (dataType() === 'string' || dataType() === 'workspaceObjectName') && value.length === 0 - ) { - return true; - } - return false; + ); } function uiClass() { diff --git a/kbase-extension/static/kbase/js/common/sdk.js b/kbase-extension/static/kbase/js/common/sdk.js index 1115847eef..d92a00b461 100644 --- a/kbase-extension/static/kbase/js/common/sdk.js +++ b/kbase-extension/static/kbase/js/common/sdk.js @@ -15,7 +15,7 @@ define(['common/props'], (Props) => { if (typeof value !== 'string') { return false; } - switch (value.toLowerCase(value)) { + switch (value.toLowerCase()) { case 'true': case 't': case 'yes': @@ -25,7 +25,6 @@ define(['common/props'], (Props) => { case 'f': case 'no': case 'n': - return false; default: return false; } @@ -39,56 +38,49 @@ define(['common/props'], (Props) => { if (converted.multipleItems) { return []; } - const nullValue = (function () { + try { + const isMultiSelect = converted.original.dropdown_options.multiselection; + if (isMultiSelect === 1) { + return []; + } + } catch (err) { + // ignore the error + } + + return (function () { switch (converted.data.type) { case 'string': return ''; - case 'int': - return null; - case 'float': - return null; - case 'workspaceObjectRef': - return null; - case 'workspaceObjectName': - return null; case 'struct': return {}; case '[]struct': return []; + // other cases: int, float, workspaceObjectRef, workspaceObjectName default: return null; } })(); - return nullValue; - } - - function updateNullValue(converted) { - converted.data.nullValue = nullValue(converted); } /* * Default values are strings. */ - function defaultToNative(converted, defaultValue) { + function defaultToNative(converted, value) { switch (converted.data.type) { - case 'string': - return defaultValue; case 'int': - return parseInt(defaultValue); + return parseInt(value); case 'float': - return parseFloat(defaultValue); + return parseFloat(value); + case 'boolean': + return coerceToBoolean(value); case 'workspaceObjectRef': - if (defaultValue === '') { + if (value === '') { return null; } - return defaultValue; - case 'workspaceObjectName': - return defaultValue; - case 'boolean': - return coerceToBoolean(defaultValue); + return value; default: // Assume it is a string... - return defaultValue; + return value; } } @@ -105,15 +97,10 @@ define(['common/props'], (Props) => { * TODO: more cases of bad default value? Or a generic * default value validator? */ - if (!defaultValues || defaultValues.length === 0) { + if (defaultValues.length === 0) { return spec.checkbox_options.unchecked_value; } return coerceToIntBoolean(defaultValues[0]); - case 'custom_textsubdata': - if (!defaultValues) { - // ?? - } - break; case 'textsubdata': if (spec.default_values) { if (spec.default_values.length === 1 && spec.default_values[0] === '') { @@ -125,9 +112,12 @@ define(['common/props'], (Props) => { } } - // No default in spec, yet required. - if (!defaultValues && converted.required) { - return converted.data.nullValue; + if ( + 'dropdown_options' in spec && + spec.allow_multiple === 0 && + spec.dropdown_options.multiselection === 1 + ) { + return spec.default_values; } if (defaultValues.length === 0) { @@ -144,39 +134,27 @@ define(['common/props'], (Props) => { return defaultToNative(converted, defaultValues[0]); } - function updateDefaultValue(converted, spec) { - converted.data.defaultValue = defaultValue(converted, spec); - } - function grokDataType(spec) { - /* - * Special case here -- - * is actually an int, although Mike says it can be any type... - */ switch (spec.field_type) { case 'checkbox': return 'int'; + // file datatype is really a file which is uploaded to shock, + // which results in a shock file handle. case 'file': - // file datatype is really a file which is uploaded to shock, which results in a - // shock file handle. maybe this field type should be "shock_file" - return 'string'; case 'textarea': - return 'string'; case 'dropdown': - return 'string'; case 'dynamic_dropdown': + case 'autocomplete': return 'string'; case 'textsubdata': return 'subdata'; case 'custom_textsubdata': return 'customSubdata'; case 'custom_button': - switch (spec.id) { - case 'input_check_other_params': - return 'boolean'; - default: - return 'unspecified'; + if (spec.id === 'input_check_other_params') { + return 'boolean'; } + return 'unspecified'; case 'custom_widget': if (spec.dropdown_options) { return '[]string'; @@ -184,8 +162,6 @@ define(['common/props'], (Props) => { break; case 'group': return 'struct'; - case 'autocomplete': - return 'string'; case 'custom': return 'custom'; } @@ -227,10 +203,8 @@ define(['common/props'], (Props) => { // Okay, if it has no specific type assigned (validate_as), and is // not flagged from the various properties above by grousing through // the text_options, we assume it is a string. - - switch (spec.field_type) { - case 'text': - return 'string'; + if (spec.field_type === 'text') { + return 'string'; } console.error('ERROR could not determine type from spec', spec); @@ -307,6 +281,10 @@ define(['common/props'], (Props) => { case 'dropdown': constraints = { options: spec.dropdown_options ? spec.dropdown_options.options : {}, + multiselection: + spec.dropdown_options && spec.dropdown_options.multiselection + ? spec.dropdown_options.multiselection + : 0, }; break; case 'textarea': @@ -317,8 +295,6 @@ define(['common/props'], (Props) => { }; break; case 'autocomplete': - constraints = {}; - break; case 'file': constraints = {}; break; @@ -356,20 +332,10 @@ define(['common/props'], (Props) => { }; break; case '[]string': - switch (fieldType) { - case 'dynamic_dropdown': - constraints = { - options: spec.text_options, - }; - break; - case 'dropdown': - break; - case 'text': - break; - case 'textarea': - break; - default: - // throw new Error('Unknown []string field type: ' + fieldType); + if (fieldType === 'dynamic_dropdown') { + constraints = { + options: spec.text_options, + }; } break; case 'subdata': @@ -383,75 +349,6 @@ define(['common/props'], (Props) => { multiple: false, }; break; - // case 'xxinput_property_x': - // return { - // defaultValue: defaultValue(), - // referredParameter: 'input_sample_property_matrix', - // subdataIncluded: 'metadata/column_metadata', - // path: 'metadata/column_metadata', - // // custom function to collect - // mapper: { - // before: function () { - // return { - // collected: {} - // }; - // }, - // during: function (values, state) { - // values.forEach(function (value) { - // if (value.entity === 'Condition') { - // state.collected[value.property_name] = true; - // } - // }); - // }, - // after: function (state) { - // return Object.keys(state.collected).map(function (key) { - // return { - // id: key, - // desc: key - // }; - // }); - // } - // } - // }; - // case 'sample_property': - // return { - // required: required(), - // defaultValue: defaultValue(), - // referredParameter: 'input_sample_property_matrix', - // subdataIncluded: 'metadata/column_metadata', - // subdataPath: 'metadata.column_metadata', - // // custom function to collect - // map: function (subdata) { - // var collected = {}; - // Object.keys(subdata).forEach(function (key) { - // var id, name, column = subdata[key]; - // column.forEach(function (value) { - // if (value.category === 'DataSeries' && value.property_name === 'SeriesID') { - // id = value.property_value; - // } else if (value.category === 'Property' && value.property_name === 'Name') { - // name = value.property_value; - // } - // if (id && name) { - // collected[id] = name; - // } - // }); - // }); - // return Object.keys(collected).map(function (key) { - // return { - // id: key, - // desc: collected[key] - // }; - // }) - // .sort(function (a, b) { - // if (a.desc < b.desc) { - // return -1; - // } else if (a.desc > b.desc) { - // return 1; - // } - // return 0; - // }); - // } - // }; case 'struct': break; case 'unspecified': @@ -488,11 +385,8 @@ define(['common/props'], (Props) => { // Stepwise conversion function updateData(converted, spec) { - switch (converted.data.type) { - case 'subdata': - converted.data.multiple = spec.textsubdata_options.multipleitems ? true : false; - break; - default: + if (converted.data.type === 'subdata') { + converted.data.multiple = spec.textsubdata_options.multipleitems ? true : false; } } @@ -526,14 +420,14 @@ define(['common/props'], (Props) => { type: dataType, sequence: false, constraints: { - required: required, + required, }, defaultValue: null, }, original: spec, }; - updateNullValue(itemSpec, spec); - updateDefaultValue(itemSpec, spec); + itemSpec.data.nullValue = nullValue(itemSpec); + itemSpec.data.defaultValue = defaultValue(itemSpec, spec); updateConstraints(itemSpec, spec); updateUI(itemSpec, spec); updateData(itemSpec, spec); @@ -578,7 +472,7 @@ define(['common/props'], (Props) => { if (spec.allow_multiple) { // except, ahem, for the custom_subdata, at least for now... if (spec.field_type === 'custom_textsubdata') { - spec.allow_multiple === 0; + spec.allow_multiple = 0; spec.textsubdata_options = { multiselection: 1, }; @@ -612,8 +506,8 @@ define(['common/props'], (Props) => { original: spec, }; - updateNullValue(converted, spec); - updateDefaultValue(converted, spec); + converted.data.nullValue = nullValue(converted); + converted.data.defaultValue = defaultValue(converted, spec); updateConstraints(converted, spec); updateUI(converted, spec); updateData(converted, spec); @@ -633,17 +527,14 @@ define(['common/props'], (Props) => { }); const required = group.optional ? false : true; - let defaultValue; - let nullValue; + const defaultValues = {}; + const zeroValue = defaultValues; - nullValue = null; - defaultValue = {}; Object.keys(groupParams).forEach((id) => { - defaultValue[id] = groupParams[id].data.defaultValue; + defaultValues[id] = groupParams[id].data.defaultValue; }); - const zeroValue = defaultValue; - const structSpec = { + return { id: group.id, multipleItems: false, ui: { @@ -660,16 +551,15 @@ define(['common/props'], (Props) => { constraints: { required: required, }, - defaultValue: defaultValue, - nullValue: nullValue, - zeroValue: zeroValue, + defaultValue: defaultValues, + nullValue: null, + zeroValue, }, parameters: { layout: group.parameter_ids, specs: groupParams, }, }; - return structSpec; } // just differs from the makeParameterSequence in that the @@ -770,10 +660,7 @@ define(['common/props'], (Props) => { // and then add the groups in. const parameterLayout = sdkAppSpec.parameters .filter((parameter) => { - if (parameterSpecs[parameter.id]) { - return true; - } - return false; + return !!parameterSpecs[parameter.id]; }) .map((parameter) => { return { @@ -786,10 +673,7 @@ define(['common/props'], (Props) => { // first filter out any groups which were not added to the parameters. // This includes ones with no parameters specified .filter((group) => { - if (parameterSpecs[group.id]) { - return true; - } - return false; + return !!parameterSpecs[group.id]; }) .map((group) => { return { @@ -822,5 +706,6 @@ define(['common/props'], (Props) => { return { convertAppSpec, + convertParameter, }; }); diff --git a/kbase-extension/static/kbase/js/common/semaphore.js b/kbase-extension/static/kbase/js/common/semaphore.js index aad50c009d..d48932dcf5 100644 --- a/kbase-extension/static/kbase/js/common/semaphore.js +++ b/kbase-extension/static/kbase/js/common/semaphore.js @@ -10,10 +10,10 @@ define(['bluebird'], (Promise) => { } /* - The sempahores mechanism has a functional interface. + The semaphores mechanism has a functional interface. */ - function factory(config) { + function factory() { function add(name, initialValue) { window.__kbase_semaphores__[name] = initialValue || null; } @@ -64,16 +64,16 @@ define(['bluebird'], (Promise) => { } return Object.freeze({ - add: add, - set: set, - remove: remove, - when: when, + add, + set, + remove, + when, }); } return { - make: function (config) { - return factory(config); + make: function () { + return factory(); }, }; }); diff --git a/kbase-extension/static/kbase/js/common/simpleLogViewer.js b/kbase-extension/static/kbase/js/common/simpleLogViewer.js index ef284cae6e..681d0eda89 100644 --- a/kbase-extension/static/kbase/js/common/simpleLogViewer.js +++ b/kbase-extension/static/kbase/js/common/simpleLogViewer.js @@ -413,7 +413,7 @@ define([ }; const lastLine = this.model.getItem('lastLine'); if (lastLine) { - requestParams.first_line = lastLine; + requestParams[jcm.PARAM.FIRST_LINE] = lastLine; } this.bus.emit(jcm.MESSAGE_TYPE.LOGS, requestParams); } @@ -704,17 +704,16 @@ define([ const jobState = this.jobManager.getJob(this.jobId) || { job_id: this.jobId }; // initial render - if (jobState && jobState.status) { + if (jobState.status) { this.handleJobStatus({ jobState }); } else { // some kind of 'await job info' message this.ui.setContent(LOG_PANEL, p(this.messages.JOB_STATUS_UNKNOWN)); this._renderButtonState('default'); + this.bus.emit(jcm.MESSAGE_TYPE.STATUS, { + [jcm.PARAM.JOB_ID]: this.jobId, + }); } - - this.bus.emit(jcm.MESSAGE_TYPE.STATUS, { - [jcm.PARAM.JOB_ID]: this.jobId, - }); }).catch((err) => { throw err; }); diff --git a/kbase-extension/static/kbase/js/common/spec.js b/kbase-extension/static/kbase/js/common/spec.js index ef60d0b922..5e41b7e7b6 100644 --- a/kbase-extension/static/kbase/js/common/spec.js +++ b/kbase-extension/static/kbase/js/common/spec.js @@ -6,7 +6,7 @@ define(['bluebird', 'util/util', 'common/sdk', 'widgets/appWidgets2/validators/r Promise, Util, sdk, - validationResolver + ValidationResolver ) => { 'use strict'; @@ -92,7 +92,7 @@ define(['bluebird', 'util/util', 'common/sdk', 'widgets/appWidgets2/validators/r const validationMap = {}; options = options || {}; paramIds.forEach((id) => { - validationMap[id] = validationResolver.validate( + validationMap[id] = ValidationResolver.validate( values[id], spec.parameters.specs[id], options[id] || {} @@ -101,11 +101,51 @@ define(['bluebird', 'util/util', 'common/sdk', 'widgets/appWidgets2/validators/r return Promise.props(validationMap); } + /** + * This validates parameter sets by using a bulk form of validator for each parameter type. + * If options are available for the parameter validation, they're expected to apply to all + * parameters of that type. + * This returns a batch of promises that resolves to a arrays of validations, keyed on + * parameter id, matching the order of arrays in the paramValues structure. + * NOTE: This expects that paramValues is normalized - each array is present and the same + * length - otherwise unexpected behavior may occur. + * @param {Array} paramIds parameter ids to validate. + * @param {Object} paramValues keys = parameter ids, values = list of parameter values + * @param {Object} options keys = parameter ids, values = set of options for that parameter + */ + function validateMultipleParamsArray(paramIds, paramValues, options = {}) { + const validationMap = {}; + for (const paramId of paramIds) { + validationMap[paramId] = validateParamsArray( + paramId, + paramValues[paramId], + options[paramId] + ); + } + return Promise.props(validationMap); + } + + /** + * This validates an array of parameters. It returns a Promise that resolves into an array + * of Validations from the validation resolver. + * @param {string} paramId + * @param {Array} paramValues + */ + function validateParamsArray(paramId, paramValues, options = {}) { + return ValidationResolver.validateArray( + paramValues, + spec.parameters.specs[paramId], + options + ); + } + return Object.freeze({ getSpec, makeDefaultedModel, validateModel, validateParams, + validateParamsArray, + validateMultipleParamsArray, }); } diff --git a/kbase-extension/static/kbase/js/common/ui.js b/kbase-extension/static/kbase/js/common/ui.js index 14d8f03dda..71779c1a7c 100644 --- a/kbase-extension/static/kbase/js/common/ui.js +++ b/kbase-extension/static/kbase/js/common/ui.js @@ -41,6 +41,7 @@ define([ showConfirmDialog, showDialog, showErrorDialog, + showGenericDialog, showInfoDialog, cssClassName, }; @@ -418,6 +419,8 @@ define([ * {function} doThisFirst - a function to perform after creating the promise; * this allows actions to be performed between creating the modal * and before the modal is dismissed by keyboard or mouse action + * {function} onConfirm - a function to perform after clicking the 'OK' button + * and before resolving the promise and closing the modal * * @returns {Promise} that resolves to false if the modal is dismissed using the * cancel button, the close button, by clicking on the modal backdrop, or by pressing @@ -427,7 +430,10 @@ define([ function showGenericDialog(args) { const dialog = _renderModal(args), confirmNode = _generateConfirmNode(dialog), - modalDialogNode = _setUpModalNodes(confirmNode); + modalDialogNode = _setUpModalNodes(confirmNode), + onConfirmFn = args.onConfirm; + + args.modalDialogNode = modalDialogNode; // this shows the modal $(modalDialogNode).modal({ keyboard: false }); @@ -444,20 +450,28 @@ define([ // 13 = enter, 27 = escape // the key is sometimes a string, hence == instead of === if (e.key == 13 || e.key == 27) { - $(modalDialogNode).modal('hide'); if (e.key == 13 && args.type === 'confirm') { resolution = true; } + $(modalDialogNode).modal('hide'); } }); return new Promise((resolve) => { + if (args.type === 'confirm' && onConfirmFn) { + $(modalDialogNode).on('hide.bs.modal', () => { + if (resolution) { + resolution = onConfirmFn(resolution, modalDialogNode); + } + }); + } + $(modalDialogNode).on('hidden.bs.modal', () => { confirmNode.remove(); resolve(resolution); }); if (args.doThisFirst) { - args.doThisFirst(); + args.doThisFirst(modalDialogNode); } }); } @@ -1193,7 +1207,7 @@ define([ fontSize = jsonBlockWidgetConfig.fontSize || 0.8; function render(obj) { - const specText = JSON.stringify(obj, false, indent), + const specText = JSON.stringify(obj, null, indent), fixedText = specText.replace(//g, '>'); return pre( { diff --git a/kbase-extension/static/kbase/js/common/viewModel/sdkImport.js b/kbase-extension/static/kbase/js/common/viewModel/sdkImport.js deleted file mode 100644 index ba2883b681..0000000000 --- a/kbase-extension/static/kbase/js/common/viewModel/sdkImport.js +++ /dev/null @@ -1,727 +0,0 @@ -define(['common/props'], (Props) => { - 'use strict'; - - function coerceToBoolean(value) { - if (!value) { - return false; - } - const intValue = parseInt(value); - if (!isNaN(intValue)) { - if (value > 0) { - return 1; - } - return false; - } - if (typeof value !== 'string') { - return false; - } - switch (value.toLowerCase(value)) { - case 'true': - case 't': - case 'yes': - case 'y': - return true; - case 'false': - case 'f': - case 'no': - case 'n': - return false; - default: - return false; - } - } - - function coerceToIntBoolean(value) { - return coerceToBoolean(value) ? 1 : 0; - } - - function nullValue(converted) { - if (converted.multipleItems) { - return []; - } - const nullValue = (function () { - switch (converted.data.type) { - case 'string': - return ''; - case 'int': - return null; - case 'float': - return null; - case 'workspaceObjectName': - return null; - case 'struct': - return {}; - case '[]struct': - return []; - default: - return null; - } - })(); - return nullValue; - } - - function updateNullValue(converted) { - converted.data.nullValue = nullValue(converted); - } - - /* - * Default values are strings. - */ - function defaultToNative(converted, defaultValue) { - switch (converted.data.type) { - case 'string': - return defaultValue; - case 'int': - return parseInt(defaultValue); - case 'float': - return parseFloat(defaultValue); - case 'workspaceObjectName': - return defaultValue; - case 'boolean': - return coerceToBoolean(defaultValue); - default: - // Assume it is a string... - return defaultValue; - } - } - - function defaultValue(converted, spec) { - const defaultValues = spec.default_values || []; - // No default value and not required? null value - - // special special cases. - switch (spec.field_type) { - case 'checkbox': - /* - * handle the special case of a checkbox with no or empty - * default value. It will promote to the "unchecked value" - * TODO: more cases of bad default value? Or a generic - * default value validator? - */ - if (!defaultValues || defaultValues.length === 0) { - return spec.checkbox_options.unchecked_value; - } - return coerceToIntBoolean(defaultValues[0]); - case 'custom_textsubdata': - if (!defaultValues) { - // ?? - } - break; - } - - // No default in spec, yet required. - if (!defaultValues && converted.required) { - return converted.data.nullValue; - } - - if (defaultValues.length === 0) { - return converted.data.nullValue; - } - // also weird case of a default value of the empty string, which is really - // the same as null... - if (defaultValues[0] === '') { - return converted.data.nullValue; - } - - // Singular item? - if (!spec.allow_multiple) { - return defaultToNative(converted, defaultValues[0]); - } - return defaultValues.map((defaultValue) => { - return defaultToNative(converted, defaultValue); - }); - } - - function updateDefaultValue(converted, spec) { - converted.data.defaultValue = defaultValue(converted, spec); - } - - function grokDataType(spec) { - /* - * Special case here -- - * is actually an int, although Mike says it can be any type... - */ - switch (spec.field_type) { - case 'checkbox': - return 'int'; - case 'textarea': - case 'dropdown': - if (spec.allow_multiple) { - return '[]string'; - } else { - return 'string'; - } - case 'textsubdata': - return 'subdata'; - case 'custom_textsubdata': - //if (spec.allow_multiple) { - // return '[]string'; - //} - return 'string'; - //var custom = customTextSubdata(); - //if (custom) { - // return custom; - //} - case 'custom_button': - switch (spec.id) { - case 'input_check_other_params': - return 'boolean'; - default: - return 'unspecified'; - } - case 'custom_widget': - if (spec.dropdown_options) { - return '[]string'; - } - break; - case 'group': - return 'struct'; - // case 'reads_group_editor': - // return 'reads_group_editor'; - } - - /* - * Otherwise, we rely on text options to provide type information. - */ - if (!spec.text_options) { - // consider it plain, unconstrained text. - //if (spec.allow_multiple) { - // return '[]string'; - //} - return 'string'; - } else { - const validateAs = spec.text_options.validate_as; - if (validateAs) { - // For int and float, "validateAs" overrides the type. - if (validateAs === 'int' || validateAs === 'float') { - //if (spec.allow_multiple) { - // return '[]' + validateAs; - //} - return validateAs; - } - } - - // Some parameter specs have valid_ws_types as an empty set, which - // does not mean what it could, it means that it is not an option. - if (spec.text_options.valid_ws_types && spec.text_options.valid_ws_types.length > 0) { - //if (spec.allow_multiple) { - // return '[]workspaceObjectName'; - //} else { - return 'workspaceObjectName'; - //} - } - } - - // Okay, if it has no specific type assigned (validate_as), and is - // not flagged from the various properties above by grousing through - // the text_options, we assume it is a string. - - switch (spec.field_type) { - case 'text': - //if (spec.allow_multiple) { - // return '[]string'; - //} else { - return 'string'; - //} - } - - return 'unspecified'; - } - - /* - * These need to be really fleshed out... - */ - function updateConstraints(converted, spec) { - const dataType = converted.data.type; - const fieldType = converted.ui.type; - const paramClass = converted.ui.class; - let constraints; - - // NOTE: - // field_type is text or dropdown, but does not always correspond to the - // type of control to build. E.g. selecting a workspace object is actually - // a dropdown even though the field_type is 'text'. - - switch (dataType) { - case 'string': - case 'text': - switch (fieldType) { - case 'text': - constraints = { - min: Props.getDataItem(spec, 'text_options.min_length', null), - max: Props.getDataItem(spec, 'text_options.max_length', null), - validate: Props.getDataItem(spec, 'text_options.validate_as', null), - }; - break; - case 'dropdown': - constraints = { - options: spec.dropdown_options.options, - }; - break; - case 'textarea': - constraints = { - min: Props.getDataItem(spec, 'text_options.min_length', null), - max: Props.getDataItem(spec, 'text_options.max_length', null), - nRows: Props.getDataItem(spec, 'text_options.n_rows', null), - }; - break; - default: - throw new Error('Unknown text param field type'); - } - break; - case 'int': - switch (fieldType) { - case 'text': - constraints = { - min: spec.text_options.min_int, - max: spec.text_options.max_int, - }; - break; - case 'checkbox': - // In theory, the checkbox - constraints = { - min: 0, - max: 0, - }; - break; - } - break; - case 'float': - constraints = { - min: spec.text_options.min_float, - max: spec.text_options.max_float, - }; - break; - case 'workspaceObjectName': - switch (paramClass) { - case 'input': - constraints = { - types: spec.text_options.valid_ws_types, - }; - break; - case 'output': - constraints = { - types: spec.text_options.valid_ws_types, - }; - break; - case 'parameter': - constraints = { - types: spec.text_options.valid_ws_types, - }; - break; - default: - throw new Error('Unknown workspaceObjectName ui class'); - } - break; - case '[]workspaceObjectName': - switch (paramClass) { - case 'input': - constraints = { - types: spec.text_options.valid_ws_types, - }; - break; - case 'parameter': - constraints = { - types: spec.text_options.valid_ws_types, - }; - break; - default: - throw new Error('Unknown []workspaceObjectName ui class'); - } - break; - case '[]string': - switch (fieldType) { - case 'dropdown': - break; - case 'text': - break; - case 'textarea': - break; - default: - throw new Error('Unknown []string field type: ' + fieldType); - } - break; - case 'subdata': - console.log('SUBDTA', spec); - constraints = { - multiple: false, - // The parameter containing the object name we derive data from - referredParameter: spec.textsubdata_options.subdata_selection.parameter_id, - // The "included" parameter to for the workspace call - subdataIncluded: spec.textsubdata_options.subdata_selection.subdata_included, - // These are for navigating the results. - - // This is the property path to the part of the subdata - // we want to deal with. - path: spec.textsubdata_options.subdata_selection.path_to_subdata, - // This is used to pluck a value off of the leaf array - // items, object properties (if object), object values (if 'value'), - // or otherwise just use the property key. This becomes the "id" - // of the subdata item. - selectionId: spec.textsubdata_options.subdata_selection.selection_id, - // Used to generate a description for each item. Becomes the "desc". - displayTemplate: - spec.textsubdata_options.subdata_selection.description_template, - }; - break; - // case 'xxinput_property_x': - // return { - // defaultValue: defaultValue(), - // referredParameter: 'input_sample_property_matrix', - // subdataIncluded: 'metadata/column_metadata', - // path: 'metadata/column_metadata', - // // custom function to collect - // mapper: { - // before: function () { - // return { - // collected: {} - // }; - // }, - // during: function (values, state) { - // values.forEach(function (value) { - // if (value.entity === 'Condition') { - // state.collected[value.property_name] = true; - // } - // }); - // }, - // after: function (state) { - // return Object.keys(state.collected).map(function (key) { - // return { - // id: key, - // desc: key - // }; - // }); - // } - // } - // }; - // case 'sample_property': - // return { - // required: required(), - // defaultValue: defaultValue(), - // referredParameter: 'input_sample_property_matrix', - // subdataIncluded: 'metadata/column_metadata', - // subdataPath: 'metadata.column_metadata', - // // custom function to collect - // map: function (subdata) { - // var collected = {}; - // Object.keys(subdata).forEach(function (key) { - // var id, name, column = subdata[key]; - // column.forEach(function (value) { - // if (value.category === 'DataSeries' && value.property_name === 'SeriesID') { - // id = value.property_value; - // } else if (value.category === 'Property' && value.property_name === 'Name') { - // name = value.property_value; - // } - // if (id && name) { - // collected[id] = name; - // } - // }); - // }); - // return Object.keys(collected).map(function (key) { - // return { - // id: key, - // desc: collected[key] - // }; - // }) - // .sort(function (a, b) { - // if (a.desc < b.desc) { - // return -1; - // } else if (a.desc > b.desc) { - // return 1; - // } - // return 0; - // }); - // } - // }; - case 'struct': - break; - case 'unspecified': - // a bunch of field types are untyped, and there are no - // options for them... - switch (fieldType) { - case 'text': - case 'checkbox': - case 'textarea': - case 'dropdown': - case 'custom_button': - case 'textsubdata': - case 'file': - case 'custom_textsubdata': - case 'custom_widget': - case 'tab': - break; - default: - throw new Error('Unknown unspecified field type'); - } - break; - default: - console.error('Unknown data type', dataType); - throw new Error('Unknown data type'); - } - if (constraints) { - Object.keys(constraints).forEach((key) => { - converted.data.constraints[key] = constraints[key]; - }); - } - } - - // Stepwise conversion - - // now with grouped params - - function convertParameter(spec) { - const dataType = grokDataType(spec); - const multiple = spec.allow_multiple ? true : false; - const required = spec.optional ? false : true; - - const paramSpec = { - ui: { - label: spec.ui_name, - hint: spec.short_hint, - description: spec.description, - class: spec.ui_class, - type: spec.field_type, - control: spec.field_type, - }, - data: { - type: dataType, - constraints: { - required: required, - }, - }, - }; - - updateNullValue(paramSpec, spec); - updateDefaultValue(paramSpec, spec); - updateConstraints(paramSpec, spec); - - if (multiple) { - return { - spec: { - ui: { - label: spec.ui_name, - hint: spec.short_hint, - description: spec.description, - class: spec.ui_class || 'parameter', - border: spec.with_border === 0 ? true : false, - }, - data: { - type: 'list', - constraints: {}, - list: { - spec: paramSpec, - }, - }, - }, - }; - } - - return { - spec: paramSpec, - }; - } - - function convertGroupList(group, params) { - const defaultValue = []; - const nullValue = []; - const structSpec = { - id: group.id, - multipleItems: true, - ui: { - label: group.ui_name, - description: group.description, - hint: group.short_hint, - class: group.ui_class || 'parameter', - control: '', - layout: group.parameter_ids, - }, - data: { - type: '[]struct', - constraints: { - required: function () { - if (group.optional === 1) { - return false; - } - return true; - }, - }, - defaultValue: defaultValue, - nullValue: nullValue, - }, - // may not need this, but it is consistent with struct. - parameters: { - layout: ['item'], - specs: { - item: convertGroupToStruct(group, params), - }, - }, - }; - params[group.id] = structSpec; - - return structSpec; - } - - function convertGroupToStruct(group, params) { - // Collect params into group and remove from original params collection. - const groupParams = {}; - group.parameter_ids.forEach((id) => { - groupParams[id] = params[id]; - delete params[id]; - }); - const defaultValue = {}; - const nullValue = {}; - // Default value is a struct of default values of the - // struct members. Note that this is fundamentally different - // from a list of structs/ groups. - Object.keys(groupParams).forEach((id) => { - // console.log('STRUCT DEF', id, groupParams) - defaultValue[id] = groupParams[id].spec.data.defaultValue; - nullValue[id] = groupParams[id].spec.data.nullValue; - }); - let required; - if (group.optional === 1) { - required = false; - } else { - required = true; - } - const structSpec = { - ui: { - label: group.ui_name, - description: group.description, - hint: group.short_hint, - class: group.ui_class || 'parameter', - control: '', - layout: group.parameter_ids, - }, - data: { - type: 'struct', - constraints: { - required: required, - }, - defaultValue: defaultValue, - nullValue: nullValue, - struct: { - layout: group.parameter_ids, - fields: groupParams, - }, - }, - }; - return structSpec; - } - - function makeListSpec(spec, params) {} - - function convertGroup(group, params) { - const structSpec = convertGroupToStruct(group, params); - if (group.allow_multiple === 1) { - // wrap in a list - console.log('GROUP', group); - const listSpec = { - spec: { - ui: { - label: group.ui_name, - hint: group.short_hint, - description: group.description, - class: group.ui_class || 'parameter', - border: group.with_border === 0 ? true : false, - }, - data: { - type: 'list', - constraints: {}, - list: { - spec: structSpec, - }, - }, - }, - }; - params[group.id] = listSpec; - } else { - // var structSpec = convertGroupToStruct(group, params); - params[group.id] = { - spec: structSpec, - }; - } - } - - function convertAppSpec(sdkAppSpec) { - // Parameters - - /// console.log('SDK APP SPEC', sdkAppSpec); - - let parameterSpecs = {}, - parameterLayout; - - // First convert all parameters - sdkAppSpec.parameters.forEach((parameter) => { - parameterSpecs[parameter.id] = convertParameter(parameter); - }); - - // Then for all groups, create a parameter of type struct, - // and populate it with the specified parameters, removing them from - // the top level of parameters. - - const groups = sdkAppSpec.parameter_groups || []; - groups.forEach((group) => { - convertGroup(group, parameterSpecs); - // don't know how the group is ordered in the spec ... so just append it later. - }); - - // first filter out the paramters which have been moved into groups, - // and then add the groups in. - parameterLayout = sdkAppSpec.parameters - .filter((parameter) => { - if (parameterSpecs[parameter.id]) { - return true; - } - return false; - }) - .map((parameter) => { - return parameter.id; - }) - .concat( - groups.map((group) => { - return group.id; - }) - ); - - return { - spec: { - data: { - type: 'struct', - struct: { - layout: parameterLayout, - fields: parameterSpecs, - }, - }, - }, - }; - - // wrap the rest of the app? - - // return { - // id: 'name', - // - // multipleItems: false, - // - // ui: { - // label: 'Reads Set Name', - // description: 'Name of the reads set', - // hint: 'The name of the set of sequence reads', - // class: 'parameter', - // control: null - // }, - // data: { - // type: 'string', - // constraints: { - // required: true, - // rule: 'WorkspaceObjectName' // ws data_type - // }, - // defaultValue: '' - // } - // }; - } - - return { - convertAppSpec: convertAppSpec, - }; -}); diff --git a/kbase-extension/static/kbase/js/narrativeConfig.js b/kbase-extension/static/kbase/js/narrativeConfig.js index d847135f55..1f89dc8739 100644 --- a/kbase-extension/static/kbase/js/narrativeConfig.js +++ b/kbase-extension/static/kbase/js/narrativeConfig.js @@ -1,16 +1,4 @@ -/** - * Loads the required narrative configuration files. - * This returns a Promise that will eventually hold the results. - * This should mainly be invoked by the starting app, then - * that result should be injected where necessary. - * - * @author Bill Riehl - * @class narrativeConfig - * @module Narrative - * @static - */ define([ - 'narrative_paths', 'jquery', 'bluebird', 'json!kbase/config/config.json', @@ -18,26 +6,23 @@ define([ 'json!kbase/config/cdn-service-config.json', 'json!kbase/config/feature-config.json', 'json!kbase/config/staging_upload.json', - 'require', -], ( - paths, - $, - Promise, - ConfigSet, - IconsSet, - ServiceSet, - FeatureSet, - StagingUpload, - localRequire -) => { +], ($, Promise, ConfigSet, IconsSet, ServiceSet, FeatureSet, StagingUpload) => { 'use strict'; - let config, debug; + /** + * Loads the required narrative configuration files. + * This returns a Promise that will eventually hold the results. + * This should mainly be invoked by the starting app, then + * that result should be injected where necessary. + * + * @author Bill Riehl + * @class narrativeConfig + * @module Narrative + * @static + */ // Get the workspace id from the URL - let workspaceId = null, - objectId = null, - narrativeRef = null; + let workspaceId = null; // m = window.location.href.match(/(ws\.)?(\d+)((\.obj\.(\d+))(\.ver\.(\d+))?)?$/); // 2 = wsid // 5 = objid @@ -69,10 +54,11 @@ define([ // const narrativeIDRegex = /.*\/(?:(?:ws.(\d+).obj.(\d+)(?:.ver.(\d+))?)|(\d*))$/; const pathMatchResults = path.match(narrativeIDRegex); + if (pathMatchResults) { // Note that wsid1 will be populated for the legacy form, and // wsid2 for the modern form. - const [, workspaceId1, _objectId, _objectVersion, workspaceId2] = pathMatchResults; + const [, workspaceId1, , , workspaceId2] = pathMatchResults; workspaceId = parseInt(workspaceId1 || workspaceId2); // Note that "narrativeRef" is not being constructed here. // I think this is a remnant which should be removed from the codebase, but is @@ -84,13 +70,12 @@ define([ // field to discover the object id for the narrative object. // Note also that the back end code ALSO checks this stuff, and will choke if the // objectId is not a valid narrative, even though we don't care here, - } else { // TODO: There doesn't appear to be a way to trigger an error on a bad url? // Not addressing this now. } // Build the config up from the configSet (from config.json) - config = { + const config = { environment: ConfigSet.config, urls: ConfigSet[ConfigSet.config], version: ConfigSet.version, @@ -102,9 +87,9 @@ define([ dev_mode: ConfigSet.dev_mode, tooltip: ConfigSet.tooltip, icons: IconsSet, - workspaceId: workspaceId, - objectId: objectId, - narrativeRef: narrativeRef, + workspaceId, + objectId: null, + narrativeRef: null, loading_gif: ConfigSet.loading_gif, use_local_widgets: ConfigSet.use_local_widgets, features: FeatureSet, @@ -116,7 +101,7 @@ define([ upload: ConfigSet.upload, }; - debug = config.mode === 'debug'; + const debug = config.mode === 'debug'; config.debug = debug; // Add a remote UI-common to the Require.js config @@ -136,12 +121,6 @@ define([ config.services[key] = { url: config.urls[key], name: key }; }); - function assertConfig() { - if (config === undefined) { - throw new Error('Config has not yet been loaded'); - } - } - /** * Updates the RequireJS config with additional locations from * a config given by the ui-common repo. This file is expected to be @@ -153,14 +132,13 @@ define([ * and just run the callback. */ function updateConfig() { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { if (window.kbconfig) { resolve(window.kbconfig); } + // eslint-disable-next-line no-console console.log('Config: checking remote widgets'); - assertConfig(); if (!config.use_local_widgets) { - // var uiCommonPaths = config.urls.ui_common_root + "widget-paths.json"; require(['uiCommonPaths'], (pathConfig) => { for (const name in pathConfig.paths) { pathConfig.paths[name] = @@ -179,17 +157,19 @@ define([ resolve(config); } }) - .then((config) => { + .then((cfg) => { + // eslint-disable-next-line no-console console.log('Config: fetching remote data configuration.'); return Promise.resolve( $.ajax({ dataType: 'json', cache: false, - url: config.urls.data_panel_sources, + url: cfg.urls.data_panel_sources, }) ); }) .then((dataCategories) => { + // eslint-disable-next-line no-console console.log('Config: processing remote data configuration.'); let env = config.environment; // little bit of a hack, but dev should => ci for all things data. @@ -209,16 +189,17 @@ define([ ); // hate embedding this stuff, but it seems the only good way. // the filename is the last step of that url path (after the last /) - const path = config.urls.data_panel_sources.split('/'); + const dataPath = config.urls.data_panel_sources.split('/'); return Promise.resolve( $.ajax({ dataType: 'json', cache: false, - url: 'static/kbase/config/' + path[path.length - 1], + url: 'static/kbase/config/' + dataPath[dataPath.length - 1], }) ) .then((dataCategories) => { + // eslint-disable-next-line no-console console.log('Config: processing local data configuration.'); let env = config.environment; if (env === 'dev') { @@ -241,7 +222,6 @@ define([ * Simple wrapper to return a URL by its key. If not present, just returns undefined. */ function url(key) { - assertConfig(); return config.urls[key]; } @@ -249,7 +229,6 @@ define([ * Simple wrapper to return some value by its key. If not present, just returns undefined. */ function get(key) { - assertConfig(); return config[key]; } @@ -262,11 +241,11 @@ define([ } return { - updateConfig: updateConfig, - config: config, - getConfig: getConfig, - url: url, - get: get, - debug: debug, + updateConfig, + config, + getConfig, + url, + get, + debug, }; }); diff --git a/kbase-extension/static/kbase/js/util/appCellUtil.js b/kbase-extension/static/kbase/js/util/appCellUtil.js index 76d927f9a7..174f9fb378 100644 --- a/kbase-extension/static/kbase/js/util/appCellUtil.js +++ b/kbase-extension/static/kbase/js/util/appCellUtil.js @@ -1,7 +1,8 @@ -define(['narrativeConfig', 'util/stagingFileCache', 'common/runtime'], ( +define(['narrativeConfig', 'util/stagingFileCache', 'common/runtime', 'util/util'], ( Config, StagingFileCache, - Runtime + Runtime, + Util ) => { 'use strict'; @@ -15,12 +16,12 @@ define(['narrativeConfig', 'util/stagingFileCache', 'common/runtime'], ( * @param {Object} paramValues - keys = param ids, values = param values * @param {Object} paramOptions - keys = param ids, values = object containing options for * validating that parameter (parameter specific). Keys can also be missing. - * @param {Array} filePathIds + * @param {Array} filePathIds - array of strings, each is a file path parameter id * @param {Array} filePathValues - array of objects, where keys = param id, values = values, * one for each file path row. - * @param {Array} filePathOptions - array of objects, where keys = param id, values = object - * containing options for validating that input. Keys can also be missing. Each object - * matches to a single row. + * @param {Object} filePathOptions - keys = param id, values = object + * containing options for validating that input. Keys can also be missing. Options are applied + * to file params in each row. * @param {Object} spec - the post-processed Spec object * @returns a promise that resolves into "complete" or "incomplete" strings */ @@ -38,92 +39,104 @@ define(['narrativeConfig', 'util/stagingFileCache', 'common/runtime'], ( * 2 - eval the array of file inputs and outputs. * If both are up to snuff, we're good. */ - // must have at least one file row of file paths to be complete if (filePathValues.length === 0) { return Promise.resolve('incomplete'); } - const filePathValidations = filePathValues.map((filePathRow, index) => { - return spec.validateParams(filePathIds, filePathRow, filePathOptions[index]); - }); + + const filePathValidationParams = filePathValues.reduce( + (paramSet, filePathRow) => { + // this forces array normalization, in case any values are missing + for (const paramId of filePathIds) { + paramSet[paramId].push(filePathRow[paramId]); + } + return paramSet; + }, + // this little snippet converts [p1,p2] to {p1: [], p2: []} + filePathIds.reduce((acc, curr) => ((acc[curr] = []), acc), {}) + ); + + const filePathValidationProms = spec.validateMultipleParamsArray( + filePathIds, + filePathValidationParams, + filePathOptions + ); + return Promise.all([ + filePathValidationProms, spec.validateParams(paramIds, paramValues, paramOptions), - ...filePathValidations, - ]).then((results) => { - const isValid = results.every((result) => { - return Object.values(result).every((param) => param.isValid); + ]) + .then(([filePathValidations, paramValidations]) => { + // filePathValidations - kvp, keys = paramIds, vals = array of validations + // paramValidations = vals = validations + const filePathsValid = Object.values(filePathValidations).every( + (filePathValidations) => { + return filePathValidations.every((validation) => validation.isValid); + } + ); + const paramsValid = Object.values(paramValidations).every((param) => param.isValid); + + return filePathsValid && paramsValid ? 'complete' : 'incomplete'; + }) + .catch((error) => { + console.error(error); }); - return isValid ? 'complete' : 'incomplete'; - }); } /** - * This builds up an Array of file path validation options. The validation call - * takes a semi-arbitrary set of options in the form of an Object. For file types - * (and for text inputs in general), this comes in the form of a Set of invalidValues. - * - * This function constructs an Array that matches the file input Array for a given fileType, - * populated with options for file inputs. + * This constructs a set of options for validating each item in a file path row. + * By default, it assigns the Set of missing files to `invalidValues` for all actual file path + * parameters, and it assigns a series of options to non-file path parameters (i.e. output + * objects) to validate the workspace object name against the Workspace service. These are: + * `shouldNotExist`: true, + * `authToken`: the current auth token + * `workspaceId`: the current workspace id + * `workspaceServiceUrl`: the URl of the workspace service * - * For example, if the filePath parameters in the data model looks like this: - * [ - * { input_file: 'file1', output_obj: 'obj1' }, - * { input_file: 'file2', output_obj: 'obj2' } - * ] + * These can be added to or overridden by adding fileOptions or outputOptions, respectively. * - * where the fileParamIds are ['input_file', 'output_obj'], and the outputParamIds - * Array is just ['output_obj'], and we have a few missing files in a Set, {'file1', 'file3'}, - * this would return: - * [ - * { - * input_file: { - * invalidValues: { 'file1', 'file3' } - * } - * }, - * { - * input_file: { - * invalidValues: { 'file1', 'file3' } - * } - * } - * ] - * - * This still seems a little bit arbitrary, but as long as the file inputs are validated as - * text (and not data objects), this will continue to work. - * @param {Object} model the main bulk import cell data model - * @param {string} fileType which filetype to build options for - * @param {Set} missingFiles the set of files that were present when this bulk import cell - * was created, but are now missing from the server - * @returns {Array[Object]} each object has a key for each file input (not output). Values - * are the validation options for each mapped input + * @param {Array} fpIds array of file parameter ids - those that describe files for import + * @param {Object} paramIds array of parameter ids to set options + * @param {Set} missingFiles Set of missing files + * @param {Object} fileOptions Options that can be used to augment or override the default file + * input validation options + * @param {Object} outputOptions Options that can be used to augment or override the default + * non-file input validation options + * @returns {Object} where keys are parameter ids and values are the sets of options to be + * passed to the validator for that parameter. */ - function getFilePathOptionsForValidation(model, fileType, missingFiles) { - let fpIds = model.getItem(['app', 'fileParamIds', fileType]) || []; - const outIds = model.getItem(['app', 'outputParamIds', fileType]) || []; - // overwrite fpIds with JUST the file inputs (not the outputs) - fpIds = new Set(fpIds.filter((id) => !outIds.includes(id))); - const fpVals = model.getItem(['params', fileType, 'filePaths']) || []; - - // fpVals = Array of input file path rows from the importer for the current fileType + function getFilePathValidationOptions( + fpIds, + paramIds, + missingFiles, + fileOptions = {}, + outputOptions = {} + ) { const runtime = Runtime.make(); - return fpVals.map((filePath) => { - const fpOptions = {}; - for (const id of Object.keys(filePath)) { - fpOptions[id] = {}; - // They're either file paths or output paths. - // File paths get the invalidValues option. - if (fpIds.has(id)) { - fpOptions[id].invalidValues = missingFiles; - } else { - fpOptions[id] = { + const fpOptions = {}; + for (const id of paramIds) { + // They're either file paths or output paths. + if (fpIds.includes(id)) { + // File paths always get the invalidValues option. + fpOptions[id] = Object.assign( + { invalidValues: missingFiles }, + Util.copy(fileOptions) + ); + } else { + // Not-file paths are expected to be workspace object names, and get the default + // things for validating those + fpOptions[id] = Object.assign( + { shouldNotExist: true, authToken: runtime.authToken(), workspaceId: runtime.workspaceId(), workspaceServiceUrl: runtime.config('services.workspace.url'), - }; - } + }, + Util.copy(outputOptions) + ); } - return fpOptions; - }); + } + return fpOptions; } /** @@ -133,21 +146,25 @@ define(['narrativeConfig', 'util/stagingFileCache', 'common/runtime'], ( * @param {Object} specs keys = app id, values = app specs * @param {Set} missingFiles Set of files that the app cell expects to be present, * but are missing from the staging area - * @returns + * @returns {Object} keys = file type ids, values = "complete" if ready, "incomplete" if not */ function evaluateConfigReadyState(model, specs, missingFiles) { - // given some missing files (precalcuate for now), set up options for evaluating all file inputs + // given some missing files (precalculate for now), set up options for evaluating all file inputs const fileTypes = Object.keys(model.getItem(['inputs'])); + const evalPromises = fileTypes.map((fileType) => { + const fileParamIds = model.getItem(['app', 'fileParamIds', fileType]); + const filePathIds = getFilePathIds(model, fileType); + const fpOptions = getFilePathValidationOptions(filePathIds, fileParamIds, missingFiles); // make an array of empty options with the same length as the // number of file path values return evaluateAppConfig( model.getItem(['app', 'otherParamIds', fileType]), model.getItem(['params', fileType, 'params']), {}, // no particular options for non-file parameters right now - model.getItem(['app', 'fileParamIds', fileType]), + fileParamIds, model.getItem(['params', fileType, 'filePaths']), - getFilePathOptionsForValidation(model, fileType, missingFiles), + fpOptions, specs[model.getItem(['inputs', fileType, 'appId'])] ); }); @@ -207,10 +224,28 @@ define(['narrativeConfig', 'util/stagingFileCache', 'common/runtime'], ( return { fileTypesDisplay, fileTypeMapping }; } + /** + * This is a convenience function used to filter the file path parameter ids in a bulk import + * cell to just those parameters that describe actual file paths for import. I.e., given a + * model and file type, it will return those parameters that represent files in the Staging + * Area. + * @param {Object} model a Props object used with a Bulk Import cell + * @param {String} fileType a file type id + * @returns {Array} file-input parameter ids + */ + function getFilePathIds(model, fileType) { + const fileParamIds = model.getItem(['app', 'fileParamIds', fileType]); + const outIds = model.getItem(['app', 'outputParamIds', fileType]) || []; + // overwrite fpIds with JUST the file inputs (not the outputs) + return fileParamIds.filter((id) => !outIds.includes(id)); + } + return { evaluateAppConfig, evaluateConfigReadyState, getMissingFiles, generateFileTypeMappings, + getFilePathValidationOptions, + getFilePathIds, }; }); diff --git a/kbase-extension/static/kbase/js/util/icon.js b/kbase-extension/static/kbase/js/util/icon.js index ed8869cfb0..790d5ffffd 100644 --- a/kbase-extension/static/kbase/js/util/icon.js +++ b/kbase-extension/static/kbase/js/util/icon.js @@ -64,18 +64,20 @@ define(['underscore', 'common/html', 'common/props', 'common/runtime', 'narrativ let parsed_color, r, g, b; // XXX: Assume color is in form '#RRGGBB' - if (color[0] == '#') { - parsed_color = color.match(/#(..)(..)(..)/); - r = parseInt(parsed_color[1], 16); - g = parseInt(parsed_color[2], 16); - b = parseInt(parsed_color[3], 16); - } - // XXX: Assume color is in form "rgb(#,#,#)" - else { - parsed_color = color.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/); - r = parsed_color[1]; - g = parsed_color[2]; - b = parsed_color[3]; + if (color) { + if (color[0] == '#') { + parsed_color = color.match(/#(..)(..)(..)/); + r = parseInt(parsed_color[1], 16); + g = parseInt(parsed_color[2], 16); + b = parseInt(parsed_color[3], 16); + } + // XXX: Assume color is in form "rgb(#,#,#)" + else { + parsed_color = color.match(/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/); + r = parsed_color[1]; + g = parsed_color[2]; + b = parsed_color[3]; + } } // Add circles with lighter colors for (let i = num_stacked_circles; i > 0; i--) { diff --git a/kbase-extension/static/kbase/js/util/jobLogViewer.js b/kbase-extension/static/kbase/js/util/jobLogViewer.js index 1fcbfdf641..3848034695 100644 --- a/kbase-extension/static/kbase/js/util/jobLogViewer.js +++ b/kbase-extension/static/kbase/js/util/jobLogViewer.js @@ -475,7 +475,7 @@ define([ this.state.awaitingLog = true; this.bus.emit(jcm.MESSAGE_TYPE.LOGS, { [jcm.PARAM.JOB_ID]: this.jobId, - first_line: firstLine, + [jcm.PARAM.FIRST_LINE]: firstLine, }); } diff --git a/kbase-extension/static/kbase/js/util/jobStateViewer.js b/kbase-extension/static/kbase/js/util/jobStateViewer.js deleted file mode 100644 index e493317075..0000000000 --- a/kbase-extension/static/kbase/js/util/jobStateViewer.js +++ /dev/null @@ -1,462 +0,0 @@ -/** - * This widget shows a simple job state viewer for the app cell. - * The viewer updates based on changes to the job state and view model. - * It reports the current job state, runtime, and how long it has been / was queued for. - */ -define([ - 'bluebird', - 'common/runtime', - 'common/ui', - 'common/format', - 'common/html', - 'common/jobs', - 'common/jobCommMessages', -], (Promise, Runtime, UI, format, html, Jobs, jcm) => { - 'use strict'; - - const t = html.tag, - div = t('div'), - p = t('p'), - span = t('span'); - - /** - * Updates the view stats. - * If there's no jobState, this just posts a message saying we're waiting for info, and stops. - * Otherwise, if the jobState has an updated time (which all EE2 job states should), we do - * the calculations and re-render here. - * - * In essence, this does all the calculation of what fields to render and passes it on to - * ui.renderFromViewModel - * @param {object} ui - the current UI object - * @param {object} viewModel - the app cell's view model - * @param {object} jobState - the app cell's current job state - */ - function updateRunStats(ui, viewModel, jobState) { - if (!jobState) { - viewModel.launch._attrib.hidden = false; - viewModel.launch.label = 'Awaiting job data...'; - } else { - const now = new Date().getTime(); - - viewModel.launch._attrib.hidden = true; - - if (jobState.updated) { - const creationTime = jobState.created; - // Queue status - at least in or has been in the queue - viewModel.queue._attrib.hidden = false; - if (jobState.running) { - // Queue Status - show it, and it has finished, so show static elapsed time and - // don't show position in queue. - viewModel.queue._attrib.style = { fontWeight: 'normal' }; - viewModel.queue.active = false; - viewModel.queue.label = 'Queued for'; - const execStartTime = jobState.running; - viewModel.queue.elapsed = format.niceDuration(execStartTime - creationTime); - viewModel.queue.position.label = ''; - viewModel.queue.position.number = ''; - - // Run Status -- by definition it is running or ran, so show it. - viewModel.run._attrib.hidden = false; - - if (jobState.finished) { - viewModel.run._attrib.style = { fontWeight: 'normal' }; - viewModel.run.active = false; - viewModel.run.label = 'Ran for'; - const finishTime = jobState.finished; - viewModel.run.elapsed = format.niceDuration(finishTime - execStartTime); - - viewModel.finish._attrib.hidden = false; - viewModel.finish._attrib.style = { fontWeight: 'bold' }; - viewModel.finish.active = true; - viewModel.finish.state = Jobs.niceState(jobState.status); - viewModel.finish.time = format.niceTime(finishTime); - viewModel.finish.elapsed = format.niceDuration(now - finishTime); - } else { - viewModel.run._attrib.style = { fontWeight: 'bold' }; - viewModel.run.active = true; - viewModel.run.label = - 'Running ' + ui.loading({ size: null, color: 'green' }); - viewModel.run.elapsed = format.niceDuration(now - execStartTime); - - viewModel.finish._attrib.hidden = true; - } - } else { - // Run Status - ensure not showing. - viewModel.run._attrib.hidden = true; - viewModel.run.active = false; - - if (jobState.finished) { - // This can only happen when a job has been cancelled or errored out during queueing. - - // Queue Status - it is out of the queue - viewModel.queue._attrib.style = { fontWeight: 'normal' }; - viewModel.queue.active = false; - viewModel.queue.label = 'Queued for'; - const finishTime = jobState.finished; - viewModel.queue.elapsed = format.niceDuration(finishTime - creationTime); - viewModel.queue.position.label = ''; - viewModel.queue.position.number = ''; - - // Finished Status - viewModel.finish._attrib.hidden = false; - viewModel.finish._attrib.style = { fontWeight: 'bold' }; - viewModel.finish.active = true; - viewModel.finish.state = Jobs.niceState(jobState.status); - viewModel.finish.time = format.niceTime(finishTime); - viewModel.finish.elapsed = format.niceDuration(now - finishTime); - } else { - // Queue Status - in the queue - viewModel.queue._attrib.style = { fontWeight: 'bold' }; - viewModel.queue.active = true; - viewModel.queue.label = - 'Queued ' + ui.loading({ size: null, color: 'orange' }); - if (jobState.position) { - viewModel.queue.position.label = ', currently at position '; - viewModel.queue.position.number = jobState.position; - } else { - viewModel.queue.position.label = ''; - viewModel.queue.position.number = ''; - } - viewModel.queue.elapsed = format.niceDuration(now - creationTime); - - // Finished status -- ensure not showing - viewModel.finish._attrib.hidden = true; - viewModel.finish.active = false; - } - } - } else { - viewModel.job_not_found._attrib.hidden = false; - } - } - - try { - ui.updateFromViewModel(viewModel); - } catch (err) { - console.error('ERROR updating from view model', err); - } - } - - /** - * Does the initial rendering set up for the run stats area. Creates rows - * for each of the various run state possibilities. - */ - function renderRunStats() { - return div({ dataElement: 'run-stats', style: { paddingTop: '6px' } }, [ - div( - { - class: 'row', - dataElement: 'launch', - }, - [ - span({ - dataElement: 'label', - }), - ' ', - span({ - dataElement: 'elapsed', - class: 'kb-elapsed-time', - }), - ] - ), - div( - { - class: 'row', - dataElement: 'job_not_found', - }, - [ - span({ - dataElement: 'message', - }), - ] - ), - div( - { - class: 'row', - dataElement: 'queue', - }, - [ - span( - { - dataElement: 'label', - }, - 'Queue' - ), - ' ', - span({ - dataElement: 'elapsed', - class: 'kb-elapsed-time', - }), - span( - { - dataElement: 'position', - }, - [ - span({ - dataElement: 'label', - }), - span({ - dataElement: 'number', - }), - ] - ), - ] - ), - div( - { - class: 'row', - dataElement: 'run', - }, - [ - span( - { - dataElement: 'label', - }, - 'Run' - ), - ' ', - span({ - dataElement: 'elapsed', - class: 'kb-elapsed-time', - }), - ] - ), - div( - { - class: 'row', - dataElement: 'finish', - }, - [ - span('Finished with '), - span({ - dataElement: 'state', - }), - ' on ', - span({ - dataElement: 'time', - }), - ' (', - span({ - dataElement: 'elapsed', - }), - ' ago)', - ] - ), - ]); - } - - /** - * Initializes this state viewer widget. - * Inits the internal viewModel as well. - */ - function factory() { - const runtime = Runtime.make(), - listeners = []; - let container, - ui, - jobState = null, - listeningForJob = false, - jobId; - - const viewModel = { - lastUpdated: { - elapsed: null, - time: null, - }, - launch: { - _attrib: { - hidden: true, - style: {}, - }, - label: null, - elapsed: null, - }, - queue: { - _attrib: { - hidden: true, - style: {}, - }, - active: null, - label: null, - elapsed: null, - position: { - label: null, - number: null, - }, - }, - run: { - _attrib: { - hidden: true, - style: {}, - }, - active: null, - label: null, - elapsed: null, - }, - finish: { - _attrib: { - hidden: true, - style: {}, - }, - active: null, - state: null, - time: null, - elapsed: null, - }, - job_not_found: { - _attrib: { - hidden: true, - style: {}, - }, - message: div([ - p([ - 'This job was not found, or may not have been registered with this Narrative.', - ]), - p(['You will not be able to inspect the job status or view the job log']), - ]), - }, - }; - - /** - * Starts listening for job updates and requests the most recent job state for this app cell. - */ - function startJobUpdates() { - if (listeningForJob) { - return; - } - runtime.bus().emit(jcm.MESSAGE_TYPE.START_UPDATE, { - [jcm.PARAM.JOB_ID]: jobId, - }); - listeningForJob = true; - } - - /** - * Stops listening for job updates - */ - function stopJobUpdates() { - listeningForJob = false; - } - - /** - * Called when the job-status message is received. - * This parses the job status message. Takes into account both NJS and EE2 style messages. - * @param {object} message - */ - function handleJobStatusUpdate(message) { - if (!(jobId in message)) { - return; - } - - jobState = message[jobId].jobState; - switch (jobState.status) { - case 'queued': - case 'created': - case 'estimating': - case 'running': - startJobUpdates(); - break; - case 'completed': - case 'error': - case 'terminated': - case 'does_not_exist': - stopJobUpdates(); - break; - default: - stopJobUpdates(); - console.error('Unknown job status', jobState.status, message[jobId]); - throw new Error('Unknown job status ' + jobState.status); - } - } - - /** - * Sets up handlers and listeners for job status updates. - * Listens on the jobId channel for these messages: - * - job-status -> respond to job update - */ - function listenForJobStatus() { - listeners.push( - // listen for job-related bus messages - runtime.bus().listen({ - channel: { - [jcm.CHANNEL.JOB]: jobId, - }, - key: { - type: jcm.MESSAGE_TYPE.STATUS, - }, - handle: handleJobStatusUpdate, - }) - ); - } - - /** - * Removes job status update listeners. - */ - function stopListeningForJobStatus() { - runtime.bus().removeListeners(listeners); - } - - function start(arg) { - return Promise.try(() => { - if (container) { - return detach(); - } - }).then(() => { - return Promise.try(() => { - container = arg.node; - ui = UI.make({ node: container }); - - container.innerHTML = renderRunStats(); - jobId = arg.jobId; - - listeners.push( - runtime.bus().on('clock-tick', () => { - updateRunStats(ui, viewModel, jobState); - }) - ); - - listenForJobStatus(); - - // request a new job status update from the kernel on start - runtime.bus().emit(jcm.MESSAGE_TYPE.STATUS, { - [jcm.PARAM.JOB_ID]: jobId, - }); - listeningForJob = true; - - ui.updateFromViewModel(viewModel); - }); - }); - } - - /** - * Lifecycle method. - * On widget stop, this removes all listeners for job status to clean itself up. - */ - function stop() { - return Promise.try(() => { - stopListeningForJobStatus(); - }); - } - - /** - * Lifecycle method. - * When told to detach, this widget cleans itself up with a call to stop(), - * then removes itself from the DOM. - */ - function detach() { - return stop().then(() => { - container.innerHTML = ''; - }); - } - - return { - start, - stop, - detach, - }; - } - - return { - make: () => { - return factory(); - }, - }; -}); diff --git a/kbase-extension/static/kbase/js/widgetApi/narrativeDataWidget.js b/kbase-extension/static/kbase/js/widgetApi/narrativeDataWidget.js index 091e709377..20264d052e 100644 --- a/kbase-extension/static/kbase/js/widgetApi/narrativeDataWidget.js +++ b/kbase-extension/static/kbase/js/widgetApi/narrativeDataWidget.js @@ -56,7 +56,7 @@ define(['bluebird', 'runtimeManager', 'narrativeConfig'], ( // 'yaml!./config.yml', 'kb_common/props', 'kb_common/session', - 'kb_common/html', + 'common/html', ], (WidgetManager, Props, Session, Html) => { // just a little synchronous auth token business for now diff --git a/kbase-extension/static/kbase/js/widgetApi/runtimeManager.js b/kbase-extension/static/kbase/js/widgetApi/runtimeManager.js index 5cc9098ee3..db7d80859a 100644 --- a/kbase-extension/static/kbase/js/widgetApi/runtimeManager.js +++ b/kbase-extension/static/kbase/js/widgetApi/runtimeManager.js @@ -82,7 +82,6 @@ define([], () => { text: 'requirejs-text/2.0.14/text', yaml: 'require-yaml/0.1.2/yaml', - // kbase // kbase kb_service: 'kbase-service-clients-js/1.4.0', kb_common: 'kbase-common-js/1.5.4', @@ -135,8 +134,8 @@ define([], () => { } return { - getRuntime: getRuntime, - getModuleLoader: getModuleLoader, + getRuntime, + getModuleLoader, }; } diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/common.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/common.js index faed606368..ffb7129655 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/common.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/common.js @@ -4,7 +4,7 @@ define([], () => { /* * A clipboard button for copying data from select boxes. */ - function clipboardButton(div, button, events, ui, node) { + function clipboardButton(div, button, events, ui, node, copyFn) { return div( { class: 'input-group-addon kb-app-row-clip-btn-addon', @@ -16,7 +16,9 @@ define([], () => { id: events.addEvent({ type: 'click', handler: async function () { - const text = node.querySelectorAll('[role=textbox]')[0].innerText; + const text = copyFn + ? copyFn() + : node.querySelectorAll('[role=textbox]')[0].innerText; await navigator.clipboard.writeText(text); }, }), @@ -28,8 +30,8 @@ define([], () => { ); } - function containerContent(div, button, events, ui, container, input) { - const clipboard = clipboardButton(div, button, events, ui, container); + function containerContent(div, button, events, ui, container, input, copyFn) { + const clipboard = clipboardButton(div, button, events, ui, container, copyFn); const content = div( { dataElement: 'input-row', diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiIntDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiIntDisplay.js index 12095bdae2..4019ab799b 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiIntDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiIntDisplay.js @@ -1,4 +1,4 @@ -define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { +define(['bluebird', 'common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { 'use strict'; // Constants @@ -7,11 +7,16 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht span = t('span'); function factory(config) { - let options = {}, + let container; + + const options = {}, spec = config.parameterSpec, - container, bus = config.bus, - model; + model = Props.make({ + onUpdate: function () { + render(); + }, + }); // Validate configuration. // Nothing to do... @@ -19,8 +24,8 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht options.required = spec.required(); function render() { - let values = model.getItem('values'), - displayValue; + const values = model.getItem('values'); + let displayValue; if (values === null) { displayValue = span({ style: { fontStyle: 'italic', color: 'orange' } }, 'NA'); } else { @@ -56,12 +61,6 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { start: start, }; diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiObjectDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiObjectDisplay.js index 267d2f49d3..696e103e31 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiObjectDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiObjectDisplay.js @@ -1,6 +1,6 @@ define([ 'bluebird', - 'kb_common/html', + 'common/html', 'kb_service/client/workspace', 'kb_service/utils', 'common/runtime', @@ -14,14 +14,16 @@ define([ div = t('div'); function factory(config) { - let options = {}, - spec = config.parameterSpec, - workspaceInfo = config.workspaceInfo, - workspaceId = config.workspaceId, + let container; + + const workspaceId = config.workspaceId, runtime = Runtime.make(), - container, bus = config.bus, - model; + model = Props.make({ + onUpdate: function () { + render(); + }, + }); // DATA @@ -87,7 +89,7 @@ define([ .join('\n'); }) .catch((err) => { - console.log(err); + console.warn(err); container.innerHTML = 'ERROR '; }); } @@ -98,20 +100,14 @@ define([ return Promise.try(() => { bus.on('run', (message) => { container = message.node; - bus.on('update', (message) => { - model.setItem('value', message.value); + bus.on('update', (msg) => { + model.setItem('value', msg.value); }); bus.emit('sync'); }); }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { start: start, }; diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiTextDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiTextDisplay.js index 0729b3e79f..561420b2d9 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiTextDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/multiTextDisplay.js @@ -1,4 +1,4 @@ -define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { +define(['bluebird', 'common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { 'use strict'; // Constants @@ -7,11 +7,16 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht span = t('span'); function factory(config) { - let options = {}, + const options = {}, spec = config.parameterSpec, - container, bus = config.bus, - model; + model = Props.make({ + onUpdate: function () { + render(); + }, + }); + + let container; // Validate configuration. // Nothing to do... @@ -22,9 +27,9 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht options.enabled = true; function render() { - let value = model.getItem('value'), - displayValue; - console.log('MULTI TEXT', value); + const value = model.getItem('value'); + let displayValue; + // console.log('MULTI TEXT', value); if (value === null || value.length === 0) { displayValue = span({ style: { fontStyle: 'italic', color: 'orange' } }, 'NA'); } else { @@ -52,20 +57,12 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht }); } - function run(params) { + function run() { return Promise.try(() => { - // model.value = params.value; - // var result = render(); - // container.innerHTML = result.content; + // }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { init: init, attach: attach, diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleCheckboxDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleCheckboxDisplay.js index bc3db17af2..58acd6327a 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleCheckboxDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleCheckboxDisplay.js @@ -1,4 +1,4 @@ -define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { +define(['bluebird', 'common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { 'use strict'; // Constants @@ -6,12 +6,16 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht div = t('div'); function factory(config) { - let options = {}, + const options = {}, spec = config.parameterSpec, - container, bus = config.bus, - model; + model = Props.make({ + onUpdate: function () { + render(); + }, + }); + let container; // Validate configuration. // Nothing to do... @@ -43,20 +47,12 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht }); } - function run(params) { + function run() { return Promise.try(() => { - // model.value = params.value; - // var result = render(); - // container.innerHTML = result.content; + // }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { init: init, attach: attach, diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleIntDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleIntDisplay.js index e6c52ff695..baf80dbabf 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleIntDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleIntDisplay.js @@ -1,4 +1,4 @@ -define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { +define(['bluebird', 'common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { 'use strict'; // Constants @@ -7,11 +7,15 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht span = t('span'); function factory(config) { - let options = {}, + const options = {}, spec = config.parameterSpec, - container, bus = config.bus, - model; + model = Props.make({ + onUpdate: function () { + render(); + }, + }); + let container; // Validate configuration. // Nothing to do... @@ -22,8 +26,8 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht options.enabled = true; function render() { - let value = model.getItem('value'), - displayValue; + const value = model.getItem('value'); + let displayValue; if (value === null) { displayValue = span({ style: { fontStyle: 'italic', color: 'orange' } }, 'NA'); } else { @@ -54,20 +58,12 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht }); } - function run(params) { + function run() { return Promise.try(() => { - // model.value = params.value; - // var result = render(); - // container.innerHTML = result.content; + // }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { init: init, attach: attach, diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleObjectDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleObjectDisplay.js index a4d2646821..e585635981 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleObjectDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleObjectDisplay.js @@ -1,6 +1,6 @@ define([ 'bluebird', - 'kb_common/html', + 'common/html', 'kb_service/client/workspace', 'kb_service/utils', 'common/runtime', @@ -14,16 +14,17 @@ define([ div = t('div'); function factory(config) { - let options = {}, - spec = config.parameterSpec, - workspaceInfo = config.workspaceInfo, - workspaceId = config.workspaceId, + const workspaceId = config.workspaceId, objectRefType = config.referenceType || 'name', runtime = Runtime.make(), - container, bus = config.bus, - model; + model = Props.make({ + onUpdate: function () { + render(); + }, + }); + let container; // DATA function getObjectRef() { @@ -33,18 +34,16 @@ define([ wsid: workspaceId, name: model.getItem('value'), }; - break; case 'ref': return { ref: model.getItem('value'), }; - break; default: throw new Error('Unsupported object reference type ' + objectRefType); } } - function getObject(value) { + function getObject() { const workspace = new Workspace(runtime.config('services.workspace.url'), { token: runtime.authToken(), }); @@ -112,20 +111,14 @@ define([ return Promise.try(() => { bus.on('run', (message) => { container = message.node; - bus.on('update', (message) => { - model.setItem('value', message.value); + bus.on('update', (msg) => { + model.setItem('value', msg.value); }); bus.emit('sync'); }); }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { start: start, }; diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleSelectDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleSelectDisplay.js index bc3db17af2..0c43d89465 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleSelectDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleSelectDisplay.js @@ -1,4 +1,4 @@ -define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { +define(['bluebird', 'common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { 'use strict'; // Constants @@ -6,11 +6,15 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht div = t('div'); function factory(config) { - let options = {}, + const options = {}, spec = config.parameterSpec, - container, bus = config.bus, - model; + model = Props.make({ + onUpdate: function () { + render(); + }, + }); + let container; // Validate configuration. // Nothing to do... @@ -43,20 +47,12 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht }); } - function run(params) { + function run() { return Promise.try(() => { - // model.value = params.value; - // var result = render(); - // container.innerHTML = result.content; + // }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { init: init, attach: attach, diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleTextDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleTextDisplay.js index 6e61274d3f..bda37120c1 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleTextDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/singleTextDisplay.js @@ -1,4 +1,4 @@ -define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { +define(['bluebird', 'common/html', 'common/props', 'bootstrap'], (Promise, html, Props) => { 'use strict'; // Constants @@ -7,12 +7,15 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht span = t('span'); function factory(config) { - let options = {}, + const options = {}, spec = config.parameterSpec, - container, bus = config.bus, - model; - + model = Props.make({ + onUpdate: function () { + render(); + }, + }); + let container; // Validate configuration. // Nothing to do... @@ -22,8 +25,8 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht options.enabled = true; function render() { - let value = model.getItem('value'), - displayValue; + const value = model.getItem('value'); + let displayValue; if (value === null || value.length === 0) { displayValue = span({ style: { fontStyle: 'italic', color: 'orange' } }, 'NA'); } else { @@ -51,20 +54,12 @@ define(['bluebird', 'kb_common/html', 'common/props', 'bootstrap'], (Promise, ht }); } - function run(params) { + function run() { return Promise.try(() => { - // model.value = params.value; - // var result = render(); - // container.innerHTML = result.content; + // }); } - model = Props.make({ - onUpdate: function (props) { - render(); - }, - }); - return { init: init, attach: attach, diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/undefinedDisplay.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/undefinedDisplay.js index a177c534ac..a005b29529 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/display/undefinedDisplay.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/display/undefinedDisplay.js @@ -1,4 +1,4 @@ -define(['bluebird', 'kb_common/html', 'bootstrap'], (Promise, html) => { +define(['bluebird', 'common/html', 'bootstrap'], (Promise, html) => { 'use strict'; // Constants @@ -6,14 +6,13 @@ define(['bluebird', 'kb_common/html', 'bootstrap'], (Promise, html) => { div = t('div'); function factory(config) { - let options = {}, + const options = {}, spec = config.parameterSpec, - container, - bus = config.bus, model = { value: undefined, }; + let container; // Validate configuration. // Nothing to do... @@ -34,18 +33,13 @@ define(['bluebird', 'kb_common/html', 'bootstrap'], (Promise, html) => { function attach(node) { return Promise.try(() => { - parent = node; container = node.appendChild(document.createElement('div')); }); } function start() { return Promise.try(() => { - // bus.on('update', function (message) { - // model.value = message.value; - // }); - // bus.emit('sync'); - // return null; + // }); } diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/errorControl.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/errorControl.js index ed5fcce771..9e14ff77bc 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/errorControl.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/errorControl.js @@ -1,13 +1,13 @@ /* This is a special widget, because it is a factory factory! */ -define(['kb_common/html', 'bootstrap'], (html) => { +define(['common/html', 'bootstrap'], (html) => { 'use strict'; const t = html.tag, div = t('div'), span = t('span'); function factoryFactory(factoryConfig) { - function factory(config) { + function factory() { function attach(node) { node.innerHTML = div( { @@ -23,8 +23,8 @@ define(['kb_common/html', 'bootstrap'], (html) => { }; } return { - make: function (config) { - return factory(config); + make: function () { + return factory(); }, }; } diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidget.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidget.js index 91c41aa784..7e463f8c54 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidget.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidget.js @@ -11,7 +11,7 @@ define([ 'bluebird', 'jquery', 'google-code-prettify/prettify', - 'kb_common/html', + 'common/html', 'common/events', 'common/ui', 'common/props', @@ -29,7 +29,6 @@ define([ th = t('th'), td = t('td'), pre = t('pre'), - textarea = t('textarea'), classSets = { standard: { nameColClass: 'col-md-2', @@ -44,12 +43,10 @@ define([ }; function factory(config) { - let ui, - bus = config.bus, - places, - container, + let ui, places, container, inputControl; + + const bus = config.bus, inputControlFactory = config.inputControlFactory, - inputControl, options = {}, fieldId = html.genId(), spec = config.parameterSpec; @@ -58,6 +55,7 @@ define([ inputControl = inputControlFactory.make({ bus: config.bus, initialValue: config.initialValue, + initialDisplayValue: config.initialDisplayValue, appSpec: config.appSpec, parameterSpec: config.parameterSpec, workspaceInfo: config.workspaceInfo, @@ -71,7 +69,6 @@ define([ }).make(); } - // options.isOutputName = spec.text_options && spec.text_options.is_output_name; options.enabled = true; options.classes = classSets.standard; @@ -145,25 +142,15 @@ define([ places.$messagePanel.addClass('hidden'); } - function hideError() { - places.$field.removeClass('-error'); - places.$messagePanel.addClass('hidden'); - places.$feedbackIndicator.removeClass(); - } - function feedbackNone() { places.$feedbackIndicator.removeClass().hide(); } function feedbackOk() { - places.$feedbackIndicator - .removeClass() - // .addClass('kb-app-parameter-accepted-glyph fa fa-check') - .prop('title', 'input is ok') - .show(); + places.$feedbackIndicator.removeClass().prop('title', 'input is ok').show(); } - function feedbackRequired(row) { + function feedbackRequired() { places.$feedbackIndicator .removeClass() .addClass('kb-app-parameter-required-glyph fa fa-arrow-left') @@ -171,20 +158,20 @@ define([ .show(); } - function feedbackError(row) { + function feedbackError() { places.$feedbackIndicator .removeClass() .addClass('kb-app-parameter-required-glyph fa fa-ban') .show(); } - function rawSpec(spec) { - const specText = JSON.stringify(spec.spec, false, 3), + function rawSpec() { + const specText = JSON.stringify(spec.spec, null, 3), fixedSpec = specText.replace(//g, '>'); return pre({ class: 'prettyprint lang-json', style: { fontSize: '80%' } }, fixedSpec); } - function parameterInfoContent(spec) { + function parameterInfoContent() { return div({ style: { padding: '4px' } }, [ div({ style: { fontWeight: 'bold' } }, spec.label()), div({ style: { fontStyle: 'italic' } }, spec.name()), @@ -192,7 +179,7 @@ define([ ]); } - function parameterInfoTypeRules(spec) { + function parameterInfoTypeRules() { switch (spec.dataType()) { case 'float': return [ @@ -232,7 +219,7 @@ define([ } } - function parameterInfoRules(spec) { + function parameterInfoRules() { return table( { class: 'table table-striped' }, [ @@ -265,17 +252,10 @@ define([ ]); } })(), - ].concat(parameterInfoTypeRules(spec)) + ].concat(parameterInfoTypeRules()) ); } - function parameterInfoLittleTip(spec) { - return spec.dataType(); - //var mult = (spec.multipleItems() ? '[]' : ''), - // type = spec.dataType(); - //return mult + type; - } - function renderInfoTip() { let infoTipText; if (spec.description() && spec.hint() !== spec.description()) { @@ -285,7 +265,6 @@ define([ } return div([ - // div({dataElement: 'little-tip'}, parameterInfoLittleTip(spec)), div( { dataElement: 'big-tip', class: 'hidden' }, html.makeTabs({ @@ -299,55 +278,27 @@ define([ { label: 'About', name: 'about', - content: parameterInfoContent(spec), + content: parameterInfoContent(), }, { label: 'Rules', name: 'rules', - content: parameterInfoRules(spec), + content: parameterInfoRules(), }, { label: 'Spec', name: 'spec', - content: rawSpec(spec), + content: rawSpec(), }, ], }) ), ]); } - // function renderLabelTip() { - // return div([ - // div({dataElement: 'little-tip', style: {display: 'none'}}, parameterInfoLittleTip(spec)) - // ]); - // } - - function render(events) { - let placeholder = '', - fieldContainer, - feedbackTip, - nameCol, - inputCol, - hintCol; - - // PLACHOLDER (todo: put it somewhere!) - if (spec.text_options && spec.text_options.placeholder) { - placeholder = spec.text_options.placeholder.replace(/(\r\n|\n|\r)/gm, ''); - } - - // FEEDBACK - if (spec.required()) { - feedbackTip = span({ - class: 'kb-app-parameter-required-glyph fa fa-arrow-left', - title: 'required field', - dataElement: 'feedback', - }); - } + function render() { const infoId = html.genId(); - console.log('HERE, really?'); - let advanced; if (spec.spec.advanced) { advanced = 'advanced-parameter-hidden'; @@ -355,7 +306,7 @@ define([ advanced = ''; } - const content = div( + return div( { class: [ 'form-horizontal', @@ -390,22 +341,7 @@ define([ style: { width: '30px', padding: '0' }, }, [div({ dataElement: 'indicator' })] - ) /* - div({ class: 'input-group-addon kb-input-group-addon', style: { width: '30px', padding: '0' } }, [ - div({ dataElement: 'info' }, button({ - class: 'btn btn-link btn-xs', - type: 'button', - id: events.addEvent({ - type: 'click', - handler: function() { - var bigTip = container.querySelector('[data-element="big-tip"]'); - bigTip.classList.toggle('hidden'); - } - }) - }, - span({ class: 'fa fa-info-circle' }) - )) - ])*/, + ), ]), ] ), @@ -424,18 +360,15 @@ define([ ]), ] ); - - return content; } // LIFECYCLE function attach(node) { return Promise.try(() => { - let events = Events.make(), - $container; + const events = Events.make(); container = node; - container.innerHTML = render(events); + container.innerHTML = render(); events.attachEvents(container); ui = UI.make({ node: container }); // TODO: use the pattern in which the redner returns an object, @@ -444,7 +377,7 @@ define([ PR.prettyPrint(null, container); // create the "places" shortcuts. - $container = $(container); + const $container = $(container); places = { $field: $container.find('#' + fieldId), $fieldPanel: $container.find('[data-element="field-panel"]'), @@ -499,16 +432,12 @@ define([ break; } }); - bus.on('touched', (message) => { + bus.on('touched', () => { places.$feedback.css('background-color', 'yellow'); - // console.log('FIELD detected touched'); }); bus.on('changed', () => { places.$feedback.css('background-color', ''); }); - bus.on('saved', (message) => { - console.log('FIELD detected saved'); - }); if (inputControl.start) { return inputControl.start().then(() => { bus.emit('run', { diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetBare.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetBare.js index 6dc48d864a..fd50544d63 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetBare.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetBare.js @@ -10,20 +10,18 @@ define([ 'bluebird', 'google-code-prettify/prettify', - 'kb_common/html', + 'common/html', 'common/events', 'common/ui', - 'common/props', 'common/runtime', './errorControl', 'css!google-code-prettify/prettify', -], (Promise, PR, html, Events, UI, Props, Runtime, ErrorControlFactory) => { +], (Promise, PR, html, Events, UI, Runtime, ErrorControlFactory) => { 'use strict'; const t = html.tag, div = t('div'), span = t('span'), - label = t('label'), button = t('button'), table = t('table'), tr = t('tr'), @@ -39,20 +37,15 @@ define([ }; function factory(config) { - let ui, - runtime = Runtime.make(), + let ui, places, parent, container, inputControl, enabled; + const runtime = Runtime.make(), bus = runtime.bus().makeChannelBus({ description: 'Field bus', }), - places, - parent, - container, inputControlFactory = config.inputControlFactory, - inputControl, options = {}, fieldId = html.genId(), - spec = config.parameterSpec, - enabled; + spec = config.parameterSpec; try { inputControl = inputControlFactory.make({ @@ -60,6 +53,7 @@ define([ paramsChannelName: config.paramsChannelName, channelName: bus.channelName, initialValue: config.initialValue, + initialDisplayValue: config.initialDisplayValue, appSpec: config.appSpec, parameterSpec: config.parameterSpec, workspaceInfo: config.workspaceInfo, @@ -171,12 +165,6 @@ define([ places.messagePanel.classList.add('hidden'); } - function hideError() { - places.field.classList.remove('-error'); - places.messagePanel.classList.add('hidden'); - places.feedbackIndicator.className = ''; - } - function feedbackNone() { if (places.feedbackIndicator) { places.feedbackIndicator.className = ''; @@ -206,13 +194,13 @@ define([ } } - function rawSpec(spec) { - const specText = JSON.stringify(spec, false, 3), + function rawSpec() { + const specText = JSON.stringify(spec, null, 3), fixedSpec = specText.replace(//g, '>'); return pre({ class: 'prettyprint lang-json', style: { fontSize: '80%' } }, fixedSpec); } - function parameterInfoContent(spec) { + function parameterInfoContent() { return div({ style: { padding: '0px' } }, [ div({ style: { fontWeight: 'bold' } }, spec.ui.label), div({ style: { fontStyle: 'italic' } }, spec.id), @@ -220,7 +208,7 @@ define([ ]); } - function parameterInfoTypeRules(spec) { + function parameterInfoTypeRules() { switch (spec.data.type) { case 'float': case 'int': @@ -231,7 +219,7 @@ define([ } } - function parameterInfoRules(spec) { + function parameterInfoRules() { return table( { class: 'table table-striped' }, [ @@ -250,17 +238,10 @@ define([ ]); } })(), - ].concat(parameterInfoTypeRules(spec)) + ].concat(parameterInfoTypeRules()) ); } - function parameterInfoLittleTip(spec) { - return spec.data.type; - //var mult = (spec.multipleItems() ? '[]' : ''), - // type = spec.dataType(); - //return mult + type; - } - function renderInfoTip() { let infoTipText; if (spec.ui.description && spec.ui.hint !== spec.ui.description) { @@ -284,17 +265,17 @@ define([ { label: 'About', name: 'about', - content: parameterInfoContent(spec), + content: parameterInfoContent(), }, { label: 'Rules', name: 'rules', - content: parameterInfoRules(spec), + content: parameterInfoRules(), }, { label: 'Spec', name: 'spec', - content: rawSpec(spec), + content: rawSpec(), }, ], }) @@ -302,7 +283,7 @@ define([ ]); } - function render(events) { + function render() { const ids = { fieldPanel: html.genId(), messagePanel: html.genId(), @@ -413,7 +394,7 @@ define([ node: container, }); - const rendered = render(events); + const rendered = render(); container.innerHTML = rendered.content; events.attachEvents(); // TODO: use the pattern in which the render returns an object, @@ -470,16 +451,10 @@ define([ break; } }); - // bus.on('touched', function (message) { - // places.feedback.style.backgroundColor = 'yellow'; - // }); - // bus.on('changed', function () { - // places.feedback.style.backgroundColor = ''; - // }); - bus.on('enable', (message) => { + bus.on('enable', () => { doEnable(); }); - bus.on('disable', (message) => { + bus.on('disable', () => { doDisable(); }); diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetCompact.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetCompact.js index 8f1c7eb3c4..4b292ab98a 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetCompact.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetCompact.js @@ -10,14 +10,13 @@ define([ 'bluebird', 'google-code-prettify/prettify', - 'kb_common/html', + 'common/html', 'common/events', 'common/ui', - 'common/props', 'common/runtime', './errorControl', 'css!google-code-prettify/prettify', -], (Promise, PR, html, Events, UI, Props, Runtime, ErrorControlFactory) => { +], (Promise, PR, html, Events, UI, Runtime, ErrorControlFactory) => { 'use strict'; const t = html.tag, @@ -56,6 +55,7 @@ define([ paramsChannelName: config.paramsChannelName, channelName: bus.channelName, initialValue: config.initialValue, + initialDisplayValue: config.initialDisplayValue, appSpec: config.appSpec, parameterSpec: config.parameterSpec, workspaceInfo: config.workspaceInfo, @@ -189,50 +189,50 @@ define([ places.feedbackIndicator.className = 'kb-app-parameter-right-error-bar'; } - function rawSpec(_spec) { - const specText = JSON.stringify(_spec, false, 3), + function rawSpec() { + const specText = JSON.stringify(spec, null, 3), fixedSpec = specText.replace(//g, '>'); return pre({ class: 'prettyprint lang-json', style: { fontSize: '80%' } }, fixedSpec); } - function parameterInfoContent(_spec) { + function parameterInfoContent() { return div({ style: { padding: '0px' } }, [ - div({ style: { fontWeight: 'bold' } }, _spec.ui.label), - div({ style: { fontStyle: 'italic' } }, _spec.id), - div({ style: { fontSize: '80%' } }, _spec.ui.description), + div({ style: { fontWeight: 'bold' } }, spec.ui.label), + div({ style: { fontStyle: 'italic' } }, spec.id), + div({ style: { fontSize: '80%' } }, spec.ui.description), ]); } - function parameterInfoTypeRules(_spec) { - switch (_spec.data.type) { + function parameterInfoTypeRules() { + switch (spec.data.type) { case 'float': case 'int': return [ - tr([th('Min'), td(_spec.data.constraints.min)]), - tr([th('Max'), td(_spec.data.constraints.max)]), + tr([th('Min'), td(spec.data.constraints.min)]), + tr([th('Max'), td(spec.data.constraints.max)]), ]; } } - function parameterInfoRules(_spec) { + function parameterInfoRules() { return table( { class: 'table table-striped' }, [ - tr([th('Required'), td(_spec.data.constraints.required ? 'yes' : 'no')]), - tr([th('Data type'), td(_spec.data.type)]), - tr([th('Multiple values?'), td(_spec.multipleItems ? 'yes' : 'no')]), + tr([th('Required'), td(spec.data.constraints.required ? 'yes' : 'no')]), + tr([th('Data type'), td(spec.data.type)]), + tr([th('Multiple values?'), td(spec.multipleItems ? 'yes' : 'no')]), (function () { - return tr([th('Default value'), td(_spec.data.defaultValue)]); + return tr([th('Default value'), td(spec.data.defaultValue)]); })(), (function () { - if (_spec.data.constraints.types) { + if (spec.data.constraints.types) { return tr([ th('Valid types'), - td(_spec.data.constraints.types.join('
')), + td(spec.data.constraints.types.join('
')), ]); } })(), - ].concat(parameterInfoTypeRules(_spec)) + ].concat(parameterInfoTypeRules()) ); } @@ -258,17 +258,17 @@ define([ { label: 'About', name: 'about', - content: parameterInfoContent(spec), + content: parameterInfoContent(), }, { label: 'Rules', name: 'rules', - content: parameterInfoRules(spec), + content: parameterInfoRules(), }, { label: 'Spec', name: 'spec', - content: rawSpec(spec), + content: rawSpec(), }, ], }) diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetMicro.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetMicro.js index 86226693ca..2ac2775068 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetMicro.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/fieldWidgetMicro.js @@ -10,14 +10,13 @@ define([ 'bluebird', 'google-code-prettify/prettify', - 'kb_common/html', + 'common/html', 'common/events', 'common/ui', - 'common/props', 'common/runtime', './errorControl', 'css!google-code-prettify/prettify', -], (Promise, PR, html, Events, UI, Props, Runtime, ErrorControlFactory) => { +], (Promise, PR, html, Events, UI, Runtime, ErrorControlFactory) => { 'use strict'; const t = html.tag, @@ -39,20 +38,15 @@ define([ }; function factory(config) { - let ui, - runtime = Runtime.make(), + let ui, places, parent, container, inputControl, enabled; + const runtime = Runtime.make(), bus = runtime.bus().makeChannelBus({ description: 'Field bus', }), - places, - parent, - container, inputControlFactory = config.inputControlFactory, - inputControl, options = {}, fieldId = html.genId(), - spec = config.parameterSpec, - enabled; + spec = config.parameterSpec; try { inputControl = inputControlFactory.make({ @@ -60,6 +54,7 @@ define([ paramsChannelName: config.paramsChannelName, channelName: bus.channelName, initialValue: config.initialValue, + initialDisplayValue: config.initialDisplayValue, appSpec: config.appSpec, parameterSpec: config.parameterSpec, workspaceInfo: config.workspaceInfo, @@ -170,12 +165,6 @@ define([ places.messagePanel.classList.add('hidden'); } - function hideError() { - places.field.classList.remove('-error'); - places.messagePanel.classList.add('hidden'); - places.feedbackIndicator.className = ''; - } - function feedbackNone() { places.feedbackIndicator.className = ''; places.feedbackIndicator.classList.add('hidden'); @@ -196,21 +185,21 @@ define([ places.feedbackIndicator.className = 'kb-app-parameter-right-error-bar'; } - function rawSpec(spec) { - const specText = JSON.stringify(spec, false, 3), + function rawSpec() { + const specText = JSON.stringify(spec, null, 3), fixedSpec = specText.replace(//g, '>'); return pre({ class: 'prettyprint lang-json', style: { fontSize: '80%' } }, fixedSpec); } - function parameterInfoContent(spec) { - return div({ style: { padding: '0px' } }, [ + function parameterInfoContent() { + return div({ style: { padding: 0 } }, [ div({ style: { fontWeight: 'bold' } }, spec.ui.label), div({ style: { fontStyle: 'italic' } }, spec.id), div({ style: { fontSize: '80%' } }, spec.ui.description), ]); } - function parameterInfoTypeRules(spec) { + function parameterInfoTypeRules() { switch (spec.data.type) { case 'float': case 'int': @@ -221,7 +210,7 @@ define([ } } - function parameterInfoRules(spec) { + function parameterInfoRules() { return table( { class: 'table table-striped' }, [ @@ -239,7 +228,7 @@ define([ ]); } })(), - ].concat(parameterInfoTypeRules(spec)) + ].concat(parameterInfoTypeRules()) ); } @@ -267,17 +256,17 @@ define([ { label: 'About', name: 'about', - content: parameterInfoContent(spec), + content: parameterInfoContent(), }, { label: 'Rules', name: 'rules', - content: parameterInfoRules(spec), + content: parameterInfoRules(), }, { label: 'Spec', name: 'spec', - content: rawSpec(spec), + content: rawSpec(), }, ], }) @@ -406,30 +395,6 @@ define([ }), ] ), - /* (function () { - if (config.showInfo === false) { - return ''; - } - return div({ - class: 'input-group-addon kb-input-group-addon', - style: { - width: '30px', - padding: '0' - } - }, [ - div({ dataElement: 'info' }, button({ - class: 'btn btn-link btn-xs', - type: 'button', - tabindex: '-1', - id: events.addEvent({ - type: 'click', - handler: function () { - places.infoPanel.querySelector('[data-element="big-tip"]').classList.toggle('hidden'); - } - }) - }, span({ class: 'fa fa-info-circle' }))) - ]); - }()) */ ] ), ] @@ -542,16 +507,10 @@ define([ break; } }); - // bus.on('touched', function (message) { - // places.feedback.style.backgroundColor = 'yellow'; - // }); - // bus.on('changed', function () { - // places.feedback.style.backgroundColor = ''; - // }); - bus.on('enable', (message) => { + bus.on('enable', () => { doEnable(); }); - bus.on('disable', (message) => { + bus.on('disable', () => { doDisable(); }); diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/checkboxInput.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/checkboxInput.js index 73aa14d770..1efc4346f9 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/checkboxInput.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/checkboxInput.js @@ -4,8 +4,8 @@ define([ 'common/events', 'common/ui', 'common/runtime', - '../validation', - '../validators/constants', + 'widgets/appWidgets2/validation', + 'widgets/appWidgets2/validators/constants', 'bootstrap', ], (Promise, html, Events, UI, Runtime, Validation, Constants) => { @@ -217,7 +217,8 @@ define([ // initialize based on config.initialValue. If it's not 0 or 1, then // note that we have an initial value error, and set to the default. - const initValue = config.initialValue || spec.data.defaultValue; + const initValue = + 'initialValue' in config ? config.initialValue : spec.data.defaultValue; if (initValue !== 0 && initValue !== 1) { model.hasInitialValueError = true; } diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInput.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInput.js index 152e61261a..f6a0fe1ca0 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInput.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInput.js @@ -1,6 +1,6 @@ define([ 'bluebird', - '../validation', + 'widgets/appWidgets2/validation', 'util/util', 'common/ui', 'common/props', diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInputs/PetInput.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInputs/PetInput.js index da5020b55b..7121173f3d 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInputs/PetInput.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customInputs/PetInput.js @@ -1,4 +1,5 @@ -define(['bluebird', 'kb_common/html', 'common/monoBus'], (Promise, html) => { +define(['bluebird', 'common/html', 'common/monoBus'], (Promise, html) => { + 'use strict'; // This is a functional html composition and generation library. const t = html.tag, div = t('div'), diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customSubdataInput.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customSubdataInput.js index c5f096213c..12f0665df9 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customSubdataInput.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/customSubdataInput.js @@ -1,15 +1,15 @@ define([ 'jquery', 'bluebird', - 'kb_common/html', - '../validation', + 'common/html', + 'widgets/appWidgets2/validation', 'common/events', 'common/runtime', 'common/ui', 'common/props', 'base/js/namespace', '../subdataMethods/manager', - '../validators/constants', + 'widgets/appWidgets2/validators/constants', 'bootstrap', ], ( $, diff --git a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/dynamicDropdownInput.js b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/dynamicDropdownInput.js index 72889f7217..3339f58882 100644 --- a/kbase-extension/static/kbase/js/widgets/appWidgets2/input/dynamicDropdownInput.js +++ b/kbase-extension/static/kbase/js/widgets/appWidgets2/input/dynamicDropdownInput.js @@ -1,39 +1,35 @@ define([ 'bluebird', 'jquery', - 'kb_common/html', - 'kb_common/utils', + 'common/html', 'StagingServiceClient', - 'kb_service/utils', - '../validation', - 'common/events', + 'widgets/appWidgets2/validation', 'common/runtime', 'common/ui', - 'common/data', - '../validators/constants', + 'common/events', + 'widgets/appWidgets2/validators/constants', 'util/timeFormat', 'util/string', 'kbase-generic-client-api', 'common/props', + 'widgets/appWidgets2/common', 'select2', 'bootstrap', ], ( Promise, $, html, - utils, StagingServiceClient, - serviceUtils, Validation, - Events, Runtime, UI, - Data, + Events, Constants, TimeFormat, StringUtil, GenericClient, - Props + Props, + WidgetCommon ) => { 'use strict'; @@ -43,27 +39,31 @@ define([ span = t('span'), b = t('b'), select = t('select'), - option = t('option'); + option = t('option'), + baseCssClass = 'kb-appInput__dynDropdown'; function factory(config) { const spec = config.parameterSpec, runtime = Runtime.make(), bus = runtime.bus().connect(), channel = bus.channel(config.channelName), - dd_options = spec.original.dynamic_dropdown_options || {}, - dataSource = dd_options.data_source || 'ftp_staging', + ddOptions = spec.original.dynamic_dropdown_options || {}, + dataSource = ddOptions.data_source || 'ftp_staging', model = { + displayValue: undefined, value: undefined, - }, - stagingService = new StagingServiceClient({ - root: runtime.config('services.staging_api_url.url'), - token: runtime.authToken(), - }), - userId = runtime.userId(); + descriptionFields: new Set(), + exactMatchError: false, + }; let parent, container, ui; + if (typeof ddOptions.query_on_empty_input === 'undefined') { + ddOptions.query_on_empty_input = 1; + } - if (typeof dd_options.query_on_empty_input === 'undefined') { - dd_options.query_on_empty_input = 1; + // if there's a template, process it so we have expected fields + if (ddOptions.description_template) { + const m = [...ddOptions.description_template.matchAll(/{{(.+?)}}/g)]; + m.forEach((match) => model.descriptionFields.add(match[1])); } /** @@ -112,7 +112,7 @@ define([ selected = $(control).select2('data')[0]; const selection_val = selected - ? selected[dd_options.selection_id] || selected.subpath + ? selected[ddOptions.selection_id] || selected.subpath : ''; if (!selected || !selection_val) { // might have just started up, and we don't have a selection value, but @@ -131,25 +131,39 @@ define([ * Sets the dropdown value to the given value. Constructs an id from it that (should) * be unique enough to apply to the dropdown. */ - function setControlValue(value) { + function updateControlValue() { + const value = model.value; + const displayValue = model.displayValue || {}; const control = ui.getElement('input-container.input'); - if ($(control).find('option[value="' + value + '"]').length) { - $(control).val(value).trigger('change'); - } else { - const newOption = new Option(value, value, true, true); - $(control).append(newOption).trigger('change'); + if (value) { + const selectorValue = value.replace(/"/g, '\\"').replace(/'/g, "\\'"); + if ($(control).find(`option[value="${selectorValue}"]`).length) { + $(control).val(value).trigger('change'); + } else { + const dataAdapter = $(control).data('select2').dataAdapter; + const newOption = dataAdapter.option( + Object.assign( + { id: String(model.value).trim(), value: model.value }, + displayValue + ) + ); + dataAdapter.addOptions(newOption); + $(control).val(value).trigger('change'); + } } } // MODEL - function setModelValue(value) { - if (model.value === undefined) { + function setModelValue(value, displayValue) { + if (value === undefined) { return; } if (model.value !== value) { model.value = value; + model.displayValue = displayValue || {}; } + updateControlValue(); } function resetModelValue() { @@ -164,6 +178,11 @@ define([ function validate() { return Promise.try(() => { + if (model.exactMatchError) { + const response = Validation.validateFalse(model.value); + response.errorMessage = `An exact match was not found for "${model.value}". Please search again.`; + return response; + } let selectedItem = getControlValue(); const validationConstraints = { min_length: spec.data.constraints.min_length, @@ -187,46 +206,58 @@ define([ token: runtime.authToken(), }); return genericClient.sync_call( - dd_options.service_function, + ddOptions.service_function, callParams, null, null, - dd_options.service_version || 'release' + ddOptions.service_version || 'release' ); } + /** + * Special case for Staging area file seach, which is a little different from the + * generalized dynamic service approach. + * This returns a list of file objects returned from searching the staging service. Each + * object contains the keys "text", "subdir", "subpath", and "id", the values of which + * are all strings. + * @param {string} searchTerm + * @returns Array + */ + async function fetchFtpStagingData(searchTerm) { + const userId = runtime.userId(); + const stagingService = new StagingServiceClient({ + root: runtime.config('services.staging_api_url.url'), + token: runtime.authToken(), + }); + let results = await Promise.resolve(stagingService.search({ query: searchTerm })); + results = JSON.parse(results).filter((file) => { + return !file.isFolder; + }); + results.forEach((file) => { + file.text = file.path; + file.subdir = file.path.substring(0, file.path.length - file.name.length); + file.subpath = file.path.substring(userId.length + 1); + file.id = file.subpath; + }); + return results; + } + async function fetchData(searchTerm) { searchTerm = searchTerm || ''; - if (!searchTerm && !dd_options.query_on_empty_input) { + if (!searchTerm && !ddOptions.query_on_empty_input) { return Promise.resolve([]); } if (dataSource === 'ftp_staging') { - return Promise.resolve(stagingService.search({ query: searchTerm })).then( - (results) => { - results = JSON.parse(results).filter((file) => { - return !file.isFolder; - }); - results.forEach((file) => { - file.text = file.path; - file.subdir = file.path.substring( - 0, - file.path.length - file.name.length - ); - file.subpath = file.path.substring(userId.length + 1); - file.id = file.subpath; - }); - return results; - } - ); + return fetchFtpStagingData(searchTerm); } else { - let callParams = JSON.stringify(dd_options.service_params).replace( + let callParams = JSON.stringify(ddOptions.service_params).replace( '{{dynamic_dropdown_input}}', searchTerm ); callParams = JSON.parse(callParams); - // TODO: wrap lines 228-252 in a check for dd_options.include_user_params and implement that in NMS + // TODO: wrap lines 228-252 in a check for ddOptions.include_user_params and implement that in NMS const params = await channel.request({}, { key: { type: 'get-parameters' } }); // text replacement for any dynamic parameter values @@ -234,18 +265,18 @@ define([ return Object.entries(callParam).reduce((acc, [k, v]) => { if (typeof v === 'string') { // match dynamic user params that are {{in brackets}} - const d_param = v.match(/[^{{]+(?=}\})/); - if (d_param !== null) { - if (!(d_param[0] in params)) { + const dParam = v.match(/[^{{]+(?=}\})/); + if (dParam !== null) { + if (!(dParam[0] in params)) { console.error( - `Parameter "{{${d_param[0]}}}" does not exist as a parameter for this method. ` + - `this dynamic parameter will be omitted in the call to ${dd_options.service_function}.` + `Parameter "{{${dParam[0]}}}" does not exist as a parameter for this method. ` + + `this dynamic parameter will be omitted in the call to ${ddOptions.service_function}.` ); - // dont include bad parameters that don't exist + // don't include bad parameters that don't exist return acc; } // replace dynamic values with actual param values - acc[k] = params[d_param[0]]; + acc[k] = params[dParam[0]]; return acc; } } @@ -255,135 +286,229 @@ define([ }, {}); }); - return Promise.resolve(genericClientCall(callParams)).then((results) => { - let index = dd_options.result_array_index; - if (!index) { - index = 0; - } - if (index >= results.length) { - console.error( - `Result array from ${dd_options.service_function} ` + - `has length ${results.length} but index ${index} ` + - 'was requested' - ); - return []; - } - results = results[index]; - let path = dd_options.path_to_selection_items; - if (!path) { - path = []; - } - results = Props.getDataItem(results, path); - if (!Array.isArray(results)) { - console.error( - 'Selection items returned from ' + - `${dd_options.service_function} at path /${path.join('/')} ` + - `in postion ${index} of the returned list are not an array` - ); - return []; - } else { - results.forEach((obj, _index) => { - // could check here that each item is a map? YAGNI - obj = flattenObject(obj); - if (!('id' in obj)) { - obj.id = _index; // what the fuck - } - //this blows away any 'text' field - obj.text = obj[dd_options.selection_id]; - results[_index] = obj; - }); - return results; - } - }); + let results = await Promise.resolve(genericClientCall(callParams)); + const index = ddOptions.result_array_index || 0; + if (index >= results.length) { + console.error( + `Result array from ${ddOptions.service_function} ` + + `has length ${results.length} but index ${index} ` + + 'was requested' + ); + return []; + } + results = results[index]; + let path = ddOptions.path_to_selection_items; + if (!path) { + path = []; + } + results = Props.getDataItem(results, path); + if (!Array.isArray(results)) { + console.error( + 'Selection items returned from ' + + `${ddOptions.service_function} at path /${path.join('/')} ` + + `in postion ${index} of the returned list are not an array` + ); + return []; + } else { + results.forEach((obj, _index) => { + // could check here that each item is a map? YAGNI + obj = flattenObject(obj); + if (!('id' in obj)) { + obj.id = String(_index); + } + // this blows away any 'text' field + obj.text = obj[ddOptions.selection_id]; + results[_index] = obj; + }); + return results; + } } } - function doChange() { - validate().then((result) => { - if (result.isValid) { - const newValue = - result.parsedValue === undefined ? result.value : result.parsedValue; - model.value = newValue; - channel.emit('changed', { - newValue: newValue, - }); - } else if (result.diagnosis === Constants.DIAGNOSIS.REQUIRED_MISSING) { - model.value = spec.data.nullValue; - channel.emit('changed', { - newValue: spec.data.nullValue, - }); + /** + * + * @param {Object} dataElement + */ + async function doChange(dataElement) { + const result = await validate(); + const changeMsg = { + newDisplayValue: undefined, + newValue: spec.data.nullValue, + }; + + if (result.isValid) { + model.exactMatchError = false; + const newValue = + result.parsedValue === undefined ? result.value : result.parsedValue; + model.value = newValue; + if (dataElement) { + model.displayValue = [...model.descriptionFields].reduce((acc, key) => { + acc[key] = dataElement[key]; + return acc; + }, {}); + } else { + model.displayValue = undefined; } - channel.emit('validation', { - errorMessage: result.errorMessage, - diagnosis: result.diagnosis, - }); - }); + changeMsg.newDisplayValue = model.displayValue; + changeMsg.newValue = newValue; + channel.emit('changed', changeMsg); + } else if (result.diagnosis === Constants.DIAGNOSIS.REQUIRED_MISSING) { + model.value = spec.data.nullValue; + channel.emit('changed', changeMsg); + } + channel.emit('validation', result); } /** * Clears the current selection and updates the model. */ function doClear() { + model.exactMatchError = false; + $(ui.getElement('input-container.input')).html(''); model.value = spec.data.nullValue; channel.emit('changed', { + newDisplayValue: undefined, newValue: spec.data.nullValue, }); } /** - * Formats the display of an object in the dropdown. - id: "data/bulk/wjriehl/subfolder/i_am_a_file.txt" - isFolder: false - mtime: 1508441424000 - name: "i_am_a_file.txt" - path: "data/bulk/wjriehl/subfolder/i_am_a_file.txt" - size: 0 - text: "data/bulk/wjriehl/subfolder/i_am_a_file.txt" + * Formats Staging Area file data for display in the dropdown. + * Expects an example fileData object as below: + * { + * id: "data/bulk/wjriehl/subfolder/i_am_a_file.txt" + * isFolder: false + * mtime: 1508441424000 + * name: "i_am_a_file.txt" + * path: "data/bulk/wjriehl/subfolder/i_am_a_file.txt" + * size: 0 + * text: "data/bulk/wjriehl/subfolder/i_am_a_file.txt" + * } + * @param {Object} fileData + * @returns {JQueryElement} a jQuery-wrapped div element */ - function formatObjectDisplay(ret_obj) { - if (!ret_obj.id) { - return ''; + function formatFtpStagingDisplay(fileData) { + return $( + div([ + span( + { + class: `${baseCssClass}_display__filepath`, + }, + [StringUtil.escape(fileData.subdir), b(StringUtil.escape(fileData.name))] + ), + div( + { + class: `${baseCssClass}_display__indent`, + }, + [ + 'Size: ' + StringUtil.readableBytes(fileData.size) + '
', + 'Uploaded ' + TimeFormat.getTimeStampStr(fileData.mtime, true), + ] + ), + ]) + ); + } + + /** + * Formats the display of an object in the dropdown. Every Option in Select2 gets passed + * through here, for better or worse. This includes temporary ones inserted by Select2, + * like "Searching..." or "Loading..." fields. + * + * This returns either a text string (which will be escaped before rendering) + * or a jQuery element, which expects pre-escaped "safe" HTML. + * + * So here are input cases: + * 1. (most common), an object with an id, text, and fields as returned from the dynamic + * search. This gets rendered using the ddOptions template. + * 2. (on search/load), an object without an id, but with a text field. Expects to + * just return the bare text or an empty string - this lets Select2 use the default + * "Searching..." or "Loading..." strings as temporary/unselectable options. + * 3. (on widget load), an object with id, text, and nothing else should just return + * the text? + * See https://select2.org/dropdown#templating for more details. + */ + function formatObjectDisplay(obj) { + if (!obj.id) { + return obj.text || ''; } else if (dataSource === 'ftp_staging') { - if (!ret_obj.id) { - return $('
').append(ret_obj.text); + return config.isViewOnly ? obj.id : formatFtpStagingDisplay(obj); + } else { + let formattedString; + // if we have a template and at least one item to fill the template with, + // do the formatted template + if ( + ddOptions.description_template && + [...model.descriptionFields].some((key) => key in obj) + ) { + formattedString = formatDescriptionTemplate(obj); } + // otherwise, if we have a text use that. And if not, use the id as a last resort. + else { + formattedString = obj.text || obj.id; + } + // and squash the result in a jQuery object with a div. return $( - div([ - span({ style: 'word-wrap: break-word' }, [ret_obj.subdir, b(ret_obj.name)]), - div({ style: 'margin-left: 7px' }, [ - 'Size: ' + StringUtil.readableBytes(ret_obj.size) + '
', - 'Uploaded ' + TimeFormat.getTimeStampStr(ret_obj.mtime, true), - ]), - ]) + div( + { + class: `${baseCssClass}_display`, + }, + formattedString + ) ); - } else { - const replacer = function (match, p1) { - return ret_obj[p1]; - }; - let formatted_string; - if (dd_options.description_template) { - // use slice to avoid modifying global description_template - formatted_string = dd_options.description_template - .slice() - .replace(/{{(.+?)}}/g, replacer); - } else { - formatted_string = JSON.stringify(ret_obj); - } - return $('
').append(formatted_string); } } - function selectionTemplate(object) { - if (dd_options.description_template) { - return formatObjectDisplay(object); + /** + * Formats the dynamic dropdown description template by replacing templated + * values with values from the given object. + * For example, if the template (in ddOptions.description_template) looks like this: + * + * Template value: {{foo}} + * + * and the given object is: + * { + * foo: "bar" + * } + * + * This returns the string "Template value: bar". + * + * Note that this assumes that ddOptions.description_template exists, for simplicity. + * @param {any} obj the object to use for replacing template fields + * @returns {String} the formatted string + */ + function formatDescriptionTemplate(obj) { + const replacer = (_match, paramId) => { + return obj[paramId]; + }; + return ddOptions.description_template.replace(/{{(.+?)}}/g, replacer); + } + + function selectionTemplate(obj) { + if (ddOptions.description_template) { + return formatObjectDisplay(obj); } - if (dd_options.selection_id) { - return object[dd_options.selection_id]; + if (ddOptions.selection_id) { + return obj[ddOptions.selection_id]; } - if (!object.id) { - return object.text; + if (!obj.id) { + return obj.text; + } + return obj.id; + } + + function getCopyString() { + const data = $(ui.getElement('input-container.input')).select2('data')[0]; + if (!data) { + return ''; + } else if (ddOptions.exact_match_on && data[ddOptions.exact_match_on]) { + return data[ddOptions.exact_match_on]; + } else { + const rendered = selectionTemplate(data); + if (typeof rendered !== 'string') { + return rendered.text(); + } + return rendered; } - return object.id; } /* @@ -391,44 +516,120 @@ define([ * Places it into the dom node * Hooks up event listeners */ - function render() { - return Promise.try(() => { - const events = Events.make(), - inputControl = makeInputControl(), - content = div({ class: 'input-group', style: { width: '100%' } }, inputControl); - - ui.setContent('input-container', content); - - $(ui.getElement('input-container.input')) - .select2({ - allowClear: true, - templateResult: formatObjectDisplay, - templateSelection: selectionTemplate, - ajax: { - delay: 250, - transport: function (params, success, failure) { - return fetchData(params.data.term) - .then((data) => { - success({ results: data }); - }) - .catch((err) => { - console.error(err); - failure(err); - }); - }, - }, - placeholder: { - id: 'select an option', - }, - }) - .on('change', () => { - doChange(); - }) - .on('select2:clear', () => { - doClear(); - }); - events.attachEvents(container); + async function render() { + const events = Events.make(); + const inputControl = makeInputControl(); + ui.setContent('input-container', ''); + const _container = ui.getElement('input-container'); + const content = WidgetCommon.containerContent( + div, + t('button'), + events, + ui, + _container, + inputControl, + getCopyString + ); + ui.setContent('input-container', content); + + const dropdown = $(ui.getElement('input-container.input')); + const data = []; + + if (config.isViewOnly) { + // For select2, ids should be a string, not "0" or empty string + // This sets the value of the