Repository: vatlab/sos-notebook Branch: master Commit: a770bbdf1069 Files: 115 Total size: 1.1 MB Directory structure: gitextract_658abc0k/ ├── .appveyor.yml ├── .github/ │ ├── linters/ │ │ └── .python-lint │ └── workflows/ │ ├── pylint.yml │ ├── pytest.yml │ └── python-publish.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .travis.yml ├── CLAUDE.md ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── development/ │ ├── README.md │ ├── docker-compose.yml │ ├── eg_sshd/ │ │ ├── .ssh/ │ │ │ ├── id_rsa │ │ │ ├── id_rsa.pub │ │ │ └── known_hosts │ │ └── Dockerfile │ ├── install_sos_notebook.sh │ └── sos_notebook_test/ │ ├── .ssh/ │ │ ├── id_rsa │ │ ├── id_rsa.pub │ │ └── known_hosts │ └── Dockerfile ├── pyproject.toml ├── setup.py.old ├── src/ │ └── sos_notebook/ │ ├── __init__.py │ ├── _version.py │ ├── comm_manager.py │ ├── completer.py │ ├── converter.py │ ├── inspector.py │ ├── install.py │ ├── install_sos_notebook.sh │ ├── kernel.py │ ├── magics.py │ ├── step_executor.py │ ├── subkernel.py │ ├── templates/ │ │ ├── README.md │ │ ├── sos-cm/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ ├── cm.tpl │ │ │ │ └── sos-mode.js │ │ │ └── sos-cm.html.j2 │ │ ├── sos-cm-toc/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ └── toc.tpl │ │ │ └── sos-cm-toc.html.j2 │ │ ├── sos-full/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ ├── preview.tpl │ │ │ │ └── sos_style.tpl │ │ │ └── sos-full.html.j2 │ │ ├── sos-full-toc/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ └── toc.tpl │ │ │ └── sos-full-toc.html.j2 │ │ ├── sos-lab-cm/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ ├── cm.tpl │ │ │ │ └── sos-mode.js │ │ │ └── sos-lab-cm.html.j2 │ │ ├── sos-lab-full/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ ├── preview.tpl │ │ │ │ └── sos_style.tpl │ │ │ ├── sos-lab-full.html.j2 │ │ │ └── static/ │ │ │ ├── index.css │ │ │ ├── theme-dark.css │ │ │ └── theme-light.css │ │ ├── sos-lab-report-only/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ └── sos-lab-report-only.html.j2 │ │ ├── sos-markdown/ │ │ │ ├── conf.json │ │ │ ├── index.md.j2 │ │ │ └── sos-markdown.md.j2 │ │ ├── sos-report/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ └── control_panel.tpl │ │ │ └── sos-report.html.j2 │ │ ├── sos-report-only/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ └── sos-report-only.html.j2 │ │ ├── sos-report-only-toc/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ └── toc.tpl │ │ │ └── sos-report-only-toc.html.j2 │ │ ├── sos-report-toc/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ └── toc.tpl │ │ │ └── sos-report-toc.html.j2 │ │ ├── sos-report-toc-v2/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ └── toc.tpl │ │ │ └── sos-report-toc-v2.html.j2 │ │ ├── sos-report-v1/ │ │ │ ├── conf.json │ │ │ ├── index.html.j2 │ │ │ ├── parts/ │ │ │ │ └── control_panel_v1.tpl │ │ │ └── sos-report-v1.html.j2 │ │ └── sos-report-v2/ │ │ ├── conf.json │ │ ├── index.html.j2 │ │ ├── parts/ │ │ │ └── control_panel.tpl │ │ └── sos-report-v2.html.j2 │ ├── test_utils.py │ └── workflow_executor.py ├── tasks.py └── test/ ├── __init__.py ├── build_test_docker.sh ├── conftest.py ├── sample_notebook.ipynb ├── sample_papermill_notebook.ipynb ├── sample_workflow.ipynb ├── test_convert.py ├── test_magics.py └── test_workflow.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .appveyor.yml ================================================ version: 1.0.{build} # docker support #image: Visual Studio 2017 #init: # - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) branches: only: - master skip_tags: true max_jobs: 100 build: none clone_folder: c:\projects\sos clone_depth: 50 shallow_clone: false environment: matrix: - PYTHON: "C:\\Miniconda36-x64" PYTHON_VERSION: 3.8 install: - set PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH% - conda config --set always_yes yes --set changeps1 no - conda update -q conda # Useful for debugging any issues with conda - conda info -a - conda install -c conda-forge feather-format r-base r-irkernel # # # add docker #- pip install docker # packages required by SoS - pip install spyder jedi notebook nbconvert nbformat pyyaml psutil tqdm matplotlib - pip install fasteners pygments ipython ptpython networkx pydot pydotplus nose selenium # https://github.com/jupyter/jupyter/issues/150 - pip install entrypoints markdown - pip install jupyter wand numpy pandas papermill sos-papermill # install github version of sos - pip install git+https://github.com/vatlab/sos.git - pip install pytest - pip install . -U - python -m sos_notebook.install - pip install sos-python sos-r test_script: - cd test - pytest -x -v #on_finish: # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) notifications: - provider: Email to: - ben.bob@gmail.com on_build_status_changed: true ================================================ FILE: .github/linters/.python-lint ================================================ [MASTER] # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code. extension-pkg-whitelist= # Specify a score threshold to be exceeded before program exits with error. fail-under=10.0 # Add files or directories to the blacklist. They should be base names, not # paths. ignore=development # Add files or directories matching the regex patterns to the blacklist. The # regex matches against base names, not paths. ignore-patterns=\d{4}_.*?.py # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the # number of processors available to use. jobs=1 # Control the amount of potential inferred values when inferring a single # object. This can help the performance when dealing with large functions or # complex, nested conditions. limit-inference-results=100 # List of plugins (as comma separated values of python module names) to load, # usually to register additional checkers. # these two plugins are good to have but super-linter does not support it. # # pylint_django, pylint_celery # load-plugins= # Pickle collected data for later comparisons. persistent=yes # When enabled, pylint would attempt to guess common misconfiguration and emit # user-friendly hints instead of false-positive error messages. # suggestion-mode=yes # removed: unrecognized in newer pylint # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no [MESSAGES CONTROL] # Only show warnings with the listed confidence levels. Leave empty to show # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. confidence= # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifiers separated by comma (,) or put this # option multiple times (only on the command line, not in the configuration # file where it should appear only once). You can also use "--disable=all" to # disable everything first and then reenable specific checks. For example, if # you want to run only the similarities checker, you can use "--disable=all # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". disable=abstract-method, arguments-differ, arguments-renamed, attribute-defined-outside-init, bad-inline-option, bare-except, broad-except, chained-comparison, consider-iterating-dictionary, consider-using-dict-items, consider-using-generator, consider-using-get, consider-using-in, consider-using-f-string, consider-using-set-comprehension, consider-using-with, cyclic-import, dangerous-default-value, deprecated-method, deprecated-pragma, duplicate-code, eval-used, exec-used, file-ignored, fixme, global-statement, import-error, import-outside-toplevel, import-self, inconsistent-return-statements, invalid-name, invalid-unary-operand-type, line-too-long, locally-disabled, logging-format-interpolation, logging-fstring-interpolation, logging-not-lazy, missing-class-docstring, missing-function-docstring, missing-module-docstring, no-member, no-name-in-module, # no-self-use, # moved to optional extension in pylint 2.14 no-value-for-parameter, pointless-statement, protected-access, raw-checker-failed, redefined-argument-from-local, redefined-builtin, redefined-outer-name, reimported, self-assigning-variable, self-cls-assignment, signature-differs, simplifiable-if-expression, super-init-not-called, suppressed-message, too-few-public-methods, too-many-ancestors, too-many-arguments, too-many-boolean-expressions, too-many-branches, too-many-instance-attributes, too-many-lines, too-many-locals, too-many-nested-blocks, too-many-public-methods, too-many-return-statements, too-many-statements, try-except-raise, undefined-loop-variable,, undefined-variable, unnecessary-comprehension, unnecessary-lambda, unneeded-not, unreachable, unspecified-encoding, unsubscriptable-object, unused-argument, unused-import, use-a-generator, use-symbolic-message-instead, useless-object-inheritance, useless-super-delegation, useless-suppression, useless-with-lock, wildcard-import, assignment-from-none, broad-exception-raised, global-variable-not-assigned, invalid-overridden-method, no-else-return, possibly-used-before-assignment, stop-iteration-return, too-many-positional-arguments, ungrouped-imports, unnecessary-dunder-call, unused-variable, used-before-assignment, useless-return, trailing-whitespace, no-else-break, unnecessary-pass # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. enable=c-extension-no-member [REPORTS] # Python expression which should return a score less than or equal to 10. You # have access to the variables 'error', 'warning', 'refactor', and 'convention' # which contain the number of messages in each category, as well as 'statement' # which is the total number of statements analyzed. This score is used by the # global evaluation report (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Template used to display messages. This is a python new-style format string # used to format the message information. See doc for all details. #msg-template= # Set the output format. Available formats are text, parseable, colorized, json # and msvs (visual studio). You can also give a reporter class, e.g. # mypackage.mymodule.MyReporterClass. output-format=text # Tells whether to display a full report or only the messages. reports=no # Activate the evaluation score. score=yes [REFACTORING] # Maximum number of nested blocks for function / method body max-nested-blocks=5 # Complete name of functions that never returns. When checking for # inconsistent-return-statements if a never returning function is called then # it will be considered as an explicit return statement and no message will be # printed. never-returning-functions=sys.exit [LOGGING] # The type of string formatting that logging methods do. `old` means using % # formatting, `new` is for `{}` formatting. logging-format-style=old # Logging modules to check that the string format arguments are in logging # function parameter format. logging-modules=logging [SPELLING] # Limits count of emitted suggestions for spelling mistakes. max-spelling-suggestions=4 # Spelling dictionary name. Available dictionaries: none. To make it work, # install the python-enchant package. spelling-dict= # List of comma separated words that should not be checked. spelling-ignore-words= # A path to a file that contains the private dictionary; one word per line. spelling-private-dict-file= # Tells whether to store unknown words to the private dictionary (see the # --spelling-private-dict-file option) instead of raising a message. spelling-store-unknown-words=no [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME, XXX, TODO # Regular expression of note tags to take in consideration. #notes-rgx= [TYPECHECK] # List of decorators that produce context managers, such as # contextlib.contextmanager. Add to this list to register other decorators that # produce valid context managers. contextmanager-decorators=contextlib.contextmanager # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E1101 when accessed. Python regular # expressions are accepted. generated-members=REQUEST,acl_users,aq_parent,"[a-zA-Z]+_set{1,2}",save,delete # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # Tells whether to warn about missing members when the owner of the attribute # is inferred to be None. ignore-none=yes # This flag controls whether pylint should warn about no-member and similar # checks whenever an opaque object is returned when inferring. The inference # can return multiple potential results while evaluating a Python object, but # some branches might not be evaluated, which results in partial inference. In # that case, it might be useful to still emit no-member and other checks for # the rest of the inferred objects. ignore-on-opaque-inference=yes # List of class names for which member attributes should not be checked (useful # for classes with dynamically set attributes). This supports the use of # qualified names. ignored-classes=optparse.Values,thread._local,_thread._local # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis). It # supports qualified module names, as well as Unix pattern matching. ignored-modules= # Show a hint with possible names when a member name was not found. The aspect # of finding the hint is based on edit distance. missing-member-hint=yes # The minimum edit distance a name should have in order to be considered a # similar match for a missing member name. missing-member-hint-distance=1 # The total number of similar names that should be taken in consideration when # showing a hint for a missing member. missing-member-max-choices=1 # List of decorators that change the signature of a decorated function. signature-mutators= [VARIABLES] # List of additional names supposed to be defined in builtins. Remember that # you should avoid defining new builtins when possible. additional-builtins= # Tells whether unused global variables should be treated as a violation. allow-global-unused-variables=yes # List of strings which can identify a callback function by name. A callback # name must start or end with one of those strings. callbacks=cb_, _cb # A regular expression matching the name of dummy variables (i.e. expected to # not be used). dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ # Argument names that match this expression will be ignored. Default to name # with leading underscore. ignored-argument-names=_.*|^ignored_|^unused_ # Tells whether we should check for unused import in __init__ files. init-import=no # List of qualified module names which can have objects that can redefine # builtins. redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io [FORMAT] # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. expected-line-ending-format= # Regexp for a line that is allowed to be longer than the limit. ignore-long-lines=^\s*(# )??$ # Number of spaces of indent required inside a hanging or continued line. indent-after-paren=4 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' # Maximum number of characters on a single line. max-line-length=120 # Maximum number of lines in a module. max-module-lines=1000 # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no # Allow the body of an if to be on the same line as the test if there is no # else. single-line-if-stmt=no [SIMILARITIES] # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=no # Minimum lines number of a similarity. min-similarity-lines=4 [BASIC] # Naming style matching correct argument names. argument-naming-style=snake_case # Regular expression matching correct argument names. Overrides argument- # naming-style. #argument-rgx= # Naming style matching correct attribute names. attr-naming-style=snake_case # Regular expression matching correct attribute names. Overrides attr-naming- # style. #attr-rgx= # Bad variable names which should always be refused, separated by a comma. bad-names=foo, bar, baz, toto, tutu, tata # Bad variable names regexes, separated by a comma. If names match any regex, # they will always be refused bad-names-rgxs= # Naming style matching correct class attribute names. class-attribute-naming-style=any # Regular expression matching correct class attribute names. Overrides class- # attribute-naming-style. #class-attribute-rgx= # Naming style matching correct class names. class-naming-style=PascalCase # Regular expression matching correct class names. Overrides class-naming- # style. #class-rgx= # Naming style matching correct constant names. const-naming-style=UPPER_CASE # Regular expression matching correct constant names. Overrides const-naming- # style. #const-rgx= # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=-1 # Naming style matching correct function names. function-naming-style=snake_case # Regular expression matching correct function names. Overrides function- # naming-style. #function-rgx= # Good variable names which should always be accepted, separated by a comma. good-names=i, j, k, ex, Run, _ # Good variable names regexes, separated by a comma. If names match any regex, # they will always be accepted good-names-rgxs= # Include a hint for the correct naming format with invalid-name. include-naming-hint=no # Naming style matching correct inline iteration names. inlinevar-naming-style=any # Regular expression matching correct inline iteration names. Overrides # inlinevar-naming-style. #inlinevar-rgx= # Naming style matching correct method names. method-naming-style=snake_case # Regular expression matching correct method names. Overrides method-naming- # style. #method-rgx= # Naming style matching correct module names. module-naming-style=snake_case # Regular expression matching correct module names. Overrides module-naming- # style. #module-rgx= # Colon-delimited sets of names that determine each other's naming style when # the name regexes allow several styles. name-group= # Regular expression which should only match function or class names that do # not require a docstring. no-docstring-rgx=^_ # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. # These decorators are taken in consideration only for invalid-name. property-classes=abc.abstractproperty # Naming style matching correct variable names. variable-naming-style=snake_case # Regular expression matching correct variable names. Overrides variable- # naming-style. #variable-rgx= [STRING] # This flag controls whether inconsistent-quotes generates a warning when the # character used as a quote delimiter is used inconsistently within a module. check-quote-consistency=no # This flag controls whether the implicit-str-concat should generate a warning # on implicit string concatenation in sequences defined over several lines. check-str-concat-over-line-jumps=no [IMPORTS] # List of modules that can be imported at any level, not just the top level # one. allow-any-import-level= # Allow wildcard imports from modules that define __all__. allow-wildcard-with-all=no # Analyse import fallback blocks. This can be used to support both Python 2 and # 3 compatible code, which means that the block might have code that exists # only in one or another interpreter, leading to false positives when analysed. analyse-fallback-blocks=no # Deprecated modules which should not be used, separated by a comma. deprecated-modules=optparse,tkinter.tix # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled). ext-import-graph= # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled). import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled). int-import-graph= # Force import order to recognize a module as part of the standard # compatibility libraries. known-standard-library= # Force import order to recognize a module as part of a third party library. known-third-party=enchant # Couples of modules and preferred modules, separated by a comma. preferred-modules= [CLASSES] # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__, __new__, setUp, __post_init__ # List of member names, which should be excluded from the protected access # warning. exclude-protected=_asdict, _fields, _replace, _source, _make # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=cls [DESIGN] # Maximum number of arguments for function / method. max-args=5 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Maximum number of boolean expressions in an if statement (see R0916). max-bool-expr=5 # Maximum number of branch for function / method body. max-branches=12 # Maximum number of locals for function / method body. max-locals=15 # Maximum number of parents for a class (see R0901). max-parents=13 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # Maximum number of return / yield for function / method body. max-returns=6 # Maximum number of statements in function / method body. max-statements=50 # Minimum number of public methods for a class (see R0903). min-public-methods=2 [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "BaseException, Exception". # overgeneral-exceptions=BaseException, # Exception ================================================ FILE: .github/workflows/pylint.yml ================================================ name: Pylint on: [push, pull_request] jobs: pylint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python 3.12 uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install pylint pip install -e . - name: Analysing the code with pylint run: | python -m pylint --rcfile .github/linters/.python-lint src ================================================ FILE: .github/workflows/pytest.yml ================================================ name: Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.10", "3.12"] fail-fast: false steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Set up R uses: r-lib/actions/setup-r@v2 - name: Install R packages run: | Rscript -e 'install.packages(c("IRkernel", "arrow"), repos="https://cloud.r-project.org")' Rscript -e 'IRkernel::installspec()' - name: Install Python dependencies run: | python -m pip install --upgrade pip pip install -e .[dev] pip install sos-r sos-python sos-bash pip install bash_kernel python -m bash_kernel.install python -m sos_notebook.install - name: Run tests run: | pytest test/ -v --tb=short -x ================================================ FILE: .github/workflows/python-publish.yml ================================================ # This workflow will upload a Python Package to PyPI when a release is created name: Upload Python Package on: release: types: [created] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install build dependencies run: | python -m pip install --upgrade pip pip install build twine - name: Build package run: python -m build - name: Publish to PyPI env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} run: twine upload dist/* ================================================ FILE: .gitignore ================================================ .sos *.swp __pycache__ tmp* build dist *egg-info .DS_Store _site/ .ipynb_checkpoints *.pem *.pyc .ipython/ .jupyter/ .viminfo geckodriver.log .bash_history .cache/ .local/ ================================================ FILE: .pre-commit-config.yaml ================================================ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - id: flake8 args: ["--ignore=E501,W504"] - repo: https://github.com/pre-commit/mirrors-yapf rev: '' hooks: - id: yapf args: [--style, "{based_on_style:chromium,indent_width:4}"] ================================================ FILE: .travis.yml ================================================ dist: trusty group: edge os: - linux # travis does not support python on osx yet (https://github.com/travis-ci/travis-ci/issues/4729) language: python python: - "3.8" addons: chrome: stable before_install: # - sudo apt-get update # - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce # - wget https://repo.continuum.io/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh -O miniconda.sh # - bash miniconda.sh -b -p $HOME/miniconda # - export PATH="$HOME/miniconda/bin:$PATH" # - hash -r # - conda config --set always_yes yes --set changeps1 no # - conda update -q conda # #- conda info -a # - pip install docker rq pyyaml psutil tqdm nose fasteners pygments networkx pydot pydotplus # - pip install entrypoints jupyter coverage codacy-coverage pytest pytest-cov python-coveralls # - conda install -q pandas numpy # - conda install -c r r-essentials r-feather # - conda install -c conda-forge feather-format # # SoS Notebook # - pip install jedi notebook nbconvert nbformat pyyaml psutil tqdm scipy markdown matplotlib # - sudo apt-get install libmagickwand-dev libmagickcore5-extra graphviz # - pip install pygments ipython wand graphviz # - pip install git+https://github.com/vatlab/sos.git # - pip install git+https://github.com/vatlab/sos-bash.git # - pip install git+https://github.com/vatlab/sos-python.git # - pip install git+https://github.com/vatlab/sos-r.git # - pip install selenium # - google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost & # - wget https://chromedriver.storage.googleapis.com/73.0.3683.20/chromedriver_linux64.zip -P ~/ # - unzip ~/chromedriver_linux64.zip -d ~/ # - rm ~/chromedriver_linux64.zip # - sudo mv -f ~/chromedriver /usr/local/share/ # - sudo chmod +x /usr/local/share/chromedriver # - sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver # - "export DISPLAY=:99.0" # - "sh -e /etc/init.d/xvfb start" # - sleep 3 sudo: required services: - docker install: - docker network create sosnet - docker pull mdabioinfo/sos_notebook_test:latest - docker pull mdabioinfo/eg_sshd:latest - cd development - export COMPOSE_PROJECT_NAME=sosnotebook - docker-compose up -d - cd .. - docker cp . sosnotebook_sos-notebook_1:/home/jovyan - docker exec -u root sosnotebook_sos-notebook_1 sh ./development/install_sos_notebook.sh before_script: # - cd test # - sh build_test_docker.sh script: #- docker exec -u root sosnotebook_sos-notebook_1 pytest ./test -x -v --cov sos_notebook --cov-report=term-missing - docker exec -u root sosnotebook_sos-notebook_1 mkdir -p /home/jovyan/.sos - docker exec -u root sosnotebook_sos-notebook_1 mkdir -p /home/jovyan/.local - docker exec -u root sosnotebook_sos-notebook_1 chown -R jovyan:users /home/jovyan/.sos/ - docker exec -u root sosnotebook_sos-notebook_1 chown -R jovyan:users /home/jovyan/.local/ - docker exec -u root sosnotebook_sos-notebook_1 chown -R jovyan:users /home/jovyan/test/ - docker exec sosnotebook_sos-notebook_1 bash -c 'cd test && pytest -v' after_success: - coverage combine - coveralls notifications: email: recipients: - ben.bob@gmail.com on_success: never on_failure: always ================================================ FILE: CLAUDE.md ================================================ # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Development Commands **Invoke Tasks (Recommended):** - `invoke --list` - Show all available development tasks - `invoke dev-setup` - Set up complete development environment with uv - `invoke venv-create` - Create virtual environment with uv - `invoke uv-sync` - Sync dependencies using uv - `invoke uv-lock` - Update uv.lock file - `invoke check` - Run all quality checks (format, lint, test) - `invoke format` - Format code with ruff - `invoke format --check` - Check code formatting without changes - `invoke lint` - Run linting with ruff - `invoke lint --fix` - Run linting with auto-fix - `invoke test` - Run tests with pytest - `invoke test --verbose` - Run tests with verbose output - `invoke test --coverage` - Run tests with coverage report - `invoke build` - Build source and wheel distributions - `invoke build --clean` - Clean build artifacts and rebuild - `invoke clean` - Clean build artifacts and caches - `invoke install` - Install package in development mode - `invoke release-check` - Run comprehensive pre-release checks - `invoke test-docker` - Run full test suite in Docker (CI environment) **uv Virtual Environment Management:** - `uv venv` - Create virtual environment - `uv sync` - Install dependencies from pyproject.toml - `uv sync --dev` - Install with development dependencies - `uv add ` - Add runtime dependency - `uv add --dev ` - Add development dependency - `uv remove ` - Remove dependency - `uv lock` - Update dependency lock file - `uv pip install -e .` - Install package in development mode - `source .venv/bin/activate` - Activate virtual environment **Direct Commands:** - `pytest -v` - Run all tests (executed in Docker container) - `docker exec sosnotebook_sos-notebook_1 bash -c 'cd test && pytest -v'` - Full test run in CI environment **Code Quality:** - `pre-commit run --all-files` - Run code formatting and linting (ruff) - `ruff check` - Run linting - `ruff check --fix` - Run linting with auto-fix - `ruff format` - Format code - `ruff format --check` - Check code formatting **Development Environment:** - Uses Docker for testing - see `development/docker-compose.yml` - `docker-compose build --no-cache` - Rebuild test images - `docker network create sosnet` - Create Docker network for testing **Build System:** - Uses modern `pyproject.toml` configuration (PEP 517/518) - `python -m build` - Build source and wheel distributions - `python -m build --sdist` - Build source distribution only - `python -m build --wheel` - Build wheel distribution only - `pip install -e .` - Install in development mode - Package entry points defined in pyproject.toml for SoS converters - Old `setup.py` kept as `setup.py.old` for reference ## Architecture Overview SoS Notebook is a Jupyter kernel that enables multi-language workflows within a single notebook. The architecture consists of several key components: **Core Kernel System:** - `kernel.py` - Main `SoS_Kernel` class extending `IPythonKernel`, handles cell execution and communication - `subkernel.py` - `Subkernels` class manages multiple language kernels (R, Bash, Python, etc.) - `comm_manager.py` - `SoSCommManager` handles inter-kernel communication and data exchange **Language Integration:** - Language modules (sos-bash, sos-r, etc.) provide language-specific data type understanding - `magics.py` - SoS-specific Jupyter magic commands for workflow control - `completer.py` - Tab completion for SoS syntax and cross-language variables **Workflow Execution:** - `step_executor.py` - Executes individual workflow steps - `workflow_executor.py` - Orchestrates complete workflows, includes `NotebookLoggingHandler` - Supports both interactive execution and batch workflow processing **Conversion System:** - `converter.py` - Multiple converters for different formats: - `ScriptToNotebookConverter` (sos-ipynb) - `NotebookToScriptConverter` (ipynb-sos) - `NotebookToHTMLConverter` (ipynb-html) - `NotebookToPDFConverter` (ipynb-pdf) - `NotebookToMarkdownConverter` (ipynb-md) **Testing Strategy:** - Integration tests in Docker containers simulate real Jupyter environment - Tests cover frontend interaction, magic commands, conversions, and workflows - Sample notebooks in `test/` directory provide test scenarios **Key Dependencies:** - Requires Python ≥3.7, built on jupyter ecosystem (jupyter_client, ipykernel, nbformat) - Core SoS package (sos>=0.22.0) provides workflow engine - pandas/numpy for data handling, psutil for system monitoring **Data Exchange:** The system enables seamless data transfer between kernels through SoS variable system, supporting dataframes, matrices, and other structured data types across R, Python, Bash, and other supported languages. ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to SoS Notebook Thank you for your interest in contributing to SoS Notebook! This document provides comprehensive guidelines for setting up your development environment, making changes, and submitting contributions. ## Table of Contents - [Prerequisites](#prerequisites) - [Development Setup](#development-setup) - [Development Workflow](#development-workflow) - [Code Quality](#code-quality) - [Testing](#testing) - [Building and Releasing](#building-and-releasing) - [Submitting Changes](#submitting-changes) - [Project Structure](#project-structure) - [Troubleshooting](#troubleshooting) ## Prerequisites ### Required Software 1. **Python 3.8+** - SoS Notebook requires Python 3.8 or later 2. **[uv](https://github.com/astral-sh/uv)** - Fast Python package installer and resolver ```bash # Install uv (recommended method) curl -LsSf https://astral.sh/uv/install.sh | sh # Or via pip pip install uv # Or via homebrew (macOS) brew install uv ``` 3. **Git** - For version control 4. **Docker** (optional) - For running the full test suite ### Verify Installation ```bash python --version # Should be 3.8+ uv --version # Should be 0.4.0+ git --version ``` ## Development Setup ### 1. Clone the Repository ```bash git clone https://github.com/vatlab/sos-notebook.git cd sos-notebook ``` ### 2. Set Up Development Environment We use `invoke` for task automation. The `dev-setup` command will: - Create a virtual environment with uv - Install the package in development mode - Install all development dependencies - Set up pre-commit hooks ```bash # One-command setup invoke dev-setup # Activate the virtual environment source .venv/bin/activate ``` ### 3. Manual Setup (Alternative) If you prefer manual setup: ```bash # Create virtual environment uv venv # Activate virtual environment source .venv/bin/activate # Linux/macOS # or .venv\Scripts\activate # Windows # Install package in development mode with dependencies uv pip install -e . uv sync --dev # Install pre-commit hooks pre-commit install ``` ### 4. Verify Setup ```bash # List available development tasks invoke --list # Run a quick check invoke format --check invoke lint ``` ## Development Workflow ### Daily Development Commands ```bash # Activate virtual environment (if not already active) source .venv/bin/activate # Make your changes... # Format code invoke format # Check and fix linting issues invoke lint --fix # Run tests invoke test # Run all quality checks invoke check ``` ### Task Automation with Invoke We use [invoke](http://www.pyinvoke.org/) for development task automation. All tasks are defined in `tasks.py`. #### Core Tasks ```bash # Environment management invoke dev-setup # Complete development setup invoke venv-create # Create virtual environment invoke uv-sync # Sync dependencies invoke uv-lock # Update lock file # Code quality invoke format # Format code with ruff invoke format --check # Check formatting without changes invoke lint # Run linting invoke lint --fix # Run linting with auto-fix invoke check # Run all quality checks (format, lint, test) # Testing invoke test # Run tests (skips Docker/selenium tests) invoke test --verbose # Verbose test output invoke test --coverage # Run tests with coverage report invoke test-docker # Full test suite in Docker (CI environment) # Building invoke build # Build source and wheel distributions invoke build --clean # Clean and rebuild invoke clean # Clean build artifacts invoke install # Install package in development mode # Release invoke release-check # Comprehensive pre-release checks ``` #### Advanced Tasks ```bash # Run specific test paths invoke test --path="test/test_magics.py" # Generate coverage report invoke test --coverage # Clean everything invoke clean --all ``` ## Code Quality ### Code Formatting and Linting We use [ruff](https://github.com/astral-sh/ruff) for both code formatting and linting. Ruff is extremely fast and replaces multiple tools (yapf, flake8, isort, etc.). #### Configuration Ruff is configured in `pyproject.toml`: ```toml [tool.ruff] target-version = "py38" line-length = 88 [tool.ruff.lint] select = ["E", "W", "F", "I", "B", "C4", "UP"] ignore = ["E501"] # line too long (handled by formatter) [tool.ruff.format] quote-style = "double" indent-style = "space" ``` #### Running Code Quality Checks ```bash # Format code invoke format # Check formatting without making changes invoke format --check # Run linting invoke lint # Auto-fix linting issues invoke lint --fix # Run all quality checks invoke check ``` ### Pre-commit Hooks Pre-commit hooks are automatically installed during `invoke dev-setup`. They run on every commit to ensure code quality: - Code formatting with ruff - Linting with ruff - Basic file checks (trailing whitespace, file size, etc.) To run pre-commit manually: ```bash pre-commit run --all-files ``` ## Testing ### Test Structure - `test/` - Main test directory - `test/test_*.py` - Unit and integration tests - Docker-based integration tests simulate real Jupyter environments ### Running Tests ```bash # Quick tests (skip Docker/selenium dependencies) invoke test # Verbose output invoke test --verbose # Run with coverage invoke test --coverage # Run specific test file invoke test --path="test/test_magics.py" # Full test suite in Docker (as run in CI) invoke test-docker ``` ### Test Dependencies Some tests require additional dependencies: - **Selenium** - For frontend integration tests - **Docker** - For containerized testing environment - **ImageMagick** - For image processing tests These are automatically skipped if not available, with appropriate skip messages. ### Writing Tests - Follow pytest conventions - Use the `NotebookTest` base class for kernel tests - Mock external dependencies when possible - Add integration tests for new features ## Building and Releasing ### Modern Build System SoS Notebook uses a modern Python build system based on: - `pyproject.toml` for project configuration (PEP 517/518) - `uv` for dependency management - `build` module for creating distributions ### Building Distributions ```bash # Build both source and wheel distributions invoke build # Clean build artifacts first invoke build --clean # Manual build (alternative) uv run python -m build ``` ### Release Preparation Before releasing: ```bash # Run comprehensive pre-release checks invoke release-check # This runs: # 1. All quality checks (format, lint, test) # 2. Clean build # 3. Distribution verification ``` ### Version Management 1. Update version in `pyproject.toml` 2. Update version in `src/sos_notebook/_version.py` 3. Update `CHANGELOG.md` (if exists) 4. Run `invoke release-check` 5. Create git tag and push ## Submitting Changes ### Pull Request Process 1. **Fork the repository** on GitHub 2. **Create a feature branch** from `master`: ```bash git checkout -b feature/your-feature-name ``` 3. **Make your changes** following the development workflow 4. **Run quality checks**: ```bash invoke check ``` 5. **Commit your changes** with descriptive messages: ```bash git add . git commit -m "Add feature: description of changes" ``` 6. **Push to your fork**: ```bash git push origin feature/your-feature-name ``` 7. **Create a Pull Request** on GitHub ### Commit Message Guidelines - Use clear, descriptive commit messages - Start with a verb in present tense ("Add", "Fix", "Update", "Remove") - Limit first line to 72 characters - Reference issues when applicable: "Fix #123: description" ### Pull Request Guidelines - **Title**: Clear, descriptive title - **Description**: Explain what changes were made and why - **Testing**: Describe how the changes were tested - **Documentation**: Update documentation if needed - **Breaking Changes**: Clearly mark any breaking changes ## Project Structure ``` sos-notebook/ ├── src/sos_notebook/ # Main package source │ ├── __init__.py │ ├── kernel.py # Main SoS kernel │ ├── subkernel.py # Multi-language kernel management │ ├── magics.py # Jupyter magic commands │ ├── converter.py # Notebook conversion utilities │ └── ... ├── test/ # Test suite │ ├── test_kernel.py │ ├── test_magics.py │ └── ... ├── development/ # Docker development environment ├── tasks.py # Invoke task definitions ├── pyproject.toml # Project configuration ├── uv.lock # Dependency lock file ├── README.md # Project overview ├── CONTRIBUTING.md # This file └── CLAUDE.md # Claude Code development guide ``` ### Key Files - **`pyproject.toml`** - Modern Python project configuration - **`tasks.py`** - Development task automation with invoke - **`uv.lock`** - Locked dependency versions for reproducible builds - **`CLAUDE.md`** - Development guidance for Claude Code AI assistant ## Troubleshooting ### Common Issues #### Virtual Environment Issues ```bash # Remove and recreate virtual environment rm -rf .venv invoke venv-create source .venv/bin/activate invoke uv-sync ``` #### Dependency Issues ```bash # Update dependencies invoke uv-sync # Regenerate lock file invoke uv-lock ``` #### Import Errors ```bash # Reinstall package in development mode uv pip install -e . ``` #### Test Failures ```bash # Run tests with verbose output invoke test --verbose # Run specific test file invoke test --path="test/test_specific.py" # Skip Docker tests if Docker isn't available invoke test # Docker tests are skipped automatically ``` ### Performance Issues - **Slow dependency resolution**: uv is much faster than pip, but if you experience issues, try clearing cache: `uv cache clean` - **Slow tests**: Use `invoke test` instead of `invoke test-docker` for faster iteration ### Getting Help 1. **Check existing issues**: [GitHub Issues](https://github.com/vatlab/sos-notebook/issues) 2. **Search documentation**: [SoS Documentation](https://vatlab.github.io/sos-docs/) 3. **Create a new issue**: Include: - Python version (`python --version`) - uv version (`uv --version`) - Operating system - Full error message - Steps to reproduce ## Development Philosophy - **Modern tooling**: We use the latest and fastest Python development tools - **Developer experience**: Commands should be simple and fast - **Code quality**: Automated formatting and linting - **Testing**: Comprehensive tests including Docker-based integration tests - **Documentation**: Clear documentation for users and developers Thank you for contributing to SoS Notebook! 🎉 ================================================ FILE: LICENSE ================================================ BSD 3-Clause License Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: MANIFEST.in ================================================ include LICENSE include README.md include pyproject.toml recursive-include src *.py *.js *.tpl *.png *.css *.j2 *.json recursive-include test *.vim *.py *.js prune */.sos global-exclude *~ global-exclude *.bak global-exclude *.pyc global-exclude *.pyo global-exclude .ipynb_checkpoints ================================================ FILE: README.md ================================================ [![Anaconda-Server Badge](https://anaconda.org/conda-forge/sos-notebook/badges/version.svg)](https://anaconda.org/conda-forge/sos-notebook) [![PyPI version](https://badge.fury.io/py/sos-notebook.svg)](https://badge.fury.io/py/sos-notebook) [![DOI](https://zenodo.org/badge/105826659.svg)](https://zenodo.org/badge/latestdoi/105826659) [![Build Status](https://travis-ci.org/vatlab/sos-notebook.svg?branch=master)](https://travis-ci.org/vatlab/sos-notebook) [![Build status](https://ci.appveyor.com/api/projects/status/nkyw7f4o97u7jl1l/branch/master?svg=true)](https://ci.appveyor.com/project/BoPeng/sos-notebook/branch/master) ## ⚠️ Deprecation Notice **The classic Jupyter notebook interface support for SoS Notebook has been deprecated.** This package no longer provides JavaScript extensions or frontend functionality for the classic Jupyter notebook interface. All frontend features have been migrated to JupyterLab and are available through [jupyterlab-sos](https://github.com/vatlab/jupyterlab-sos). **This package is still required** as a backend dependency for jupyterlab-sos and contains the SoS kernel, magics, notebook converters (HTML, PDF, Markdown), and other core functionality. However, **for the best SoS experience, please use JupyterLab with the jupyterlab-sos extension**. For more information, see the [JupyterLab SoS extension](https://github.com/vatlab/jupyterlab-sos). # SoS Notebook SoS Notebook is a [Jupyter](https://jupyter.org/) kernel that allows the use of multiple kernels in one Jupyter notebook. Using language modules that understand datatypes of underlying languages (modules [sos-bash](https://github.com/vatlab/sos-bash), [sos-r](https://github.com/vatlab/sos-r), [sos-matlab](https://github.com/vatlab/sos-matlab), etc), SoS Notebook allows data exchange among live kernels of supported languages. SoS Notebook also extends the Jupyter frontend and adds a console panel for the execution of scratch commands and display of intermediate results and progress information, and a number of shortcuts and magics to facilitate interactive data analysis. All these features have been ported to JupyterLab, either in the sos extension [jupyterlab-sos](https://github.com/vatlab/jupyterlab-sos) or contributed to JupyterLab as core features. SoS Notebook also serves as the IDE for the [SoS Workflow](https://github.com/vatlab/sos) that allows the development and execution of workflows from Jupyter notebooks. This not only allows easy translation of scripts developed for interactive data analysis to workflows running in containers and remote systems, but also allows the creation of scientific workflows in a format with narratives, sample input and output. SoS Notebook is part of the SoS suite of tools. Please refer to the [SoS Homepage](http://vatlab.github.io/SoS/) for details about SoS, and [this page](https://vatlab.github.io/sos-docs/notebook.html#content) for documentations and examples on SoS Notebook. If a language that you are using is not yet supported by SoS, please [submit a ticket](https://github.com/vatlab/sos-notebook/issues), or consider adding a language module by yourself following the guideline [here](https://vatlab.github.io/sos-docs/doc/user_guide/language_module.html). ## Installation ### For Users Install from PyPI: ```bash pip install sos-notebook ``` Install from conda-forge: ```bash conda install -c conda-forge sos-notebook ``` ### For Developers SoS Notebook uses modern Python packaging and development tools. See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed development setup instructions. Quick development setup: ```bash # Prerequisites: Python 3.8+ and uv (https://github.com/astral-sh/uv) git clone https://github.com/vatlab/sos-notebook.git cd sos-notebook invoke dev-setup # Sets up virtual environment and dependencies source .venv/bin/activate ``` ## Development This project uses modern Python development tools: - **[uv](https://github.com/astral-sh/uv)** for fast dependency management and virtual environments - **[ruff](https://github.com/astral-sh/ruff)** for linting and code formatting - **[invoke](http://www.pyinvoke.org/)** for task automation - **[pytest](https://pytest.org/)** for testing - **Modern build system** with `pyproject.toml` (PEP 517/518) ### Quick Commands ```bash # Set up development environment invoke dev-setup # Run quality checks invoke check # Run all checks (format, lint, test) invoke format # Format code with ruff invoke lint --fix # Lint and auto-fix issues invoke test # Run tests # Build and release invoke build # Build distributions invoke release-check # Comprehensive pre-release checks ``` For detailed contribution guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md). ## Testing The project includes comprehensive tests that run in Docker containers to simulate real Jupyter environments: ```bash invoke test # Quick tests (skip Docker/selenium) invoke test-docker # Full test suite in Docker (as in CI) ``` ## License This project is licensed under the 3-clause BSD License. ================================================ FILE: development/README.md ================================================ 1. Update docker images docker-compose build --no-cache 2. push docker images to dockerhub docker push mdabioinfo/eg_sshd docker push mdabioinfo/sos_notebook_test ================================================ FILE: development/docker-compose.yml ================================================ version: '3' services: sos-notebook: build: context: ./sos_notebook_test image: mdabioinfo/sos_notebook_test:latest restart: "no" shm_size: 8gb networks: - sosnet sos: build: context: ./eg_sshd image: mdabioinfo/eg_sshd:latest hostname: sos restart: always networks: - sosnet networks: sosnet: external: true ================================================ FILE: development/eg_sshd/.ssh/id_rsa ================================================ -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAwOw86WfZeC8AAkhgfr0PMCqEtwTXqK4q8hOuvruQa9TN/dcG kUFukzfJ0XAUz4anw16PMnwfOuvwk9ya5Hz1UwGjcu+l2AxSWeG+KJkpbBtnOls9 ELrE+7pwOurVolP1Qevf6y2vfJNGN78uNuiupp/hJ5sSWqashMoqqqsT7631d+9C PdrzOWZd3TL1CFl8uNkCWt8i7vtPhRycrS9Wkpmdu1CflJbgab9vfn02jeY4Cx2z vToQz3AMmt3QnuKf2DEHC+QeLDayF0TgOhuqLvjl1gP+Hm4GWWvHCiPJBQ4idMm0 Z+ujR4uafuIIZ5u3N3O6z45SDi2JorqzpYmsywIDAQABAoIBAQCMSHv2YQxyZwLD pit8nS85IAHHL589yf/ybTuI98yJjIGJTl05LHIiXNPFFpIbYVgGKXFJDZaL+trC Ogzrjq25AR0AS6C1nCgZsZvb25uSP87tUUDzNExem3BWd0KHOjPCDqmRUnQjytep W7xYMxQkl2darFlJT59tI7Coz6O8iOUTYdTJtKfaQEC4zE5oTQ3AxqaWpiPc4i9/ /kEGYDbFitz6id7zWBS6cYGmvIhsCUwVNMany+R0QFGP6AqSv0knp4vvd1IMzDUO q1mt8OyZ/ZKkaw8sA2UACkdxnp+iejNiE64tmJVGxPf5J4FuNoU25Ecwm9cnvGPv MlOiYVMBAoGBAP7gvztmnrhYkhTZB7CfcyRlH1pWRfznLlQU3E2U094/rnjck/av atdPcko/UoMjwCZ4dVgZFBkVYuPhlELPiHfs2OGEcSry+GhWgguZoSCKsE+vaZuN kA75Eb2GEQCklN1LX+0x2cfux0CbYUqODoT1VNXJpwpqaSWiQXgR5giBAoGBAMHF qonSbizig/VsVhM8smtl+3dPFkpl/fulo4+Xuu29YxYDtR1quUeaPQH2Zx+lQJmb +o4Jp1P/9+4eulXYn/nCLkOFRaKNb7i0rWfHaqkgjUIQVSSSwUOR14ivvdW1oBKN Gvsqy5psxrM2dDHphGkwh8EpGwov2/Fo5bsU1a9LAoGBAJfJVnlUms9kB9MckKTR wGt7QVm2KUX8ky2FotEdAbPIrunRStjNDM6exIyM+2GXx9XhRNirTrnFb7gQXhAP sdDhnyNmkVKnkeHpKtcnrbpIfclmyHjXrGQOVk9M6RE98l17huwmFPEpNUY3gpA4 21K5G8WZqr3cMzQzVdPgrOKBAoGAcX4F2b1ffHibk3aFn7TQR6kutP2kb6T3Mpoc h3D2MmLXk0BOp1En/fEvxGN+mQFgKdg601CCKeflXhmvR7KeWFnMYQ3A8Glow0VH v14EcdS4B7arN8Wg3qOgGtXcGTzM6bCt2eiB4gvOAY9mVQmR3U5oZNFfngLUDrxC ueWFFqsCgYBFJe38Kby6SpaXpaWDF9rNE8a4QkYXi3N7TDUUYePJ4LbDhfff1oty 6x8SkbFqR0Bb4NQa1fRCozjhlFqQgZvRHkDNqRaTPUNZ1AtTBElVCgWNQKPFL1s7 bUSgkIBztPFI7wGUvUViAFQsFOPSgArkQq7feGHBHrzY/Xu6aXxb4g== -----END RSA PRIVATE KEY----- ================================================ FILE: development/eg_sshd/.ssh/id_rsa.pub ================================================ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA7DzpZ9l4LwACSGB+vQ8wKoS3BNeoriryE66+u5Br1M391waRQW6TN8nRcBTPhqfDXo8yfB866/CT3JrkfPVTAaNy76XYDFJZ4b4omSlsG2c6Wz0QusT7unA66tWiU/VB69/rLa98k0Y3vy426K6mn+EnmxJapqyEyiqqqxPvrfV370I92vM5Zl3dMvUIWXy42QJa3yLu+0+FHJytL1aSmZ27UJ+UluBpv29+fTaN5jgLHbO9OhDPcAya3dCe4p/YMQcL5B4sNrIXROA6G6ou+OXWA/4ebgZZa8cKI8kFDiJ0ybRn66NHi5p+4ghnm7c3c7rPjlIOLYmiurOliazL root@9740cb7bc090 ================================================ FILE: development/eg_sshd/.ssh/known_hosts ================================================ |1|ifI8r7TTuuavRoHPCWi/zRhT7Xg=|cJEU9IuPFryWuUqX7WDDGFBSwxU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= |1|yCnH65n1ZVw+qPTMEqT56AEZT4M=|2pj5jSP74KW6M1eQZYG0j8V2B8s= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= |1|bTROh2skcuquL75pSr4wX75zvJE=|nLhgDUKf0rdGtDyc0DkYeb4eId8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= |1|ecfY0BlbNYKAPb3UsJLmuDx20oQ=|3JKsJ85O666utGbMe0BTGw0sG98= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= ================================================ FILE: development/eg_sshd/Dockerfile ================================================ FROM python:3.6 RUN apt-get update && apt-get install -y openssh-server rsync task-spooler RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile RUN [ -d /root/.ssh ] || mkdir -p /root/.ssh # install sos on the remote host RUN pip install spyder jedi notebook nbconvert nbformat pyyaml psutil tqdm RUN pip install fasteners pygments ipython ptpython networkx pydotplus RUN SHA=$(git ls-remote https://github.com/vatlab/sos.git -t master) RUN SHA=$SHA git clone http://github.com/vatlab/sos sos RUN cd sos && pip install . -U RUN echo "export TS_SLOTS=10" >> /root/.bash_profile COPY ./.ssh/id_rsa.pub /root/.ssh/authorized_keys EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] ================================================ FILE: development/install_sos_notebook.sh ================================================ #!/usr/bin/bash pip install . -U python -m sos_notebook.install # jupyter notebook ================================================ FILE: development/sos_notebook_test/.ssh/id_rsa ================================================ -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAwOw86WfZeC8AAkhgfr0PMCqEtwTXqK4q8hOuvruQa9TN/dcG kUFukzfJ0XAUz4anw16PMnwfOuvwk9ya5Hz1UwGjcu+l2AxSWeG+KJkpbBtnOls9 ELrE+7pwOurVolP1Qevf6y2vfJNGN78uNuiupp/hJ5sSWqashMoqqqsT7631d+9C PdrzOWZd3TL1CFl8uNkCWt8i7vtPhRycrS9Wkpmdu1CflJbgab9vfn02jeY4Cx2z vToQz3AMmt3QnuKf2DEHC+QeLDayF0TgOhuqLvjl1gP+Hm4GWWvHCiPJBQ4idMm0 Z+ujR4uafuIIZ5u3N3O6z45SDi2JorqzpYmsywIDAQABAoIBAQCMSHv2YQxyZwLD pit8nS85IAHHL589yf/ybTuI98yJjIGJTl05LHIiXNPFFpIbYVgGKXFJDZaL+trC Ogzrjq25AR0AS6C1nCgZsZvb25uSP87tUUDzNExem3BWd0KHOjPCDqmRUnQjytep W7xYMxQkl2darFlJT59tI7Coz6O8iOUTYdTJtKfaQEC4zE5oTQ3AxqaWpiPc4i9/ /kEGYDbFitz6id7zWBS6cYGmvIhsCUwVNMany+R0QFGP6AqSv0knp4vvd1IMzDUO q1mt8OyZ/ZKkaw8sA2UACkdxnp+iejNiE64tmJVGxPf5J4FuNoU25Ecwm9cnvGPv MlOiYVMBAoGBAP7gvztmnrhYkhTZB7CfcyRlH1pWRfznLlQU3E2U094/rnjck/av atdPcko/UoMjwCZ4dVgZFBkVYuPhlELPiHfs2OGEcSry+GhWgguZoSCKsE+vaZuN kA75Eb2GEQCklN1LX+0x2cfux0CbYUqODoT1VNXJpwpqaSWiQXgR5giBAoGBAMHF qonSbizig/VsVhM8smtl+3dPFkpl/fulo4+Xuu29YxYDtR1quUeaPQH2Zx+lQJmb +o4Jp1P/9+4eulXYn/nCLkOFRaKNb7i0rWfHaqkgjUIQVSSSwUOR14ivvdW1oBKN Gvsqy5psxrM2dDHphGkwh8EpGwov2/Fo5bsU1a9LAoGBAJfJVnlUms9kB9MckKTR wGt7QVm2KUX8ky2FotEdAbPIrunRStjNDM6exIyM+2GXx9XhRNirTrnFb7gQXhAP sdDhnyNmkVKnkeHpKtcnrbpIfclmyHjXrGQOVk9M6RE98l17huwmFPEpNUY3gpA4 21K5G8WZqr3cMzQzVdPgrOKBAoGAcX4F2b1ffHibk3aFn7TQR6kutP2kb6T3Mpoc h3D2MmLXk0BOp1En/fEvxGN+mQFgKdg601CCKeflXhmvR7KeWFnMYQ3A8Glow0VH v14EcdS4B7arN8Wg3qOgGtXcGTzM6bCt2eiB4gvOAY9mVQmR3U5oZNFfngLUDrxC ueWFFqsCgYBFJe38Kby6SpaXpaWDF9rNE8a4QkYXi3N7TDUUYePJ4LbDhfff1oty 6x8SkbFqR0Bb4NQa1fRCozjhlFqQgZvRHkDNqRaTPUNZ1AtTBElVCgWNQKPFL1s7 bUSgkIBztPFI7wGUvUViAFQsFOPSgArkQq7feGHBHrzY/Xu6aXxb4g== -----END RSA PRIVATE KEY----- ================================================ FILE: development/sos_notebook_test/.ssh/id_rsa.pub ================================================ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDA7DzpZ9l4LwACSGB+vQ8wKoS3BNeoriryE66+u5Br1M391waRQW6TN8nRcBTPhqfDXo8yfB866/CT3JrkfPVTAaNy76XYDFJZ4b4omSlsG2c6Wz0QusT7unA66tWiU/VB69/rLa98k0Y3vy426K6mn+EnmxJapqyEyiqqqxPvrfV370I92vM5Zl3dMvUIWXy42QJa3yLu+0+FHJytL1aSmZ27UJ+UluBpv29+fTaN5jgLHbO9OhDPcAya3dCe4p/YMQcL5B4sNrIXROA6G6ou+OXWA/4ebgZZa8cKI8kFDiJ0ybRn66NHi5p+4ghnm7c3c7rPjlIOLYmiurOliazL root@9740cb7bc090 ================================================ FILE: development/sos_notebook_test/.ssh/known_hosts ================================================ |1|ifI8r7TTuuavRoHPCWi/zRhT7Xg=|cJEU9IuPFryWuUqX7WDDGFBSwxU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= |1|yCnH65n1ZVw+qPTMEqT56AEZT4M=|2pj5jSP74KW6M1eQZYG0j8V2B8s= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= |1|bTROh2skcuquL75pSr4wX75zvJE=|nLhgDUKf0rdGtDyc0DkYeb4eId8= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= |1|ecfY0BlbNYKAPb3UsJLmuDx20oQ=|3JKsJ85O666utGbMe0BTGw0sG98= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBV5pS+Um9ke91Rmq1E83GnlS2EdvwpELdU563V8O9Dc9/DMmliPoaWO/oLLW5tz1y2hu9e7ISZytvaeHUnTVg8= ================================================ FILE: development/sos_notebook_test/Dockerfile ================================================ # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. # tag created in March 2019 FROM jupyter/r-notebook:83ed2c63671f MAINTAINER Bo Peng USER root # Tools RUN apt-get update && apt-get install -y graphviz texlive-xetex texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended libssl1.0.0 libssl-dev libappindicator3-1 libxtst6 libgmp3-dev software-properties-common rsync ssh USER jovyan RUN pip install bash_kernel selenium nose RUN python -m bash_kernel.install --user RUN pip install markdown wand graphviz imageio pillow nbformat coverage codacy-coverage pytest pytest-cov python-coveralls RUN conda install -y feather-format -c conda-forge RUN conda install -c r r-arrow r-dplyr ## trigger rerun for sos updates RUN DUMMY=$(git ls-remote https://github.com/vatlab/sos.git -t master) RUN DUMMY=${DUMMY} pip install git+https://github.com/vatlab/sos.git RUN pip install sos-r sos-python sos-bash --upgrade RUN pip install ipython -U USER root RUN curl https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -o /chrome.deb RUN dpkg -i /chrome.deb || apt-get install -yf RUN rm /chrome.deb RUN wget -q "https://chromedriver.storage.googleapis.com/76.0.3809.126/chromedriver_linux64.zip" -O /tmp/chromedriver.zip \ && unzip /tmp/chromedriver.zip -d /usr/bin/ \ && rm /tmp/chromedriver.zip ENV DISPLAY=:99 RUN ln -s /usr/bin/chromedriver && chmod 777 /usr/bin/chromedriver RUN chmod 777 /home/jovyan/.local/share/jupyter/ COPY ./.ssh /root/.ssh RUN chmod 700 /root/.ssh RUN chmod 600 /root/.ssh/* COPY ./.ssh /home/jovyan/.ssh RUN chmod 700 /home/jovyan/.ssh RUN chmod 600 /home/jovyan/.ssh/* USER jovyan ================================================ FILE: pyproject.toml ================================================ [build-system] requires = ["setuptools>=61.0", "wheel"] build-backend = "setuptools.build_meta" [project] name = "sos-notebook" version = "0.24.7" description = "Script of Scripts (SoS) kernel and backend for Jupyter - backend dependency for jupyterlab-sos" readme = "README.md" requires-python = ">=3.8" license = {text = "3-clause BSD"} authors = [ {name = "Bo Peng", email = "Bo.Peng@bcm.edu"}, ] maintainers = [ {name = "Bo Peng", email = "Bo.Peng@bcm.edu"}, ] keywords = ["jupyter", "notebook", "workflow", "reproducible-research", "multi-language"] classifiers = [ "Development Status :: 4 - Beta", "Environment :: Console", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Operating System :: POSIX :: Linux", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", ] dependencies = [ "jupyter_client>=8.0.0", "jupyter_core", "sos>=0.22.0", "nbformat", "nbconvert>=6.0.1", "ipython", "ipykernel>=6.18.0", # 6.18.0 and newer has a new comm manager interface "jinja2", # https://github.com/spatialaudio/nbsphinx/issues/563 "notebook>=5.0.0", "tabulate", "pandas", "numpy", "psutil", ] [project.optional-dependencies] dev = [ "invoke>=2.0", "pre-commit", "pytest>=6.0", "pytest-cov", "ruff", "build", ] [project.urls] Homepage = "https://github.com/vatlab/SOS" Repository = "https://github.com/vatlab/sos-notebook" Documentation = "https://vatlab.github.io/sos-docs/notebook.html" "Bug Tracker" = "https://github.com/vatlab/sos-notebook/issues" [project.entry-points.sos_converters] "sos-ipynb" = "sos_notebook.converter:ScriptToNotebookConverter" "ipynb-sos" = "sos_notebook.converter:NotebookToScriptConverter" "ipynb-html" = "sos_notebook.converter:NotebookToHTMLConverter" "ipynb-pdf" = "sos_notebook.converter:NotebookToPDFConverter" "ipynb-md" = "sos_notebook.converter:NotebookToMarkdownConverter" "ipynb-ipynb" = "sos_notebook.converter:NotebookToNotebookConverter" [tool.setuptools] zip-safe = false [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.package-data] "*" = ["*.js", "*.tpl", "*.png", "*.css", "*.j2", "*.json"] [tool.uv] dev-dependencies = [ "invoke>=2.0", "pre-commit", "pytest>=6.0", "pytest-cov", "ruff", "build", "mypy>=1.14.1", "types-psutil>=6.1.0.20241221", "pandas-stubs>=2.0.2.230605", "types-tabulate>=0.9.0.20241207", "papermill>=2.6.0", "sos-papermill>=0.2.1", "testpath>=0.6.0", ] [tool.ruff] target-version = "py38" line-length = 88 exclude = [ ".git", ".venv", "__pycache__", "build", "dist", "*.egg-info", ] [tool.ruff.lint] select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade ] ignore = [ "E501", # line too long (handled by formatter) ] [tool.ruff.format] quote-style = "double" indent-style = "space" skip-magic-trailing-comma = false line-ending = "auto" [tool.mypy] python_version = "3.9" warn_return_any = true warn_unused_configs = true disallow_untyped_defs = false ignore_missing_imports = true no_implicit_optional = true warn_redundant_casts = true warn_unused_ignores = true warn_no_return = true check_untyped_defs = false # Ignore specific modules that don't have type hints [[tool.mypy.overrides]] module = [ "sos.*", "selenium.*", "ipykernel.*", "papermill.*", "IPython.*", ] ignore_missing_imports = true ignore_errors = true ================================================ FILE: setup.py.old ================================================ #!/usr/bin/env python # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import os import sys from setuptools import find_packages, setup _py_ver = sys.version_info if _py_ver.major == 2 or (_py_ver.major == 3 and (_py_ver.minor, _py_ver.micro) < (6, 0)): raise SystemError( 'sos-notebook requires Python 3.6 or higher. Please upgrade your Python {}.{}.{}.' .format(_py_ver.major, _py_ver.minor, _py_ver.micro)) # obtain version of SoS with open('src/sos_notebook/_version.py') as version: for line in version: if line.startswith('__version__'): __version__ = eval(line.split('=')[1]) break kernel_json = { "argv": ["python", "-m", "sos_notebook.kernel", "-f", "{connection_file}"], "display_name": "SoS", "language": "sos", } CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) def get_long_description(): with open(os.path.join(CURRENT_DIR, "README.md"), "r") as ld_file: return ld_file.read() setup( name="sos-notebook", version=__version__, description='Script of Scripts (SoS): an interactive, cross-platform, and cross-language workflow system for reproducible data analysis', long_description=get_long_description(), long_description_content_type="text/markdown", author='Bo Peng', url='https://github.com/vatlab/SOS', author_email='Bo.Peng@bcm.edu', maintainer='Bo Peng', maintainer_email='Bo.Peng@bcm.edu', license='3-clause BSD', include_package_data=True, classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console', 'License :: OSI Approved :: BSD License', 'Natural Language :: English', 'Operating System :: POSIX :: Linux', 'Operating System :: MacOS :: MacOS X', 'Operating System :: Microsoft :: Windows', 'Intended Audience :: Information Technology', 'Intended Audience :: Science/Research', 'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: Implementation :: CPython', ], zip_safe=False, packages=find_packages('src'), package_dir={'': 'src'}, python_requires='>=3.7', install_requires=[ 'jupyter_client>=8.0.0', 'jupyter_core', 'sos>=0.22.0', 'nbformat', 'nbconvert>=6.0.1', 'ipython', # 6.18.0 and newer has a new comm manager interface 'ipykernel>=6.18.0', # https://github.com/spatialaudio/nbsphinx/issues/563 'jinja2', 'notebook>=5.0.0', 'tabulate', # 'markdown', 'pandas', 'numpy', # 'selenium', # 'requests', # 'pytest', 'psutil', ], entry_points=''' [sos_converters] sos-ipynb = sos_notebook.converter:ScriptToNotebookConverter ipynb-sos = sos_notebook.converter:NotebookToScriptConverter ipynb-html = sos_notebook.converter:NotebookToHTMLConverter ipynb-pdf = sos_notebook.converter:NotebookToPDFConverter ipynb-md = sos_notebook.converter:NotebookToMarkdownConverter ipynb-ipynb = sos_notebook.converter:NotebookToNotebookConverter ''') ================================================ FILE: src/sos_notebook/__init__.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. from ._version import __version__ # suppress warning _ = __version__ ================================================ FILE: src/sos_notebook/_version.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import sys __all__ = ["__version__", "SOS_FULL_VERSION"] _py_ver = sys.version_info if _py_ver.major == 2 or ( _py_ver.major == 3 and (_py_ver.minor, _py_ver.micro) < (7, 0) ): raise SystemError( f"SOS requires Python 3.7 or higher. Please upgrade your Python {_py_ver.major}.{_py_ver.minor}.{_py_ver.micro}." ) # version of the SoS language __sos_version__ = "1.0" # version of the sos command __version__ = "0.24.7" __py_version__ = f"{_py_ver.major}.{_py_ver.minor}.{_py_ver.micro}" # SOS_FULL_VERSION = ( f"{__version__} for Python {_py_ver.major}.{_py_ver.minor}.{_py_ver.micro}" ) SOS_COPYRIGHT = f"""SoS {__version__} : Copyright (c) 2016 Bo Peng""" SOS_CONTACT = """Please visit http://github.com/vatlab/SOS for more information.""" ================================================ FILE: src/sos_notebook/comm_manager.py ================================================ """Base class to manage comms""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import logging import time import traitlets import traitlets.config from ipykernel.comm.manager import CommManager logger = logging.getLogger("soskernel.comm") class CommProxyHandler: def __init__(self, KC, sos_kernel): self._KC = KC self._sos_kernel = sos_kernel def handle_msg(self, msg): self._KC.shell_channel.send(msg) # wait for subkernel to handle comm_msg_started = False comm_msg_ended = False while not (comm_msg_started and comm_msg_ended): while self._KC.iopub_channel.msg_ready(): sub_msg = self._KC.iopub_channel.get_msg() if sub_msg["header"]["msg_type"] == "status": if sub_msg["content"]["execution_state"] == "busy": comm_msg_started = True elif ( comm_msg_started and sub_msg["content"]["execution_state"] == "idle" ): comm_msg_ended = True continue self._sos_kernel.session.send(self._sos_kernel.iopub_socket, sub_msg) time.sleep(0.001) class SoSCommManager(CommManager): """This comm manager will replace the system default comm manager. When a comm is requested, it will return a `CommProxyHandler` instead of a real comm if the comm is created by the subkerel. """ kernel = traitlets.Instance("sos_notebook.kernel.SoS_Kernel") def __init__(self, **kwargs): super().__init__(**kwargs) self._forwarders = {} def register_subcomm(self, comm_id, KC, sos_kernel): self._forwarders[comm_id] = CommProxyHandler(KC, sos_kernel) def get_comm(self, comm_id): try: return self.comms[comm_id] except Exception: if comm_id in self._forwarders: # self._sos_kernel.start_forwarding_ioPub() return self._forwarders[comm_id] self.log.warning("No such comm: %s", comm_id) if self.log.isEnabledFor(logging.DEBUG): # don't create the list of keys if debug messages aren't enabled self.log.debug("Current comms: %s", list(self.comms.keys())) ================================================ FILE: src/sos_notebook/completer.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import glob import os import rlcompleter from sos.utils import env from .magics import SoS_Magics def last_valid(line): text = line for char in (" ", "\t", '"', "'", "=", "("): if text.endswith(char): text = "" elif char in text: text = text.rsplit(char, 1)[-1] return text class SoS_MagicsCompleter: def __init__(self, kernel): self.kernel = kernel def get_completions(self, line): text = last_valid(line) if not text.strip(): if line.startswith("%get"): return text, [ x for x in env.sos_dict.keys() if x not in self.kernel.original_keys and not x.startswith("_") ] if any(line.startswith(x) for x in ("%use", "%with", "%shutdown")): return text, ["SoS"] + list(self.kernel.supported_languages.keys()) return None if text.startswith("%") and line.startswith(text): return text, [ "%" + x + " " for x in SoS_Magics.names if x.startswith(text[1:]) ] if any(line.startswith(x) for x in ("%use", "%with", "%shutdown")): return text, [ x for x in self.kernel.supported_languages.keys() if x.startswith(text) ] if line.startswith("%get "): return text, [ x for x in env.sos_dict.keys() if x.startswith(text) and x not in self.kernel.original_keys and not x.startswith("_") ] return None class SoS_PathCompleter: """PathCompleter.. The problem with ptpython's path completor is that it only matched 'text_before_cursor', which would not match cases such as %cd ~/, which we will need.""" def __init__(self): pass def get_completions(self, line): text = last_valid(line) if not text.strip(): return text, glob.glob("*") matches = glob.glob(os.path.expanduser(text) + "*") if ( len(matches) == 1 and matches[0] == os.path.expanduser(text) and os.path.isdir(os.path.expanduser(text)) ): return text, glob.glob(os.path.expanduser(text) + "/*") return text, matches class PythonCompleter: def __init__(self): pass def get_completions(self, line): text = last_valid(line) completer = rlcompleter.Completer(env.sos_dict._dict) return text, completer.global_matches(text) class SoS_Completer: def __init__(self, kernel): self.completers = [ SoS_MagicsCompleter(kernel), SoS_PathCompleter(), PythonCompleter(), ] def complete_text(self, code, cursor_pos=None): if cursor_pos is None: cursor_pos = len(code) # get current line before cursor doc = code[:cursor_pos].rpartition("\n")[2] for c in self.completers: matched = c.get_completions(doc) if matched is None: continue if isinstance(matched, tuple): if matched[1]: return matched else: raise RuntimeError(f"Unrecognized completer return type {matched}") # No match return "", [] ================================================ FILE: src/sos_notebook/converter.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import argparse import os import sys import tempfile import time from importlib import metadata from io import StringIO import nbformat from nbconvert.exporters import Exporter from nbformat.v4 import new_code_cell, new_markdown_cell, new_notebook from sos.syntax import SOS_SECTION_HEADER from sos.utils import env def execute_sos_notebook( input_notebook, output_notebook=None, return_content=True, parameters=None ): # execute input notebook # if input_notebook is a string, it will be loaded. Otherwise it should be a notebook object # if output_notebook is a string, it will be used as output filename. Otherwise # the notebook will be returned. if parameters is None: parameters = {} try: from papermill.execute import execute_notebook except ImportError as e: raise RuntimeError( "Please install papermill for the use of option --execute." ) from e if not any( entrypoint.name == "sos" for entrypoint in metadata.entry_points(group="papermill.engine") ): raise RuntimeError( "Please install sos-papermill for the use of option --execute." ) if isinstance(input_notebook, str): input_file = input_notebook else: input_file = tempfile.NamedTemporaryFile( prefix="__tmp_input_nb", dir=os.getcwd(), suffix=".ipynb", delete=False ).name with open(input_file, "w") as notebook_file: nbformat.write(input_notebook, notebook_file, 4) if output_notebook is None: output_file = tempfile.NamedTemporaryFile( prefix="__tmp_output_nb", dir=os.getcwd(), suffix=".ipynb", delete=False ).name else: output_file = output_notebook execute_notebook( input_path=input_file, output_path=output_file, engine_name="sos", kernel_name="sos", parameters=parameters, ) if os.path.basename(input_file).startswith("__tmp_input_nb"): try: os.remove(input_file) except Exception as e: env.logger.warning( f"Failed to remove temporary input file {input_file}: {e}" ) if os.path.basename(output_file).startswith("__tmp_output_nb") and return_content: new_nb = nbformat.read(output_file, nbformat.NO_CONVERT) try: os.remove(output_file) except Exception as e: env.logger.warning( f"Failed to remove temporary output file {output_file}: {e}" ) return new_nb return output_file # This class cannot be defined in .kernel because it would cause some # weird problem with unittesting not able to resolve __main__ class SoS_Exporter(Exporter): def __init__(self, config=None, **kwargs): self.output_extension = ".sos" self.output_mimetype = "text/x-sos" Exporter.__init__(self, config, **kwargs) def content_from_notebook_cell(self, cell, fh, idx=0): # in non-all mode, markdown cells are ignored because they can be mistakenly # treated as markdown content of an action or script #806 if cell.cell_type != "code": return # # Non-sos code cells are also ignored fh.write( f"# cell {idx + 1}, kernel={cell.metadata['kernel']}\n{cell.source}\n\n" ) return idx def workflow_from_notebook_cell(self, cell, fh, idx=0): # in non-all mode, markdown cells are ignored because they can be mistakenly # treated as markdown content of an action or script #806 if cell.cell_type != "code": return # # Non-sos code cells are also ignored if "kernel" in cell.metadata and cell.metadata["kernel"] not in ( "sos", "SoS", None, ): return lines = cell.source.split("\n") valid_cell = False for idx, line in enumerate(lines): if valid_cell or (line.startswith("%include") or line.startswith("%from")): fh.write(line + "\n") elif SOS_SECTION_HEADER.match(line): valid_cell = True # look retrospectively for comments c = idx - 1 comment = "" while c >= 0 and lines[c].startswith("#"): comment = lines[c] + "\n" + comment c -= 1 fh.write(comment + line + "\n") # other content, namely non-%include lines before section header is ignored if valid_cell: fh.write("\n") return idx def from_notebook_node(self, nb, resources, **kwargs): # cells = nb.cells with StringIO() as fh: fh.write("#!/usr/bin/env sos-runner\n") fh.write("#fileformat=SOS1.0\n\n") for idx, cell in enumerate(cells): if "all_content" in kwargs and kwargs["all_content"]: self.content_from_notebook_cell(cell, fh, idx) else: self.workflow_from_notebook_cell(cell, fh, idx) content = fh.getvalue() resources["output_extension"] = ".sos" return content, resources # # Converter to Notebook # class ScriptToNotebookConverter: def get_parser(self): parser = argparse.ArgumentParser( "sos convert FILE.sos FILE._ipynb (or --to ipynb)", description="""Convert a sos script to Jupyter notebook (.ipynb) so that it can be opened by Jupyter notebook.""", ) return parser def convert(self, script_file, notebook_file, args=None, unknown_args=None): """ Convert a sos script to iPython notebook (.ipynb) so that it can be opened by Jupyter notebook. """ if unknown_args: raise ValueError(f"Unrecognized parameter {unknown_args}") cells = [] cell_count = 1 cell_type = "code" metainfo = {} content = [] def add_cell(cells, content, cell_type, cell_count, metainfo): # if a section consist of all report, report it as a markdown cell if not content: return if cell_type not in ("code", "markdown"): env.logger.warning(f"Unrecognized cell type {cell_type}, code assumed.") if cell_type == "markdown" and any( x.strip() and not x.startswith("#! ") for x in content ): env.logger.warning( "Markdown lines not starting with #!, code cell assumed." ) cell_type = "code" # if cell_type == "markdown": cells.append( new_markdown_cell( source="".join([x[3:] for x in content]).strip(), metadata=metainfo, ) ) else: cells.append( new_code_cell( # remove any trailing blank lines... source="".join(content).strip(), execution_count=cell_count, metadata=metainfo, ) ) with open(script_file) as script: first_block = True for line in script: if line.startswith("#") and first_block: if line.startswith("#!"): continue if line.startswith("#fileformat="): if not line[12:].startswith("SOS"): raise RuntimeError( f"{script_file} is not a SoS script according to #fileformat line." ) continue first_block = False mo = SOS_SECTION_HEADER.match(line) if mo: # get rid of empty content if not any(x.strip() for x in content): content = [] if content: # the comment should be absorbed into the next section i = len(content) - 1 while i >= 0 and content[i].startswith("#"): i -= 1 # i point to the last non comment line if i >= 0: add_cell( cells, content[: i + 1], cell_type, cell_count, metainfo ) content = content[i + 1 :] cell_type = "code" cell_count += 1 metainfo = {"kernel": "SoS"} content += [line] continue if line.startswith("#!"): if cell_type == "markdown": content.append(line) continue # get ride of empty content if not any(x.strip() for x in content): content = [] if content: add_cell(cells, content, cell_type, cell_count, metainfo) cell_type = "markdown" cell_count += 1 content = [line] continue # other cases content.append(line) # if content and any(x.strip() for x in content): add_cell(cells, content, cell_type, cell_count, metainfo) # nb = new_notebook( cells=cells, metadata={ "kernelspec": {"display_name": "SoS", "language": "sos", "name": "sos"}, "language_info": { "codemirror_mode": "sos", "file_extension": ".sos", "mimetype": "text/x-sos", "name": "sos", "pygments_lexer": "python", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", }, "sos": {"kernels": [["SoS", "sos", "", ""]]}, }, ) if not notebook_file: nbformat.write(nb, sys.stdout, 4) else: with open(notebook_file, "w") as notebook: nbformat.write(nb, notebook, 4) env.logger.info(f"Jupyter notebook saved to {notebook_file}") # if err: # raise RuntimeError(repr(err)) # # notebook to sos script # class NotebookToScriptConverter: def get_parser(self): parser = argparse.ArgumentParser( "sos convert FILE.ipynb FILE.sos (or --to sos)", description="""Export Jupyter notebook with a SoS kernel to a .sos file. The cells are presented in the .sos file as cell structure lines, which will be ignored if executed in batch mode """, ) parser.add_argument( "-a", "--all", action="store_true", help="""If set, export all cells to the output file, which does not have to be a valid sos workflow.""", ) return parser def convert(self, notebook_file, sos_file, args=None, unknown_args=None): """ Convert a ipython notebook to sos format. """ if unknown_args: raise ValueError(f"Unrecognized parameter {unknown_args}") exporter = SoS_Exporter() notebook = nbformat.read(notebook_file, nbformat.NO_CONVERT) output, _ = exporter.from_notebook_node( notebook, {}, all_content=args.all if args else False ) if not sos_file: sys.stdout.write(output) elif isinstance(sos_file, str): with open(sos_file, "w") as sosfile: sosfile.write(output) env.logger.info(f"SoS script saved to {sos_file}") else: sos_file.write(output) # # notebook to HTML # def get_template_args(): return [ "--TemplateExporter.extra_template_basedirs", os.path.join(f"{os.path.split(os.path.abspath(__file__))[0]}", "templates"), ] def export_notebook( exporter_class, to_format, notebook_file, output_file, unknown_args=None, view=False ): import subprocess if not os.path.isfile(notebook_file): raise RuntimeError(f"{notebook_file} does not exist") if not output_file: tmp = tempfile.NamedTemporaryFile(delete=False, suffix="." + to_format).name tmp_stderr = tempfile.NamedTemporaryFile( delete=False, suffix="." + to_format ).name with open(tmp_stderr, "w") as err: ret = subprocess.call( [ "jupyter", "nbconvert", notebook_file, "--to", to_format, "--output", tmp, ] + ([] if unknown_args is None else unknown_args), stderr=err, ) with open(tmp_stderr) as err: err_msg = err.read() if ret != 0: env.logger.error(err_msg) raise RuntimeError( f"Failed to convert {notebook_file} to {to_format} format" ) # identify output files dest_file = err_msg.rsplit()[-1] if not os.path.isfile(dest_file): env.logger.error(err_msg) raise RuntimeError("Failed to get converted file.") if view: import webbrowser url = f"file://{os.path.abspath(dest_file)}" env.logger.info(f"Viewing {url} in a browser") webbrowser.open(url, new=2) # allow browser some time to process the file before this process removes it time.sleep(2) else: with open(dest_file, "rb") as tfile: sys.stdout.buffer.write(tfile.read()) try: os.remove(tmp) except Exception: pass else: ret = subprocess.call( [ "jupyter", "nbconvert", os.path.abspath(notebook_file), "--to", to_format, "--output", os.path.abspath(output_file), ] + ([] if unknown_args is None else unknown_args) ) if ret != 0: raise RuntimeError( f"Failed to convert {notebook_file} to {to_format} format" ) env.logger.info(f"Output saved to {output_file}") def _is_int(value): """Use casting to check if value can convert to an `int`.""" try: int(value) except ValueError: return False else: return True def _is_float(value): """Use casting to check if value can convert to a `float`.""" try: float(value) except ValueError: return False else: return True def parse_papermill_parameters(values): parameters = {} for value in values: if "=" not in value: parameters[value] = True continue k, v = value.split("=", 1) if v == "True": parameters[k] = True elif v == "False": parameters[k] = False elif value == "None": parameters[k] = None elif _is_int(v): parameters[k] = int(v) elif _is_float(v): parameters[k] = float(v) else: parameters[k] = v return parameters class NotebookToHTMLConverter: def get_parser(self): parser = argparse.ArgumentParser( "sos convert FILE.ipynb FILE.html (or --to html)", description="""Export Jupyter notebook with a SoS kernel to a .html file. Additional command line arguments are passed directly to command "jupyter nbconvert --to html" so please refer to nbconvert manual for available options.""", ) parser.add_argument( "--template", help="""Template to export Jupyter notebook with sos kernel. SoS provides a number of templates, with sos-report displays markdown cells and only output of cells with prominent tag, and a control panel to control the display of the rest of the content """, ) parser.add_argument( "-e", "--execute", nargs="*", help="""Execute the workflow using sos-papermill before exporting to HTML format. One or more parameters are acceptable and should be specified as name=value, where the type of value will be automatically guessed. An exception of this rule is that `name' without `=` will be considered as value True.""", ) parser.add_argument( "-a", "--all", action="store_true", help="""If specified, save content of all cells to .sos file.""", ) parser.add_argument( "-v", "--view", action="store_true", help="""Open the output file in a broswer. In case no html file is specified, this option will display the HTML file in a browser, instead of writing its content to standard output.""", ) return parser def convert(self, notebook_file, output_file, sargs=None, unknown_args=None): from nbconvert.exporters.html import HTMLExporter if unknown_args is None: unknown_args = [] if sargs.template: template_path, template_name = os.path.split(sargs.template) if template_path == "": unknown_args = ( get_template_args() + ["--template", template_name] + unknown_args ) else: unknown_args = ( get_template_args() + [ "--TemplateExporter.extra_template_basedirs", template_path, "--template", template_name, ] + unknown_args ) if sargs.execute is not None: notebook_file = execute_sos_notebook( notebook_file, return_content=False, parameters=parse_papermill_parameters(sargs.execute), ) export_notebook( HTMLExporter, "html", notebook_file, output_file, unknown_args, view=sargs.view, ) if os.path.basename(notebook_file).startswith("__tmp_output_nb"): try: os.remove(notebook_file) except Exception as e: env.logger.warning( f"Failed to remove temporary output file {notebook_file}: {e}" ) # # Notebook to PDF # class NotebookToPDFConverter: def get_parser(self): parser = argparse.ArgumentParser( "sos convert FILE.ipynb FILE.pdf (or --to pdf)", description="""Export Jupyter notebook with a SoS kernel to a .pdf file. Additional command line arguments are passed directly to command "jupyter nbconvert --to pdf" so please refer to nbconvert manual for available options.""", ) parser.add_argument( "-e", "--execute", nargs="*", help="""Execute the workflow using sos-papermill before exporting to PDF format. One or more parameters are acceptable and should be specified as name=value, where the type of value will be automatically guessed. An exception of this rule is that `name' without `=` will be considered as value True.""", ) parser.add_argument( "--template", help="""Template to export Jupyter notebook with sos kernel. SoS provides a number of templates, with sos-report displays markdown cells and only output of cells with prominent tag, and a control panel to control the display of the rest of the content """, ) return parser def convert(self, notebook_file, output_file, sargs=None, unknown_args=None): from nbconvert.exporters.pdf import PDFExporter if sargs.execute is not None: notebook_file = execute_sos_notebook( notebook_file, return_content=False, parameters=parse_papermill_parameters(sargs.execute), ) if unknown_args is None: unknown_args = [] if sargs.template: template_path, template_name = os.path.split(sargs.template) if template_path == "": unknown_args = ( get_template_args() + ["--template", template_name] + unknown_args ) else: unknown_args = ( get_template_args() + [ "--TemplateExporter.extra_template_basedirs", template_path, "--template", template_name, ] + unknown_args ) # jupyter convert will add extension to output file... if output_file is not None and output_file.endswith(".pdf"): output_file = output_file[:-4] export_notebook( PDFExporter, "pdf", notebook_file, output_file, get_template_args() + unknown_args, ) if os.path.basename(notebook_file).startswith("__tmp_output_nb"): try: os.remove(notebook_file) except Exception as e: env.logger.warning( f"Failed to remove temporary output file {notebook_file}: {e}" ) # # Notebook to Markdown # class NotebookToMarkdownConverter: def get_parser(self): parser = argparse.ArgumentParser( "sos convert FILE.ipynb FILE.md (or --to md)", description="""Export Jupyter notebook with a SoS kernel to a markdown file. Additional command line arguments are passed directly to command "jupyter nbconvert --to markdown" so please refer to nbconvert manual for available options.""", ) parser.add_argument( "-e", "--execute", nargs="*", help="""Execute the workflow using sos-papermill before exporting to markdown format. One or more parameters are acceptable and should be specified as name=value, where the type of value will be automatically guessed. An exception of this rule is that `name' without `=` will be considered as value True.""", ) return parser def convert(self, notebook_file, output_file, sargs=None, unknown_args=None): from nbconvert.exporters.markdown import MarkdownExporter if sargs.execute is not None: notebook_file = execute_sos_notebook( notebook_file, return_content=False, parameters=parse_papermill_parameters(sargs.execute), ) export_notebook( MarkdownExporter, "markdown", notebook_file, output_file, get_template_args() + ["--template", "sos-markdown"] + unknown_args, ) if os.path.basename(notebook_file).startswith("__tmp_output_nb"): try: os.remove(notebook_file) except Exception as e: env.logger.warning( f"Failed to remove temporary output file {notebook_file}: {e}" ) # # Notebook to Notebook # class NotebookToNotebookConverter: def get_parser(self): parser = argparse.ArgumentParser( "sos convert FILE.ipynb FILE.ipynb (or --to ipynb)", description="""Export a Jupyter notebook with a non-SoS kernel to a SoS notebook with SoS kernel, or from a SoS notebook to a regular notebook with specified kernel, or execute a SoS notebook.""", ) parser.add_argument( "-k", "--kernel", help="""Kernel for the destination notebook. The default kernel is SoS which converts a non-SoS notebook to SoS Notebook. If another kernel is specified, this command will remove cell-specific kernel information and convert a SoS Notebook to regular notebook with specified kernel.""", ) parser.add_argument( "--python3-to-sos", action="store_true", help="""Convert python3 cells to SoS.""", ) parser.add_argument( "--execute", nargs="*", help="""Execute the workflow using sos-papermill. One or more parameters are acceptable and should be specified as name=value, where the type of value will be automatically guessed. An exception of this rule is that `name' without `=` will be considered as value True.""", ) parser.add_argument( "--inplace", action="store_true", help="""Overwrite input notebook with the output.""", ) return parser def nonSoS_to_SoS_notebook(self, notebook, args): """Converting a nonSoS notebook to SoS notebook by adding kernel metadata""" # get the kernel of the notebook # this is like 'R', there is another 'display_name' lan_name = notebook["metadata"]["kernelspec"]["language"] if lan_name == "python": lan_name = "Python3" # this is like 'ir' kernel_name = notebook["metadata"]["kernelspec"]["name"] # if it is already a SoS notebook, do nothing. if kernel_name == "sos": if args.inplace: return env.logger.warning( "Notebook is already using the sos kernel. No conversion is needed." ) return notebook # convert to? if kernel_name == "python3" and args.python3_to_sos: to_lan = "SoS" to_kernel = "sos" else: to_lan = lan_name to_kernel = kernel_name # cells = [] for cell in notebook.cells: if cell.cell_type == "code": cell.metadata["kernel"] = to_lan cells.append(cell) # # new header kernels = [["SoS", "sos", "", "", ""]] if to_lan != "SoS": kernels += [[to_lan, to_kernel, "", "", ""]] metadata = { "kernelspec": {"display_name": "SoS", "language": "sos", "name": "sos"}, "language_info": { "file_extension": ".sos", "mimetype": "text/x-sos", "name": "sos", "pygments_lexer": "python", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", }, "sos": {"kernels": kernels}, } return new_notebook(cells=cells, metadata=metadata) def SoS_to_nonSoS_notebook(self, notebook, args): kernel_name = notebook["metadata"]["kernelspec"]["name"] if kernel_name != "sos": raise ValueError( f"Cannot convert a notebook with kernel {kernel_name} to a notebook with kernel {args.kernel}" ) all_subkernels = [ x[1] for x in notebook["metadata"]["sos"]["kernels"] if x[1] != "sos" ] kinfo = [ x for x in notebook["metadata"]["sos"]["kernels"] if x[1] == args.kernel ] if not kinfo: if args.kernel == "python3": # converting SoS cells to python3, should be more or less ok kinfo = [ [ "Python3", "python3", "Python3", "", {"name": "ipython", "version": 3}, ] ] else: raise ValueError( f"Specified kernel {args.kernel} is not one of the subkernels ({', '.join(all_subkernels)}) used in the SoS notebook. " ) if len(all_subkernels) > 1: env.logger.warning( f"More than one subkernels ({', '.join(all_subkernels)}) are used in the SoS notebook. They will all be considered as {args.kernel} cells." ) # from SoS to args.kernel, we will need to first strip the cell-level kernel info cells = [] for cell in notebook.cells: if cell.cell_type == "code": cell.metadata.pop("kernel") cells.append(cell) # NOTE: we do not have enough information to restore language_info # which contains things such as codemirros mode and mimetype. However, # Jupyter should be able to open the notebook and retrieve such information # from the kernel, and langauge_info will be written if the notebook is # saved again. metadata = { "kernelspec": { "display_name": kinfo[0][0], "language": kinfo[0][2], "name": kinfo[0][1], } } return new_notebook(cells=cells, metadata=metadata) def convert(self, notebook_file, output_file, sargs=None, unknown_args=None): notebook = nbformat.read(notebook_file, nbformat.NO_CONVERT) kernel_name = notebook["metadata"]["kernelspec"]["name"] nb = None # what are we supposed to do? if kernel_name == "sos" and sargs.kernel and sargs.kernel not in ("sos", "SoS"): # sos => nonSoS if sargs.execute is not None: notebook = execute_sos_notebook( notebook_file, parameters=parse_papermill_parameters(sargs.execute) ) nb = self.SoS_to_nonSoS_notebook(notebook, sargs) elif kernel_name == "sos" and not sargs.kernel: if sargs.execute is not None: if output_file and notebook_file != output_file: execute_sos_notebook( notebook_file, output_file, parameters=parse_papermill_parameters(sargs.execute), ) env.logger.info(f"Jupyter notebook saved to {output_file}") return nb = execute_sos_notebook( notebook_file, parameters=parse_papermill_parameters(sargs.execute) ) # sos => sos elif kernel_name != "sos" and sargs.kernel in ("sos", "SoS", None): nb = self.nonSoS_to_SoS_notebook(notebook, sargs) if sargs.execute is not None: nb = execute_sos_notebook( nb, parameters=parse_papermill_parameters(sargs.execute) ) if nb is None: # nothing to do (e.g. sos -> sos) without --execute return if sargs.inplace: with open(notebook_file, "w") as new_nb: nbformat.write(nb, new_nb, 4) env.logger.info(f"Jupyter notebook saved to {notebook_file}") elif not output_file: nbformat.write(nb, sys.stdout, 4) else: with open(output_file, "w") as new_nb: nbformat.write(nb, new_nb, 4) env.logger.info(f"Jupyter notebook saved to {output_file}") ================================================ FILE: src/sos_notebook/inspector.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import pydoc from sos.syntax import SOS_USAGES from sos.utils import env from .magics import SoS_Magics class SoS_VariableInspector: def __init__(self, kernel): self.kernel = kernel self.preview_magic = kernel.magics.get("preview") def inspect(self, name, line, pos): try: obj_desc, preview = self.preview_magic.preview_var(name, style=None) if preview is None: return {} format_dict, _ = preview if "text/plain" in format_dict: return format_dict return {"text/plain": f"{repr(env.sos_dict['name'])} ({obj_desc})"} except Exception: return {} class SoS_SyntaxInspector: def __init__(self, kernel): self.kernel = kernel def inspect(self, name, line, pos): if line.startswith("%") and name in SoS_Magics.names and pos <= len(name) + 1: try: magic = SoS_Magics(self.kernel).get(name) parser = magic.get_parser() return {"text/plain": parser.format_help()} except Exception as e: return {"text/plain": f"Magic %{name}: {e}"} if line.startswith(name + ":") and pos <= len(name): if self.kernel.original_keys is None: self.kernel._reset_dict() # input: etc if name in SOS_USAGES: return {"text/plain": SOS_USAGES[name]} if name in env.sos_dict: # action? return { "text/plain": pydoc.render_doc( env.sos_dict[name], title="%s", renderer=pydoc.plaintext ), "text/html": pydoc.render_doc( env.sos_dict[name], title="%s", renderer=pydoc.html ), } return {} class SoS_Inspector: def __init__(self, kernel): self.inspectors = [ SoS_SyntaxInspector(kernel), SoS_VariableInspector(kernel), ] def inspect(self, name, line, pos): for c in self.inspectors: try: data = c.inspect(name, line, pos) if data: return data except Exception: continue # No match return {} ================================================ FILE: src/sos_notebook/install.py ================================================ #!/usr/bin/env python # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import argparse import json import os import shutil import sys from IPython.utils.tempdir import TemporaryDirectory from jupyter_client.kernelspec import KernelSpecManager kernel_json = { "argv": [sys.executable, "-m", "sos_notebook.kernel", "-f", "{connection_file}"], "display_name": "SoS", "language": "sos", } def _is_root(): try: return os.geteuid() == 0 except AttributeError: return False # assume not an admin on non-Unix platforms def get_install_sos_kernel_spec_parser(): parser = argparse.ArgumentParser(description="Install KernelSpec for sos Kernel") prefix_locations = parser.add_mutually_exclusive_group() prefix_locations.add_argument( "--user", help="Install KernelSpec in user homedirectory", action="store_true" ) prefix_locations.add_argument( "--sys-prefix", help="Install KernelSpec in sys.prefix. Useful in conda / virtualenv", action="store_true", dest="sys_prefix", ) prefix_locations.add_argument( "--prefix", help="Install KernelSpec in this prefix", default=None ) return parser def install_sos_kernel_spec(user, prefix): with TemporaryDirectory() as td: os.chmod(td, 0o755) # Starts off as 700, not user readable with open(os.path.join(td, "kernel.json"), "w") as f: json.dump(kernel_json, f, sort_keys=True) shutil.copy( os.path.join(os.path.split(__file__)[0], "logo-64x64.png"), os.path.join(td, "logo-64x64.png"), ) KS = KernelSpecManager() KS.install_kernel_spec(td, "sos", user=user, prefix=prefix) destination = KS._get_destination_dir("sos", user=user, prefix=prefix) print(f"sos jupyter kernel spec is installed to {destination}") def main(): parser = get_install_sos_kernel_spec_parser() args = parser.parse_args() user = False prefix = None if args.sys_prefix: prefix = sys.prefix elif args.prefix: prefix = args.prefix elif args.user or not _is_root(): user = True install_sos_kernel_spec(user, prefix) if __name__ == "__main__": main() ================================================ FILE: src/sos_notebook/install_sos_notebook.sh ================================================ #!/usr/bin/bash pip install . -U python -m sos_notebook.install ================================================ FILE: src/sos_notebook/kernel.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import asyncio import atexit import contextlib import inspect import logging import os import pprint import subprocess import sys import threading import time from collections import defaultdict from importlib import metadata from textwrap import dedent import comm import pandas as pd from ipykernel._version import version_info as ipykernel_version_info from ipykernel.ipkernel import IPythonKernel from IPython.utils.tokenutil import line_at_cursor, token_at_cursor from jupyter_client import manager from sos._version import __sos_version__, __version__ from sos.eval import SoS_eval, interpolate from sos.executor_utils import prepare_env from sos.syntax import SOS_DIRECTIVE, SOS_SECTION_HEADER from sos.utils import env, load_config_files, short_repr from ._version import __version__ as __notebook_version__ from .comm_manager import SoSCommManager from .completer import SoS_Completer from .inspector import SoS_Inspector from .magics import SoS_Magics from .subkernel import Subkernels from .workflow_executor import ( NotebookLoggingHandler, execute_scratch_cell, run_sos_workflow, start_controller, ) class FlushableStringIO: def __init__(self, kernel, name, *args, **kwargs): self.kernel = kernel self.name = name def write(self, content): if content.startswith("HINT: "): content = content.splitlines() hint_line = content[0][6:].strip() content = "\n".join(content[1:]) self.kernel.send_response( self.kernel.iopub_socket, "display_data", { "metadata": {}, "data": {"text/html": f'
{hint_line}
'}, }, ) if content: if self.kernel._meta["capture_result"] is not None: self.kernel._meta["capture_result"].append( ("stream", {"name": self.name, "text": content}) ) if self.kernel._meta["render_result"] is False: self.kernel.send_response( self.kernel.iopub_socket, "stream", {"name": self.name, "text": content}, ) def flush(self): pass __all__ = ["SoS_Kernel"] # translate a message to transient_display_data message def make_transient_msg(msg_type, content): if msg_type == "display_data": return { "data": content.get("data", {}), "metadata": content.get("metadata", {}), } if msg_type == "stream": if content["name"] == "stdout": return { "data": { "text/plain": content["text"], "application/vnd.jupyter.stdout": content["text"], }, "metadata": {}, } return { "data": { "text/plain": content["text"], "application/vnd.jupyter.stderr": content["text"], }, "metadata": {}, } raise ValueError( f"failed to translate message {msg_type} to transient_display_data message" ) class SoS_Kernel(IPythonKernel): implementation = "SOS" implementation_version = __version__ language = "sos" language_version = __sos_version__ language_info = { "mimetype": "text/x-sos", "name": "sos", "file_extension": ".sos", "pygments_lexer": "sos", "codemirror_mode": "sos", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", } banner = "SoS kernel - script of scripts" def get_supported_languages(self): if self._supported_languages is not None: return self._supported_languages group = "sos_languages" self._supported_languages = {} for entrypoint in metadata.entry_points(group=group): # Grab the function that is the actual plugin. name = entrypoint.name env.log_to_file("KERNEL", f"Found registered language {name}") try: plugin = entrypoint.load() self._supported_languages[name] = plugin except Exception as e: env.log_to_file( "KERNEL", f"Failed to load registered language {name}: {e}" ) self._failed_languages[name] = e return self._supported_languages supported_languages = property(lambda self: self.get_supported_languages()) def get_kernel_list(self): if not hasattr(self, "_subkernels"): self._subkernels = Subkernels(self) # sort kernel list by name to avoid unnecessary change of .ipynb files return self._subkernels subkernels = property(lambda self: self.get_kernel_list()) def get_completer(self): if self._completer is None: self._completer = SoS_Completer(self) return self._completer completer = property(lambda self: self.get_completer()) def get_inspector(self): if self._inspector is None: self._inspector = SoS_Inspector(self) return self._inspector inspector = property(lambda self: self.get_inspector()) def __init__(self, **kwargs): super().__init__(**kwargs) self.options = "" self.kernel = "SoS" # a dictionary of started kernels, with the format of # # 'R': ['ir', 'sos.R.sos_R', '#FFEEAABB'] # # Note that: # # 'R' is the displayed name of the kernel. # 'ir' is the kernel name. # 'sos.R.sos_R' is the language module. # '#FFEEAABB' is the background color # env.log_to_file( "KERNEL", f"Starting SoS Kernel version {__notebook_version__} with SoS {__version__}", ) self.kernels = {} self._shutting_down = False atexit.register(self._atexit_shutdown) # self.shell = InteractiveShell.instance() self.format_obj = self.shell.display_formatter.format self._meta = { "workflow": "", "workflow_mode": False, "render_result": False, "capture_result": None, "cell_id": "0", "notebook_name": "", "notebook_path": "", "use_panel": True, "use_iopub": False, "default_kernel": "SoS", "cell_kernel": "SoS", "batch_mode": False, } self._debug_mode = False self._supported_languages = None self._completer = None self._inspector = None self._real_execution_count = 1 self._execution_count = 1 self.frontend_comm = None self.frontend_comm_cache = [] # self.comm_manager = comm.get_comm_manager() # remove the old comm_manager self.shell.configurables.pop() self.shell.configurables.append(self.comm_manager) for msg_type in ["comm_open", "comm_msg", "comm_close"]: self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type) self.comm_manager.register_target("sos_comm", self.sos_comm) self.my_tasks = {} self.magics = SoS_Magics(self) self._failed_languages = {} # enable matplotlib by default #77 self.shell.enable_gui = lambda gui: None self.editor_kernel = "sos" # initialize env prepare_env("") self.original_keys = set(env.sos_dict._dict.keys()) | { "SOS_VERSION", "CONFIG", "step_name", "__builtins__", "input", "output", "depends", } env.logger.handlers = [ x for x in env.logger.handlers if not isinstance(x, logging.StreamHandler) ] env.logger.addHandler( NotebookLoggingHandler( { 0: logging.ERROR, 1: logging.WARNING, 2: logging.INFO, 3: logging.DEBUG, 4: logging.DEBUG, None: logging.INFO, }[env.verbosity], kernel=self, ) ) env.logger.print = lambda cell_id, msg, *args: ( self.send_response( self.iopub_socket, "stream", {"name": "stdout", "text": msg} ) if self._meta["batch_mode"] else self.send_frontend_msg("print", [cell_id, msg]) ) self.controller = None cell_id = property(lambda self: self._meta["cell_id"]) _workflow_mode = property(lambda self: self._meta["workflow_mode"]) def sos_comm(self, comm, msg): # record frontend_comm to send messages self.frontend_comm = comm @comm.on_msg def handle_frontend_msg(msg): content = msg["content"]["data"] # log_to_file(msg) for k, v in content.items(): if k == "list-kernel": if v: self.subkernels.update(v) self.subkernels.notify_frontend() elif k == "set-editor-kernel": self.editor_kernel = v elif k == "cancel-workflow": from .workflow_executor import cancel_workflow cancel_workflow(v[0], self) elif k == "execute-workflow": from .workflow_executor import execute_pending_workflow execute_pending_workflow(v, self) elif k == "update-task-status": if not isinstance(v, list): env.log_to_file( "KERNEL", f"Failed to parse message for update-task-status {v}", ) continue # split by host ... host_status = defaultdict(list) for name in v: try: tqu, tid, _ = name.rsplit("_", 2) except Exception as e: env.log_to_file( "KERNEL", f"Failed to parse task ID {name}: {e}" ) # incorrect ID... continue host_status[tqu].append(tid) # log_to_file(host_status) # from sos.hosts import Host for tqu, tids in host_status.items(): try: h = Host(tqu, start_engine=True) except Exception as e: env.log_to_file( "KERNEL", f"Failed to connect to host {tqu}: {e}" ) for tid in tids: self.send_frontend_msg( "task_status", { "task_id": tid, "queue": tqu, "status": "missing", "duration": "", }, ) continue for tid, tst, tdt in h._task_engine.monitor_tasks(tids): self.send_frontend_msg( "task_status", { "task_id": tid, "queue": tqu, "status": tst, "duration": tdt, }, ) self.send_frontend_msg("update-duration", {}) elif k == "paste-table": try: from tabulate import tabulate df = pd.read_clipboard() tbl = tabulate(df, headers="keys", tablefmt="pipe") self.send_frontend_msg("paste-table", tbl) except Exception as e: self.send_frontend_msg( "alert", f"Failed to paste clipboard as table: {e}" ) elif k == "notebook-version": # send the version of notebook, right now we will not do anything to it, but # we will send the version of sos-notebook there self.send_frontend_msg("notebook-version", __notebook_version__) else: # this somehow does not work self.warn(f"Unknown message {k}: {v}") def notify_error(self, e): msg = { "status": "error", "ename": e.__class__.__name__, "evalue": str(e), "traceback": [f"\033[91m{e}\033[0m"], "execution_count": self._execution_count, } if self._meta["suppress_error"]: self.send_response( self.iopub_socket, "stream", {"name": "stderr", "text": f"{msg['ename']}: {msg['evalue']}"}, ) else: self.send_response(self.iopub_socket, "error", msg) return msg def send_frontend_msg(self, msg_type, msg=None): # if comm is never created by frontend, the kernel is in test mode without frontend if msg_type in ("display_data", "stream"): if self._meta["use_panel"] is False or self._meta["cell_id"] == -1: self.send_response( self.iopub_socket, msg_type, {} if msg is None else msg ) elif self._meta["use_iopub"]: self.send_response( self.iopub_socket, "transient_display_data", make_transient_msg(msg_type, msg), ) elif self.frontend_comm: if self.frontend_comm_cache: for mt, mg in self.frontend_comm_cache: self.frontend_comm.send( make_transient_msg(mt, mg), {"msg_type": "transient_display_data"}, ) self.frontend_comm_cache = [] self.frontend_comm.send( make_transient_msg(msg_type, msg), {"msg_type": "transient_display_data"}, ) elif self._meta["batch_mode"]: env.log_to_file( "MESSAGE", f"frontend message of type {msg_type} is sent in batch mode.", ) else: self.frontend_comm_cache.append([msg_type, msg]) env.log_to_file( "MESSAGE", f"fronten not ready or broken. Message of type {msg_type} is cached", ) elif self.frontend_comm: if self.frontend_comm_cache: for mt, mg in self.frontend_comm_cache: self.frontend_comm.send({} if mg is None else mg, {"msg_type": mt}) self.frontend_comm_cache = [] self.frontend_comm.send({} if msg is None else msg, {"msg_type": msg_type}) elif self._meta["batch_mode"]: env.log_to_file( "MESSAGE", f"frontend message of type {msg_type} is sent in batch mode." ) else: # frontend_comm is not ready self.frontend_comm_cache.append([msg_type, msg]) env.log_to_file( "MESSAGE", f"fronten not ready or broken. Message of type {msg_type} is cached", ) @contextlib.contextmanager def redirect_sos_io(self): save_stdout = sys.stdout save_stderr = sys.stderr sys.stdout = FlushableStringIO(self, "stdout") sys.stderr = FlushableStringIO(self, "stderr") yield sys.stdout = save_stdout sys.stderr = save_stderr async def get_vars_from(self, items, from_kernel=None, explicit=False, as_var=None): if as_var is not None: if not isinstance(as_var, str): self.warn("Option --as should be a string.") return if len(items) > 1: self.warn("Only one expression is allowed when option --as is used") return if from_kernel is None or from_kernel.lower() == "sos": # Feature removed #253 # autmatically get all variables with names start with 'sos' # default_items = [ # x for x in env.sos_dict.keys() # if x.startswith('sos') and x not in self.original_keys # ] if not items: return for item in items: if item not in env.sos_dict: self.warn(f"Variable {item} does not exist") return kinfo = self.subkernels.find(self.kernel) if kinfo.language in self.supported_languages: lan = self.supported_languages[kinfo.language] try: get_vars_func = lan(self, kinfo.kernel).get_vars args = inspect.getfullargspec(get_vars_func).args if "as_var" in args: await get_vars_func(items, as_var=as_var) else: if as_var is not None: self.warn( f"Subkernel {kinfo.language} does not support option --as" ) await get_vars_func(items) except Exception as e: self.warn(f"Failed to get variable: {e}\n") return elif self.kernel == "SoS": self.warn( "Magic %get without option --kernel can only be executed by subkernels" ) return else: if explicit: self.warn( f"Magic %get failed because the language module for {self.kernel} is not properly installed. Please install it according to language specific instructions on the Running SoS section of the SoS homepage and restart Jupyter server." ) return elif self.kernel.lower() == "sos": # if another kernel is specified and the current kernel is sos # we get from subkernel try: await self.switch_kernel(from_kernel) await self.put_vars_to(items, as_var=as_var) except Exception as e: self.warn(f"Failed to get {', '.join(items)} from {from_kernel}: {e}") finally: await self.switch_kernel("SoS") else: # if another kernel is specified, we should try to let that kernel pass # the variables to this one directly try: my_kernel = self.kernel await self.switch_kernel(from_kernel) # put stuff to sos or my_kernel directly await self.put_vars_to( items, to_kernel=my_kernel, explicit=explicit, as_var=as_var ) except Exception as e: self.warn(f"Failed to get {', '.join(items)} from {from_kernel}: {e}") finally: # then switch back await self.switch_kernel(my_kernel) async def put_vars_to(self, items, to_kernel=None, explicit=False, as_var=None): if not items: return if as_var is not None: if not isinstance(as_var, str): self.warn("Option --as should be a string.") return if len(items) > 1: self.warn("Only one expression is allowed when option --as is used") return if self.kernel.lower() == "sos": if to_kernel is None: self.warn( "Magic %put without option --kernel can only be executed by subkernels" ) return # if another kernel is specified and the current kernel is sos try: # switch to kernel and bring in items await self.switch_kernel(to_kernel, in_vars=items, as_var=as_var) except Exception as e: self.warn(f"Failed to put {', '.join(items)} to {to_kernel}: {e}") finally: # switch back await self.switch_kernel("SoS") else: # put to sos kernel or another kernel kinfo = self.subkernels.find(self.kernel) if kinfo.language not in self.supported_languages: if explicit: self.warn(f"Subkernel {self.kernel} does not support magic %put.") return # lan = self.supported_languages[kinfo.language] # pass language name to to_kernel try: put_vars_func = lan(self, kinfo.kernel).put_vars args = inspect.getfullargspec(put_vars_func).args to_kernel_name = ( self.subkernels.find(to_kernel).language if to_kernel else "SoS" ) if "as_var" in args: objects = put_vars_func( items, to_kernel=to_kernel_name, as_var=as_var ) else: objects = put_vars_func(items, to_kernel=to_kernel_name) except Exception as e: # if somethign goes wrong in the subkernel does not matter env.log_to_file( "MAGIC", f"Failed to call put_var({items}) from {kinfo.kernel}: {e}" ) objects = {} if isinstance(objects, dict): # returns a SOS dictionary try: # if the variable is passing through SoS, let us try to restore variables in SoS if to_kernel is not None: missing_vars = [ x for x in objects.keys() if x not in env.sos_dict ] existing_vars = { x: env.sos_dict[x] for x in objects.keys() if x in env.sos_dict } env.sos_dict.update(objects) except Exception as e: self.warn(f"Failed to put {', '.join(items)} to {to_kernel}: {e}") return if to_kernel is None: return # if another kernel is specified and the current kernel is not sos # we need to first put to sos then to another kernel my_kernel = self.kernel try: # switch to the destination kernel and bring in vars await self.switch_kernel( to_kernel, in_vars=[as_var] if as_var else items ) except Exception as e: self.warn(f"Failed to put {', '.join(items)} to {to_kernel}: {e}") finally: # switch back to the original kernel await self.switch_kernel(my_kernel) # restore sos_dict to avoid bypassing effect #252 for missing_var in missing_vars: env.sos_dict.pop(missing_var) env.sos_dict.update(existing_vars) elif isinstance(objects, str): # an statement that will be executed in the destination kernel if to_kernel is None or to_kernel == "SoS": # evaluate in SoS, this should not happen or rarely happen # because the subkernel should return a dictionary for SoS kernel try: exec(objects, env.sos_dict._dict) except Exception as e: self.warn(f"Failed to put variables {items} to SoS kernel: {e}") return try: my_kernel = self.kernel # switch to the destination kernel await self.switch_kernel(to_kernel) # execute the statement to pass variables directly to destination kernel await self.run_cell(objects, True, False) except Exception as e: self.warn(f"Failed to put {', '.join(items)} to {to_kernel}: {e}") finally: # switch back to the original kernel await self.switch_kernel(my_kernel) else: self.warn( f"Unrecognized return value of type {object.__class__.__name__} for action %put" ) async def expand_text_in(self, text, sigil=None, kernel="SoS"): """ Expand a piece of (markdown) text in specified kernel, used by magic %expand """ if not text: return "" if sigil is None: sigil = "{ }" if sigil.count(" ") != 1: raise ValueError( f'Invalid interpolation delimiter "{sigil}": should be in the format of "L R"' ) if sigil.split(" ")[0] not in text: return text if not kernel or kernel.lower() == "sos": if sigil != "{ }": from sos.parser import replace_sigil text = replace_sigil(text, sigil) return interpolate(text, local_dict=env.sos_dict._dict) # check if the language supports expand protocol kinfo = self.subkernels.find(kernel) if kinfo.language not in self.supported_languages: self.warn(f"Subkernel {kernel} does not support magic %expand --in") return text lan = self.supported_languages[kinfo.language](self, kinfo.kernel) if not hasattr(lan, "expand"): self.warn(f"Subkernel {kernel} does not support magic %expand --in") return text orig_kernel = self.kernel try: await self.switch_kernel(kernel) return lan.expand(text, sigil) except Exception as e: self.warn( f"Failed to expand {text} with sigin {sigil} in kernel {kernel}: {e}" ) return text finally: await self.switch_kernel(orig_kernel) def do_is_complete(self, code): """check if new line is in order""" code = code.strip() if not code: return {"status": "complete", "indent": ""} env.log_to_file("MESSAGE", f'Checking is_complete of "{code}"') lines = code.split("\n") # first let us remove "valid" magics while any(line.startswith("%") or line.startswith("!") for line in lines): for idx, line in enumerate(lines): if line.startswith("%") or line.startswith("!"): # if the last line ending with \, incomplete if line.endswith("\\"): if idx == len(lines) - 1: return {"status": "incomplete", "indent": ""} lines[idx] = lines[idx][:-1] + lines[idx + 1] lines[idx + 1] = "" else: # valid, complete, ignore lines[idx] = "" if self.kernel == "SoS": for idx, line in enumerate(lines): # remove header if SOS_SECTION_HEADER.match(line): lines[idx] = "" # remove input stuff? if SOS_DIRECTIVE.match(line): if any( line.startswith(x) for x in ("input:", "output:", "depends:", "parameter:") ): # directive, remvoe them lines[idx] = lines[idx].split(":", 1)[-1] elif idx == len(lines) - 1: # sh: with no script, incomplete return {"status": "incomplete", "indent": " "} else: # remove the rest of them because they are embedded script for i in range(idx, len(lines)): lines[i] = "" # check the rest if it is ok try: from IPython.core.inputtransformer2 import TransformerManager as ipf except ImportError: from IPython.core.inputsplitter import InputSplitter as ipf code = "\n".join(lines) + "\n\n" res = ipf().check_complete(code) env.log_to_file("MESSAGE", f"SoS kernel returns {res} for code {code}") return {"status": res[0], "indent": res[1]} # non-SoS kernels try: cell_kernel = self.subkernels.find(self.editor_kernel) if cell_kernel.name not in self.kernels: orig_kernel = self.kernel try: # switch to start the new kernel asyncio.run(self.switch_kernel(cell_kernel.name)) finally: asyncio.run(self.switch_kernel(orig_kernel)) KC = self.kernels[cell_kernel.name][1] # clear the shell channel while KC.shell_channel.msg_ready(): KC.shell_channel.get_msg() code = "\n".join(lines) KC.is_complete(code) msg = KC.shell_channel.get_msg() if msg["header"]["msg_type"] == "is_complete_reply": env.log_to_file( "MESSAGE", f"{self.kernel} kernel returns {msg['content']} for code {code}", ) return msg["content"] raise RuntimeError( f"is_complete_reply not obtained: {msg['header']['msg_type']} {msg['content']} returned instead" ) except Exception as e: env.logger.debug(f"Completion fail with exception: {e}") return {"status": "incomplete", "indent": ""} def do_inspect(self, code, cursor_pos, detail_level=0): if self.editor_kernel.lower() == "sos": line, offset = line_at_cursor(code, cursor_pos) name = token_at_cursor(code, cursor_pos) data = self.inspector.inspect(name, line, cursor_pos - offset) return { "status": "ok", "metadata": {}, "found": True if data else False, "data": data, } cell_kernel = self.subkernels.find(self.editor_kernel) try: _, KC = self.kernels[cell_kernel.name] except Exception as e: env.log_to_file( "KERNEL", f"Failed to get subkernels {cell_kernel.name}: {e}" ) KC = self.KC try: KC.inspect(code, cursor_pos) while KC.shell_channel.msg_ready(): msg = KC.shell_channel.get_msg() if msg["header"]["msg_type"] == "inspect_reply": return msg["content"] # other messages, do not know what is going on but # we should not wait forever and cause a deadloop here env.log_to_file( "MESSAGE", f"complete_reply not obtained: {msg['header']['msg_type']} {msg['content']} returned instead", ) break except Exception as e: env.log_to_file("KERNEL", f"Completion fail with exception: {e}") async def do_complete(self, code, cursor_pos): if self.editor_kernel.lower() == "sos": text, matches = self.completer.complete_text(code, cursor_pos) return { "matches": matches, "cursor_end": cursor_pos, "cursor_start": cursor_pos - len(text), "metadata": {}, "status": "ok", } try: cell_kernel = self.subkernels.find(self.editor_kernel) if cell_kernel.name not in self.kernels: orig_kernel = self.kernel try: # switch to start the new kernel await self.switch_kernel(cell_kernel.name) finally: await self.switch_kernel(orig_kernel) KC = self.kernels[cell_kernel.name][1] # clear the shell channel while KC.shell_channel.msg_ready(): KC.shell_channel.get_msg() KC.complete(code, cursor_pos) msg = KC.shell_channel.get_msg() if msg["header"]["msg_type"] == "complete_reply": return msg["content"] raise RuntimeError( f"complete_reply not obtained: {msg['header']['msg_type']} {msg['content']} returned instead" ) except Exception as e: env.logger.debug(f"Completion fail with exception: {e}") return { "matches": [], "cursor_end": cursor_pos, "cursor_start": cursor_pos, "metadata": {}, "status": "error", } def warn(self, message): message = str(message).rstrip() + "\n" if message.strip(): self.send_response( self.iopub_socket, "stream", {"name": "stderr", "text": message} ) async def run_cell(self, code, silent, store_history, on_error=None): # if not self.KM.is_alive(): self.send_response( self.iopub_socket, "stream", {"name": "stdout", "text": f'Restarting kernel "{self.kernel}"\n'}, ) self.KM.restart_kernel(now=False) self.KC = self.KM.client() # flush stale replies, which could have been ignored, due to missed heartbeats while self.KC.shell_channel.msg_ready(): self.KC.shell_channel.get_msg() # executing code in another kernel. # https://github.com/ipython/ipykernel/blob/604ee892623cca29eb495933eb5aa26bd166c7ff/ipykernel/inprocess/client.py#L94 content = { "code": code, "silent": silent, "store_history": store_history, "user_expressions": {}, "allow_stdin": False, } msg = self.KC.session.msg("execute_request", content) # use the msg_id of the sos kernel for the subkernel to make sure that the messages sent # from the subkernel has the correct msg_id in parent_header so that they can be # displayed directly in the notebook (without using self._parent_header if ipykernel_version_info[0] >= 6: msg["msg_id"] = self.get_parent()["header"]["msg_id"] else: msg["msg_id"] = self._parent_header["header"]["msg_id"] msg["header"]["msg_id"] = msg["msg_id"] self.KC.shell_channel.send(msg) # first thing is wait for any side effects (output, stdin, etc.) iopub_started = False iopub_ended = False shell_ended = False res = None while not (iopub_started and iopub_ended and shell_ended): try: # display intermediate print statements, etc. while self.KC.stdin_channel.msg_ready(): sub_msg = self.KC.stdin_channel.get_msg() env.log_to_file( "MESSAGE", f"MSG TYPE {sub_msg['header']['msg_type']} CONTENT\n {pprint.pformat(sub_msg)}", ) if sub_msg["header"]["msg_type"] != "input_request": self.session.send(self.stdin_socket, sub_msg) else: content = sub_msg["content"] if content["password"]: res = self.getpass(prompt=content["prompt"]) else: res = self.raw_input(prompt=content["prompt"]) self.KC.input(res) while self.KC.iopub_channel.msg_ready(): sub_msg = self.KC.iopub_channel.get_msg() msg_type = sub_msg["header"]["msg_type"] env.log_to_file( "MESSAGE", f"IOPUB MSG TYPE {sub_msg['header']['msg_type']} CONTENT \n {pprint.pformat(sub_msg)}", ) if msg_type == "status": if sub_msg["content"]["execution_state"] == "busy": iopub_started = True elif ( iopub_started and sub_msg["content"]["execution_state"] == "idle" ): iopub_ended = True continue if msg_type in ("execute_input", "execute_result"): # override execution count with the master count, # not sure if it is needed sub_msg["content"]["execution_count"] = self._execution_count # if msg_type in [ "display_data", "stream", "execute_result", "update_display_data", "error", ]: if self._meta["capture_result"] is not None: self._meta["capture_result"].append( (msg_type, sub_msg["content"]) ) if msg_type == "execute_result" or ( not silent and self._meta["render_result"] is False ): if msg_type == "error" and self._meta["suppress_error"]: self.send_response( self.iopub_socket, "stream", { "name": "stderr", "text": f"{sub_msg['content']['ename']}: {sub_msg['content']['evalue']}", }, ) else: self.session.send(self.iopub_socket, sub_msg) else: # if the subkernel tried to create a customized comm if msg_type == "comm_open": self.comm_manager.register_subcomm( sub_msg["content"]["comm_id"], self.KC, self ) self.session.send(self.iopub_socket, sub_msg) if self.KC.shell_channel.msg_ready(): # now get the real result reply = self.KC.get_shell_msg() reply["content"]["execution_count"] = self._execution_count env.log_to_file("MESSAGE", f"GET SHELL MSG {pprint.pformat(reply)}") res = reply["content"] shell_ended = True time.sleep(0.001) except KeyboardInterrupt: self.KM.interrupt_kernel() return res def get_info_of_subkernels(self): from jupyter_client.kernelspec import KernelSpecManager km = KernelSpecManager() available_subkernels = """""" for sk in self.subkernels.kernel_list(): spec = km.get_kernel_spec(sk.kernel) if sk.name in ("SoS", "Markdown"): lan_module = "" elif sk.language in self.supported_languages: lan_module = f"{self.supported_languages[sk.language].__module__.split('.')[0]}" else: lan_module = 'Unavailable' available_subkernels += f"""\ """ available_subkernels += "
Subkernel Kernel Name Language Language Module Interpreter
{sk.name} {sk.kernel} {spec.language} {lan_module} {spec.argv[0]}
" return available_subkernels async def switch_kernel( self, kernel, in_vars=None, kernel_name=None, language=None, color=None, as_var=None, ): # switching to a non-sos kernel if not kernel: kinfo = self.subkernels.find(self.kernel) self.send_response( self.iopub_socket, "display_data", {"metadata": {}, "data": {"text/html": self.get_info_of_subkernels()}}, ) return kinfo = self.subkernels.find(kernel, kernel_name, language, color) if kinfo.name == self.kernel: return if kinfo.name == "SoS": # non-SoS to SoS if in_vars: await self.put_vars_to(in_vars, as_var=as_var) self.kernel = "SoS" elif self.kernel != "SoS": # Non-SoS to Non-SoS await self.switch_kernel("SoS", in_vars) await self.switch_kernel(kinfo.name, in_vars) else: # SoS to non-SoS env.log_to_file("KERNEL", f"Switch from {self.kernel} to {kinfo.name}") # case when self.kernel == 'sos', kernel != 'sos' # to a subkernel new_kernel = False if kinfo.name not in self.kernels: # start a new kernel try: env.log_to_file("KERNEL", f"Starting subkernel {kinfo.name}") self.kernels[kinfo.name] = manager.start_new_kernel( startup_timeout=30, kernel_name=kinfo.kernel, cwd=os.getcwd() ) new_kernel = True except Exception: env.log_to_file( "KERNEL", f"Failed to start kernel {kinfo.kernel}. Trying again...", ) # try toget error message import tempfile with tempfile.TemporaryFile() as ferr: try: # this should fail, but sometimes the second attempt will succeed #282 self.kernels[kinfo.name] = manager.start_new_kernel( startup_timeout=60, kernel_name=kinfo.kernel, cwd=os.getcwd(), stdout=subprocess.DEVNULL, stderr=ferr, ) new_kernel = True env.log_to_file( "KERNEL", f"Kernel {kinfo.kernel} started with the second attempt.", ) except Exception as e: ferr.seek(0) raise RuntimeError( f'Failed to start kernel "{kernel}". {e}\nError Message:\n{ferr.read().decode()}' ) from e self.KM, self.KC = self.kernels[kinfo.name] self.kernel = kinfo.name if new_kernel and not kinfo.codemirror_mode: self.KC.kernel_info() kinfo.codemirror_mode = self.KC.get_shell_msg(timeout=10)["content"][ "language_info" ].get("codemirror_mode", "") self.subkernels.notify_frontend() if new_kernel and kinfo.language in self.supported_languages: lan_module = self.supported_languages[kinfo.language]( self, kinfo.kernel ) init_stmts = lan_module.init_statements if hasattr(lan_module, "__version__"): module_version = f" (version {lan_module.__version__})" else: module_version = " (version unavailable)" env.log_to_file( "KERNEL", f"Loading language module for kernel {kinfo.name}{module_version}", ) if init_stmts: await self.run_cell(init_stmts, True, False) # passing if in_vars: await self.get_vars_from(in_vars, as_var=as_var) def shutdown_kernel(self, kernel, restart=False): kernel = self.subkernels.find(kernel).name if kernel == "SoS": # cannot restart myself ... self.warn("Cannot restart SoS kernel from within SoS.") elif kernel: if kernel not in self.kernels: self.send_response( self.iopub_socket, "stream", {"name": "stdout", "text": f"{kernel} is not running"}, ) elif restart: orig_kernel = self.kernel try: # shutdown self.shutdown_kernel(kernel) # switch back to kernel (start a new one) asyncio.run(self.switch_kernel(kernel)) finally: # finally switch to starting kernel asyncio.run(self.switch_kernel(orig_kernel)) else: # shutdown if self.kernel == kernel: asyncio.run(self.switch_kernel("SoS")) try: self.kernels[kernel][0].shutdown_kernel(restart=False) except Exception as e: self.warn(f"Failed to shutdown kernel {kernel}: {e}\n") finally: self.kernels.pop(kernel) else: self.send_response( self.iopub_socket, "stream", { "name": "stdout", "text": "Specify one of the kernels to shutdown: SoS{}\n".format( "".join(f", {x}" for x in self.kernels) ), }, ) # stop_controller(self.controller) # def get_response(self, statement, msg_types, name=None): # return asyncio.run(self._async_get_response(statement, msg_types, name)) def get_response(self, statement, msg_types, name=None): # get response of statement of specific msg types. while self.KC.shell_channel.msg_ready(): self.KC.shell_channel.get_msg() while self.KC.iopub_channel.msg_ready(): sub_msg = self.KC.iopub_channel.get_msg() if sub_msg["header"]["msg_type"] != "status": env.log_to_file( "MESSAGE", f"Overflow message in iopub {sub_msg['header']['msg_type']} {sub_msg['content']}", ) responses = [] self.KC.execute(statement, silent=False, store_history=False) # first thing is wait for any side effects (output, stdin, etc.) iopub_started = False iopub_ended = False shell_ended = False while not (iopub_started and iopub_ended and shell_ended): # display intermediate print statements, etc. while self.KC.iopub_channel.msg_ready(): sub_msg = self.KC.iopub_channel.get_msg() msg_type = sub_msg["header"]["msg_type"] env.log_to_file("MESSAGE", f"Received {msg_type} {sub_msg['content']}") if msg_type == "status": if sub_msg["content"]["execution_state"] == "busy": iopub_started = True elif ( iopub_started and sub_msg["content"]["execution_state"] == "idle" ): iopub_ended = True continue if msg_type in msg_types and ( name is None or sub_msg["content"].get("name", None) in name or any(x in name for x in sub_msg["content"].keys()) ): env.log_to_file( "MESSAGE", f"Capture response: {msg_type}: {sub_msg['content']}" ) responses.append([msg_type, sub_msg["content"]]) else: env.log_to_file( "MESSAGE", f"Non-response: {msg_type}: {sub_msg['content']}" ) # # we ignore the messages we are not interested. # # self.send_response( # self.iopub_socket, msg_type, sub_msg['content']) if self.KC.shell_channel.msg_ready(): # now get the real result reply = self.KC.get_shell_msg() env.log_to_file("MESSAGE", f"GET SHELL MSG {reply}") shell_ended = True time.sleep(0.001) if not responses: env.log_to_file( "MESSAGE", f"Failed to get a response from message type {msg_types} for the execution of {statement}", ) return responses def run_sos_code(self, code, silent): code = dedent(code) with self.redirect_sos_io(): try: if self._workflow_mode: res = run_sos_workflow( code=code, raw_args=self.options, kernel=self, run_in_queue=self._workflow_mode == "nowait" and not self._meta["batch_mode"], ) else: res = execute_scratch_cell( code=code, raw_args=self.options, kernel=self ) self.send_result(res, silent) except Exception as e: sys.stderr.flush() sys.stdout.flush() raise e except KeyboardInterrupt: # this only occurs when the executor does not capture the signal. self.warn("KeyboardInterrupt\n") return {"status": "abort", "execution_count": self._execution_count} finally: sys.stderr.flush() sys.stdout.flush() def render_result(self, res): if not self._meta["render_result"]: return res if not isinstance(res, str): self.warn( f"Cannot render result {short_repr(res)} in type {res.__class__.__name__} as {self._meta['render_result']}." ) else: # import the object from IPython.display mod = __import__("IPython.display") if not hasattr(mod.display, self._meta["render_result"]): self.warn(f"Unrecognized render format {self._meta['render_result']}") else: func = getattr(mod.display, self._meta["render_result"]) res = func(res) return res def send_result(self, res, silent=False): # this is Ok, send result back if not silent and res is not None: format_dict, md_dict = self.format_obj(self.render_result(res)) if self._meta["capture_result"] is not None: self._meta["capture_result"].append(("execute_result", format_dict)) env.log_to_file( "MESSAGE", f"IOPUB execute_result with content {format_dict}" ) self.send_response( self.iopub_socket, "execute_result", { "execution_count": self._execution_count, "data": format_dict, "metadata": md_dict, }, ) def init_metadata(self, metadata): super().init_metadata(metadata) env.log_to_file("KERNEL", f"GOT METADATA {metadata}") if "sos" in metadata["metadata"]: # jupyterlab-sos sends meta data through metadata meta = metadata["metadata"]["sos"] elif "sos" in metadata["content"]: # classic jupyter does not use metadata but allow additional fields # in content meta = metadata["content"]["sos"] else: # if there is no sos metadata, the execution should be started from a test suite # just ignore self._meta = { "workflow": "", "workflow_mode": False, "render_result": False, "capture_result": None, "cell_id": "0", "notebook_name": "", "notebook_path": "", "use_panel": False, "use_iopub": False, "default_kernel": self.kernel, "cell_kernel": self.kernel, "batch_mode": False, "suppress_error": False, } return self._meta env.log_to_file("KERNEL", f"Meta info: {meta}") self._meta = { "workflow": meta["workflow"] if "workflow" in meta else "", "workflow_mode": False, "render_result": False, "capture_result": None, "cell_id": meta["cell_id"] if "cell_id" in meta else "0", "notebook_path": meta["path"] if "path" in meta else "Untitled.ipynb", "use_panel": "use_panel" in meta and meta["use_panel"] is True, "use_iopub": "use_iopub" in meta and meta["use_iopub"] is True, "default_kernel": meta["default_kernel"] if "default_kernel" in meta else "SoS", "cell_kernel": meta["cell_kernel"] if "cell_kernel" in meta else (meta["default_kernel"] if "default_kernel" in meta else "SoS"), "batch_mode": meta.get("batch_mode", False), "suppress_error": False, } # remove path and extension self._meta["notebook_name"] = os.path.basename( self._meta["notebook_path"] ).rsplit(".", 1)[0] if "list_kernel" in meta and meta["list_kernel"]: # https://github.com/jupyter/help/issues/153#issuecomment-289026056 # # when the frontend is refreshed, cached comm would be lost and # communication would be discontinued. However, a kernel-list # request would be sent by the new-connection so we reset the # frontend_comm to re-connect to the frontend. self.comm_manager.register_target("sos_comm", self.sos_comm) return self._meta async def do_execute( self, code, silent, store_history=True, user_expressions=None, allow_stdin=True ): env.log_to_file("KERNEL", f"execute: {code}") if not self.controller: self.controller = start_controller(self) # load basic configuration each time in case user modifies the configuration during # runs. This is not very efficient but should not matter much during interactive # data analysis try: load_config_files() except Exception as e: self.warn(f"Failed to load configuration files: {e}") self._forward_input(allow_stdin) # switch to global default kernel try: if ( self.subkernels.find(self._meta["default_kernel"]).name != self.subkernels.find(self.kernel).name ): await self.switch_kernel(self._meta["default_kernel"]) # evaluate user expression except Exception as e: return self.notify_error(e) # switch to cell kernel try: if ( self.subkernels.find(self._meta["cell_kernel"]).name != self.subkernels.find(self.kernel).name ): await self.switch_kernel(self._meta["cell_kernel"]) except Exception as e: return self.notify_error(e) # execute with cell kernel try: ret = await self._do_execute( code=code, silent=silent, store_history=store_history, user_expressions=user_expressions, allow_stdin=allow_stdin, ) except Exception as e: return self.notify_error(e) if ret is None: ret = { "status": "ok", "payload": [], "user_expressions": {}, "execution_count": self._execution_count, } out = {} for key, expr in (user_expressions or {}).items(): try: # value = self.shell._format_user_obj(SoS_eval(expr)) value = SoS_eval(expr) value = self.shell._format_user_obj(value) except Exception as e: self.warn(f"Failed to evaluate user expression {expr}: {e}") value = self.shell._user_obj_error() out[key] = value ret["user_expressions"] = out # if not silent and store_history: self._real_execution_count += 1 self._execution_count = self._real_execution_count # make sure post_executed is triggered after the completion of all cell content self.shell.user_ns.update(env.sos_dict._dict) # trigger post processing of object and display matplotlib figures self.shell.events.trigger("post_execute") # tell the frontend the kernel for the "next" cell return ret async def _do_execute( self, code, silent, store_history=True, user_expressions=None, allow_stdin=True ): # handles windows/unix newline code = "\n".join(code.splitlines()) + "\n" if code == "import os\n_pid = os.getpid()": # this is a special probing command from vim-ipython. Let us handle it specially # so that vim-python can get the pid. return for magic in self.magics.values(): if magic.match(code): return await magic.apply( code, silent, store_history, user_expressions, allow_stdin ) if self.kernel != "SoS": # handle string interpolation before sending to the underlying kernel if self._meta["cell_id"] != "0" and not self._meta["batch_mode"]: self.send_frontend_msg( "cell-kernel", [self._meta["cell_id"], self.kernel] ) if code is None or not code.strip(): return try: # We remove leading new line in case that users have a SoS # magic and a cell magic, separated by newline. # issue #58 and #33 return await self.run_cell(code.lstrip(), silent, store_history) except KeyboardInterrupt: self.warn( "KeyboardInterrupt. This will only be captured if the subkernel failed to process the signal.\n" ) return {"status": "abort", "execution_count": self._execution_count} else: # if the cell starts with comment, and newline, remove it lines = code.splitlines() empties = [x.startswith("#") or not x.strip() for x in lines] if not self._meta["batch_mode"]: self.send_frontend_msg("cell-kernel", [self._meta["cell_id"], "SoS"]) if all(empties): return { "status": "ok", "payload": [], "user_expressions": {}, "execution_count": self._execution_count, } idx = empties.index(False) if idx != 0 and (lines[idx].startswith("%") or lines[idx].startswith("!")): # not start from empty, but might have magic etc return await self._do_execute( "\n".join(lines[idx:]) + "\n", silent, store_history, user_expressions, allow_stdin, ) # if there is no more empty, magic etc, enter workflow mode # run sos try: self.run_sos_code(code, silent) return { "status": "ok", "payload": [], "user_expressions": {}, "execution_count": self._execution_count, } except Exception as e: return self.notify_error(e) finally: # even if something goes wrong, we clear output so that the "preview" # will not be viewed by a later step. env.sos_dict.pop("input", None) env.sos_dict.pop("output", None) def do_shutdown(self, restart): if self._shutting_down: return self._shutting_down = True try: for name, (km, _) in self.kernels.items(): try: km.shutdown_kernel(restart=restart) except Exception as e: self.warn(f"Failed to shutdown kernel {name}: {e}") finally: if not restart: self.kernels.clear() self._shutting_down = False def _atexit_shutdown(self): """Ensure all subkernels are shut down when the process exits. This is more reliable than __del__ which is not guaranteed to be called during interpreter shutdown, especially with reference cycles. """ self.do_shutdown(False) def __del__(self): self.do_shutdown(False) # there can only be one comm manager in a ipykernel process _comm_lock = threading.Lock() _comm_manager = None def _get_comm_manager(*args, **kwargs): """Create a new CommManager.""" global _comm_manager # noqa if _comm_manager is None: with _comm_lock: if _comm_manager is None: _comm_manager = SoSCommManager(*args, **kwargs) return _comm_manager comm.get_comm_manager = _get_comm_manager if __name__ == "__main__": from ipykernel.kernelapp import IPKernelApp IPKernelApp.launch_instance(kernel_class=SoS_Kernel) ================================================ FILE: src/sos_notebook/magics.py ================================================ import argparse import builtins import copy import fnmatch import os import pydoc import re import shlex import subprocess import sys from collections import OrderedDict from collections.abc import Sequence, Sized from io import StringIO from types import ModuleType import pandas as pd from IPython.core.error import UsageError from IPython.lib.clipboard import ( ClipboardEmpty, osx_clipboard_get, tkinter_clipboard_get, ) from jupyter_client import find_connection_file from sos._version import __version__ from sos.eval import interpolate from sos.syntax import SOS_SECTION_HEADER from sos.targets import path from sos.utils import env, load_config_files, pexpect_run, pretty_size, short_repr class SoS_Magic: name = "BaseMagic" def __init__(self, kernel): self.sos_kernel = kernel self.pattern = re.compile(rf"%{self.name}(\s|$)") def _interpolate_text(self, text, quiet=False): # interpolate command try: new_text = interpolate(text, local_dict=env.sos_dict._dict) if new_text != text and not quiet: self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", { "metadata": {}, "data": { "text/html": f'
> {new_text.strip() + "
"}
' }, }, ) return new_text except Exception as e: self.sos_kernel.warn(f"Failed to interpolate {short_repr(text)}: {e}\n") return None def get_magic_and_code(self, code, warn_remaining=False): if code.startswith("%") or code.startswith("!"): lines = re.split(r"(? 1 else "" if warn_remaining and remaining_code.strip(): self.sos_kernel.warn(f"Statement {short_repr(remaining_code)} ignored") return command_line, remaining_code def match(self, code): return self.pattern.match(code) def run_shell_command(self, cmd): # interpolate command if not cmd: return try: with self.sos_kernel.redirect_sos_io(): pexpect_run( cmd, shell=True, win_width=40 if self.sos_kernel._meta["cell_id"] == "" else 80, ) except Exception as e: self.sos_kernel.warn(e) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): raise RuntimeError(f"Unimplemented magic {self.name}") def _parse_error(self, msg): self.sos_kernel.warn(msg) class Command_Magic(SoS_Magic): name = "!" def match(self, code): return code.startswith("!") async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) self.run_shell_command(code.split(" ")[0][1:] + " " + options) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Capture_Magic(SoS_Magic): name = "capture" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%capture", description="""Capture output from a subkernel as variable in SoS""", ) parser.add_argument( "msg_type", nargs="?", default="raw", choices=["stdout", "stderr", "text", "markdown", "html", "raw", "error"], help="""Message type to capture. In terms of Jupyter message types, "stdout" refers to "stream" message with "stdout" type, "stderr" refers to "stream" message with "stderr" type, "text", "markdown" and "html" refers to "display_data" or "execute_result" messages with "text/plain", "text/markdown" and "text/html" type respectively, and 'error' refers to "evalue" of "error" messages. If no value or "raw" is specified, all returned messages will be returned in alist format, and will be displayed in the console panel. This will help you determine the right type to capture.""", ) parser.add_argument( "--as", dest="as_type", default="text", nargs="?", choices=("text", "json", "csv", "tsv"), help="""How to interpret the captured text. This only applicable to stdout, stderr and text message type where the text from cell output will be collected. If this option is given, SoS will try to parse the text as json, csv (comma separated text), tsv (tab separated text), and store text (from text), Pandas DataFrame (from csv or tsv), dict or other types (from json) to the variable.""", ) grp = parser.add_mutually_exclusive_group(required=False) grp.add_argument( "-t", "--to", dest="__to__", metavar="VAR", help="""Name of variable to which the captured content will be saved. If no varialbe is specified, the return value will be saved to variable "__captured" and be displayed at the side panel. """, ) grp.add_argument( "-a", "--append", dest="__append__", metavar="VAR", help="""Name of variable to which the captured content will be appended. This option is equivalent to --to if VAR does not exist. If VAR exists and is of the same type of new content (str or dict or DataFrame), the new content will be appended to VAR if VAR is of str (str concatenation), dict (dict update), or DataFrame (DataFrame.append) types. If VAR is of list type, the new content will be appended to the end of the list.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return try: self.sos_kernel._meta["capture_result"] = [] return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) finally: # parse capture_result content = "" if args.msg_type == "stdout": for msg in self.sos_kernel._meta["capture_result"]: if msg[0] == "stream" and msg[1]["name"] == "stdout": content += msg[1]["text"] elif args.msg_type == "stderr": for msg in self.sos_kernel._meta["capture_result"]: if msg[0] == "stream" and msg[1]["name"] == "stderr": content += msg[1]["text"] elif args.msg_type == "text": for msg in self.sos_kernel._meta["capture_result"]: if ( msg[0] == "display_data" and "data" in msg[1] and "text/plain" in msg[1]["data"] ): content += msg[1]["data"]["text/plain"] elif args.msg_type == "markdown": for msg in self.sos_kernel._meta["capture_result"]: if ( msg[0] == "display_data" and "data" in msg[1] and "text/markdown" in msg[1]["data"] ): content += msg[1]["data"]["text/markdown"] elif args.msg_type == "html": for msg in self.sos_kernel._meta["capture_result"]: if ( msg[0] == "display_data" and "data" in msg[1] and "text/html" in msg[1]["data"] ): content += msg[1]["data"]["text/html"] elif args.msg_type == "error": for msg in self.sos_kernel._meta["capture_result"]: if msg[0] == "error" and "evalue" in msg[1]: content += msg[1]["evalue"] else: args.as_type = "raw" content = self.sos_kernel._meta["capture_result"] env.log_to_file( "MAGIC", f"Captured {self.sos_kernel._meta['capture_result'][:40]}" ) if not args.as_type or args.as_type == "text": if not isinstance(content, str): self.sos_kernel.warn( "Option --as is only available for message types stdout, stderr, and text." ) elif args.as_type == "json": import json try: if isinstance(content, str): content = json.loads(content) else: self.sos_kernel.warn( "Option --as is only available for message types stdout, stderr, and text." ) except Exception as e: self.sos_kernel.warn( f"Failed to capture output in JSON format, text returned: {e}" ) elif args.as_type == "csv": try: if isinstance(content, str): with StringIO(content) as ifile: content = pd.read_csv(ifile) else: self.sos_kernel.warn( "Option --as is only available for message types stdout, stderr, and text." ) except Exception as e: self.sos_kernel.warn( f"Failed to capture output in {args.as_type} format, text returned: {e}" ) elif args.as_type == "tsv": try: if isinstance(content, str): with StringIO(content) as ifile: content = pd.read_csv(ifile, sep="\t") else: self.sos_kernel.warn( "Option --as is only available for message types stdout, stderr, and text." ) except Exception as e: self.sos_kernel.warn( f"Failed to capture output in {args.as_type} format, text returned: {e}" ) # if args.__to__ and not args.__to__.isidentifier(): self.sos_kernel.warn(f"Invalid variable name {args.__to__}") self.sos_kernel._meta["capture_result"] = None elif args.__append__ and not args.__append__.isidentifier(): self.sos_kernel.warn(f"Invalid variable name {args.__append__}") self.sos_kernel._meta["capture_result"] = None elif args.__to__: env.sos_dict.set(args.__to__, content) elif args.__append__: if args.__append__ not in env.sos_dict: env.sos_dict.set(args.__append__, content) elif isinstance(env.sos_dict[args.__append__], str): if isinstance(content, str): env.sos_dict[args.__append__] += content else: self.sos_kernel.warn( f"Cannot append new content of type {type(content).__name__} to {args.__append__} of type {type(env.sos_dict[args.__append__]).__name__}" ) elif isinstance(env.sos_dict[args.__append__], dict): if isinstance(content, dict): env.sos_dict[args.__append__].update(content) else: self.sos_kernel.warn( f"Cannot append new content of type {type(content).__name__} to {args.__append__} of type {type(env.sos_dict[args.__append__]).__name__}" ) elif isinstance(env.sos_dict[args.__append__], pd.DataFrame): if isinstance(content, pd.DataFrame): env.sos_dict.set( args.__append__, env.sos_dict[args.__append__].append(content), ) else: self.sos_kernel.warn( f"Cannot append new content of type {type(content).__name__} to {args.__append__} of type {type(env.sos_dict[args.__append__]).__name__}" ) elif isinstance(env.sos_dict[args.__append__], list): env.sos_dict[args.__append__].append(content) else: self.sos_kernel.warn( f"Cannot append new content of type {type(content).__name__} to {args.__append__} of type {type(env.sos_dict[args.__append__]).__name__}" ) else: env.sos_dict.set("__captured", content) import pprint self.sos_kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/html": '
Cell output captured to variable __captured with content
' }, }, ) self.sos_kernel.send_frontend_msg( "display_data", {"metadata": {}, "data": {"text/plain": pprint.pformat(content)}}, ) self.sos_kernel._meta["capture_result"] = None class Cd_Magic(SoS_Magic): name = "cd" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%cd", description="""change directory of SoS and all subkernels.""" ) parser.add_argument("dir", help="""destination directory""") parser.error = self._parse_error return parser async def handle_magic_cd(self, option): if not option: return to_dir = option.strip() try: os.chdir(path(to_dir)) self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", {"name": "stdout", "text": os.getcwd()}, ) except Exception as e: self.sos_kernel.warn( f"Failed to change dir to {os.path.expanduser(to_dir)}: {e}" ) return # cur_kernel = self.sos_kernel.kernel try: for kernel in self.sos_kernel.kernels.keys(): if kernel not in self.sos_kernel.supported_languages: self.sos_kernel.warn( f"Current directory of kernel {kernel} is not changed: unsupported language" ) continue lan = self.sos_kernel.supported_languages[kernel] if hasattr(lan, "cd_command"): try: await self.sos_kernel.switch_kernel(kernel) cmd = interpolate(lan.cd_command, {"dir": str(path(to_dir))}) await self.sos_kernel.run_cell( cmd, True, False, on_error=f"Failed to execute {cmd} in {kernel}", ) except Exception as e: self.sos_kernel.warn( f"Current directory of kernel {kernel} is not changed: {e}" ) else: self.sos_kernel.warn( f"Current directory of kernel {kernel} is not changed: cd_command not defined" ) finally: await self.sos_kernel.switch_kernel(cur_kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return await self.handle_magic_cd(args.dir) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Clear_Magic(SoS_Magic): name = "clear" def __init__(self, kernel): super().__init__(kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): self.sos_kernel.warn("Magic %clear is deprecated.") _, remaining_code = self.get_magic_and_code(code, False) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class ConnectInfo_Magic(SoS_Magic): name = "connectinfo" def __init__(self, kernel): super().__init__(kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): _, remaining_code = self.get_magic_and_code(code, False) cfile = find_connection_file() with open(cfile) as conn: conn_info = conn.read() self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", { "name": "stdout", "text": f"Connection file: {cfile}\n{conn_info}", }, ) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Convert_Magic(SoS_Magic): name = "convert" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%convert", description="""Convert the current notebook to another format.""", ) parser.add_argument( "filename", nargs="?", help="""Filename of saved report or script. Default to notebookname with file extension determined by option --to.""", ) parser.add_argument( "-t", "--to", dest="__to__", choices=["sos", "html"], help="""Destination format, default to html.""", ) parser.add_argument( "-a", "--all", action="store_true", help="""Convert all cells, not only sos workflow cells, to .sos file. The result might not be a valid .sos file.""", ) parser.add_argument( "-f", "--force", action="store_true", help="""If destination file already exists, overwrite it.""", ) parser.add_argument( "--template", default="default-sos-template", help="""Template to generate HTML output. The default template is a template defined by configuration key default-sos-template, or sos-report-toc if such a key does not exist.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): # get the saved filename options, _ = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return if args.filename: filename = args.filename if filename.lower().endswith(".html"): if args.__to__ is None: ftype = "html" elif args.__to__ != "html": self.sos_kernel.warn( f"%sossave to an .html file in {args.__to__} format" ) ftype = args.__to__ else: ftype = "sos" else: ftype = args.__to__ if args.__to__ else "sos" filename = self.sos_kernel._meta["notebook_name"] + "." + ftype filename = os.path.expanduser(filename) if os.path.isfile(filename) and not args.force: raise ValueError(f"Cannot overwrite existing output file {filename}") # self.sos_kernel.send_frontend_msg('preview-workflow', self.sos_kernel._meta['workflow']) if ftype == "sos": # --all is processed from frontend if not self.sos_kernel._meta["workflow"] and not args.all: raise ValueError("No workflow is defined in this notebook.") with open(filename, "w") as script: script.write(self.sos_kernel._meta["workflow"]) else: # convert to sos report from .converter import NotebookToHTMLConverter arg = argparse.Namespace() if args.template == "default-sos-template": cfg = load_config_files() if "default-sos-template" in cfg: arg.template = cfg["default-sos-template"] else: arg.template = "sos-report-toc" else: arg.template = args.template arg.view = False arg.execute = None NotebookToHTMLConverter().convert( self.sos_kernel._meta["notebook_name"] + ".ipynb", filename, sargs=arg, unknown_args=[], ) self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", { "metadata": {}, "data": { "text/plain": f"Notebook saved to {filename}\n", "text/html": f'
Notebook saved to {filename}
', }, }, ) # return except Exception as e: self.sos_kernel.warn(str(e)) msg = { "status": "error", "ename": e.__class__.__name__, "evalue": str(e), "traceback": [], "execution_count": self.sos_kernel._execution_count, } return msg class Debug_Magic(SoS_Magic): name = "debug" def __init__(self, kernel): super().__init__(kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): _, remaining_code = self.get_magic_and_code(code, False) self.sos_kernel.warn( "Magic %debug is deprecated. Please set environment variable SOS_DEBUG to ALL or a comma " "separated topics such as KERNEL, MESSAGE, and MAGIC, and check log messages in ~/.sos/sos_debug.log." ) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Dict_Magic(SoS_Magic): name = "dict" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%dict", description="Inspect or reset SoS dictionary" ) parser.add_argument("vars", nargs="*") parser.add_argument( "-k", "--keys", action="store_true", help="Return only keys" ) parser.add_argument( "-r", "--reset", action="store_true", help="Rest SoS dictionary (clear all user variables)", ) parser.add_argument( "-a", "--all", action="store_true", help="Return all variales, including system functions and variables", ) parser.add_argument( "-d", "--del", nargs="+", metavar="VAR", dest="__del__", help="Remove specified variables from SoS dictionary", ) parser.error = self._parse_error return parser async def handle_magic_dict(self, line): "Magic that displays content of the dictionary" # do not return __builtins__ beacuse it is too long... parser = self.get_parser() try: args = parser.parse_args(shlex.split(line)) except SystemExit: return for x in args.vars: if x not in env.sos_dict: self.sos_kernel.warn( f"Unrecognized sosdict option or variable name {x}" ) return if args.reset: from sos.executor_utils import prepare_env prepare_env("") return if args.__del__: for x in args.__del__: if x in env.sos_dict: env.sos_dict.pop(x) return if args.keys: if args.all: self.sos_kernel.send_result(env.sos_dict._dict.keys()) elif args.vars: self.sos_kernel.send_result(set(args.vars)) else: self.sos_kernel.send_result( {x for x in env.sos_dict._dict.keys() if not x.startswith("__")} - self.sos_kernel.original_keys ) else: if args.all: self.sos_kernel.send_result(env.sos_dict._dict) elif args.vars: self.sos_kernel.send_result( {x: y for x, y in env.sos_dict._dict.items() if x in args.vars} ) else: self.sos_kernel.send_result( { x: y for x, y in env.sos_dict._dict.items() if x not in self.sos_kernel.original_keys and not x.startswith("__") } ) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): # %dict should be the last magic options, remaining_code = self.get_magic_and_code(code, False) await self.handle_magic_dict(options) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Env_Magic(SoS_Magic): name = "env" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%env", description="""Adjust the running environment for the cell, such as running with a new dict, under a different directory, and expect an error from the execution of the cell.""", ) parser.add_argument( "--new", action="store_true", help="""Execute workflow with a fresh SoS environment""", ) parser.add_argument( "--set", nargs="+", help="""Set one more more environment variables. Parameters of this option can be 'KEY=VALUE' or just 'KEY'. An empty evnironment variable will be set in the latter case. Note that the environments will be reset out of the cell.""", ) parser.add_argument( "--prepend-path", nargs="+", help="""Prepend one or more paths before "$PATH" so that commands in those paths will take priority. Note that `$PATH` will be reset after the completion of the cell.""", ) parser.add_argument( "--tempdir", action="store_true", help="""Execute workflow in temporary directory, which will be removed after the completion of the cell. Therefore you cannot use this option when running the cell content in background mode.""", ) parser.add_argument( "--expect-error", action="store_true", help="""If set, expect error from the excution and report success if an error occurs, and report error if an error does not occur.""", ) parser.add_argument( "--allow-error", action="store_true", help="""If set, return success even if the underlying cell reports error.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): import shutil import tempfile options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return try: old_dict = env.sos_dict new_dir = None original_env = None if args.new: from sos.eval import SoS_exec from sos.utils import WorkflowDict env.sos_dict = WorkflowDict() SoS_exec("from sos.runtime import *", None) env.sos_dict.set("__interactive__", True) env.sos_dict.set("CONFIG", old_dict["CONFIG"]) old_dir = os.getcwd() if args.tempdir: new_dir = tempfile.mkdtemp() env.exec_dir = os.path.abspath(new_dir) os.chdir(new_dir) if args.set or args.prepend_path: original_env = copy.deepcopy(os.environ) if args.set: for item in args.set: if "=" in item: key, value = item.split("=", 1) else: key = item value = "" os.environ[key] = value if args.prepend_path: new_path = os.pathsep.join(args.prepend_path) if new_path: os.environ["PATH"] = os.pathsep.join( [new_path, os.environ.get("PATH", "")] ) if args.expect_error or args.allow_error: self.sos_kernel._meta["suppress_error"] = True ret = await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) if args.expect_error: if ret["status"] == "error": # self.sos_kernel.warn('\nSandbox execution failed.') return { "status": "ok", "payload": [], "user_expressions": {}, "execution_count": self.sos_kernel._execution_count, } return self.sos_kernel.notify_error( RuntimeError("No error received with option --expect error.") ) if args.allow_error: return { "status": "ok", "payload": [], "user_expressions": {}, "execution_count": self.sos_kernel._execution_count, } return ret finally: env.sos_dict = old_dict if new_dir is not None: os.chdir(old_dir) shutil.rmtree(new_dir) if original_env is not None: os.environ.clear() os.environ.update(original_env) self.sos_kernel._meta["suppress_error"] = False class Expand_Magic(SoS_Magic): name = "expand" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%expand", description="""Expand the script in the current cell with default ({}) or specified sigil.""", ) parser.add_argument( "sigil", nargs="?", help="""Sigil to be used to interpolated the texts. It can be quoted, or be specified as two options.""", ) parser.add_argument( "right_sigil", nargs="?", help="""Right sigil if the sigil is specified as two pieces.""", ) parser.add_argument( "-i", "--in", dest="kernel", help="""Expand the cell content in specific kernel, default to "SoS". This requires that the language module supports the "expand" featire.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): lines = code.splitlines() options = lines[0] parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)[1:]) except SystemExit: return if self.sos_kernel.kernel.lower() == "sos": self.sos_kernel.warn("Use of %expand magic in SoS cells is deprecated.") if args.sigil in ("None", None): args.sigil = "{ }" if args.right_sigil is not None: args.sigil = f"{args.sigil} {args.right_sigil}" # now we need to expand the text, but separate the SoS magics first lines = lines[1:] start_line: int = 0 for idx, line in enumerate(lines): if ( line.strip() and not any(line.startswith(f"%{x} ") for x in SoS_Magics.names) and not line.startswith("!") ): start_line = idx break text = "\n".join(lines[start_line:]) try: expanded = await self.sos_kernel.expand_text_in( text, args.sigil, kernel=args.kernel ) remaining_code = "\n".join(lines[:start_line] + [expanded]) + "\n" # self.sos_kernel.options will be set to inflence the execution of remaing_code return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) except Exception as e: self.sos_kernel.warn(e) return class Get_Magic(SoS_Magic): name = "get" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%get", description="""Get specified variables from another kernel, which is by default the SoS kernel.""", ) parser.add_argument( "--from", dest="__from__", help="""Name of kernel from which the variables will be obtained. Default to the SoS kernel.""", ) parser.add_argument( "--as", dest="__as__", help="""Name of the variable that will be saved in the destination kernel, default to the name of the original variable.""", ) parser.add_argument( "vars", nargs="*", help="""Names of SoS variables, or one name or expression if option --as is used (e.g. var.attribute --as another_name).""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return except Exception as e: return self.sos_kernel.notify_error(e) await self.sos_kernel.get_vars_from( args.vars, args.__from__, explicit=True, as_var=args.__as__ ) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Matplotlib_Magic(SoS_Magic): name = "matplotlib" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%matplotlib", description="""Set matplotlib parser type""" ) parser.add_argument( "gui", choices=[ "agg", "gtk", "gtk3", "inline", "ipympl", "nbagg", "notebook", "osx", "pdf", "ps", "qt", "qt4", "qt5", "svg", "tk", "widget", "wx", ], nargs="?", help="""Name of the matplotlib backend to use (‘agg’, ‘gtk’, ‘gtk3’,""", ) parser.add_argument( "-l", "--list", action="store_true", help="""Show available matplotlib backends""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return if args.list: self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", { "name": "stdout", "text": "Available matplotlib backends: {}".format( [ "agg", "gtk", "gtk3", "inline", "ipympl", "nbagg", "notebook", "osx", "pdf", "ps", "qt", "qt4", "qt5", "svg", "tk", "widget", "wx", ] ), }, ) return try: _, backend = self.sos_kernel.shell.enable_matplotlib(args.gui) if not args.gui or args.gui == "auto": self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", {"name": "stdout", "text": f"Using matplotlib backend {backend}"}, ) except Exception as e: self.sos_kernel.warn(f"Failed to set matplotlib backnd {options}: {e}") return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Paste_Magic(SoS_Magic): name = "paste" def __init__(self, kernel): super().__init__(kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): if self.sos_kernel._meta.get("batch_mode", False): return options, _ = self.get_magic_and_code(code, True) try: self.sos_kernel.options = options try: if sys.platform == "darwin": try: code = osx_clipboard_get() except Exception: code = tkinter_clipboard_get() else: code = tkinter_clipboard_get() except ClipboardEmpty as e: raise UsageError("The clipboard appears to be empty") from e except Exception as e: env.logger.warn(f"Failed to get text from the clipboard: {e}") return # self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", { "name": "stdout", "text": code.strip() + "\n## -- End pasted text --\n", }, ) return await self.sos_kernel._do_execute( code, silent, store_history, user_expressions, allow_stdin ) finally: self.sos_kernel.options = "" class Preview_Magic(SoS_Magic): name = "preview" def __init__(self, kernel): super().__init__(kernel) self.previewers = None def preview_var(self, item, style=None): if item in env.sos_dict: obj = env.sos_dict[item] elif item in dir(builtins): obj = getattr(builtins, item) else: return None, f"Unknown variable {item}" # get the basic information of object txt = type(obj).__name__ # we could potentially check the shape of data frame and matrix # but then we will need to import the numpy and pandas libraries if hasattr(obj, "shape") and obj.shape is not None: txt += f" of shape {obj.shape}" elif isinstance(obj, Sized): txt += f" of length {obj.__len__()}" if isinstance(obj, ModuleType): return txt, ( {"text/plain": pydoc.render_doc(obj, renderer=pydoc.plaintext)}, {}, ) if callable(obj): return txt, ( {"text/plain": pydoc.render_doc(obj, renderer=pydoc.plaintext)}, {}, ) if hasattr(obj, "to_html") and obj.to_html is not None: try: from sos.visualize import Visualizer result = Visualizer(self.sos_kernel, style).preview(obj) if isinstance(result, (list, tuple)) and len(result) == 2: return txt, result if isinstance(result, dict): return txt, (result, {}) if result is None: return txt, None raise ValueError( f"Unrecognized return value from visualizer: {short_repr(result)}." ) except Exception as e: self.sos_kernel.warn(f"Failed to preview variable: {e}") return txt, self.sos_kernel.format_obj(obj) return txt, self.sos_kernel.format_obj(obj) def show_preview_result(self, result): if not result: return if isinstance(result, str): if result.startswith("HINT: "): result = result.splitlines() hint_line = result[0][6:].strip() result = "\n".join(result[1:]) self.sos_kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/html": f'
{hint_line}
' }, }, ) if result: self.sos_kernel.send_frontend_msg( "stream", {"name": "stdout", "text": result}, ) elif isinstance(result, dict): self.sos_kernel.send_frontend_msg( "display_data", {"data": result, "metadata": {}}, ) elif isinstance(result, (list, tuple)) and len(result) == 2: self.sos_kernel.send_frontend_msg( "display_data", {"data": result[0], "metadata": result[1]}, ) else: self.sos_kernel.send_frontend_msg( "stream", {"name": "stderr", "text": f"Unrecognized preview content: {result}"}, ) def preview_file(self, filename, style=None): if not os.path.isfile(filename): self.sos_kernel.warn("\n> " + filename + " does not exist") return self.sos_kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/plain": f"\n> {filename} ({pretty_size(os.path.getsize(filename))}):", "text/html": f'
> {filename} ({pretty_size(os.path.getsize(filename))}):
', }, }, ) previewer_func = None # lazy import of previewers if self.previewers is None: from sos.preview import get_previewers self.previewers = get_previewers() for x, y, _ in self.previewers: if isinstance(x, str): if fnmatch.fnmatch(os.path.basename(filename), x): # we load entrypoint only before it is used. This is to avoid # loading previewers that require additional external modules # we can cache the loaded function but there does not seem to be # a strong performance need for this. previewer_func = y.load() break else: # it should be a function try: if x(filename): try: previewer_func = y.load() except Exception as e: self.sos_kernel.send_frontend_msg( "stream", { "name": "stderr", "text": f"Failed to load previewer {y}: {e}", }, ) continue break except Exception as e: self.sos_kernel.send_frontend_msg( "stream", {"name": "stderr", "text": str(e)} ) continue # # if no previewer can be found if previewer_func is None: return try: result = previewer_func(filename, self.sos_kernel, style) self.show_preview_result(result) except Exception as e: env.log_to_file("MAGIC", f"Failed to preview {filename}: {e}") def get_parser(self): parser = argparse.ArgumentParser( prog="%preview", description="""Preview files, sos variables, or expressions in the side panel, or notebook if side panel is not opened, unless options --panel or --notebook is specified.""", ) parser.add_argument( "items", nargs="*", help="""Filename, variable name, or expression. Wildcard characters such as '*' and '?' are allowed for filenames.""", ) parser.add_argument( "-k", "--kernel", help="""kernel in which variables will be previewed. By default the variable will be previewed in the current kernel of the cell.""", ) parser.add_argument( "-w", "--workflow", action="store_true", help="""Preview notebook workflow""", ) # this option is currently hidden parser.add_argument( "-s", "--style", choices=["table", "scatterplot", "png"], help="""Option for preview file or variable, which by default is "table" for Pandas DataFrame. The %%preview magic also accepts arbitrary additional keyword arguments, which would be interpreted by individual style. Passing '-h' with '--style' would display the usage information of particular style.""", ) parser.add_argument( "-r", "--host", dest="host", metavar="HOST", help="""Preview files on specified remote host, which should be one of the hosts defined in sos configuration files.""", ) loc = parser.add_mutually_exclusive_group() loc.add_argument( "-p", "--panel", action="store_true", help="""Preview in side panel even if the panel is currently closed""", ) loc.add_argument( "-n", "--notebook", action="store_true", help="""Preview in the main notebook.""", ) parser.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global or local sos config.yml files.""", ) parser.error = self._parse_error return parser async def handle_magic_preview(self, items, kernel=None, style=None): handled = [False for x in items] for idx, item in enumerate(items): try: # quoted if (item.startswith('"') and item.endswith('"')) or ( item.startswith("'") and item.endswith("'") ): try: item = eval(item) except Exception: pass item = os.path.expanduser(item) if os.path.isfile(item): self.preview_file(item, style) handled[idx] = True continue if os.path.isdir(item): handled[idx] = True _, dirs, files = os.walk(item).__next__() self.sos_kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/plain": ">>> " + item + ":\n", "text/html": f'
> {item}: directory
{len(files)} file{"s" if len(files) > 1 else ""}
{len(dirs)} subdirector{"y" if len(dirs) <= 1 else "ies"}
', }, }, ) continue import glob files = glob.glob(item) if files: for pfile in files: self.preview_file(pfile, style) handled[idx] = True continue except Exception as e: self.sos_kernel.warn(f"\n> Failed to preview file {item}: {e}") continue # non-sos kernel use_sos = kernel in ("sos", "SoS") or ( kernel is None and self.sos_kernel.kernel == "SoS" ) orig_kernel = self.sos_kernel.kernel if ( kernel is not None and self.sos_kernel.kernel != self.sos_kernel.subkernels.find(kernel).name ): await self.sos_kernel.switch_kernel(kernel) if self.sos_kernel._meta["use_panel"]: self.sos_kernel.send_frontend_msg("preview-kernel", self.sos_kernel.kernel) try: for idx, item in enumerate(items): try: # quoted if (item.startswith('"') and item.endswith('"')) or ( item.startswith("'") and item.endswith("'") ): try: item = eval(item) except Exception: pass if use_sos: obj_desc, preview = self.preview_var(item, style) if ( isinstance(preview, str) and preview.startswith("Unknown variable") and handled[idx] ): continue self.sos_kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/plain": ">>> " + item + ":\n", "text/html": f'
> {item}: {obj_desc}
', }, }, ) self.show_preview_result(preview) continue # not sos if self.sos_kernel.kernel in self.sos_kernel.supported_languages: lan = self.sos_kernel.supported_languages[ self.sos_kernel.kernel ] kinfo = self.sos_kernel.subkernels.find(self.sos_kernel.kernel) lan_obj = lan(self.sos_kernel, kinfo.kernel) if hasattr(lan_obj, "preview") and callable(lan_obj.preview): try: obj_desc, preview = lan_obj.preview(item) if ( preview.startswith("Unknown variable") and handled[idx] ): continue self.sos_kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/plain": ">>> " + item + ":\n", "text/html": f'
> {item}: {obj_desc}
', }, }, ) self.show_preview_result(preview) except Exception: pass # self.sos_kernel.warn(f'Failed to preview {item}: {e}') continue # if no preview function defined # evaluate the expression itself responses = self.sos_kernel.get_response( item, ["stream", "display_data", "execute_result", "error"] ) if responses: self.sos_kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/plain": ">>> " + item + ":\n", "text/html": f'
> {item}:
', }, }, ) for response in responses: # self.sos_kernel.warn(f'{response[0]} {response[1]}' ) if response[0] == "execute_result": self.sos_kernel.send_frontend_msg( "display_data", response[1] ) else: self.sos_kernel.send_frontend_msg( response[0], response[1] ) else: raise ValueError(f"Cannot preview expresison {item}") except Exception as e: if not handled[idx]: self.sos_kernel.send_frontend_msg( "stream", { "name": "stderr", "text": "> Failed to preview file or expression {item}", }, ) env.log_to_file("MAGIC", str(e)) finally: await self.sos_kernel.switch_kernel(orig_kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() options = shlex.split(options, posix=False) help_option = [] if ("-s" in options or "--style" in options) and "-h" in options: # defer -h to subparser options.remove("-h") help_option = ["-h"] try: args, style_options = parser.parse_known_args(options) except SystemExit: return # style_options.extend(help_option) style = {"style": args.style, "options": style_options} # if args.panel: self.sos_kernel._meta["use_panel"] = True elif args.notebook: self.sos_kernel._meta["use_panel"] = False # else, use default _use_panel try: # inside a %preview magic, auto preview will be disabled self.sos_kernel._no_auto_preview = True self.sos_kernel._meta["auto_preview"] = False return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) finally: self.sos_kernel._no_auto_preview = False # preview workflow if args.workflow: if self.sos_kernel._meta["batch_mode"]: # in batch mode, we cannot use codemirror to format a textarea # and will send the workflow as plain text. # we could send pygments highlighted code to the HTML file, but # adding css is another hassle. self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", {"name": "stdout", "text": self.sos_kernel._meta["workflow"]}, ) else: import random ta_id = f"preview_wf_{random.randint(1, 1000000)}" self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", { "data": { "text/plain": self.sos_kernel._meta["workflow"], "text/html": f'', }, "metadata": {}, "transient": {"display_id": ta_id}, }, ) self.sos_kernel.send_frontend_msg( "highlight-workflow", [self.sos_kernel._meta["cell_id"], ta_id] ) if args.items: if args.host is None: await self.handle_magic_preview(args.items, args.kernel, style) elif args.workflow: self.sos_kernel.warn("Invalid option --kernel with -r (--host)") elif args.kernel: self.sos_kernel.warn("Invalid option --kernel with -r (--host)") else: load_config_files(args.config) try: rargs = ["sos", "preview", "--html"] + options rargs = [ x for x in rargs if x not in ("-n", "--notebook", "-p", "--panel") ] env.log_to_file("MAGIC", f'Running "{" ".join(rargs)}"') for msg in eval(subprocess.check_output(rargs)): self.sos_kernel.send_frontend_msg(msg[0], msg[1]) except Exception as e: self.sos_kernel.warn( f"Failed to preview {args.items} on remote host {args.host}" ) env.log_to_file("MAGIC", str(e)) class Pull_Magic(SoS_Magic): name = "pull" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( "pull", description="""Pull files or directories from remote host to local host""", ) parser.add_argument( "items", nargs="+", help="""Files or directories to be retrieved from remote host. The files should be relative to local file system. The files to retrieve are determined by "path_map" determined by "paths" definitions of local and remote hosts.""", ) parser.add_argument( "-f", "--from", dest="host", help="""Remote host to which the files will be sent, which should be one of the hosts defined in sos configuration files.""", ) parser.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global or local sos config.yml files.""", ) parser.add_argument( "-v", "--verbosity", type=int, choices=range(5), default=2, help="""Output error (0), warning (1), info (2), and debug (3) information to standard output (default to 2).""", ) parser.error = self._parse_error return parser async def handle_magic_pull(self, args): from sos.hosts import Host load_config_files(args.config) try: host = Host(args.host) # received = host.receive_from_host(args.items) # msg = "{} item{} received from {}:
{}".format( len(received), " is" if len(received) <= 1 else "s are", args.host, "
".join([f"{x} <= {received[x]}" for x in sorted(received.keys())]), ) self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", { "metadata": {}, "data": {"text/html": f'
{msg}
'}, }, ) except Exception as e: self.sos_kernel.warn(f"Failed to retrieve {', '.join(args.items)}: {e}") async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return except Exception as e: return self.sos_kernel.notify_error(e) await self.handle_magic_pull(args) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Push_Magic(SoS_Magic): name = "push" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( "push", description="""Push local files or directory to a remote host""" ) parser.add_argument( "items", nargs="+", help="""Files or directories to be sent to remote host. The location of remote files are determined by "path_map" determined by "paths" definitions of local and remote hosts.""", ) parser.add_argument( "-t", "--to", dest="host", help="""Remote host to which the files will be sent. SoS will list all configured queues if no such key is defined""", ) parser.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global or local sos config.yml files.""", ) parser.add_argument( "-v", "--verbosity", type=int, choices=range(5), default=2, help="""Output error (0), warning (1), info (2), and debug (3) information to standard output (default to 2).""", ) parser.error = self._parse_error return parser async def handle_magic_push(self, args): from sos.hosts import Host load_config_files(args.config) try: host = Host(args.host) # sent = host.send_to_host(args.items) # msg = "{} item{} sent to {}:
{}".format( len(sent), " is" if len(sent) <= 1 else "s are", args.host, "
".join([f"{x} => {sent[x]}" for x in sorted(sent.keys())]), ) self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", { "metadata": {}, "data": {"text/html": f'
{msg}
'}, }, ) except Exception as e: self.sos_kernel.warn(f"Failed to send {', '.join(args.items)}: {e}") async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return except Exception as e: return self.sos_kernel.notify_error(e) await self.handle_magic_push(args) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Put_Magic(SoS_Magic): name = "put" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%put", description="""Put specified variables in the subkernel to another kernel, which is by default the SoS kernel.""", ) parser.add_argument( "--to", dest="__to__", help="""Name of kernel from which the variables will be obtained. Default to the SoS kernel.""", ) parser.add_argument( "--as", dest="__as__", help="""Name of the variable that will be saved in the destination kernel, default to the name of the original variable.""", ) parser.add_argument( "vars", nargs="*", help="""Names of SoS variables, or one name or expression if option --as is used (e.g. var.attribute --as another_name).""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return except Exception as e: return self.sos_kernel.notify_error(e) try: return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) finally: await self.sos_kernel.put_vars_to( args.vars, args.__to__, explicit=True, as_var=args.__as__ ) class Render_Magic(SoS_Magic): name = "render" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%render", description="""Treat the output of a SoS cell as another format, default to markdown.""", ) parser.add_argument( "msg_type", default="stdout", choices=["stdout", "text"], nargs="?", help="""Message type to capture, default to standard output. In terms of Jupyter message types, "stdout" refers to "stream" message with "stdout" type, and "text" refers to "display_data" message with "text/plain" type.""", ) parser.add_argument( "--as", dest="as_type", default="Markdown", nargs="?", help="""Format to render output of cell, default to Markdown, but can be any format that is supported by the IPython.display module such as HTML, Math, JSON, JavaScript and SVG.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return try: self.sos_kernel._meta["capture_result"] = [] self.sos_kernel._meta["render_result"] = args.as_type return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) finally: content = "" if args.msg_type == "stdout": for msg in self.sos_kernel._meta["capture_result"]: if msg[0] == "stream" and msg[1]["name"] == "stdout": content += msg[1]["text"] elif args.msg_type == "text": for msg in self.sos_kernel._meta["capture_result"]: if ( msg[0] == "display_data" and "data" in msg[1] and "text/plain" in msg[1]["data"] ): content += msg[1]["data"]["text/plain"] try: if content: format_dict, md_dict = self.sos_kernel.format_obj( self.sos_kernel.render_result(content) ) self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", {"metadata": md_dict, "data": format_dict}, ) finally: self.sos_kernel._meta["capture_result"] = None self.sos_kernel._meta["render_result"] = False class Runfile_Magic(SoS_Magic): name = "runfile" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%runfile", description="""Execute an external SoS script, which is identical to run !sos run script but allows the display of task and workflow status in notebook. It also accepts default parameters of %set magic.""", ) parser.add_argument("script", help="""Script to be executed.""") parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) if options.strip().endswith("&"): self.sos_kernel._meta["workflow_mode"] = "nowait" options = options[:-1] else: self.sos_kernel._meta["workflow_mode"] = "wait" parser = self.get_parser() try: args, run_options = parser.parse_known_args(shlex.split(options)) except SystemExit: return self.sos_kernel.options = " ".join(run_options) try: if os.path.isfile(os.path.expanduser(args.script)): if args.script.endswith(".ipynb"): from sos.converter import extract_workflow content = extract_workflow(os.path.expanduser(args.script)) else: with open(os.path.expanduser(args.script)) as script: content = script.read() elif os.path.isfile(os.path.expanduser(args.script + ".sos")): with open(os.path.expanduser(args.script + ".sos")) as script: content = script.read() elif os.path.isfile(os.path.expanduser(args.script + ".ipynb")): from sos.converter import extract_workflow content = extract_workflow(os.path.expanduser(args.script + ".ipynb")) else: raise RuntimeError( f"{args.script}, {args.script}.sos or {args.script}.ipynb) does not exist." ) if self.sos_kernel.kernel != "SoS": self.sos_kernel.switch_kernel("SoS") ret = await self.sos_kernel._do_execute( content, silent, store_history, user_expressions, allow_stdin ) if ret["status"] == "error": return ret except Exception as e: self.sos_kernel.warn(f"Failed to execute workflow: {e}") raise finally: self.sos_kernel._meta["workflow_mode"] = False self.sos_kernel.options = "" return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Revisions_Magic(SoS_Magic): name = "revisions" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%revision", description="""Revision history of the document, parsed from the log message of the notebook if it is kept in a git repository. Additional parameters to "git log" command (e.g. -n 5 --since --after) could be specified to limit the revisions to display.""", ) parser.add_argument( "-s", "--source", nargs="?", default="", help="""Source URL to to create links for revisions. SoS automatically parse source URL of the origin and provides variables "repo" for complete origin URL without trailing ".git" (e.g. https://github.com/vatlab/sos-notebook), "path" for complete path name (e.g. src/document/doc.ipynb), "filename" for only the name of the "path", and "revision" for revisions. Because sos interpolates command line by default, variables in URL template should be included with double braceses (e.g. --source {{repo}}/blob/{{revision}}/{{path}})). If this option is provided without value and the document is hosted on github, a default template will be provided.""", ) parser.add_argument( "-l", "--links", nargs="+", help="""Name and URL or additional links for related files (e.g. --links report URL_to_repo ) with URL interpolated as option --source.""", ) parser.error = self._parse_error return parser async def handle_magic_revisions(self, args, unknown_args): filename = self.sos_kernel._meta["notebook_name"] + ".ipynb" nbpath = self.sos_kernel._meta["notebook_path"] revisions = subprocess.check_output( ["git", "log"] + unknown_args + ["--date=short", "--pretty=%H!%cN!%cd!%s", "--", filename] ) revisions = revisions.decode().splitlines() if not revisions: return # args.source is None for --source without option if args.source != "" or args.links: # need to determine origin etc for interpolation try: origin = ( subprocess.check_output(["git", "ls-remote", "--get-url", "origin"]) .decode() .strip() ) repo = origin[:-4] if origin.endswith(".git") else origin except Exception as e: repo = "" env.log_to_file("MAGIC", f"Failed to get repo URL: {e}") if args.source is None: if "github.com" in repo: args.source = "{repo}/blob/{revision}/{nbpath}" env.log_to_file( "MAGIC", f"source is set to {args.source} with repo={repo}" ) else: args.source = "" self.sos_kernel.warn( f"A default source URL is unavailable for repository {repo}" ) text = """ """ for line in revisions: fields = line.split("!", 3) revision = fields[0] fields[0] = f'{fields[0][:7]}' if args.source != "": # source URL URL = interpolate( args.source, { "revision": revision, "repo": repo, "filename": filename, "path": nbpath, }, ) fields[0] = f'{fields[0]}' links = [] if args.links: for i in range(len(args.links) // 2): name = args.links[2 * i] if len(args.links) == 2 * i + 1: continue URL = interpolate( args.links[2 * i + 1], { "revision": revision, "repo": repo, "filename": filename, "path": nbpath, }, ) links.append(f'{name}') if links: fields[0] += " (" + ", ".join(links) + ")" text += "" + "\n".join(f"" for x in fields) + "" text += "
Revision Author Date Message
{x}
" self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", {"metadata": {}, "data": {"text/html": text}}, ) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, True) parser = self.get_parser() try: args, unknown_args = parser.parse_known_args(shlex.split(options)) except SystemExit: return try: await self.handle_magic_revisions(args, unknown_args) except Exception as e: self.sos_kernel.warn(f"Failed to retrieve revisions of notebook: {e}") return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Run_Magic(SoS_Magic): name = "run" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%run", description="""Execute the current cell with specified command line arguments. If the magic ends with "&", it will be sent to a queue to be executed sequentially.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): # there can be multiple %run magic, but there should not be any other magics run_code = code run_options = [] while True: if self.pattern.match(run_code): options, run_code = self.get_magic_and_code(run_code, False) run_options.append(options) else: break # if not run_code.strip(): parser = self.get_parser() try: parser.parse_known_args(shlex.split(options)) except SystemExit: return # if there are more magics after %run, they will be ignored so a warning # is needed. if run_code.lstrip().startswith("%") and not any( run_code.lstrip().startswith(x) for x in ("%include", "%from") ): self.sos_kernel.warn( f"Magic {run_code.split()[0]} after magic %run will be ignored." ) if not any(SOS_SECTION_HEADER.match(line) for line in run_code.splitlines()): run_code = "[default]\n" + run_code # now we need to run the code multiple times with each option for options in run_options: if options.strip().endswith("&"): self.sos_kernel._meta["workflow_mode"] = "nowait" options = options[:-1] else: self.sos_kernel._meta["workflow_mode"] = "wait" self.sos_kernel.options = options try: # %run is executed in its own namespace env.log_to_file("MAGIC", f"Executing\n{run_code}") if self.sos_kernel.kernel != "SoS": self.sos_kernel.switch_kernel("SoS") ret = await self.sos_kernel._do_execute( run_code, silent, store_history, user_expressions, allow_stdin ) except Exception as e: self.sos_kernel.warn(f"Failed to execute workflow: {e}") raise finally: self.sos_kernel._meta["workflow_mode"] = False self.sos_kernel.options = "" return ret class Sandbox_Magic(SoS_Magic): name = "sandbox" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%sandbox", description="""Execute content of a cell in a temporary directory with fresh dictionary (by default).""", ) parser.add_argument( "-d", "--dir", help="""Execute workflow in specified directory. The directory will be created if does not exist, and will not be removed after the completion. """, ) parser.add_argument( "-k", "--keep-dict", action="store_true", help="""Keep current sos dictionary.""", ) parser.add_argument( "-e", "--expect-error", action="store_true", help="""If set, expect error from the excution and report success if an error occurs.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): import shutil import tempfile options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return self.in_sandbox = True try: old_dir = os.getcwd() if args.dir: args.dir = os.path.expanduser(args.dir) if not os.path.isdir(args.dir): os.makedirs(args.dir) env.exec_dir = os.path.abspath(args.dir) os.chdir(args.dir) else: new_dir = tempfile.mkdtemp() env.exec_dir = os.path.abspath(new_dir) os.chdir(new_dir) if not args.keep_dict: old_dict = env.sos_dict env.sos_dict._dict.clear() ret = await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) if args.expect_error and ret["status"] == "error": # self.sos_kernel.warn('\nSandbox execution failed.') return { "status": "ok", "payload": [], "user_expressions": {}, "execution_count": self.sos_kernel._execution_count, } return ret finally: if not args.keep_dict: env.sos_dict = old_dict os.chdir(old_dir) if not args.dir: shutil.rmtree(new_dir) self.in_sandbox = False # env.exec_dir = old_dir class Save_Magic(SoS_Magic): name = "save" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%save", description="""Save the content of the cell to specified file. It ignores magic lines after the %save magic unless a blank line is used to separate the magics and the content to be saved.""", ) parser.add_argument("filename", help="""Filename of saved report or script.""") parser.add_argument( "-r", "--run", action="store_true", help="""Continue to execute the cell once content is saved.""", ) parser.add_argument( "-f", "--force", action="store_true", help="""If destination file already exists, overwrite it.""", ) parser.add_argument( "-a", "--append", action="store_true", help="""If destination file already exists, append to it.""", ) parser.add_argument( "-x", "--set-executable", dest="setx", action="store_true", help="""Set `executable` permission to saved script.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): # if sos kernel ... options, remaining_code = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return filename = os.path.expanduser(args.filename) if os.path.isfile(filename) and not args.force: raise ValueError( f'{filename} already exists. Use "-f" if you would like to overwrite this file.' ) with open(filename, "a" if args.append else "w") as script: line_no = -1 for line in remaining_code.splitlines(): if line.startswith("%") and line_no < 0: continue if line_no <= 0 and not line.strip(): # started line_no = 0 continue line_no += 1 script.write(line + "\n") if args.setx: import stat os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC) about_run = "" if args.run else ", use option -r to also execute the cell." self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", { "metadata": {}, "data": { "text/plain": f"Cell content saved to {filename}{about_run}\n", "text/html": f'
Cell content saved to {filename}{about_run}
', }, }, ) if args.run: return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) return None except Exception as e: return self.sos_kernel.notify_error(e) class SessionInfo_Magic(SoS_Magic): name = "sessioninfo" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%sessioninfo", description="""List the session info of all subkernels, and information stored in variable sessioninfo""", ) parser.add_argument( "-w", "--with", dest="__with__", help="""Name of variable that contains extra information to be appended. This variable should be a dictionary, with keys being the section headers and items being the session information, which can be a string, a list of strings, a dictionary, or a list of `(key, value)` pairs. Encoded strings (bytes) are acceptable in places of strings. """, ) parser.error = self._parse_error return parser async def handle_sessioninfo(self, args): # from sos.utils import loaded_modules result = OrderedDict() # result["SoS"] = [("SoS Version", __version__)] result["SoS"].extend(loaded_modules(env.sos_dict)) # cur_kernel = self.sos_kernel.kernel try: for kernel in self.sos_kernel.kernels.keys(): kinfo = self.sos_kernel.subkernels.find(kernel) await self.sos_kernel.switch_kernel(kernel) result[kernel] = [ ("Kernel", kinfo.kernel), ("Language", kinfo.language), ] if kernel not in self.sos_kernel.supported_languages: continue lan = self.sos_kernel.supported_languages[kernel] if hasattr(lan, "sessioninfo"): try: sinfo = lan(self.sos_kernel, kinfo.kernel).sessioninfo() if isinstance(sinfo, str): result[kernel].append([sinfo]) elif isinstance(sinfo, dict): result[kernel].extend(list(sinfo.items())) elif isinstance(sinfo, list): result[kernel].extend(sinfo) else: self.sos_kernel.warn(f"Unrecognized session info: {sinfo}") except Exception as e: self.sos_kernel.warn( f"Failed to obtain sessioninfo of kernel {kernel}: {e}" ) finally: await self.sos_kernel.switch_kernel(cur_kernel) # if args.__with__: if args.__with__ not in env.sos_dict: self.sos_kernel.warn( f"Variable {args.__with__} not defined for additional session information." ) result.update(env.sos_dict[args.__with__]) # res = "" for key, items in result.items(): res += f'

{key}

\n' res += '\n' if isinstance(items, (str, bytes)): items = [items] elif isinstance(items, dict): items = list(items.items()) for item in items: res += "\n" if isinstance(item, (str, bytes)): res += ( f'\n' ) elif isinstance(item, Sequence): if len(item) == 1: res += f'\n' elif len(item) == 2: res += f"\n" else: self.sos_kernel.warn( f"Invalid session info item of type {item.__class__.__name__}: {short_repr(item)}" ) else: self.sos_kernel.warn( f"Invalid session info item of type {item.__class__.__name__}: {short_repr(item)}" ) res += "\n" res += "
{self.prepare_string(item)}
{self.prepare_string(item[0])}
{self.prepare_string(item[0])}
{self.prepare_string(item[1])}
\n" self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", {"metadata": {}, "data": {"text/html": res}}, ) def prepare_string(self, item): """trim string, and decode if needed""" if isinstance(item, bytes): try: item = item.decode("utf-8") except Exception: return str(item) return item.strip() async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return await self.handle_sessioninfo(args) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Set_Magic(SoS_Magic): name = "set" def __init__(self, kernel): super().__init__(kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): _, remaining_code = self.get_magic_and_code(code, False) self.sos_kernel.warn("Magic %set is deprecated (vatlab/sos-notebook#231)") # self.sos_kernel.options will be set to inflence the execution of remaing_code return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Shutdown_Magic(SoS_Magic): name = "shutdown" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%shutdown", description="""Shutdown or restart specified subkernel""" ) parser.add_argument( "kernel", nargs="?", help="""Name of the kernel to be restarted, default to the current running kernel.""", ) parser.add_argument( "-r", "--restart", action="store_true", help="""Restart the kernel""" ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return self.sos_kernel.shutdown_kernel( args.kernel if args.kernel else self.sos_kernel.kernel, args.restart ) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class SoSRun_Magic(SoS_Magic): name = "sosrun" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%sosrun", description="""Execute the entire notebook with steps consisting of SoS cells (cells with SoS kernel) with section header, with specified command line arguments. Arguments set by magic %set will be appended at the end of command line. If the magic ends with "&", it will be sent to a queue to be executed sequentially.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: # only show message with %sosrun -h, not with any other parameter because # the pipeline can have help message if options.strip() == "-h": parser.parse_args([options]) except SystemExit: return if options.strip().endswith("&"): self.sos_kernel._meta["workflow_mode"] = "nowait" options = options[:-1] else: self.sos_kernel._meta["workflow_mode"] = "wait" self.sos_kernel.options = options try: if self.sos_kernel.kernel != "SoS": await self.sos_kernel.switch_kernel("SoS") # self.sos_kernel.send_frontend_msg('preview-workflow', self.sos_kernel._meta['workflow']) if not self.sos_kernel._meta["workflow"]: self.sos_kernel.warn("Nothing to execute (notebook workflow is empty).") else: await self.sos_kernel._do_execute( self.sos_kernel._meta["workflow"], silent, store_history, user_expressions, allow_stdin, ) except Exception as e: self.sos_kernel.warn(f"Failed to execute workflow: {e}") raise finally: self.sos_kernel._meta["workflow_mode"] = False self.sos_kernel.options = "" return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class SoSSave_Magic(SoS_Magic): name = "sossave" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%sossave", description="""Save the jupyter notebook as workflow (consisting of all sos steps defined in cells starting with section header) or a HTML report to specified file.""", ) parser.add_argument( "filename", nargs="?", help="""Filename of saved report or script. Default to notebookname with file extension determined by option --to.""", ) parser.add_argument( "-t", "--to", dest="__to__", choices=["sos", "html"], help="""Destination format, default to sos.""", ) parser.add_argument( "-c", "--commit", action="store_true", help="""Commit the saved file to git directory using command git commit FILE""", ) parser.add_argument( "-m", "--message", help='''Message for git commit. Default to "save FILENAME"''', ) parser.add_argument( "-p", "--push", action="store_true", help='''Push the commit with command "git push"''', ) parser.add_argument( "-f", "--force", action="store_true", help="""If destination file already exists, overwrite it.""", ) parser.add_argument( "-x", "--set-executable", dest="setx", action="store_true", help="""Set `executable` permission to saved script.""", ) parser.add_argument( "--template", default="default-sos-template", help="""Template to generate HTML output. The default template is a template defined by configuration key default-sos-template, or sos-report-toc if such a key does not exist.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): self.sos_kernel.warn("Magic %sossave is depcated. Please use %convert instead.") # get the saved filename options, _ = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return if args.filename: filename = args.filename if filename.lower().endswith(".html"): if args.__to__ is None: ftype = "html" elif args.__to__ != "html": self.sos_kernel.warn( f"%sossave to an .html file in {args.__to__} format" ) ftype = args.__to__ else: ftype = "sos" else: ftype = args.__to__ if args.__to__ else "sos" filename = self.sos_kernel._meta["notebook_name"] + "." + ftype filename = os.path.expanduser(filename) if os.path.isfile(filename) and not args.force: raise ValueError(f"Cannot overwrite existing output file {filename}") # self.sos_kernel.send_frontend_msg('preview-workflow', self.sos_kernel._meta['workflow']) if ftype == "sos": with open(filename, "w") as script: script.write(self.sos_kernel._meta["workflow"]) if args.setx: import stat os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC) else: # convert to sos report from .converter import NotebookToHTMLConverter arg = argparse.Namespace() if args.template == "default-sos-template": cfg = load_config_files() if "default-sos-template" in cfg: arg.template = cfg["default-sos-template"] else: arg.template = "sos-report-toc" else: arg.template = args.template arg.view = False arg.execute = False NotebookToHTMLConverter().convert( self.sos_kernel._meta["notebook_name"] + ".ipynb", filename, sargs=arg, unknown_args=[], ) self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "display_data", { "metadata": {}, "data": { "text/plain": f"Notebook saved to {filename}\n", "text/html": f'
Notebook saved to {filename}
', }, }, ) # if args.commit: self.run_shell_command( { "git", "commit", filename, "-m", args.message if args.message else f"save {filename}", } ) if args.push: self.run_shell_command(["git", "push"]) return except Exception as e: return self.sos_kernel.notify_error(e) class Task_Magic(SoS_Magic): name = "task" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%task", description="""Get information on specified task. By default sos would query against all running task queues but it would start a task queue and query status if option -q is specified. """, ) subparsers = parser.add_subparsers(help="actions") status = subparsers.add_parser("status", help="task status") status.add_argument( "tasks", nargs="*", help="""ID of the task. All tasks that are releted to the workflow executed under the current directory will be checked if unspecified. There is no need to specify compelete task IDs because SoS will match specified name with tasks starting with these names.""", ) status.add_argument( "-q", "--queue", help="""Check the status of job on specified tasks queue or remote host if the tasks . The queue can be defined in global or local sos configuration file, or a file specified by option --config. A host is assumed to be a remote machine with process type if no configuration is found.""", ) status.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global sos config.yml files.""", ) status.add_argument("-a", "--all", action="store_true", help=argparse.SUPPRESS) status.add_argument( "-v", dest="verbosity", type=int, choices=range(5), default=2, help="""Output error (0), warning (1), info (2), and debug (3) information to standard output (default to 2).""", ) status.add_argument( "-t", "--tags", nargs="*", help="""Only list tasks with one of the specified tags.""", ) status.add_argument( "-s", "--status", nargs="*", help="""Display tasks with one of the specified status.""", ) status.add_argument( "--age", help="""Limit to tasks that are created more than (default) or within specified age. Value of this parameter can be in units s (second), m (minute), h (hour), or d (day, default), or in the foramt of HH:MM:SS, with optional prefix + for older (default) and - for newer than specified age.""", ) status.add_argument("--html", action="store_true", help=argparse.SUPPRESS) status.add_argument( "--numeric-times", action="store_true", help=argparse.SUPPRESS ) status.set_defaults(func=self.status) execute = subparsers.add_parser("execute", help="execute task") execute.add_argument( "tasks", nargs="*", help="""ID of the tasks to be removed. There is no need to specify compelete task IDs because SoS will match specified name with tasks starting with these names. If no task ID is specified, all tasks related to specified workflows (option -w) will be removed.""", ) execute.add_argument( "-q", "--queue", help="""Remove tasks on specified tasks queue or remote host if the tasks . The queue can be defined in global or local sos configuration file, or a file specified by option --config. A host is assumed to be a remote machine with process type if no configuration is found. """, ) execute.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global sos config.yml files.""", ) execute.add_argument( "-v", dest="verbosity", type=int, choices=range(5), default=2, help="""Output error (0), warning (1), info (2), and debug (3) information to standard output (default to 2).""", ) execute.set_defaults(func=self.execute) kill = subparsers.add_parser( "kill", help="kill single task or tasks with the same tags" ) kill.add_argument( "tasks", nargs="*", help="""IDs of the tasks that will be killed. There is no need to specify compelete task IDs because SoS will match specified name with tasks starting with these names.""", ) kill.add_argument( "-a", "--all", action="store_true", help="""Kill all tasks in local or specified remote task queue""", ) kill.add_argument( "-q", "--queue", help="""Kill jobs on specified tasks queue or remote host if the tasks . The queue can be defined in global or local sos configuration file, or a file specified by option --config. A host is assumed to be a remote machine with process type if no configuration is found.""", ) kill.add_argument( "-t", "--tags", nargs="*", help="""Only kill tasks with one of the specified tags.""", ) kill.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global sos config.yml files.""", ) kill.add_argument( "-v", "--verbosity", type=int, choices=range(5), default=2, help="""Output error (0), warning (1), info (2), and debug (3) information to standard output (default to 2).""", ) kill.set_defaults(func=self.kill) purge = subparsers.add_parser("purge", help="kill and purge task") purge.add_argument( "tasks", nargs="*", help="""ID of the tasks to be removed. There is no need to specify compelete task IDs because SoS will match specified name with tasks starting with these names. If no task ID is specified, all tasks related to specified workflows (option -w) will be removed.""", ) group = purge.add_mutually_exclusive_group(required=False) group.add_argument( "-a", "--all", action="store_true", help="""Clear all task information on local or specified remote task queue, including tasks created by other workflows.""", ) group.add_argument( "--age", help="""Remove all tasks that are created more than (default) or within specified age. Value of this parameter can be in units s (second), m (minute), h (hour), or d (day, default), or in the foramt of HH:MM:SS, with optional prefix + for older (default) and - for newer than specified age.""", ) group.add_argument( "-s", "--status", nargs="+", help="""Remove all tasks with specified status, which can be pending, submitted, running, completed, failed, and aborted. One of more status can be specified.""", ) group.add_argument( "-t", "--tags", nargs="*", help="""Remove all tsks with one of the specified tags.""", ) purge.add_argument( "-q", "--queue", help="""Remove tasks on specified tasks queue or remote host if the tasks . The queue can be defined in global or local sos configuration file, or a file specified by option --config. A host is assumed to be a remote machine with process type if no configuration is found. """, ) purge.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global sos config.yml files.""", ) purge.add_argument( "-v", dest="verbosity", type=int, choices=range(5), default=2, help="""Output error (0), warning (1), info (2), and debug (3) information to standard output (default to 2).""", ) purge.set_defaults(func=self.purge) parser.error = self._parse_error return parser def status(self, args): from sos.hosts import Host try: host = Host(args.queue) except Exception as e: self.sos_kernel.warn(f"Invalid task queue {args.queue}: {e}") return result = host._task_engine.query_tasks( tasks=args.tasks, check_all=not args.tasks, verbosity=2, html=len(args.tasks) == 1, numeric_times=False, age=args.age, tags=args.tags, status=args.status, ) # now, there is a possibility that the status of the task is different from what # task engine knows (e.g. a task is runfile outside of jupyter). In this case, since we # already get the status, we should update the task engine... # # HTML output if len(args.tasks) == 1: self.sos_kernel.send_frontend_msg( "display_data", {"metadata": {}, "data": {"text/plain": result, "text/html": result}}, ) # Status
completed
status = result.split(">Status<", 1)[-1].split("")[-1] self.sos_kernel.send_frontend_msg( "task_status", { "update_only": True, "queue": host.alias, "task_id": args.tasks[0], "status": status, }, ) else: self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", {"name": "stdout", "text": result}, ) # regular output for line in result.split("\n"): if not line.strip(): continue try: # return creation time, start time, and duration tid, tags, _, tst = line.split("\t") self.sos_kernel.send_frontend_msg( "task_status", { "update_only": True, "queue": host.alias, "task_id": tid, "status": tst, "tags": tags, }, ) except Exception as e: env.logger.warning( f'Unrecognized response "{line}" ({e.__class__.__name__}): {e}' ) def execute(self, args): from sos.hosts import Host try: host = Host(args.queue) except Exception as e: self.sos_kernel.warn(f"Invalid task queue {args.queue}: {e}") return for task in args.tasks: host._task_engine.submit_task(task) self.sos_kernel.send_frontend_msg( "task_status", { "update_only": True, "queue": args.queue, "task_id": task, "status": "pening", }, ) def kill(self, args): # kill specified task from sos.hosts import Host try: host = Host(args.queue) except Exception as e: self.sos_kernel.warn(f"Invalid task queue {args.queue}: {e}") return if args.tasks: # kill specified task ret = host._task_engine.kill_tasks(args.tasks) elif args.tags: ret = host._task_engine.kill_tasks([], tags=args.tags) else: self.sos_kernel.warn("Please specify either a list of task or a tag") return self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", {"name": "stdout", "text": ret} ) for line in ret.split("\n"): if not line.strip(): continue try: # return creation time, start time, and duration tid, tst = line.split("\t") self.sos_kernel.send_frontend_msg( "task_status", { "update_only": True, "queue": args.queue, "task_id": tid, "status": tst, }, ) except Exception as e: env.logger.warning( f'Unrecognized response "{line}" ({e.__class__.__name__}): {e}' ) def purge(self, args): # kill specified task from sos.hosts import Host try: host = Host(args.queue) except Exception as e: self.sos_kernel.warn(f"Invalid task queue {args.queue}: {e}") return ret = host._task_engine.purge_tasks( tasks=args.tasks, purge_all=args.all, age=args.age, status=args.status, tags=args.tags, verbosity=env.verbosity, ) if ret: self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", {"name": "stdout", "text": ret} ) else: self.sos_kernel.send_response( self.sos_kernel.iopub_socket, "stream", {"name": "stderr", "text": "No matching task to purge"}, ) if args.tasks: for task in args.tasks: self.sos_kernel.send_frontend_msg( "task_status", { "update_only": True, "queue": args.queue, "task_id": task, "status": "purged", }, ) else: for tag in args.tags: self.sos_kernel.send_frontend_msg( "task_status", { "update_only": True, "queue": args.queue, "tag": tag, "status": "purged", }, ) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return load_config_files(args.config) args.func(args) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Tasks_Magic(SoS_Magic): name = "tasks" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%tasks", description="""Show a list of tasks from specified queue""" ) parser.add_argument("tasks", nargs="*", help="ID of tasks") parser.add_argument( "-s", "--status", nargs="*", help="""Display tasks of specified status. Default to all.""", ) parser.add_argument( "-q", "--queue", help="""Task queue on which the tasks are retrived.""" ) parser.add_argument( "--age", help="""Limit to tasks that is created more than (default) or within specified age. Value of this parameter can be in units s (second), m (minute), h (hour), or d (day, default), with optional prefix + for older (default) and - for younder than specified age.""", ) parser.add_argument( "-c", "--config", help="""A configuration file with host definitions, in case the definitions are not defined in global or local sos config.yml files.""", ) parser.error = self._parse_error return parser def handle_tasks(self, tasks, queue="localhost", status=None, age=None): from sos.hosts import Host try: host = Host(queue) except Exception as e: self.sos_kernel.warn(f"Invalid task queue {queue}: {e}") return # get all tasks for tid, tst, _ in host._task_engine.monitor_tasks( tasks, status=status, age=age ): self.sos_kernel.send_frontend_msg( "task_status", { "cell_id": self.sos_kernel.cell_id, "queue": queue, "task_id": tid, "status": tst, }, ) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return load_config_files(args.config) self.handle_tasks( args.tasks, args.queue if args.queue else "localhost", args.status, args.age ) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Toc_Magic(SoS_Magic): name = "toc" def __init__(self, kernel): super().__init__(kernel) async def apply(self, code, silent, store_history, user_expressions, allow_stdin): self.sos_kernel.warn("Magic %toc is deprecated.") _, remaining_code = self.get_magic_and_code(code, False) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) class Use_Magic(SoS_Magic): name = "use" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%use", description="""Switch to an existing subkernel or start a new subkernel.""", ) parser.add_argument( "name", nargs="?", default="", help="""Displayed name of kernel to start (if no kernel with name is specified) or switch to (if a kernel with this name is already started). The name is usually a kernel name (e.g. %%use ir) or a language name (e.g. %%use R) in which case the language name will be used. One or more parameters --language or --kernel will need to be specified if a new name is used to start a separate instance of a kernel.""", ) parser.add_argument( "-k", "--kernel", help="""kernel name as displayed in the output of jupyter kernelspec list. Default to the default kernel of selected language (e.g. ir for language R.""", ) parser.add_argument( "-l", "--language", help="""Language extension that enables magics such as %%get and %%put for the kernel, which should be in the name of a registered language (e.g. R), or a specific language module in the format of package.module:class. SoS maitains a list of languages and kernels so this option is only needed for starting a new instance of a kernel. """, ) parser.add_argument( "-c", "--color", help="""Background color of new or existing kernel, which overrides the default color of the language. A special value "default" can be used to reset color to default.""", ) parser.add_argument( "-r", "--restart", action="store_true", help="""Restart the kernel if it is running.""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return except Exception as e: self.sos_kernel.warn(f'Invalid option "{options}": {e}\n') return { "status": "abort", "ename": e.__class__.__name__, "evalue": str(e), "traceback": [], "execution_count": self.sos_kernel._execution_count, } if args.restart and args.name in self.sos_kernel.kernels: self.sos_kernel.shutdown_kernel(args.name) self.sos_kernel.warn(f"{args.name} is shutdown") try: await self.sos_kernel.switch_kernel( args.name, None, args.kernel, args.language, args.color ) return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) except Exception as e: return self.sos_kernel.notify_error(e) class With_Magic(SoS_Magic): name = "with" def __init__(self, kernel): super().__init__(kernel) def get_parser(self): parser = argparse.ArgumentParser( prog="%with", description="""Use specified subkernel to evaluate current cell, with optional input and output variables""", ) parser.add_argument( "name", nargs="?", default="", help="""Name of an existing kernel.""" ) parser.add_argument( "-i", "--in", nargs="*", dest="in_vars", help="Input variables (variables to get from SoS kernel)", ) parser.add_argument( "-o", "--out", nargs="*", dest="out_vars", help="""Output variables (variables to put back to SoS kernel before switching back to the SoS kernel""", ) parser.error = self._parse_error return parser async def apply(self, code, silent, store_history, user_expressions, allow_stdin): options, remaining_code = self.get_magic_and_code(code, False) try: parser = self.get_parser() try: args = parser.parse_args(shlex.split(options)) except SystemExit: return except Exception as e: return self.sos_kernel.notify_error(e) original_kernel = self.sos_kernel.kernel try: await self.sos_kernel.switch_kernel(args.name, args.in_vars) except Exception as e: return self.sos_kernel.notify_error(e) try: return await self.sos_kernel._do_execute( remaining_code, silent, store_history, user_expressions, allow_stdin ) finally: await self.sos_kernel.switch_kernel(original_kernel, args.out_vars) self.sos_kernel.send_frontend_msg( "cell-kernel", [self.sos_kernel._meta["cell_id"], original_kernel] ) class SoS_Magics: magics = [ Command_Magic, Capture_Magic, Cd_Magic, Clear_Magic, ConnectInfo_Magic, Convert_Magic, Debug_Magic, Dict_Magic, Env_Magic, Expand_Magic, Get_Magic, Matplotlib_Magic, Preview_Magic, Pull_Magic, Paste_Magic, Push_Magic, Put_Magic, Render_Magic, Run_Magic, Runfile_Magic, Revisions_Magic, Save_Magic, Set_Magic, SessionInfo_Magic, Shutdown_Magic, SoSRun_Magic, SoSSave_Magic, Task_Magic, Toc_Magic, Sandbox_Magic, Use_Magic, With_Magic, ] names = [x.name for x in magics if x.name != "!"] def __init__(self, kernel=None): self._magics = {x.name: x(kernel) for x in self.magics} def get(self, name): return self._magics[name] def values(self): return self._magics.values() ================================================ FILE: src/sos_notebook/step_executor.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. from sos.hosts import Host from sos.step_executor import Base_Step_Executor from sos.targets import sos_targets from sos.utils import TerminateExecution, env, short_repr class Interactive_Step_Executor(Base_Step_Executor): def __init__(self, step, mode="interactive"): super().__init__(step) self.run_mode = mode self.host = None def init_input_output_vars(self): # we keep these variables (which can be result of stepping through previous statements) # if no input and/or output statement is defined for key in ( "step_input", "_depends", "step_output", "step_depends", "_depends", ): if key not in env.sos_dict: env.sos_dict.set(key, sos_targets([])) if "_output" not in env.sos_dict: env.sos_dict.set("_output", sos_targets(_undetermined=True)) if any(x[0] == ":" and x[1] == "input" for x in self.step.statements): env.sos_dict.set("step_input", sos_targets([])) env.sos_dict.set("_input", sos_targets([])) if any(x[0] == ":" and x[1] == "output" for x in self.step.statements): env.sos_dict.set("step_output", sos_targets([])) env.sos_dict.set("_output", sos_targets([])) env.sos_dict.pop("__default_output__", None) def submit_tasks(self, tasks): if not tasks: return if self.host is None: if "queue" in env.sos_dict["_runtime"]: queue = env.sos_dict["_runtime"]["queue"] elif env.config["default_queue"]: queue = env.config["default_queue"] else: queue = "localhost" self.host = Host(queue) for task in tasks: self.host.submit_task(task) def wait_for_tasks(self, tasks, all_submitted): if not tasks: return {} # when we wait, the "outsiders" also need to see the tags etc # of the tasks so we have to write to the database. #156 env.master_push_socket.send_pyobj(["commit_sig"]) # turn this function to a generator to satisfy the interface, but do not # actually wait for any socket. yield None # wait till the executor responde if all(x == "completed" for x in self.host.check_status(tasks)): if len(tasks) > 4: print( "HINT: {} task{} completed: {}, {}, ..., {}".format( len(tasks), "s" if len(tasks) > 1 else "", f"""{tasks[0][:4]}""", f"""{tasks[1][:4]}""", f"""{tasks[-1][:4]}""", ) ) else: print( "HINT: {} task{} completed: {}".format( len(tasks), "s" if len(tasks) > 1 else "", ",".join( [ f"""{x[:4]}""" for x in tasks ] ), ) ) return self.host.retrieve_results(tasks) res = self.host.check_status(tasks) if all(x not in ("submitted", "pending", "running") for x in res): # completed = [task for task, status in zip(tasks, res) if status == 'completed'] return self.host.retrieve_results(tasks) raise TerminateExecution("Terminate with Running Tasks") def run(self): try: runner = Base_Step_Executor.run(self) yreq = next(runner) while True: yreq = runner.send(yreq) except StopIteration as e: return e.value def log(self, stage=None, msg=None): if stage == "start": env.logger.debug( "{} ``{}``: {}".format( "Checking" if self.run_mode == "dryrun" else "Executing", self.step.step_name(), self.step.comment.strip(), ) ) elif stage == "input": if env.sos_dict["step_input"] is not None: env.logger.debug( "input: ``{}``".format(short_repr(env.sos_dict["step_input"])) ) elif stage == "output": if env.sos_dict["step_output"] is not None: env.logger.debug( "output: ``{}``".format(short_repr(env.sos_dict["step_output"])) ) def wait_for_subworkflows(self, workflow_results): """Wait for results from subworkflows""" raise RuntimeError("Nested workflow is not supported in interactive mode") def handle_unknown_target(self, e): # wait for the clearnce of unknown target yield None raise e def verify_dynamic_targets(self, targets): raise RuntimeError("Dynamic targets are not supported in interative mode") ================================================ FILE: src/sos_notebook/subkernel.py ================================================ import fnmatch from importlib import metadata from sos.utils import env class subkernel: # a class to information on subkernel def __init__( self, name=None, kernel=None, language="", color="", options=None, codemirror_mode="", ): if options is None: options = {} self.name = name self.kernel = kernel self.language = language self.color = color self.options = options self.codemirror_mode = codemirror_mode def __repr__(self): return f"subkernel {self.name} with kernel {self.kernel} for language {self.language} with color {self.color}" class Subkernels: # a collection of subkernels def __init__(self, kernel): self.sos_kernel = kernel self.language_info = kernel.supported_languages from jupyter_client.kernelspec import KernelSpecManager km = KernelSpecManager() specs = km.find_kernel_specs() # get supported languages self._kernel_list = [] lan_map = {} for x in self.language_info.keys(): for lname, knames in kernel.supported_languages[ x ].supported_kernels.items(): for kname in knames: if x != kname: lan_map[kname] = ( lname, self.get_background_color(self.language_info[x], lname), getattr(self.language_info[x], "options", {}), "", ) # kernel_list has the following items # # 1. displayed name # 2. kernel name # 3. language name # 4. color for spec in specs.keys(): if spec == "sos": # the SoS kernel will be default theme color. self._kernel_list.append( subkernel( name="SoS", kernel="sos", options={ "variable_pattern": r"^\s*[_A-Za-z][_A-Za-z0-9\.]*\s*$", "assignment_pattern": r"^\s*([_A-Za-z0-9\.]+)\s*=.*$", }, codemirror_mode="sos", ) ) elif spec in lan_map: # e.g. ir ==> R self._kernel_list.append( subkernel( name=lan_map[spec][0], kernel=spec, language=lan_map[spec][0], color=lan_map[spec][1], options=lan_map[spec][2], ) ) elif any(fnmatch.fnmatch(spec, x) for x in lan_map.keys()): matched = [y for x, y in lan_map.items() if fnmatch.fnmatch(spec, x)][0] self._kernel_list.append( subkernel( name=matched[0], kernel=spec, language=matched[0], color=matched[1], options=matched[2], ) ) else: lan_name = km.get_kernel_spec(spec).language if lan_name == "python": lan_name = "python3" avail_names = [ x for x in lan_map.keys() if x.lower() == lan_name.lower() ] if avail_names: self._kernel_list.append( subkernel( name=spec, kernel=spec, language=lan_map[avail_names[0]][0], color=lan_map[avail_names[0]][1], options=lan_map[avail_names[0]][2], ) ) else: # undefined language also use default theme color self._kernel_list.append( subkernel( name=km.get_kernel_spec(spec).display_name, kernel=spec, language=lan_name, ) ) def kernel_list(self): return self._kernel_list default_cm_mode = { "sos": "", "python": {"name": "python", "version": 3}, "python2": {"name": "python", "version": 2}, "python3": {"name": "python", "version": 3}, "r": "r", "report": "markdown", "pandoc": "markdown", "download": "markdown", "markdown": "markdown", "ruby": "ruby", "sas": "sas", "bash": "shell", "sh": "shell", "julia": "julia", "run": "shell", "javascript": "javascript", "typescript": {"name": "javascript", "typescript": True}, "octave": "octave", "matlab": "octave", } # now, no kernel is found, name has to be a new name and we need some definition # if kernel is defined def add_or_replace(self, kdef): for idx, x in enumerate(self._kernel_list): if x.name == kdef.name: self._kernel_list[idx] = kdef return self._kernel_list[idx] self._kernel_list.append(kdef) return self._kernel_list[-1] def get_background_color(self, plugin, lan): # if a single color is defined, it is used for all supported # languages if isinstance(plugin.background_color, str): # return the same background color for all inquiry return plugin.background_color # return color for specified, or any color if unknown inquiry is made return plugin.background_color.get( lan, next(iter(plugin.background_color.values())) ) def find( self, name, kernel=None, language=None, color=None, codemirror_mode="", notify_frontend=True, ): codemirror_mode = ( codemirror_mode if codemirror_mode else self.default_cm_mode.get("codemirror_mode", codemirror_mode) ) # find from subkernel name def update_existing(idx): x = self._kernel_list[idx] # [Bash, some_sh, ....] # but the provided kernel does not match... if kernel is not None and kernel != x.kernel: # env.logger.warning( # f"Overriding kernel {x.kernel} used by subkernel {x.name} with kernel {kernel}." # ) # self._kernel_list[idx].kernel = kernel if notify_frontend: self.notify_frontend() # similarly, identified by kernel but language names are different if language not in (None, "", "None") and language != x.language: env.logger.warning( f"Overriding language {x.language} used by subkernel {x.name} with language {language}." ) self._kernel_list[idx].language = language if notify_frontend: self.notify_frontend() if codemirror_mode: self._kernel_list[idx].codemirror_mode = codemirror_mode if color is not None: if color == "default": if self._kernel_list[idx].language: self._kernel_list[idx].color = self.get_background_color( self.language_info[self._kernel_list[idx].language], self._kernel_list[idx].language, ) else: self._kernel_list[idx].color = "" else: self._kernel_list[idx].color = color if notify_frontend: self.notify_frontend() # if the language module cannot be loaded for some reason if name in self.sos_kernel._failed_languages: raise self.sos_kernel._failed_languages[name] # find from language name (subkernel name, which is usually language name) for idx, x in enumerate(self._kernel_list): if x.name == name: if x.name == "SoS" or x.language or language is None: update_existing(idx) return x if not kernel: kernel = name break # find from kernel name for idx, x in enumerate(self._kernel_list): if x.kernel == name: # if exist language or no new language defined. if x.language or language is None: update_existing(idx) return x # otherwise, try to use the new language kernel = name break if kernel is not None: # in this case kernel should have been defined in kernel list if kernel not in [x.kernel for x in self._kernel_list]: raise ValueError( f'Unrecognized Jupyter kernel name {kernel}. Please make sure it is properly installed and appear in the output of command "jupyter kenelspec list"' ) # now this a new instance for an existing kernel kdef = [x for x in self._kernel_list if x.kernel == kernel][0] if not language: if color == "default": if kdef.language: color = self.get_background_color( self.language_info[kdef.language], kdef.language ) else: color = kdef.color new_def = self.add_or_replace( subkernel( name, kdef.kernel, kdef.language, kdef.color if color is None else color, getattr(self.language_info[kdef.language], "options", {}) if kdef.language else {}, codemirror_mode=codemirror_mode, ) ) if notify_frontend: self.notify_frontend() return new_def # if language is defined, if ":" in language: # if this is a new module, load it directly mn, attr = language.split(":", 1) try: import importlib module = importlib.import_module(mn) plugin = module for a in attr.split("."): plugin = getattr(plugin, a) self.language_info[name] = plugin # for convenience, we create two entries for, e.g. R and ir # but only if there is no existing definition for ( supported_lan, supported_kernels, ) in plugin.supported_kernels.items(): for supported_kernel in supported_kernels: if ( name != supported_kernel and supported_kernel not in self.language_info ): self.language_info[supported_kernel] = plugin if supported_lan not in self.language_info: self.language_info[supported_lan] = plugin except Exception as e: raise RuntimeError( f"Failed to load language {language}: {e}" ) from e # if color == "default": color = self.get_background_color(plugin, kernel) new_def = self.add_or_replace( subkernel( name, kdef.kernel, kernel, kdef.color if color is None else color, getattr(plugin, "options", {}), codemirror_mode=codemirror_mode, ) ) else: # if should be defined ... if language not in self.language_info: raise RuntimeError( f"Unrecognized language definition {language}, which should be a known language name or a class in the format of package.module:class" ) # self.language_info[name] = self.language_info[language] if color == "default": color = self.get_background_color( self.language_info[name], language ) new_def = self.add_or_replace( subkernel( name, kdef.kernel, language, kdef.color if color is None else color, getattr(self.language_info[name], "options", {}), codemirror_mode=codemirror_mode, ) ) if notify_frontend: self.notify_frontend() return new_def if language is not None: # kernel is not defined and we only have language if ":" in language: # if this is a new module, load it directly mn, attr = language.split(":", 1) try: import importlib module = importlib.import_module(mn) plugin = module for a in attr.split("."): plugin = getattr(plugin, a) self.language_info[name] = plugin except Exception as e: raise RuntimeError( f"Failed to load language {language}: {e}" ) from e avail_kernels = [ y.kernel for y in self._kernel_list if y.kernel in sum(plugin.supported_kernels.values(), []) or any( fnmatch.fnmatch(y.kernel, x) for x in sum(plugin.supported_kernels.values(), []) ) ] if not avail_kernels: raise ValueError( 'Failed to find any of the kernels {} supported by language {}. Please make sure it is properly installed and appear in the output of command "jupyter kenelspec list"'.format( ", ".join(sum(plugin.supported_kernels.values(), [])), language, ) ) # use the first available kernel # find the language that has the kernel lan_name = list( { x: y for x, y in plugin.supported_kernels.items() if avail_kernels[0] in y or any(fnmatch.fnmatch(avail_kernels[0], z) for z in y) }.keys() )[0] if color == "default": color = self.get_background_color(plugin, lan_name) new_def = self.add_or_replace( subkernel( name, avail_kernels[0], lan_name, self.get_background_color(plugin, lan_name) if color is None else color, getattr(plugin, "options", {}), codemirror_mode=codemirror_mode, ) ) else: # if a language name is specified (not a path to module), if should be defined in setup.py if language not in self.language_info: raise RuntimeError(f"Unrecognized language definition {language}") # plugin = self.language_info[language] if language in plugin.supported_kernels: avail_kernels = [ y.kernel for y in self._kernel_list if y.kernel in plugin.supported_kernels[language] or any( fnmatch.fnmatch(y.kernel, x) for x in plugin.supported_kernels[language] ) ] else: avail_kernels = [ y.kernel for y in self._kernel_list if y.kernel in sum(plugin.supported_kernels.values(), []) or any( fnmatch.fnmatch(y.kernel, x) for x in sum(plugin.supported_kernels.values(), []) ) ] if not avail_kernels: raise ValueError( 'Failed to find any of the kernels {} supported by language {}. Please make sure it is properly installed and appear in the output of command "jupyter kenelspec list"'.format( ", ".join( sum( self.language_info[ language ].supported_kernels.values(), [], ) ), language, ) ) new_def = self.add_or_replace( subkernel( name, avail_kernels[0], language, self.get_background_color( self.language_info[language], language ) if color is None or color == "default" else color, getattr(self.language_info[language], "options", {}), codemirror_mode=codemirror_mode, ) ) self.notify_frontend() return new_def # let us check if there is something wrong with the pre-defined language for entrypoint in metadata.entry_points(group="sos_languages"): if entrypoint.name == name: # there must be something wrong, let us trigger the exception here entrypoint.load() # if nothing is triggerred, kernel is not defined, return a general message raise ValueError( f'No subkernel named {name} is found. Please use magic "%use" without option to see a list of available kernels and language modules.' ) def update(self, notebook_kernel_list): for kinfo in notebook_kernel_list: try: # if we can find the kernel, fine... self.find( name=kinfo[0], kernel=kinfo[1], language=kinfo[2], color=kinfo[3], codemirror_mode="" if len(kinfo) >= 4 else kinfo[4], notify_frontend=False, ) except Exception as e: # otherwise do not worry about it. env.logger.warning( f'Failed to locate subkernel {kinfo[0]} with kernel "{kinfo[1]}" and language "{kinfo[2]}": {e}' ) def notify_frontend(self): self._kernel_list.sort(key=lambda x: x.name) self.sos_kernel.send_frontend_msg( "kernel-list", [ [x.name, x.kernel, x.language, x.color, x.codemirror_mode, x.options] for x in self._kernel_list ], ) ================================================ FILE: src/sos_notebook/templates/README.md ================================================ # nbconvert templates for SoS Notebooks Nbconvert templates for exporting SoS Notebooks in various formats. ## Basic Usage: Use command ``` sos convert input.ipynb output.html --template NAME ``` To generate a HTML report from a SoS notebook. ## Templates ### `sos-full` ### `sos-full-toc` ### `sos-markdown` ### `sos-cm` ### `sos-report` ### `sos-report-v1` ### `sos-report-toc` ### `sos-report-toc-v2` ================================================ FILE: src/sos_notebook/templates/sos-cm/conf.json ================================================ { "base_template": "sos-full", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-cm/index.html.j2 ================================================ {% extends 'sos-cm.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-cm/parts/cm.tpl ================================================ {% macro css() %} {% endmacro %} {% macro js() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-cm/parts/sos-mode.js ================================================ /** * Copyright (c) Bo Peng and UT MD Anderson Cancer Center * Distributed under the terms of the Modified BSD License. **/ (function (mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS mod(require("codemirror/lib/codemirror"), require("codemirror/mode/python/python"), require("codemirror/mode/r/r"), require("codemirror/mode/octave/octave"), require("codemirror/mode/ruby/ruby"), require("codemirror/mode/sas/sas"), require("codemirror/mode/javascript/javascript"), require("codemirror/mode/shell/shell"), require("codemirror/mode/julia/julia"), require("codemirror/mode/markdown/markdown"), require("codemirror/mode/htmlembedded/htmlembedded"), require("codemirror/mode/xml/xml"), require("codemirror/mode/yaml/yaml"), require("codemirror/mode/javascript/javascript"), require("codemirror/mode/stex/stex"), require("codemirror/addon/selection/active-line"), require("codemirror/addon/fold/foldcode"), require("codemirror/addon/fold/foldgutter"), require("codemirror/addon/fold/indent-fold"), require("codemirror/addon/display/autorefresh")); else if (typeof define == "function" && define.amd) // AMD define(["codemirror/lib/codemirror", "codemirror/mode/python/python", "codemirror/mode/markdown/markdown", "codemirror/mode/r/r" ], mod); else // Plain browser env mod(CodeMirror); })(function (CodeMirror) { "use strict"; var sosKeywords = ["input", "output", "depends", "parameter"]; var sosActionWords = ["script", "download", "run", "bash", "sh", "csh", "tcsh", "zsh", "python", "python2", "python3", "R", "node", "julia", "matlab", "octave", "ruby", "perl", "report", "pandoc", "docker_build", "Rmarkdown" ]; var sosMagicWords = ['cd', 'capture', 'clear', 'debug', 'dict', 'expand', 'get', 'matplotlib', 'paste', 'preview', 'pull', 'push', 'put', 'render', 'rerun', 'run', 'save', 'sandbox', 'set', 'sessioninfo', 'sosrun', 'sossave', 'shutdown', 'taskinfo', 'tasks', 'toc', 'use', 'with' ] var sosFunctionWords = ["sos_run", "logger", "get_output"]; var hintWords = sosKeywords.concat(sosActionWords).concat(sosFunctionWords) .concat(sosMagicWords); var sosDirectives = sosKeywords.map(x => x + ":"); var sosActions = sosActionWords.map(x => new RegExp("^\\s*" + x + ":")); var sosMagics = sosMagicWords.map(x => '%' + x); // hint word for SoS mode CodeMirror.registerHelper("hintWords", "sos", hintWords); var modeMap = { 'sos': null, 'python': { name: 'python', version: 3 }, 'python2': { name: 'python', version: 2 }, 'python3': { name: 'python', version: 3 }, 'r': 'r', 'report': 'markdown', 'pandoc': 'markdown', 'download': 'markdown', 'markdown': 'markdown', 'ruby': 'ruby', 'sas': 'sas', 'bash': 'shell', 'sh': 'shell', 'julia': 'julia', 'run': 'shell', 'javascript': 'javascript', 'typescript': { name: "javascript", typescript: true }, 'octave': 'octave', 'matlab': 'octave', html: "htmlembedded", xml: "xml", yaml: "yaml", json: { name: "javascript", jsonMode: true }, stex: "stex" }; var extMap = { sos: 'python3', py: "python3", r: "r", md: "markdown", rb: "ruby", sas: "sas", sh: "shell", jl: "julia", js: "javascript", ts: "typecript", m: "matlab", html: "html", xml: "xml", yaml: "yaml", yml: "yaml", json: "json", tex: "stex" }; function findMode(mode) { if (mode in modeMap) { return modeMap[mode]; } return null; } function findModeFromFilename(filename) { if (!filename) { return 'markdown'; } let ext = filename.split('.').pop().toLowerCase(); if (ext in extMap) { return extMap[ext]; } return 'markdown'; } function markExpr(python_mode) { return { startState: function () { return { in_python: false, sigil: null, matched: true, python_state: CodeMirror.startState(python_mode), }; }, copyState: function (state) { return { in_python: state.in_python, sigil: state.sigil, matched: state.matched, python_state: CodeMirror.copyState(python_mode, state.python_state) }; }, token: function (stream, state) { if (state.in_python) { if (stream.match(state.sigil.right)) { state.in_python = false; state.python_state = CodeMirror.startState(python_mode); return "sos-sigil"; } let it = null; try { it = python_mode.token(stream, state.python_state); } catch (error) { return "sos-interpolated error" + (state.matched ? "" : " sos-unmatched"); } if (it == 'variable' || it == 'builtin') { let ct = stream.current(); // warn users in the use of input and output in {} if (ct === 'input' || ct === 'output') it += ' error'; } return (it ? ("sos-interpolated " + it) : "sos-interpolated") + (state.matched ? "" : " sos-unmatched"); } else { // remove the double brace case, the syntax highlighter // does not have to worry (highlight) }}, although it would // probably mark an error for single } if (state.sigil.left === '{' && stream.match(/\{\{/)) return null; if (stream.match(state.sigil.left)) { state.in_python = true; // let us see if there is any right sigil till the end of the editor. try { let rest = stream.string.slice(stream.pos); if (!rest.includes(state.sigil.right)) { state.matched = false; for (let idx = 1; idx < 5; ++idx) { if (stream.lookAhead(idx).includes(state.sigil.right)) { state.matched = true; break; } } } } catch (error) { // only codemirror 5.27.0 supports this function } return "sos-sigil" + (state.matched ? "" : " sos-unmatched"); } while (stream.next() && !stream.match(state.sigil.left, false)) { } return null; } } } } CodeMirror.defineMode("sos", function (conf, parserConf) { let sosPythonConf = {}; for (let prop in parserConf) { if (parserConf.hasOwnProperty(prop)) { sosPythonConf[prop] = parserConf[prop]; } } sosPythonConf.name = 'python'; sosPythonConf.version = 3; sosPythonConf.extra_keywords = sosActionWords.concat(sosFunctionWords); // this is the SoS flavored python mode with more identifiers var base_mode = null; if ('base_mode' in parserConf && parserConf.base_mode && parserConf.base_mode !== 'sos' && parserConf.base_mode !== 'SoS') { let mode = findMode(parserConf.base_mode.toLowerCase()); if (mode) { base_mode = CodeMirror.getMode(conf, mode); } else { console.log(`No base mode is found for ${parserConf.base_mode}. Python mode used.`); } } else if ('base_mode' in conf && conf.base_mode && conf.base_mode !== 'sos' && conf.base_mode !== 'SoS') { let mode = findMode(conf.base_mode.toLowerCase()); if (mode) { base_mode = CodeMirror.getMode(conf, mode); } else { console.log(`No base mode is found for ${conf.base_mode}. Python mode used.`); } } // if there is a user specified base mode, this is the single cell mode if (base_mode) { var python_mode = CodeMirror.getMode({}, { name: 'python', version: 3 }); var overlay_mode = markExpr(python_mode); return { startState: function () { return { sos_mode: true, base_state: CodeMirror.startState(base_mode), overlay_state: CodeMirror.startState(overlay_mode), // for overlay basePos: 0, baseCur: null, overlayPos: 0, overlayCur: null, streamSeen: null }; }, copyState: function (state) { return { sos_mode: state.sos_mode, base_state: CodeMirror.copyState(base_mode, state.base_state), overlay_state: CodeMirror.copyState(overlay_mode, state.overlay_state), // for overlay basePos: state.basePos, baseCur: null, overlayPos: state.overlayPos, overlayCur: null }; }, token: function (stream, state) { if (state.sos_mode) { if (stream.sol()) { let sl = stream.peek(); if (sl == '!') { stream.skipToEnd(); return "meta"; } else if (sl == '#') { stream.skipToEnd(); return 'comment' } for (var i = 0; i < sosMagics.length; i++) { if (stream.match(sosMagics[i])) { if (sosMagics[i] === "%expand") { if (stream.eol() || stream.match(/\s*$/, false)) { state.overlay_state.sigil = { 'left': '{', 'right': '}' } } else { let found = stream.match(/\s+(\S+)\s+(\S+)$/, false); if (found) { state.overlay_state.sigil = { 'left': found[1], 'right': found[2] } } else { state.overlay_state.sigil = null; } } } // the rest of the lines will be processed as Python code return "meta"; } } state.sos_mode = false; } else { stream.skipToEnd(); return null; } } if (state.overlay_state.sigil) { if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) { state.streamSeen = stream; state.basePos = state.overlayPos = stream.start; } if (stream.start == state.basePos) { state.baseCur = base_mode.token(stream, state.base_state); state.basePos = stream.pos; } if (stream.start == state.overlayPos) { stream.pos = stream.start; state.overlayCur = overlay_mode.token(stream, state.overlay_state); state.overlayPos = stream.pos; } stream.pos = Math.min(state.basePos, state.overlayPos); // state.overlay.combineTokens always takes precedence over combine, // unless set to null return state.overlayCur ? state.overlayCur : state.baseCur; } else { return base_mode.token(stream, state.base_state); } }, indent: function (state, textAfter) { // inner indent if (!state.sos_mode) { if (!base_mode.indent) return CodeMirror.Pass; return base_mode.indent(state.base_state, textAfter); } else { // sos mode has no indent return 0; } }, innerMode: function (state) { return state.sos_mode ? { state: state.base_state, mode: base_mode } : null; }, lineComment: "#", fold: "indent" }; } else { // this is SoS mode base_mode = CodeMirror.getMode(conf, sosPythonConf); overlay_mode = markExpr(base_mode); return { startState: function () { return { sos_state: null, base_state: CodeMirror.startState(base_mode), overlay_state: CodeMirror.startState(overlay_mode), inner_mode: null, inner_state: null, // for overlay basePos: 0, baseCur: null, overlayPos: 0, overlayCur: null, streamSeen: null }; }, copyState: function (state) { return { sos_state: state.sos_state, base_state: CodeMirror.copyState(base_mode, state.base_state), overlay_state: CodeMirror.copyState(overlay_mode, state.overlay_state), inner_mode: state.inner_mode, inner_state: state.inner_mode && CodeMirror.copyState(state.inner_mode, state.inner_state), // for overlay basePos: state.basePos, baseCur: null, overlayPos: state.overlayPos, overlayCur: null }; }, token: function (stream, state) { if (stream.sol()) { let sl = stream.peek(); if (sl == '[') { if (stream.match(/^\[.*\]$/, false)) { // if there is : if (stream.match(/^\[[\s\w_,-]+:/)) { state.sos_state = 'header_option'; return "header line-section-header"; } else if (stream.match(/^\[[\s\w,-]+\]$/)) { // reset state state.sos_state = null; state.inner_mode = null; return "header line-section-header"; } } } else if (sl == '!') { stream.eatWhile(/\S/); return "meta"; } else if (sl == '#') { stream.skipToEnd(); return "comment"; } else if (sl == '%') { stream.eatWhile(/\S/); return "meta"; } else if (state.sos_state && state.sos_state.startsWith('entering')) { // the second parameter is starting column let mode = findMode(state.sos_state.slice(9).toLowerCase()); state.inner_mode = CodeMirror.getMode(conf, mode); state.inner_state = CodeMirror.startState(state.inner_mode, stream.indentation()); state.sos_state = null; } for (var i = 0; i < sosDirectives.length; i++) { if (stream.match(sosDirectives[i])) { // the rest of the lines will be processed as Python code state.sos_state = 'directive_option' return "keyword strong"; } } for (var i = 0; i < sosActions.length; i++) { if (stream.match(sosActions[i])) { // switch to submode? if (stream.eol()) { // really let mode = findMode(stream.current().slice(0, -1).toLowerCase()); if (mode) { state.sos_state = "entering " + stream.current().slice(0, -1); } else { state.sos_state = 'unknown_language'; } } else { state.sos_state = 'start ' + stream.current().slice(0, -1); } state.overlay_state.sigil = null; return "builtin strong"; } } // if unknown action if (stream.match(/\w+:/)) { state.overlay_state.sigil = null; state.sos_state = 'start ' + stream.current().slice(0, -1); return "builtin strong"; } } else if (state.sos_state == 'header_option') { // stuff after : if (stream.peek() == ']') { // move next stream.next(); // ] is the last char if (stream.eol()) { state.sos_state = null; state.inner_mode = null; return "header line-section-header"; } else { stream.backUp(1); let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } } else { let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } } else if (state.sos_state == 'directive_option') { // stuff after input:, R: etc if (stream.peek() == ',') { // move next stream.next(); // , is the last char, continue option line if (stream.eol()) { stream.backUp(1); let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } stream.backUp(1); } else if (stream.eol()) { // end of line stops option mode state.sos_state = null; state.inner_mode = null; } let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } else if (state.sos_state && state.sos_state.startsWith("start ")) { // try to understand option expand= if (stream.match(/expand\s*=\s*True/, false)) { // highlight {} state.overlay_state.sigil = { 'left': '{', 'right': '}' } } else { let found = stream.match(/expand\s*=\s*"(\S+) (\S+)"/, false); if (!found) found = stream.match(/expand\s*=\s*'(\S+) (\S+)'/, false); if (found) { state.overlay_state.sigil = { 'left': found[1], 'right': found[2] } } } let mode_string = state.sos_state.slice(6).toLowerCase(); // for report, we need to find "output" option if (mode_string === "report" && stream.match(/^.*output\s*=\s*/, false)) { let found = stream.match(/^.*output\s*=\s*[rRbufF]*"""([^"]+)"""/, false); if (!found) found = stream.match(/^.*output\s*=\s*[rRbufF]*'''([^.]+)'''/, false); if (!found) found = stream.match(/^.*output\s*=\s*[rRbufF]*"([^"]+)"/, false); if (!found) found = stream.match(/^.*output\s*=\s*[rRbufF]*'([^']+)'/, false); // found[1] is the filename state.sos_state = 'start ' + findModeFromFilename(found ? found[1] : found); } let token = base_mode.token(stream, state.base_state); // if it is end of line, ending the starting switch mode if (stream.eol() && stream.peek() !== ',') { // really let mode = findMode(state.sos_state.slice(6).toLowerCase()); if (mode) { state.sos_state = "entering " + state.sos_state.slice(6); } else { state.sos_state = 'unknown_language'; } } return token + ' sos-option'; } // can be start of line but not special if (state.sos_state == 'unknown_language') { // we still handle {} in no man unknown_language if (state.overlay_state.sigil) { return overlay_mode.token(stream, state.overlay_state); } else { stream.skipToEnd(); return null; } } else if (state.inner_mode) { let it = 'sos_script '; if (!state.overlay_state.sigil) { let st = state.inner_mode.token(stream, state.inner_state); return st ? it + st : null; } else { // overlay mode, more complicated if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) { state.streamSeen = stream; state.basePos = state.overlayPos = stream.start; } if (stream.start == state.basePos) { state.baseCur = state.inner_mode.token(stream, state.inner_state); state.basePos = stream.pos; } if (stream.start == state.overlayPos) { stream.pos = stream.start; state.overlayCur = overlay_mode.token(stream, state.overlay_state); state.overlayPos = stream.pos; } stream.pos = Math.min(state.basePos, state.overlayPos); // state.overlay.combineTokens always takes precedence over combine, // unless set to null return (state.overlayCur ? state.overlayCur : state.baseCur) + " sos-script"; } } else { return base_mode.token(stream, state.base_state); } }, indent: function (state, textAfter) { // inner indent if (state.inner_mode) { if (!state.inner_mode.indent) return CodeMirror.Pass; return state.inner_mode.indent(state.inner_mode, textAfter) + 2; } else { return base_mode.indent(state.base_state, textAfter); } }, innerMode: function (state) { return state.inner_mode ? null : { state: state.base_state, mode: base_mode }; }, lineComment: "#", fold: "indent", electricInput: /^\s*[\}\]\)]$/, }; }; }, "python"); CodeMirror.defineMIME("text/x-sos", "sos"); }); ================================================ FILE: src/sos_notebook/templates/sos-cm/sos-cm.html.j2 ================================================ {% extends 'sos-full.html.j2' %} {% import 'parts/cm.tpl' as cm %} {%- block html_head -%} {{ super() | replace(' ', '') }} {{ cm.css() }} {%- endblock html_head %} {% block input %} {%- if cell['metadata'].get('kernel',none) is not none -%}
{% else %} {{ super() }} {%- endif -%} {%- endblock input %} {% block footer_js %} {{ cm.js() }} {{ super() }} {% endblock footer_js %} ================================================ FILE: src/sos_notebook/templates/sos-cm-toc/conf.json ================================================ { "base_template": "sos-cm", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-cm-toc/index.html.j2 ================================================ {% extends 'sos-cm-toc.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-cm-toc/parts/toc.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %} {% endmacro %} {% macro js(headers='h1, h2, h3, h4', remove_only_top_header='true') %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-cm-toc/sos-cm-toc.html.j2 ================================================ {% extends 'sos-cm.html.j2' %} {% import 'parts/toc.tpl' as toc %} {% block html_head %} {{ super() | replace('', '') | replace('', '')}} {{ toc.css() }} {% endblock html_head %} {% block body %}
{{ super() | replace('', '') | replace('', '') | replace('class="container"', 'class="notebook-container"')}}
{% endblock body %} {% block footer_js %} {{ super() }} {% block toc %} {{ toc.js(headers='h1, h2, h3', remove_only_top_header='true') }} {% endblock %} {% endblock footer_js %} {% block markdowncell %} {{ super() | replace('¶', '')}} {%- endblock markdowncell -%} ================================================ FILE: src/sos_notebook/templates/sos-full/conf.json ================================================ { "base_template": "classic", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-full/index.html.j2 ================================================ {% extends 'sos-full.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-full/parts/preview.tpl ================================================ {% macro css() %} {% endmacro %} {% macro js() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-full/parts/sos_style.tpl ================================================ {% macro css() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-full/sos-full.html.j2 ================================================ {% extends 'classic/index.html.j2' %} {% import 'parts/sos_style.tpl' as sos_style %} {% import 'parts/preview.tpl' as preview %} {% block html_head %} {{ super().replace('', '') }} {{ sos_style.css() }} {{ preview.css() }} {{ preview.js() }} {% block header_js %} {% endblock header_js %} {% endblock html_head %} {% block codecell %} {% if cell['metadata'].get('kernel',none) is not none %}
{{ super() }}
{% else %} {{ super() }} {% endif %} {% endblock codecell %} ================================================ FILE: src/sos_notebook/templates/sos-full-toc/conf.json ================================================ { "base_template": "sos-full", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-full-toc/index.html.j2 ================================================ {% extends 'sos-full-toc.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-full-toc/parts/toc.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %} {% endmacro %} {% macro js(headers='h1, h2, h3, h4', remove_only_top_header='true') %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-full-toc/sos-full-toc.html.j2 ================================================ {% extends 'sos-full.html.j2' %} {% import 'parts/toc.tpl' as toc %} {% block html_head %} {{ super() | replace('', '') | replace('', '')}} {{ toc.css() }} {% endblock html_head %} {% block body %}
{{ super() | replace('', '') | replace('', '') | replace('class="container"', 'class="notebook-container"')}}
{% endblock body %} {% block footer_js %} {{ super() }} {{ toc.js() }} {% endblock footer_js %} {% block markdowncell %} {{ super() | replace('¶', '')}} {%- endblock markdowncell -%} ================================================ FILE: src/sos_notebook/templates/sos-lab-cm/conf.json ================================================ { "base_template": "sos-lab-full", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-lab-cm/index.html.j2 ================================================ {% extends 'sos-lab-cm.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-lab-cm/parts/cm.tpl ================================================ {% macro css() %} {% endmacro %} {% macro js() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-lab-cm/parts/sos-mode.js ================================================ /** * Copyright (c) Bo Peng and UT MD Anderson Cancer Center * Distributed under the terms of the Modified BSD License. **/ (function (mod) { if (typeof exports == "object" && typeof module == "object") // CommonJS mod(require("codemirror/lib/codemirror"), require("codemirror/mode/python/python"), require("codemirror/mode/r/r"), require("codemirror/mode/octave/octave"), require("codemirror/mode/ruby/ruby"), require("codemirror/mode/sas/sas"), require("codemirror/mode/javascript/javascript"), require("codemirror/mode/shell/shell"), require("codemirror/mode/julia/julia"), require("codemirror/mode/markdown/markdown"), require("codemirror/mode/htmlembedded/htmlembedded"), require("codemirror/mode/xml/xml"), require("codemirror/mode/yaml/yaml"), require("codemirror/mode/javascript/javascript"), require("codemirror/mode/stex/stex"), require("codemirror/addon/selection/active-line"), require("codemirror/addon/fold/foldcode"), require("codemirror/addon/fold/foldgutter"), require("codemirror/addon/fold/indent-fold"), require("codemirror/addon/display/autorefresh")); else if (typeof define == "function" && define.amd) // AMD define(["codemirror/lib/codemirror", "codemirror/mode/python/python", "codemirror/mode/markdown/markdown", "codemirror/mode/r/r" ], mod); else // Plain browser env mod(CodeMirror); })(function (CodeMirror) { "use strict"; var sosKeywords = ["input", "output", "depends", "parameter"]; var sosActionWords = ["script", "download", "run", "bash", "sh", "csh", "tcsh", "zsh", "python", "python2", "python3", "R", "node", "julia", "matlab", "octave", "ruby", "perl", "report", "pandoc", "docker_build", "Rmarkdown" ]; var sosMagicWords = ['cd', 'capture', 'clear', 'debug', 'dict', 'expand', 'get', 'matplotlib', 'paste', 'preview', 'pull', 'push', 'put', 'render', 'rerun', 'run', 'save', 'sandbox', 'set', 'sessioninfo', 'sosrun', 'sossave', 'shutdown', 'taskinfo', 'tasks', 'toc', 'use', 'with' ] var sosFunctionWords = ["sos_run", "logger", "get_output"]; var hintWords = sosKeywords.concat(sosActionWords).concat(sosFunctionWords) .concat(sosMagicWords); var sosDirectives = sosKeywords.map(x => x + ":"); var sosActions = sosActionWords.map(x => new RegExp("^\\s*" + x + ":")); var sosMagics = sosMagicWords.map(x => '%' + x); // hint word for SoS mode CodeMirror.registerHelper("hintWords", "sos", hintWords); var modeMap = { 'sos': null, 'python': { name: 'python', version: 3 }, 'python2': { name: 'python', version: 2 }, 'python3': { name: 'python', version: 3 }, 'r': 'r', 'report': 'markdown', 'pandoc': 'markdown', 'download': 'markdown', 'markdown': 'markdown', 'ruby': 'ruby', 'sas': 'sas', 'bash': 'shell', 'sh': 'shell', 'julia': 'julia', 'run': 'shell', 'javascript': 'javascript', 'typescript': { name: "javascript", typescript: true }, 'octave': 'octave', 'matlab': 'octave', html: "htmlembedded", xml: "xml", yaml: "yaml", json: { name: "javascript", jsonMode: true }, stex: "stex" }; var extMap = { sos: 'python3', py: "python3", r: "r", md: "markdown", rb: "ruby", sas: "sas", sh: "shell", jl: "julia", js: "javascript", ts: "typecript", m: "matlab", html: "html", xml: "xml", yaml: "yaml", yml: "yaml", json: "json", tex: "stex" }; function findMode(mode) { if (mode in modeMap) { return modeMap[mode]; } return null; } function findModeFromFilename(filename) { if (!filename) { return 'markdown'; } let ext = filename.split('.').pop().toLowerCase(); if (ext in extMap) { return extMap[ext]; } return 'markdown'; } function markExpr(python_mode) { return { startState: function () { return { in_python: false, sigil: null, matched: true, python_state: CodeMirror.startState(python_mode), }; }, copyState: function (state) { return { in_python: state.in_python, sigil: state.sigil, matched: state.matched, python_state: CodeMirror.copyState(python_mode, state.python_state) }; }, token: function (stream, state) { if (state.in_python) { if (stream.match(state.sigil.right)) { state.in_python = false; state.python_state = CodeMirror.startState(python_mode); return "sos-sigil"; } let it = null; try { it = python_mode.token(stream, state.python_state); } catch (error) { return "sos-interpolated error" + (state.matched ? "" : " sos-unmatched"); } if (it == 'variable' || it == 'builtin') { let ct = stream.current(); // warn users in the use of input and output in {} if (ct === 'input' || ct === 'output') it += ' error'; } return (it ? ("sos-interpolated " + it) : "sos-interpolated") + (state.matched ? "" : " sos-unmatched"); } else { // remove the double brace case, the syntax highlighter // does not have to worry (highlight) }}, although it would // probably mark an error for single } if (state.sigil.left === '{' && stream.match(/\{\{/)) return null; if (stream.match(state.sigil.left)) { state.in_python = true; // let us see if there is any right sigil till the end of the editor. try { let rest = stream.string.slice(stream.pos); if (!rest.includes(state.sigil.right)) { state.matched = false; for (let idx = 1; idx < 5; ++idx) { if (stream.lookAhead(idx).includes(state.sigil.right)) { state.matched = true; break; } } } } catch (error) { // only codemirror 5.27.0 supports this function } return "sos-sigil" + (state.matched ? "" : " sos-unmatched"); } while (stream.next() && !stream.match(state.sigil.left, false)) { } return null; } } } } CodeMirror.defineMode("sos", function (conf, parserConf) { let sosPythonConf = {}; for (let prop in parserConf) { if (parserConf.hasOwnProperty(prop)) { sosPythonConf[prop] = parserConf[prop]; } } sosPythonConf.name = 'python'; sosPythonConf.version = 3; sosPythonConf.extra_keywords = sosActionWords.concat(sosFunctionWords); // this is the SoS flavored python mode with more identifiers var base_mode = null; if ('base_mode' in parserConf && parserConf.base_mode && parserConf.base_mode !== 'sos' && parserConf.base_mode !== 'SoS') { let mode = findMode(parserConf.base_mode.toLowerCase()); if (mode) { base_mode = CodeMirror.getMode(conf, mode); } else { console.log(`No base mode is found for ${parserConf.base_mode}. Python mode used.`); } } else if ('base_mode' in conf && conf.base_mode && conf.base_mode !== 'sos' && conf.base_mode !== 'SoS') { let mode = findMode(conf.base_mode.toLowerCase()); if (mode) { base_mode = CodeMirror.getMode(conf, mode); } else { console.log(`No base mode is found for ${conf.base_mode}. Python mode used.`); } } // if there is a user specified base mode, this is the single cell mode if (base_mode) { var python_mode = CodeMirror.getMode({}, { name: 'python', version: 3 }); var overlay_mode = markExpr(python_mode); return { startState: function () { return { sos_mode: true, base_state: CodeMirror.startState(base_mode), overlay_state: CodeMirror.startState(overlay_mode), // for overlay basePos: 0, baseCur: null, overlayPos: 0, overlayCur: null, streamSeen: null }; }, copyState: function (state) { return { sos_mode: state.sos_mode, base_state: CodeMirror.copyState(base_mode, state.base_state), overlay_state: CodeMirror.copyState(overlay_mode, state.overlay_state), // for overlay basePos: state.basePos, baseCur: null, overlayPos: state.overlayPos, overlayCur: null }; }, token: function (stream, state) { if (state.sos_mode) { if (stream.sol()) { let sl = stream.peek(); if (sl == '!') { stream.skipToEnd(); return "meta"; } else if (sl == '#') { stream.skipToEnd(); return 'comment' } for (var i = 0; i < sosMagics.length; i++) { if (stream.match(sosMagics[i])) { if (sosMagics[i] === "%expand") { if (stream.eol() || stream.match(/\s*$/, false)) { state.overlay_state.sigil = { 'left': '{', 'right': '}' } } else { let found = stream.match(/\s+(\S+)\s+(\S+)$/, false); if (found) { state.overlay_state.sigil = { 'left': found[1], 'right': found[2] } } else { state.overlay_state.sigil = null; } } } // the rest of the lines will be processed as Python code return "meta"; } } state.sos_mode = false; } else { stream.skipToEnd(); return null; } } if (state.overlay_state.sigil) { if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) { state.streamSeen = stream; state.basePos = state.overlayPos = stream.start; } if (stream.start == state.basePos) { state.baseCur = base_mode.token(stream, state.base_state); state.basePos = stream.pos; } if (stream.start == state.overlayPos) { stream.pos = stream.start; state.overlayCur = overlay_mode.token(stream, state.overlay_state); state.overlayPos = stream.pos; } stream.pos = Math.min(state.basePos, state.overlayPos); // state.overlay.combineTokens always takes precedence over combine, // unless set to null return state.overlayCur ? state.overlayCur : state.baseCur; } else { return base_mode.token(stream, state.base_state); } }, indent: function (state, textAfter) { // inner indent if (!state.sos_mode) { if (!base_mode.indent) return CodeMirror.Pass; return base_mode.indent(state.base_state, textAfter); } else { // sos mode has no indent return 0; } }, innerMode: function (state) { return state.sos_mode ? { state: state.base_state, mode: base_mode } : null; }, lineComment: "#", fold: "indent" }; } else { // this is SoS mode base_mode = CodeMirror.getMode(conf, sosPythonConf); overlay_mode = markExpr(base_mode); return { startState: function () { return { sos_state: null, base_state: CodeMirror.startState(base_mode), overlay_state: CodeMirror.startState(overlay_mode), inner_mode: null, inner_state: null, // for overlay basePos: 0, baseCur: null, overlayPos: 0, overlayCur: null, streamSeen: null }; }, copyState: function (state) { return { sos_state: state.sos_state, base_state: CodeMirror.copyState(base_mode, state.base_state), overlay_state: CodeMirror.copyState(overlay_mode, state.overlay_state), inner_mode: state.inner_mode, inner_state: state.inner_mode && CodeMirror.copyState(state.inner_mode, state.inner_state), // for overlay basePos: state.basePos, baseCur: null, overlayPos: state.overlayPos, overlayCur: null }; }, token: function (stream, state) { if (stream.sol()) { let sl = stream.peek(); if (sl == '[') { if (stream.match(/^\[.*\]$/, false)) { // if there is : if (stream.match(/^\[[\s\w_,-]+:/)) { state.sos_state = 'header_option'; return "header line-section-header"; } else if (stream.match(/^\[[\s\w,-]+\]$/)) { // reset state state.sos_state = null; state.inner_mode = null; return "header line-section-header"; } } } else if (sl == '!') { stream.eatWhile(/\S/); return "meta"; } else if (sl == '#') { stream.skipToEnd(); return "comment"; } else if (sl == '%') { stream.eatWhile(/\S/); return "meta"; } else if (state.sos_state && state.sos_state.startsWith('entering')) { // the second parameter is starting column let mode = findMode(state.sos_state.slice(9).toLowerCase()); state.inner_mode = CodeMirror.getMode(conf, mode); state.inner_state = CodeMirror.startState(state.inner_mode, stream.indentation()); state.sos_state = null; } for (var i = 0; i < sosDirectives.length; i++) { if (stream.match(sosDirectives[i])) { // the rest of the lines will be processed as Python code state.sos_state = 'directive_option' return "keyword strong"; } } for (var i = 0; i < sosActions.length; i++) { if (stream.match(sosActions[i])) { // switch to submode? if (stream.eol()) { // really let mode = findMode(stream.current().slice(0, -1).toLowerCase()); if (mode) { state.sos_state = "entering " + stream.current().slice(0, -1); } else { state.sos_state = 'unknown_language'; } } else { state.sos_state = 'start ' + stream.current().slice(0, -1); } state.overlay_state.sigil = null; return "builtin strong"; } } // if unknown action if (stream.match(/\w+:/)) { state.overlay_state.sigil = null; state.sos_state = 'start ' + stream.current().slice(0, -1); return "builtin strong"; } } else if (state.sos_state == 'header_option') { // stuff after : if (stream.peek() == ']') { // move next stream.next(); // ] is the last char if (stream.eol()) { state.sos_state = null; state.inner_mode = null; return "header line-section-header"; } else { stream.backUp(1); let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } } else { let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } } else if (state.sos_state == 'directive_option') { // stuff after input:, R: etc if (stream.peek() == ',') { // move next stream.next(); // , is the last char, continue option line if (stream.eol()) { stream.backUp(1); let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } stream.backUp(1); } else if (stream.eol()) { // end of line stops option mode state.sos_state = null; state.inner_mode = null; } let it = base_mode.token(stream, state.base_state); return it ? it + ' sos-option' : null; } else if (state.sos_state && state.sos_state.startsWith("start ")) { // try to understand option expand= if (stream.match(/expand\s*=\s*True/, false)) { // highlight {} state.overlay_state.sigil = { 'left': '{', 'right': '}' } } else { let found = stream.match(/expand\s*=\s*"(\S+) (\S+)"/, false); if (!found) found = stream.match(/expand\s*=\s*'(\S+) (\S+)'/, false); if (found) { state.overlay_state.sigil = { 'left': found[1], 'right': found[2] } } } let mode_string = state.sos_state.slice(6).toLowerCase(); // for report, we need to find "output" option if (mode_string === "report" && stream.match(/^.*output\s*=\s*/, false)) { let found = stream.match(/^.*output\s*=\s*[rRbufF]*"""([^"]+)"""/, false); if (!found) found = stream.match(/^.*output\s*=\s*[rRbufF]*'''([^.]+)'''/, false); if (!found) found = stream.match(/^.*output\s*=\s*[rRbufF]*"([^"]+)"/, false); if (!found) found = stream.match(/^.*output\s*=\s*[rRbufF]*'([^']+)'/, false); // found[1] is the filename state.sos_state = 'start ' + findModeFromFilename(found ? found[1] : found); } let token = base_mode.token(stream, state.base_state); // if it is end of line, ending the starting switch mode if (stream.eol() && stream.peek() !== ',') { // really let mode = findMode(state.sos_state.slice(6).toLowerCase()); if (mode) { state.sos_state = "entering " + state.sos_state.slice(6); } else { state.sos_state = 'unknown_language'; } } return token + ' sos-option'; } // can be start of line but not special if (state.sos_state == 'unknown_language') { // we still handle {} in no man unknown_language if (state.overlay_state.sigil) { return overlay_mode.token(stream, state.overlay_state); } else { stream.skipToEnd(); return null; } } else if (state.inner_mode) { let it = 'sos_script '; if (!state.overlay_state.sigil) { let st = state.inner_mode.token(stream, state.inner_state); return st ? it + st : null; } else { // overlay mode, more complicated if (stream != state.streamSeen || Math.min(state.basePos, state.overlayPos) < stream.start) { state.streamSeen = stream; state.basePos = state.overlayPos = stream.start; } if (stream.start == state.basePos) { state.baseCur = state.inner_mode.token(stream, state.inner_state); state.basePos = stream.pos; } if (stream.start == state.overlayPos) { stream.pos = stream.start; state.overlayCur = overlay_mode.token(stream, state.overlay_state); state.overlayPos = stream.pos; } stream.pos = Math.min(state.basePos, state.overlayPos); // state.overlay.combineTokens always takes precedence over combine, // unless set to null return (state.overlayCur ? state.overlayCur : state.baseCur) + " sos-script"; } } else { return base_mode.token(stream, state.base_state); } }, indent: function (state, textAfter) { // inner indent if (state.inner_mode) { if (!state.inner_mode.indent) return CodeMirror.Pass; return state.inner_mode.indent(state.inner_mode, textAfter) + 2; } else { return base_mode.indent(state.base_state, textAfter); } }, innerMode: function (state) { return state.inner_mode ? null : { state: state.base_state, mode: base_mode }; }, lineComment: "#", fold: "indent", electricInput: /^\s*[\}\]\)]$/, }; }; }, "python"); CodeMirror.defineMIME("text/x-sos", "sos"); }); ================================================ FILE: src/sos_notebook/templates/sos-lab-cm/sos-lab-cm.html.j2 ================================================ {% extends 'sos-lab-full.html.j2' %} {% import 'parts/cm.tpl' as cm %} {%- block html_head -%} {{ super() | replace(' ', '') }} {{ cm.css() }} {%- endblock html_head %} {% block input %} {%- if cell['metadata'].get('kernel',none) is not none -%}
{% else %} {{ super() }} {%- endif -%} {%- endblock input %} {% block footer_js %} {{ cm.js() }} {{ super() }} {% endblock footer_js %} ================================================ FILE: src/sos_notebook/templates/sos-lab-full/conf.json ================================================ { "base_template": "lab", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-lab-full/index.html.j2 ================================================ {% extends 'sos-lab-full.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-lab-full/parts/preview.tpl ================================================ {% macro css() %} {% endmacro %} {% macro js() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-lab-full/parts/sos_style.tpl ================================================ {% macro css() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-lab-full/sos-lab-full.html.j2 ================================================ {% extends 'lab/index.html.j2' %} {% import 'parts/sos_style.tpl' as sos_style %} {% import 'parts/preview.tpl' as preview %} {% block html_head %} {{ super().replace('', '') }} {{ sos_style.css() }} {{ preview.css() }} {{ preview.js() }} {% block header_js %} {% endblock header_js %} {% endblock html_head %} {% block codecell %} {% if cell['metadata'].get('kernel',none) is not none %}
{{ super() }}
{% else %} {{ super() }} {% endif %} {% endblock codecell %} ================================================ FILE: src/sos_notebook/templates/sos-lab-full/static/index.css ================================================ /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /* * Mozilla scrollbar styling */ /* use standard opaque scrollbars for most nodes */ [data-jp-theme-scrollbars='true'] { scrollbar-color: rgb(var(--jp-scrollbar-thumb-color)) var(--jp-scrollbar-background-color); } /* for code nodes, use a transparent style of scrollbar. These selectors * will match lower in the tree, and so will override the above */ [data-jp-theme-scrollbars='true'] .CodeMirror-hscrollbar, [data-jp-theme-scrollbars='true'] .CodeMirror-vscrollbar { scrollbar-color: rgba(var(--jp-scrollbar-thumb-color), 0.5) transparent; } /* tiny scrollbar */ .jp-scrollbar-tiny { scrollbar-color: rgba(var(--jp-scrollbar-thumb-color), 0.5) transparent; scrollbar-width: thin; } /* * Webkit scrollbar styling */ /* use standard opaque scrollbars for most nodes */ [data-jp-theme-scrollbars='true'] ::-webkit-scrollbar, [data-jp-theme-scrollbars='true'] ::-webkit-scrollbar-corner { background: var(--jp-scrollbar-background-color); } [data-jp-theme-scrollbars='true'] ::-webkit-scrollbar-thumb { background: rgb(var(--jp-scrollbar-thumb-color)); border: var(--jp-scrollbar-thumb-margin) solid transparent; background-clip: content-box; border-radius: var(--jp-scrollbar-thumb-radius); } [data-jp-theme-scrollbars='true'] ::-webkit-scrollbar-track:horizontal { border-left: var(--jp-scrollbar-endpad) solid var(--jp-scrollbar-background-color); border-right: var(--jp-scrollbar-endpad) solid var(--jp-scrollbar-background-color); } [data-jp-theme-scrollbars='true'] ::-webkit-scrollbar-track:vertical { border-top: var(--jp-scrollbar-endpad) solid var(--jp-scrollbar-background-color); border-bottom: var(--jp-scrollbar-endpad) solid var(--jp-scrollbar-background-color); } /* for code nodes, use a transparent style of scrollbar */ [data-jp-theme-scrollbars='true'] .CodeMirror-hscrollbar::-webkit-scrollbar, [data-jp-theme-scrollbars='true'] .CodeMirror-vscrollbar::-webkit-scrollbar, [data-jp-theme-scrollbars='true'] .CodeMirror-hscrollbar::-webkit-scrollbar-corner, [data-jp-theme-scrollbars='true'] .CodeMirror-vscrollbar::-webkit-scrollbar-corner { background-color: transparent; } [data-jp-theme-scrollbars='true'] .CodeMirror-hscrollbar::-webkit-scrollbar-thumb, [data-jp-theme-scrollbars='true'] .CodeMirror-vscrollbar::-webkit-scrollbar-thumb { background: rgba(var(--jp-scrollbar-thumb-color), 0.5); border: var(--jp-scrollbar-thumb-margin) solid transparent; background-clip: content-box; border-radius: var(--jp-scrollbar-thumb-radius); } [data-jp-theme-scrollbars='true'] .CodeMirror-hscrollbar::-webkit-scrollbar-track:horizontal { border-left: var(--jp-scrollbar-endpad) solid transparent; border-right: var(--jp-scrollbar-endpad) solid transparent; } [data-jp-theme-scrollbars='true'] .CodeMirror-vscrollbar::-webkit-scrollbar-track:vertical { border-top: var(--jp-scrollbar-endpad) solid transparent; border-bottom: var(--jp-scrollbar-endpad) solid transparent; } /* tiny scrollbar */ .jp-scrollbar-tiny::-webkit-scrollbar, .jp-scrollbar-tiny::-webkit-scrollbar-corner { background-color: transparent; height: 4px; width: 4px; } .jp-scrollbar-tiny::-webkit-scrollbar-thumb { background: rgba(var(--jp-scrollbar-thumb-color), 0.5); } .jp-scrollbar-tiny::-webkit-scrollbar-track:horizontal { border-left: 0px solid transparent; border-right: 0px solid transparent; } .jp-scrollbar-tiny::-webkit-scrollbar-track:vertical { border-top: 0px solid transparent; border-bottom: 0px solid transparent; } /* * Phosphor */ .lm-ScrollBar[data-orientation='horizontal'] { min-height: 16px; max-height: 16px; min-width: 45px; border-top: 1px solid #a0a0a0; } .lm-ScrollBar[data-orientation='vertical'] { min-width: 16px; max-width: 16px; min-height: 45px; border-left: 1px solid #a0a0a0; } .lm-ScrollBar-button { background-color: #f0f0f0; background-position: center center; min-height: 15px; max-height: 15px; min-width: 15px; max-width: 15px; } .lm-ScrollBar-button:hover { background-color: #dadada; } .lm-ScrollBar-button.lm-mod-active { background-color: #cdcdcd; } .lm-ScrollBar-track { background: #f0f0f0; } .lm-ScrollBar-thumb { background: #cdcdcd; } .lm-ScrollBar-thumb:hover { background: #bababa; } .lm-ScrollBar-thumb.lm-mod-active { background: #a0a0a0; } .lm-ScrollBar[data-orientation='horizontal'] .lm-ScrollBar-thumb { height: 100%; min-width: 15px; border-left: 1px solid #a0a0a0; border-right: 1px solid #a0a0a0; } .lm-ScrollBar[data-orientation='vertical'] .lm-ScrollBar-thumb { width: 100%; min-height: 15px; border-top: 1px solid #a0a0a0; border-bottom: 1px solid #a0a0a0; } .lm-ScrollBar[data-orientation='horizontal'] .lm-ScrollBar-button[data-action='decrement'] { background-image: var(--jp-icon-caret-left); background-size: 17px; } .lm-ScrollBar[data-orientation='horizontal'] .lm-ScrollBar-button[data-action='increment'] { background-image: var(--jp-icon-caret-right); background-size: 17px; } .lm-ScrollBar[data-orientation='vertical'] .lm-ScrollBar-button[data-action='decrement'] { background-image: var(--jp-icon-caret-up); background-size: 17px; } .lm-ScrollBar[data-orientation='vertical'] .lm-ScrollBar-button[data-action='increment'] { background-image: var(--jp-icon-caret-down); background-size: 17px; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-Widget, /* */ .lm-Widget { box-sizing: border-box; position: relative; overflow: hidden; cursor: default; } /* */ .p-Widget.p-mod-hidden, /* */ .lm-Widget.lm-mod-hidden { display: none !important; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-CommandPalette, /* */ .lm-CommandPalette { display: flex; flex-direction: column; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } /* */ .p-CommandPalette-search, /* */ .lm-CommandPalette-search { flex: 0 0 auto; } /* */ .p-CommandPalette-content, /* */ .lm-CommandPalette-content { flex: 1 1 auto; margin: 0; padding: 0; min-height: 0; overflow: auto; list-style-type: none; } /* */ .p-CommandPalette-header, /* */ .lm-CommandPalette-header { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } /* */ .p-CommandPalette-item, /* */ .lm-CommandPalette-item { display: flex; flex-direction: row; } /* */ .p-CommandPalette-itemIcon, /* */ .lm-CommandPalette-itemIcon { flex: 0 0 auto; } /* */ .p-CommandPalette-itemContent, /* */ .lm-CommandPalette-itemContent { flex: 1 1 auto; overflow: hidden; } /* */ .p-CommandPalette-itemShortcut, /* */ .lm-CommandPalette-itemShortcut { flex: 0 0 auto; } /* */ .p-CommandPalette-itemLabel, /* */ .lm-CommandPalette-itemLabel { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .lm-close-icon { border:1px solid transparent; background-color: transparent; position: absolute; z-index:1; right:3%; top: 0; bottom: 0; margin: auto; padding: 7px 0; display: none; vertical-align: middle; outline: 0; cursor: pointer; } .lm-close-icon:after { content: "X"; display: block; width: 15px; height: 15px; text-align: center; color:#000; font-weight: normal; font-size: 12px; cursor: pointer; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-DockPanel, /* */ .lm-DockPanel { z-index: 0; } /* */ .p-DockPanel-widget, /* */ .lm-DockPanel-widget { z-index: 0; } /* */ .p-DockPanel-tabBar, /* */ .lm-DockPanel-tabBar { z-index: 1; } /* */ .p-DockPanel-handle, /* */ .lm-DockPanel-handle { z-index: 2; } /* */ .p-DockPanel-handle.p-mod-hidden, /* */ .lm-DockPanel-handle.lm-mod-hidden { display: none !important; } /* */ .p-DockPanel-handle:after, /* */ .lm-DockPanel-handle:after { position: absolute; top: 0; left: 0; width: 100%; height: 100%; content: ''; } /* */ .p-DockPanel-handle[data-orientation='horizontal'], /* */ .lm-DockPanel-handle[data-orientation='horizontal'] { cursor: ew-resize; } /* */ .p-DockPanel-handle[data-orientation='vertical'], /* */ .lm-DockPanel-handle[data-orientation='vertical'] { cursor: ns-resize; } /* */ .p-DockPanel-handle[data-orientation='horizontal']:after, /* */ .lm-DockPanel-handle[data-orientation='horizontal']:after { left: 50%; min-width: 8px; transform: translateX(-50%); } /* */ .p-DockPanel-handle[data-orientation='vertical']:after, /* */ .lm-DockPanel-handle[data-orientation='vertical']:after { top: 50%; min-height: 8px; transform: translateY(-50%); } /* */ .p-DockPanel-overlay, /* */ .lm-DockPanel-overlay { z-index: 3; box-sizing: border-box; pointer-events: none; } /* */ .p-DockPanel-overlay.p-mod-hidden, /* */ .lm-DockPanel-overlay.lm-mod-hidden { display: none !important; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-Menu, /* */ .lm-Menu { z-index: 10000; position: absolute; white-space: nowrap; overflow-x: hidden; overflow-y: auto; outline: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } /* */ .p-Menu-content, /* */ .lm-Menu-content { margin: 0; padding: 0; display: table; list-style-type: none; } /* */ .p-Menu-item, /* */ .lm-Menu-item { display: table-row; } /* */ .p-Menu-item.p-mod-hidden, .p-Menu-item.p-mod-collapsed, /* */ .lm-Menu-item.lm-mod-hidden, .lm-Menu-item.lm-mod-collapsed { display: none !important; } /* */ .p-Menu-itemIcon, .p-Menu-itemSubmenuIcon, /* */ .lm-Menu-itemIcon, .lm-Menu-itemSubmenuIcon { display: table-cell; text-align: center; } /* */ .p-Menu-itemLabel, /* */ .lm-Menu-itemLabel { display: table-cell; text-align: left; } /* */ .p-Menu-itemShortcut, /* */ .lm-Menu-itemShortcut { display: table-cell; text-align: right; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-MenuBar, /* */ .lm-MenuBar { outline: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } /* */ .p-MenuBar-content, /* */ .lm-MenuBar-content { margin: 0; padding: 0; display: flex; flex-direction: row; list-style-type: none; } /* */ .p--MenuBar-item, /* */ .lm-MenuBar-item { box-sizing: border-box; } /* */ .p-MenuBar-itemIcon, .p-MenuBar-itemLabel, /* */ .lm-MenuBar-itemIcon, .lm-MenuBar-itemLabel { display: inline-block; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-ScrollBar, /* */ .lm-ScrollBar { display: flex; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } /* */ .p-ScrollBar[data-orientation='horizontal'], /* */ .lm-ScrollBar[data-orientation='horizontal'] { flex-direction: row; } /* */ .p-ScrollBar[data-orientation='vertical'], /* */ .lm-ScrollBar[data-orientation='vertical'] { flex-direction: column; } /* */ .p-ScrollBar-button, /* */ .lm-ScrollBar-button { box-sizing: border-box; flex: 0 0 auto; } /* */ .p-ScrollBar-track, /* */ .lm-ScrollBar-track { box-sizing: border-box; position: relative; overflow: hidden; flex: 1 1 auto; } /* */ .p-ScrollBar-thumb, /* */ .lm-ScrollBar-thumb { box-sizing: border-box; position: absolute; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-SplitPanel-child, /* */ .lm-SplitPanel-child { z-index: 0; } /* */ .p-SplitPanel-handle, /* */ .lm-SplitPanel-handle { z-index: 1; } /* */ .p-SplitPanel-handle.p-mod-hidden, /* */ .lm-SplitPanel-handle.lm-mod-hidden { display: none !important; } /* */ .p-SplitPanel-handle:after, /* */ .lm-SplitPanel-handle:after { position: absolute; top: 0; left: 0; width: 100%; height: 100%; content: ''; } /* */ .p-SplitPanel[data-orientation='horizontal'] > .p-SplitPanel-handle, /* */ .lm-SplitPanel[data-orientation='horizontal'] > .lm-SplitPanel-handle { cursor: ew-resize; } /* */ .p-SplitPanel[data-orientation='vertical'] > .p-SplitPanel-handle, /* */ .lm-SplitPanel[data-orientation='vertical'] > .lm-SplitPanel-handle { cursor: ns-resize; } /* */ .p-SplitPanel[data-orientation='horizontal'] > .p-SplitPanel-handle:after, /* */ .lm-SplitPanel[data-orientation='horizontal'] > .lm-SplitPanel-handle:after { left: 50%; min-width: 8px; transform: translateX(-50%); } /* */ .p-SplitPanel[data-orientation='vertical'] > .p-SplitPanel-handle:after, /* */ .lm-SplitPanel[data-orientation='vertical'] > .lm-SplitPanel-handle:after { top: 50%; min-height: 8px; transform: translateY(-50%); } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-TabBar, /* */ .lm-TabBar { display: flex; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } /* */ .p-TabBar[data-orientation='horizontal'], /* */ .lm-TabBar[data-orientation='horizontal'] { flex-direction: row; align-items: flex-end; } /* */ .p-TabBar[data-orientation='vertical'], /* */ .lm-TabBar[data-orientation='vertical'] { flex-direction: column; align-items: flex-end; } /* */ .p-TabBar-content, /* */ .lm-TabBar-content { margin: 0; padding: 0; display: flex; flex: 1 1 auto; list-style-type: none; } /* */ .p-TabBar[data-orientation='horizontal'] > .p-TabBar-content, /* */ .lm-TabBar[data-orientation='horizontal'] > .lm-TabBar-content { flex-direction: row; } /* */ .p-TabBar[data-orientation='vertical'] > .p-TabBar-content, /* */ .lm-TabBar[data-orientation='vertical'] > .lm-TabBar-content { flex-direction: column; } /* */ .p-TabBar-tab, /* */ .lm-TabBar-tab { display: flex; flex-direction: row; box-sizing: border-box; overflow: hidden; } /* */ .p-TabBar-tabIcon, .p-TabBar-tabCloseIcon, /* */ .lm-TabBar-tabIcon, .lm-TabBar-tabCloseIcon { flex: 0 0 auto; } /* */ .p-TabBar-tabLabel, /* */ .lm-TabBar-tabLabel { flex: 1 1 auto; overflow: hidden; white-space: nowrap; } .lm-TabBar-tabInput { user-select: all; width: 100%; box-sizing : border-box; } /* */ .p-TabBar-tab.p-mod-hidden, /* */ .lm-TabBar-tab.lm-mod-hidden { display: none !important; } .lm-TabBar-addButton.lm-mod-hidden { display: none !important; } /* */ .p-TabBar.p-mod-dragging .p-TabBar-tab, /* */ .lm-TabBar.lm-mod-dragging .lm-TabBar-tab { position: relative; } /* */ .p-TabBar.p-mod-dragging[data-orientation='horizontal'] .p-TabBar-tab, /* */ .lm-TabBar.lm-mod-dragging[data-orientation='horizontal'] .lm-TabBar-tab { left: 0; transition: left 150ms ease; } /* */ .p-TabBar.p-mod-dragging[data-orientation='vertical'] .p-TabBar-tab, /* */ .lm-TabBar.lm-mod-dragging[data-orientation='vertical'] .lm-TabBar-tab { top: 0; transition: top 150ms ease; } /* */ .p-TabBar.p-mod-dragging .p-TabBar-tab.p-mod-dragging, /* */ .lm-TabBar.lm-mod-dragging .lm-TabBar-tab.lm-mod-dragging { transition: none; } .lm-TabBar-tabLabel .lm-TabBar-tabInput { user-select: all; width: 100%; box-sizing : border-box; background: inherit; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ .p-TabPanel-tabBar, /* */ .lm-TabPanel-tabBar { z-index: 1; } /* */ .p-TabPanel-stackedPanel, /* */ .lm-TabPanel-stackedPanel { z-index: 0; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ @charset "UTF-8"; html{ -webkit-box-sizing:border-box; box-sizing:border-box; } *, *::before, *::after{ -webkit-box-sizing:inherit; box-sizing:inherit; } body{ font-size:14px; font-weight:400; letter-spacing:0; line-height:1.28581; text-transform:none; color:#182026; font-family:-apple-system, "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Open Sans", "Helvetica Neue", "Icons16", sans-serif; } p{ margin-bottom:10px; margin-top:0; } small{ font-size:12px; } strong{ font-weight:600; } ::-moz-selection{ background:rgba(125, 188, 255, 0.6); } ::selection{ background:rgba(125, 188, 255, 0.6); } .bp3-heading{ color:#182026; font-weight:600; margin:0 0 10px; padding:0; } .bp3-dark .bp3-heading{ color:#f5f8fa; } h1.bp3-heading, .bp3-running-text h1{ font-size:36px; line-height:40px; } h2.bp3-heading, .bp3-running-text h2{ font-size:28px; line-height:32px; } h3.bp3-heading, .bp3-running-text h3{ font-size:22px; line-height:25px; } h4.bp3-heading, .bp3-running-text h4{ font-size:18px; line-height:21px; } h5.bp3-heading, .bp3-running-text h5{ font-size:16px; line-height:19px; } h6.bp3-heading, .bp3-running-text h6{ font-size:14px; line-height:16px; } .bp3-ui-text{ font-size:14px; font-weight:400; letter-spacing:0; line-height:1.28581; text-transform:none; } .bp3-monospace-text{ font-family:monospace; text-transform:none; } .bp3-text-muted{ color:#5c7080; } .bp3-dark .bp3-text-muted{ color:#a7b6c2; } .bp3-text-disabled{ color:rgba(92, 112, 128, 0.6); } .bp3-dark .bp3-text-disabled{ color:rgba(167, 182, 194, 0.6); } .bp3-text-overflow-ellipsis{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; } .bp3-running-text{ font-size:14px; line-height:1.5; } .bp3-running-text h1{ color:#182026; font-weight:600; margin-bottom:20px; margin-top:40px; } .bp3-dark .bp3-running-text h1{ color:#f5f8fa; } .bp3-running-text h2{ color:#182026; font-weight:600; margin-bottom:20px; margin-top:40px; } .bp3-dark .bp3-running-text h2{ color:#f5f8fa; } .bp3-running-text h3{ color:#182026; font-weight:600; margin-bottom:20px; margin-top:40px; } .bp3-dark .bp3-running-text h3{ color:#f5f8fa; } .bp3-running-text h4{ color:#182026; font-weight:600; margin-bottom:20px; margin-top:40px; } .bp3-dark .bp3-running-text h4{ color:#f5f8fa; } .bp3-running-text h5{ color:#182026; font-weight:600; margin-bottom:20px; margin-top:40px; } .bp3-dark .bp3-running-text h5{ color:#f5f8fa; } .bp3-running-text h6{ color:#182026; font-weight:600; margin-bottom:20px; margin-top:40px; } .bp3-dark .bp3-running-text h6{ color:#f5f8fa; } .bp3-running-text hr{ border:none; border-bottom:1px solid rgba(16, 22, 26, 0.15); margin:20px 0; } .bp3-dark .bp3-running-text hr{ border-color:rgba(255, 255, 255, 0.15); } .bp3-running-text p{ margin:0 0 10px; padding:0; } .bp3-text-large{ font-size:16px; } .bp3-text-small{ font-size:12px; } a{ color:#106ba3; text-decoration:none; } a:hover{ color:#106ba3; cursor:pointer; text-decoration:underline; } a .bp3-icon, a .bp3-icon-standard, a .bp3-icon-large{ color:inherit; } a code, .bp3-dark a code{ color:inherit; } .bp3-dark a, .bp3-dark a:hover{ color:#48aff0; } .bp3-dark a .bp3-icon, .bp3-dark a .bp3-icon-standard, .bp3-dark a .bp3-icon-large, .bp3-dark a:hover .bp3-icon, .bp3-dark a:hover .bp3-icon-standard, .bp3-dark a:hover .bp3-icon-large{ color:inherit; } .bp3-running-text code, .bp3-code{ font-family:monospace; text-transform:none; background:rgba(255, 255, 255, 0.7); border-radius:3px; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2); color:#5c7080; font-size:smaller; padding:2px 5px; } .bp3-dark .bp3-running-text code, .bp3-running-text .bp3-dark code, .bp3-dark .bp3-code{ background:rgba(16, 22, 26, 0.3); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); color:#a7b6c2; } .bp3-running-text a > code, a > .bp3-code{ color:#137cbd; } .bp3-dark .bp3-running-text a > code, .bp3-running-text .bp3-dark a > code, .bp3-dark a > .bp3-code{ color:inherit; } .bp3-running-text pre, .bp3-code-block{ font-family:monospace; text-transform:none; background:rgba(255, 255, 255, 0.7); border-radius:3px; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.15); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.15); color:#182026; display:block; font-size:13px; line-height:1.4; margin:10px 0; padding:13px 15px 12px; word-break:break-all; word-wrap:break-word; } .bp3-dark .bp3-running-text pre, .bp3-running-text .bp3-dark pre, .bp3-dark .bp3-code-block{ background:rgba(16, 22, 26, 0.3); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-running-text pre > code, .bp3-code-block > code{ background:none; -webkit-box-shadow:none; box-shadow:none; color:inherit; font-size:inherit; padding:0; } .bp3-running-text kbd, .bp3-key{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; background:#ffffff; border-radius:3px; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); color:#5c7080; display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; font-family:inherit; font-size:12px; height:24px; -webkit-box-pack:center; -ms-flex-pack:center; justify-content:center; line-height:24px; min-width:24px; padding:3px 6px; vertical-align:middle; } .bp3-running-text kbd .bp3-icon, .bp3-key .bp3-icon, .bp3-running-text kbd .bp3-icon-standard, .bp3-key .bp3-icon-standard, .bp3-running-text kbd .bp3-icon-large, .bp3-key .bp3-icon-large{ margin-right:5px; } .bp3-dark .bp3-running-text kbd, .bp3-running-text .bp3-dark kbd, .bp3-dark .bp3-key{ background:#394b59; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); color:#a7b6c2; } .bp3-running-text blockquote, .bp3-blockquote{ border-left:solid 4px rgba(167, 182, 194, 0.5); margin:0 0 10px; padding:0 20px; } .bp3-dark .bp3-running-text blockquote, .bp3-running-text .bp3-dark blockquote, .bp3-dark .bp3-blockquote{ border-color:rgba(115, 134, 148, 0.5); } .bp3-running-text ul, .bp3-running-text ol, .bp3-list{ margin:10px 0; padding-left:30px; } .bp3-running-text ul li:not(:last-child), .bp3-running-text ol li:not(:last-child), .bp3-list li:not(:last-child){ margin-bottom:5px; } .bp3-running-text ul ol, .bp3-running-text ol ol, .bp3-list ol, .bp3-running-text ul ul, .bp3-running-text ol ul, .bp3-list ul{ margin-top:5px; } .bp3-list-unstyled{ list-style:none; margin:0; padding:0; } .bp3-list-unstyled li{ padding:0; } .bp3-rtl{ text-align:right; } .bp3-dark{ color:#f5f8fa; } :focus{ outline:rgba(19, 124, 189, 0.6) auto 2px; outline-offset:2px; -moz-outline-radius:6px; } .bp3-focus-disabled :focus{ outline:none !important; } .bp3-focus-disabled :focus ~ .bp3-control-indicator{ outline:none !important; } .bp3-alert{ max-width:400px; padding:20px; } .bp3-alert-body{ display:-webkit-box; display:-ms-flexbox; display:flex; } .bp3-alert-body .bp3-icon{ font-size:40px; margin-right:20px; margin-top:0; } .bp3-alert-contents{ word-break:break-word; } .bp3-alert-footer{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:horizontal; -webkit-box-direction:reverse; -ms-flex-direction:row-reverse; flex-direction:row-reverse; margin-top:10px; } .bp3-alert-footer .bp3-button{ margin-left:10px; } .bp3-breadcrumbs{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; cursor:default; display:-webkit-box; display:-ms-flexbox; display:flex; -ms-flex-wrap:wrap; flex-wrap:wrap; height:30px; list-style:none; margin:0; padding:0; } .bp3-breadcrumbs > li{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box; display:-ms-flexbox; display:flex; } .bp3-breadcrumbs > li::after{ background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill-rule='evenodd' clip-rule='evenodd' d='M10.71 7.29l-4-4a1.003 1.003 0 00-1.42 1.42L8.59 8 5.3 11.29c-.19.18-.3.43-.3.71a1.003 1.003 0 001.71.71l4-4c.18-.18.29-.43.29-.71 0-.28-.11-.53-.29-.71z' fill='%235C7080'/%3e%3c/svg%3e"); content:""; display:block; height:16px; margin:0 5px; width:16px; } .bp3-breadcrumbs > li:last-of-type::after{ display:none; } .bp3-breadcrumb, .bp3-breadcrumb-current, .bp3-breadcrumbs-collapsed{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; font-size:16px; } .bp3-breadcrumb, .bp3-breadcrumbs-collapsed{ color:#5c7080; } .bp3-breadcrumb:hover{ text-decoration:none; } .bp3-breadcrumb.bp3-disabled{ color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-breadcrumb .bp3-icon{ margin-right:5px; } .bp3-breadcrumb-current{ color:inherit; font-weight:600; } .bp3-breadcrumb-current .bp3-input{ font-size:inherit; font-weight:inherit; vertical-align:baseline; } .bp3-breadcrumbs-collapsed{ background:#ced9e0; border:none; border-radius:3px; cursor:pointer; margin-right:2px; padding:1px 5px; vertical-align:text-bottom; } .bp3-breadcrumbs-collapsed::before{ background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cg fill='%235C7080'%3e%3ccircle cx='2' cy='8.03' r='2'/%3e%3ccircle cx='14' cy='8.03' r='2'/%3e%3ccircle cx='8' cy='8.03' r='2'/%3e%3c/g%3e%3c/svg%3e") center no-repeat; content:""; display:block; height:16px; width:16px; } .bp3-breadcrumbs-collapsed:hover{ background:#bfccd6; color:#182026; text-decoration:none; } .bp3-dark .bp3-breadcrumb, .bp3-dark .bp3-breadcrumbs-collapsed{ color:#a7b6c2; } .bp3-dark .bp3-breadcrumbs > li::after{ color:#a7b6c2; } .bp3-dark .bp3-breadcrumb.bp3-disabled{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-breadcrumb-current{ color:#f5f8fa; } .bp3-dark .bp3-breadcrumbs-collapsed{ background:rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-breadcrumbs-collapsed:hover{ background:rgba(16, 22, 26, 0.6); color:#f5f8fa; } .bp3-button{ display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:center; -ms-flex-align:center; align-items:center; border:none; border-radius:3px; cursor:pointer; font-size:14px; -webkit-box-pack:center; -ms-flex-pack:center; justify-content:center; padding:5px 10px; text-align:left; vertical-align:middle; min-height:30px; min-width:30px; } .bp3-button > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-button > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-button::before, .bp3-button > *{ margin-right:7px; } .bp3-button:empty::before, .bp3-button > :last-child{ margin-right:0; } .bp3-button:empty{ padding:0 !important; } .bp3-button:disabled, .bp3-button.bp3-disabled{ cursor:not-allowed; } .bp3-button.bp3-fill{ display:-webkit-box; display:-ms-flexbox; display:flex; width:100%; } .bp3-button.bp3-align-right, .bp3-align-right .bp3-button{ text-align:right; } .bp3-button.bp3-align-left, .bp3-align-left .bp3-button{ text-align:left; } .bp3-button:not([class*="bp3-intent-"]){ background-color:#f5f8fa; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.8)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); color:#182026; } .bp3-button:not([class*="bp3-intent-"]):hover{ background-clip:padding-box; background-color:#ebf1f5; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); } .bp3-button:not([class*="bp3-intent-"]):active, .bp3-button:not([class*="bp3-intent-"]).bp3-active{ background-color:#d8e1e8; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-button:not([class*="bp3-intent-"]):disabled, .bp3-button:not([class*="bp3-intent-"]).bp3-disabled{ background-color:rgba(206, 217, 224, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; outline:none; } .bp3-button:not([class*="bp3-intent-"]):disabled.bp3-active, .bp3-button:not([class*="bp3-intent-"]):disabled.bp3-active:hover, .bp3-button:not([class*="bp3-intent-"]).bp3-disabled.bp3-active, .bp3-button:not([class*="bp3-intent-"]).bp3-disabled.bp3-active:hover{ background:rgba(206, 217, 224, 0.7); } .bp3-button.bp3-intent-primary{ background-color:#137cbd; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.1)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); color:#ffffff; } .bp3-button.bp3-intent-primary:hover, .bp3-button.bp3-intent-primary:active, .bp3-button.bp3-intent-primary.bp3-active{ color:#ffffff; } .bp3-button.bp3-intent-primary:hover{ background-color:#106ba3; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-primary:active, .bp3-button.bp3-intent-primary.bp3-active{ background-color:#0e5a8a; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-primary:disabled, .bp3-button.bp3-intent-primary.bp3-disabled{ background-color:rgba(19, 124, 189, 0.5); background-image:none; border-color:transparent; -webkit-box-shadow:none; box-shadow:none; color:rgba(255, 255, 255, 0.6); } .bp3-button.bp3-intent-success{ background-color:#0f9960; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.1)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); color:#ffffff; } .bp3-button.bp3-intent-success:hover, .bp3-button.bp3-intent-success:active, .bp3-button.bp3-intent-success.bp3-active{ color:#ffffff; } .bp3-button.bp3-intent-success:hover{ background-color:#0d8050; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-success:active, .bp3-button.bp3-intent-success.bp3-active{ background-color:#0a6640; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-success:disabled, .bp3-button.bp3-intent-success.bp3-disabled{ background-color:rgba(15, 153, 96, 0.5); background-image:none; border-color:transparent; -webkit-box-shadow:none; box-shadow:none; color:rgba(255, 255, 255, 0.6); } .bp3-button.bp3-intent-warning{ background-color:#d9822b; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.1)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); color:#ffffff; } .bp3-button.bp3-intent-warning:hover, .bp3-button.bp3-intent-warning:active, .bp3-button.bp3-intent-warning.bp3-active{ color:#ffffff; } .bp3-button.bp3-intent-warning:hover{ background-color:#bf7326; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-warning:active, .bp3-button.bp3-intent-warning.bp3-active{ background-color:#a66321; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-warning:disabled, .bp3-button.bp3-intent-warning.bp3-disabled{ background-color:rgba(217, 130, 43, 0.5); background-image:none; border-color:transparent; -webkit-box-shadow:none; box-shadow:none; color:rgba(255, 255, 255, 0.6); } .bp3-button.bp3-intent-danger{ background-color:#db3737; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.1)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); color:#ffffff; } .bp3-button.bp3-intent-danger:hover, .bp3-button.bp3-intent-danger:active, .bp3-button.bp3-intent-danger.bp3-active{ color:#ffffff; } .bp3-button.bp3-intent-danger:hover{ background-color:#c23030; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-danger:active, .bp3-button.bp3-intent-danger.bp3-active{ background-color:#a82a2a; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-button.bp3-intent-danger:disabled, .bp3-button.bp3-intent-danger.bp3-disabled{ background-color:rgba(219, 55, 55, 0.5); background-image:none; border-color:transparent; -webkit-box-shadow:none; box-shadow:none; color:rgba(255, 255, 255, 0.6); } .bp3-button[class*="bp3-intent-"] .bp3-button-spinner .bp3-spinner-head{ stroke:#ffffff; } .bp3-button.bp3-large, .bp3-large .bp3-button{ min-height:40px; min-width:40px; font-size:16px; padding:5px 15px; } .bp3-button.bp3-large::before, .bp3-button.bp3-large > *, .bp3-large .bp3-button::before, .bp3-large .bp3-button > *{ margin-right:10px; } .bp3-button.bp3-large:empty::before, .bp3-button.bp3-large > :last-child, .bp3-large .bp3-button:empty::before, .bp3-large .bp3-button > :last-child{ margin-right:0; } .bp3-button.bp3-small, .bp3-small .bp3-button{ min-height:24px; min-width:24px; padding:0 7px; } .bp3-button.bp3-loading{ position:relative; } .bp3-button.bp3-loading[class*="bp3-icon-"]::before{ visibility:hidden; } .bp3-button.bp3-loading .bp3-button-spinner{ margin:0; position:absolute; } .bp3-button.bp3-loading > :not(.bp3-button-spinner){ visibility:hidden; } .bp3-button[class*="bp3-icon-"]::before{ font-family:"Icons16", sans-serif; font-size:16px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; color:#5c7080; } .bp3-button .bp3-icon, .bp3-button .bp3-icon-standard, .bp3-button .bp3-icon-large{ color:#5c7080; } .bp3-button .bp3-icon.bp3-align-right, .bp3-button .bp3-icon-standard.bp3-align-right, .bp3-button .bp3-icon-large.bp3-align-right{ margin-left:7px; } .bp3-button .bp3-icon:first-child:last-child, .bp3-button .bp3-spinner + .bp3-icon:last-child{ margin:0 -7px; } .bp3-dark .bp3-button:not([class*="bp3-intent-"]){ background-color:#394b59; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.05)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0)); -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-dark .bp3-button:not([class*="bp3-intent-"]):hover, .bp3-dark .bp3-button:not([class*="bp3-intent-"]):active, .bp3-dark .bp3-button:not([class*="bp3-intent-"]).bp3-active{ color:#f5f8fa; } .bp3-dark .bp3-button:not([class*="bp3-intent-"]):hover{ background-color:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-button:not([class*="bp3-intent-"]):active, .bp3-dark .bp3-button:not([class*="bp3-intent-"]).bp3-active{ background-color:#202b33; background-image:none; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-button:not([class*="bp3-intent-"]):disabled, .bp3-dark .bp3-button:not([class*="bp3-intent-"]).bp3-disabled{ background-color:rgba(57, 75, 89, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-button:not([class*="bp3-intent-"]):disabled.bp3-active, .bp3-dark .bp3-button:not([class*="bp3-intent-"]).bp3-disabled.bp3-active{ background:rgba(57, 75, 89, 0.7); } .bp3-dark .bp3-button:not([class*="bp3-intent-"]) .bp3-button-spinner .bp3-spinner-head{ background:rgba(16, 22, 26, 0.5); stroke:#8a9ba8; } .bp3-dark .bp3-button:not([class*="bp3-intent-"])[class*="bp3-icon-"]::before{ color:#a7b6c2; } .bp3-dark .bp3-button:not([class*="bp3-intent-"]) .bp3-icon, .bp3-dark .bp3-button:not([class*="bp3-intent-"]) .bp3-icon-standard, .bp3-dark .bp3-button:not([class*="bp3-intent-"]) .bp3-icon-large{ color:#a7b6c2; } .bp3-dark .bp3-button[class*="bp3-intent-"]{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-button[class*="bp3-intent-"]:hover{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-button[class*="bp3-intent-"]:active, .bp3-dark .bp3-button[class*="bp3-intent-"].bp3-active{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-button[class*="bp3-intent-"]:disabled, .bp3-dark .bp3-button[class*="bp3-intent-"].bp3-disabled{ background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(255, 255, 255, 0.3); } .bp3-dark .bp3-button[class*="bp3-intent-"] .bp3-button-spinner .bp3-spinner-head{ stroke:#8a9ba8; } .bp3-button:disabled::before, .bp3-button:disabled .bp3-icon, .bp3-button:disabled .bp3-icon-standard, .bp3-button:disabled .bp3-icon-large, .bp3-button.bp3-disabled::before, .bp3-button.bp3-disabled .bp3-icon, .bp3-button.bp3-disabled .bp3-icon-standard, .bp3-button.bp3-disabled .bp3-icon-large, .bp3-button[class*="bp3-intent-"]::before, .bp3-button[class*="bp3-intent-"] .bp3-icon, .bp3-button[class*="bp3-intent-"] .bp3-icon-standard, .bp3-button[class*="bp3-intent-"] .bp3-icon-large{ color:inherit !important; } .bp3-button.bp3-minimal{ background:none; -webkit-box-shadow:none; box-shadow:none; } .bp3-button.bp3-minimal:hover{ background:rgba(167, 182, 194, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; text-decoration:none; } .bp3-button.bp3-minimal:active, .bp3-button.bp3-minimal.bp3-active{ background:rgba(115, 134, 148, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; } .bp3-button.bp3-minimal:disabled, .bp3-button.bp3-minimal:disabled:hover, .bp3-button.bp3-minimal.bp3-disabled, .bp3-button.bp3-minimal.bp3-disabled:hover{ background:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-button.bp3-minimal:disabled.bp3-active, .bp3-button.bp3-minimal:disabled:hover.bp3-active, .bp3-button.bp3-minimal.bp3-disabled.bp3-active, .bp3-button.bp3-minimal.bp3-disabled:hover.bp3-active{ background:rgba(115, 134, 148, 0.3); } .bp3-dark .bp3-button.bp3-minimal{ background:none; -webkit-box-shadow:none; box-shadow:none; color:inherit; } .bp3-dark .bp3-button.bp3-minimal:hover, .bp3-dark .bp3-button.bp3-minimal:active, .bp3-dark .bp3-button.bp3-minimal.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-button.bp3-minimal:hover{ background:rgba(138, 155, 168, 0.15); } .bp3-dark .bp3-button.bp3-minimal:active, .bp3-dark .bp3-button.bp3-minimal.bp3-active{ background:rgba(138, 155, 168, 0.3); color:#f5f8fa; } .bp3-dark .bp3-button.bp3-minimal:disabled, .bp3-dark .bp3-button.bp3-minimal:disabled:hover, .bp3-dark .bp3-button.bp3-minimal.bp3-disabled, .bp3-dark .bp3-button.bp3-minimal.bp3-disabled:hover{ background:none; color:rgba(167, 182, 194, 0.6); cursor:not-allowed; } .bp3-dark .bp3-button.bp3-minimal:disabled.bp3-active, .bp3-dark .bp3-button.bp3-minimal:disabled:hover.bp3-active, .bp3-dark .bp3-button.bp3-minimal.bp3-disabled.bp3-active, .bp3-dark .bp3-button.bp3-minimal.bp3-disabled:hover.bp3-active{ background:rgba(138, 155, 168, 0.3); } .bp3-button.bp3-minimal.bp3-intent-primary{ color:#106ba3; } .bp3-button.bp3-minimal.bp3-intent-primary:hover, .bp3-button.bp3-minimal.bp3-intent-primary:active, .bp3-button.bp3-minimal.bp3-intent-primary.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#106ba3; } .bp3-button.bp3-minimal.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.15); color:#106ba3; } .bp3-button.bp3-minimal.bp3-intent-primary:active, .bp3-button.bp3-minimal.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#106ba3; } .bp3-button.bp3-minimal.bp3-intent-primary:disabled, .bp3-button.bp3-minimal.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(16, 107, 163, 0.5); } .bp3-button.bp3-minimal.bp3-intent-primary:disabled.bp3-active, .bp3-button.bp3-minimal.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-button.bp3-minimal.bp3-intent-primary .bp3-button-spinner .bp3-spinner-head{ stroke:#106ba3; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary{ color:#48aff0; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.2); color:#48aff0; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary:active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#48aff0; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary:disabled, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(72, 175, 240, 0.5); } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary:disabled.bp3-active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-button.bp3-minimal.bp3-intent-success{ color:#0d8050; } .bp3-button.bp3-minimal.bp3-intent-success:hover, .bp3-button.bp3-minimal.bp3-intent-success:active, .bp3-button.bp3-minimal.bp3-intent-success.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#0d8050; } .bp3-button.bp3-minimal.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.15); color:#0d8050; } .bp3-button.bp3-minimal.bp3-intent-success:active, .bp3-button.bp3-minimal.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#0d8050; } .bp3-button.bp3-minimal.bp3-intent-success:disabled, .bp3-button.bp3-minimal.bp3-intent-success.bp3-disabled{ background:none; color:rgba(13, 128, 80, 0.5); } .bp3-button.bp3-minimal.bp3-intent-success:disabled.bp3-active, .bp3-button.bp3-minimal.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-button.bp3-minimal.bp3-intent-success .bp3-button-spinner .bp3-spinner-head{ stroke:#0d8050; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success{ color:#3dcc91; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.2); color:#3dcc91; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success:active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#3dcc91; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success:disabled, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success.bp3-disabled{ background:none; color:rgba(61, 204, 145, 0.5); } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success:disabled.bp3-active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-button.bp3-minimal.bp3-intent-warning{ color:#bf7326; } .bp3-button.bp3-minimal.bp3-intent-warning:hover, .bp3-button.bp3-minimal.bp3-intent-warning:active, .bp3-button.bp3-minimal.bp3-intent-warning.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#bf7326; } .bp3-button.bp3-minimal.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.15); color:#bf7326; } .bp3-button.bp3-minimal.bp3-intent-warning:active, .bp3-button.bp3-minimal.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#bf7326; } .bp3-button.bp3-minimal.bp3-intent-warning:disabled, .bp3-button.bp3-minimal.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(191, 115, 38, 0.5); } .bp3-button.bp3-minimal.bp3-intent-warning:disabled.bp3-active, .bp3-button.bp3-minimal.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-button.bp3-minimal.bp3-intent-warning .bp3-button-spinner .bp3-spinner-head{ stroke:#bf7326; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning{ color:#ffb366; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.2); color:#ffb366; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning:active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#ffb366; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning:disabled, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(255, 179, 102, 0.5); } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning:disabled.bp3-active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-button.bp3-minimal.bp3-intent-danger{ color:#c23030; } .bp3-button.bp3-minimal.bp3-intent-danger:hover, .bp3-button.bp3-minimal.bp3-intent-danger:active, .bp3-button.bp3-minimal.bp3-intent-danger.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#c23030; } .bp3-button.bp3-minimal.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.15); color:#c23030; } .bp3-button.bp3-minimal.bp3-intent-danger:active, .bp3-button.bp3-minimal.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#c23030; } .bp3-button.bp3-minimal.bp3-intent-danger:disabled, .bp3-button.bp3-minimal.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(194, 48, 48, 0.5); } .bp3-button.bp3-minimal.bp3-intent-danger:disabled.bp3-active, .bp3-button.bp3-minimal.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-button.bp3-minimal.bp3-intent-danger .bp3-button-spinner .bp3-spinner-head{ stroke:#c23030; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger{ color:#ff7373; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.2); color:#ff7373; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger:active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#ff7373; } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger:disabled, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(255, 115, 115, 0.5); } .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger:disabled.bp3-active, .bp3-dark .bp3-button.bp3-minimal.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-button.bp3-outlined{ background:none; -webkit-box-shadow:none; box-shadow:none; border:1px solid rgba(24, 32, 38, 0.2); -webkit-box-sizing:border-box; box-sizing:border-box; } .bp3-button.bp3-outlined:hover{ background:rgba(167, 182, 194, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; text-decoration:none; } .bp3-button.bp3-outlined:active, .bp3-button.bp3-outlined.bp3-active{ background:rgba(115, 134, 148, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; } .bp3-button.bp3-outlined:disabled, .bp3-button.bp3-outlined:disabled:hover, .bp3-button.bp3-outlined.bp3-disabled, .bp3-button.bp3-outlined.bp3-disabled:hover{ background:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-button.bp3-outlined:disabled.bp3-active, .bp3-button.bp3-outlined:disabled:hover.bp3-active, .bp3-button.bp3-outlined.bp3-disabled.bp3-active, .bp3-button.bp3-outlined.bp3-disabled:hover.bp3-active{ background:rgba(115, 134, 148, 0.3); } .bp3-dark .bp3-button.bp3-outlined{ background:none; -webkit-box-shadow:none; box-shadow:none; color:inherit; } .bp3-dark .bp3-button.bp3-outlined:hover, .bp3-dark .bp3-button.bp3-outlined:active, .bp3-dark .bp3-button.bp3-outlined.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-button.bp3-outlined:hover{ background:rgba(138, 155, 168, 0.15); } .bp3-dark .bp3-button.bp3-outlined:active, .bp3-dark .bp3-button.bp3-outlined.bp3-active{ background:rgba(138, 155, 168, 0.3); color:#f5f8fa; } .bp3-dark .bp3-button.bp3-outlined:disabled, .bp3-dark .bp3-button.bp3-outlined:disabled:hover, .bp3-dark .bp3-button.bp3-outlined.bp3-disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-disabled:hover{ background:none; color:rgba(167, 182, 194, 0.6); cursor:not-allowed; } .bp3-dark .bp3-button.bp3-outlined:disabled.bp3-active, .bp3-dark .bp3-button.bp3-outlined:disabled:hover.bp3-active, .bp3-dark .bp3-button.bp3-outlined.bp3-disabled.bp3-active, .bp3-dark .bp3-button.bp3-outlined.bp3-disabled:hover.bp3-active{ background:rgba(138, 155, 168, 0.3); } .bp3-button.bp3-outlined.bp3-intent-primary{ color:#106ba3; } .bp3-button.bp3-outlined.bp3-intent-primary:hover, .bp3-button.bp3-outlined.bp3-intent-primary:active, .bp3-button.bp3-outlined.bp3-intent-primary.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#106ba3; } .bp3-button.bp3-outlined.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.15); color:#106ba3; } .bp3-button.bp3-outlined.bp3-intent-primary:active, .bp3-button.bp3-outlined.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#106ba3; } .bp3-button.bp3-outlined.bp3-intent-primary:disabled, .bp3-button.bp3-outlined.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(16, 107, 163, 0.5); } .bp3-button.bp3-outlined.bp3-intent-primary:disabled.bp3-active, .bp3-button.bp3-outlined.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-button.bp3-outlined.bp3-intent-primary .bp3-button-spinner .bp3-spinner-head{ stroke:#106ba3; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary{ color:#48aff0; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.2); color:#48aff0; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary:active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#48aff0; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(72, 175, 240, 0.5); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary:disabled.bp3-active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-button.bp3-outlined.bp3-intent-success{ color:#0d8050; } .bp3-button.bp3-outlined.bp3-intent-success:hover, .bp3-button.bp3-outlined.bp3-intent-success:active, .bp3-button.bp3-outlined.bp3-intent-success.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#0d8050; } .bp3-button.bp3-outlined.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.15); color:#0d8050; } .bp3-button.bp3-outlined.bp3-intent-success:active, .bp3-button.bp3-outlined.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#0d8050; } .bp3-button.bp3-outlined.bp3-intent-success:disabled, .bp3-button.bp3-outlined.bp3-intent-success.bp3-disabled{ background:none; color:rgba(13, 128, 80, 0.5); } .bp3-button.bp3-outlined.bp3-intent-success:disabled.bp3-active, .bp3-button.bp3-outlined.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-button.bp3-outlined.bp3-intent-success .bp3-button-spinner .bp3-spinner-head{ stroke:#0d8050; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success{ color:#3dcc91; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.2); color:#3dcc91; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success:active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#3dcc91; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success.bp3-disabled{ background:none; color:rgba(61, 204, 145, 0.5); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success:disabled.bp3-active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-button.bp3-outlined.bp3-intent-warning{ color:#bf7326; } .bp3-button.bp3-outlined.bp3-intent-warning:hover, .bp3-button.bp3-outlined.bp3-intent-warning:active, .bp3-button.bp3-outlined.bp3-intent-warning.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#bf7326; } .bp3-button.bp3-outlined.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.15); color:#bf7326; } .bp3-button.bp3-outlined.bp3-intent-warning:active, .bp3-button.bp3-outlined.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#bf7326; } .bp3-button.bp3-outlined.bp3-intent-warning:disabled, .bp3-button.bp3-outlined.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(191, 115, 38, 0.5); } .bp3-button.bp3-outlined.bp3-intent-warning:disabled.bp3-active, .bp3-button.bp3-outlined.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-button.bp3-outlined.bp3-intent-warning .bp3-button-spinner .bp3-spinner-head{ stroke:#bf7326; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning{ color:#ffb366; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.2); color:#ffb366; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning:active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#ffb366; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(255, 179, 102, 0.5); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning:disabled.bp3-active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-button.bp3-outlined.bp3-intent-danger{ color:#c23030; } .bp3-button.bp3-outlined.bp3-intent-danger:hover, .bp3-button.bp3-outlined.bp3-intent-danger:active, .bp3-button.bp3-outlined.bp3-intent-danger.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#c23030; } .bp3-button.bp3-outlined.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.15); color:#c23030; } .bp3-button.bp3-outlined.bp3-intent-danger:active, .bp3-button.bp3-outlined.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#c23030; } .bp3-button.bp3-outlined.bp3-intent-danger:disabled, .bp3-button.bp3-outlined.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(194, 48, 48, 0.5); } .bp3-button.bp3-outlined.bp3-intent-danger:disabled.bp3-active, .bp3-button.bp3-outlined.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-button.bp3-outlined.bp3-intent-danger .bp3-button-spinner .bp3-spinner-head{ stroke:#c23030; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger{ color:#ff7373; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.2); color:#ff7373; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger:active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#ff7373; } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(255, 115, 115, 0.5); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger:disabled.bp3-active, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-button.bp3-outlined:disabled, .bp3-button.bp3-outlined.bp3-disabled, .bp3-button.bp3-outlined:disabled:hover, .bp3-button.bp3-outlined.bp3-disabled:hover{ border-color:rgba(92, 112, 128, 0.1); } .bp3-dark .bp3-button.bp3-outlined{ border-color:rgba(255, 255, 255, 0.4); } .bp3-dark .bp3-button.bp3-outlined:disabled, .bp3-dark .bp3-button.bp3-outlined:disabled:hover, .bp3-dark .bp3-button.bp3-outlined.bp3-disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-disabled:hover{ border-color:rgba(255, 255, 255, 0.2); } .bp3-button.bp3-outlined.bp3-intent-primary{ border-color:rgba(16, 107, 163, 0.6); } .bp3-button.bp3-outlined.bp3-intent-primary:disabled, .bp3-button.bp3-outlined.bp3-intent-primary.bp3-disabled{ border-color:rgba(16, 107, 163, 0.2); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary{ border-color:rgba(72, 175, 240, 0.6); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-primary.bp3-disabled{ border-color:rgba(72, 175, 240, 0.2); } .bp3-button.bp3-outlined.bp3-intent-success{ border-color:rgba(13, 128, 80, 0.6); } .bp3-button.bp3-outlined.bp3-intent-success:disabled, .bp3-button.bp3-outlined.bp3-intent-success.bp3-disabled{ border-color:rgba(13, 128, 80, 0.2); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success{ border-color:rgba(61, 204, 145, 0.6); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-success.bp3-disabled{ border-color:rgba(61, 204, 145, 0.2); } .bp3-button.bp3-outlined.bp3-intent-warning{ border-color:rgba(191, 115, 38, 0.6); } .bp3-button.bp3-outlined.bp3-intent-warning:disabled, .bp3-button.bp3-outlined.bp3-intent-warning.bp3-disabled{ border-color:rgba(191, 115, 38, 0.2); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning{ border-color:rgba(255, 179, 102, 0.6); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-warning.bp3-disabled{ border-color:rgba(255, 179, 102, 0.2); } .bp3-button.bp3-outlined.bp3-intent-danger{ border-color:rgba(194, 48, 48, 0.6); } .bp3-button.bp3-outlined.bp3-intent-danger:disabled, .bp3-button.bp3-outlined.bp3-intent-danger.bp3-disabled{ border-color:rgba(194, 48, 48, 0.2); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger{ border-color:rgba(255, 115, 115, 0.6); } .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger:disabled, .bp3-dark .bp3-button.bp3-outlined.bp3-intent-danger.bp3-disabled{ border-color:rgba(255, 115, 115, 0.2); } a.bp3-button{ text-align:center; text-decoration:none; -webkit-transition:none; transition:none; } a.bp3-button, a.bp3-button:hover, a.bp3-button:active{ color:#182026; } a.bp3-button.bp3-disabled{ color:rgba(92, 112, 128, 0.6); } .bp3-button-text{ -webkit-box-flex:0; -ms-flex:0 1 auto; flex:0 1 auto; } .bp3-button.bp3-align-left .bp3-button-text, .bp3-button.bp3-align-right .bp3-button-text, .bp3-button-group.bp3-align-left .bp3-button-text, .bp3-button-group.bp3-align-right .bp3-button-text{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; } .bp3-button-group{ display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; } .bp3-button-group .bp3-button{ -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; position:relative; z-index:4; } .bp3-button-group .bp3-button:focus{ z-index:5; } .bp3-button-group .bp3-button:hover{ z-index:6; } .bp3-button-group .bp3-button:active, .bp3-button-group .bp3-button.bp3-active{ z-index:7; } .bp3-button-group .bp3-button:disabled, .bp3-button-group .bp3-button.bp3-disabled{ z-index:3; } .bp3-button-group .bp3-button[class*="bp3-intent-"]{ z-index:9; } .bp3-button-group .bp3-button[class*="bp3-intent-"]:focus{ z-index:10; } .bp3-button-group .bp3-button[class*="bp3-intent-"]:hover{ z-index:11; } .bp3-button-group .bp3-button[class*="bp3-intent-"]:active, .bp3-button-group .bp3-button[class*="bp3-intent-"].bp3-active{ z-index:12; } .bp3-button-group .bp3-button[class*="bp3-intent-"]:disabled, .bp3-button-group .bp3-button[class*="bp3-intent-"].bp3-disabled{ z-index:8; } .bp3-button-group:not(.bp3-minimal) > .bp3-popover-wrapper:not(:first-child) .bp3-button, .bp3-button-group:not(.bp3-minimal) > .bp3-button:not(:first-child){ border-bottom-left-radius:0; border-top-left-radius:0; } .bp3-button-group:not(.bp3-minimal) > .bp3-popover-wrapper:not(:last-child) .bp3-button, .bp3-button-group:not(.bp3-minimal) > .bp3-button:not(:last-child){ border-bottom-right-radius:0; border-top-right-radius:0; margin-right:-1px; } .bp3-button-group.bp3-minimal .bp3-button{ background:none; -webkit-box-shadow:none; box-shadow:none; } .bp3-button-group.bp3-minimal .bp3-button:hover{ background:rgba(167, 182, 194, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; text-decoration:none; } .bp3-button-group.bp3-minimal .bp3-button:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-active{ background:rgba(115, 134, 148, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; } .bp3-button-group.bp3-minimal .bp3-button:disabled, .bp3-button-group.bp3-minimal .bp3-button:disabled:hover, .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled, .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled:hover{ background:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-button-group.bp3-minimal .bp3-button:disabled.bp3-active, .bp3-button-group.bp3-minimal .bp3-button:disabled:hover.bp3-active, .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled.bp3-active, .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled:hover.bp3-active{ background:rgba(115, 134, 148, 0.3); } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button{ background:none; -webkit-box-shadow:none; box-shadow:none; color:inherit; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:hover, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:hover{ background:rgba(138, 155, 168, 0.15); } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-active{ background:rgba(138, 155, 168, 0.3); color:#f5f8fa; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:disabled, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:disabled:hover, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled:hover{ background:none; color:rgba(167, 182, 194, 0.6); cursor:not-allowed; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:disabled.bp3-active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button:disabled:hover.bp3-active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled.bp3-active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-disabled:hover.bp3-active{ background:rgba(138, 155, 168, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary{ color:#106ba3; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:hover, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#106ba3; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.15); color:#106ba3; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#106ba3; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:disabled, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(16, 107, 163, 0.5); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:disabled.bp3-active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary .bp3-button-spinner .bp3-spinner-head{ stroke:#106ba3; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary{ color:#48aff0; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.2); color:#48aff0; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#48aff0; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:disabled, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(72, 175, 240, 0.5); } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary:disabled.bp3-active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success{ color:#0d8050; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:hover, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#0d8050; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.15); color:#0d8050; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#0d8050; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:disabled, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success.bp3-disabled{ background:none; color:rgba(13, 128, 80, 0.5); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:disabled.bp3-active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success .bp3-button-spinner .bp3-spinner-head{ stroke:#0d8050; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success{ color:#3dcc91; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.2); color:#3dcc91; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#3dcc91; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:disabled, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success.bp3-disabled{ background:none; color:rgba(61, 204, 145, 0.5); } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success:disabled.bp3-active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning{ color:#bf7326; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:hover, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#bf7326; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.15); color:#bf7326; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#bf7326; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:disabled, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(191, 115, 38, 0.5); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:disabled.bp3-active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning .bp3-button-spinner .bp3-spinner-head{ stroke:#bf7326; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning{ color:#ffb366; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.2); color:#ffb366; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#ffb366; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:disabled, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(255, 179, 102, 0.5); } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning:disabled.bp3-active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger{ color:#c23030; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:hover, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#c23030; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.15); color:#c23030; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#c23030; } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:disabled, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(194, 48, 48, 0.5); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:disabled.bp3-active, .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger .bp3-button-spinner .bp3-spinner-head{ stroke:#c23030; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger{ color:#ff7373; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.2); color:#ff7373; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#ff7373; } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:disabled, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(255, 115, 115, 0.5); } .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger:disabled.bp3-active, .bp3-dark .bp3-button-group.bp3-minimal .bp3-button.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-button-group .bp3-popover-wrapper, .bp3-button-group .bp3-popover-target{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; } .bp3-button-group.bp3-fill{ display:-webkit-box; display:-ms-flexbox; display:flex; width:100%; } .bp3-button-group .bp3-button.bp3-fill, .bp3-button-group.bp3-fill .bp3-button:not(.bp3-fixed){ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; } .bp3-button-group.bp3-vertical{ -webkit-box-align:stretch; -ms-flex-align:stretch; align-items:stretch; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; vertical-align:top; } .bp3-button-group.bp3-vertical.bp3-fill{ height:100%; width:unset; } .bp3-button-group.bp3-vertical .bp3-button{ margin-right:0 !important; width:100%; } .bp3-button-group.bp3-vertical:not(.bp3-minimal) > .bp3-popover-wrapper:first-child .bp3-button, .bp3-button-group.bp3-vertical:not(.bp3-minimal) > .bp3-button:first-child{ border-radius:3px 3px 0 0; } .bp3-button-group.bp3-vertical:not(.bp3-minimal) > .bp3-popover-wrapper:last-child .bp3-button, .bp3-button-group.bp3-vertical:not(.bp3-minimal) > .bp3-button:last-child{ border-radius:0 0 3px 3px; } .bp3-button-group.bp3-vertical:not(.bp3-minimal) > .bp3-popover-wrapper:not(:last-child) .bp3-button, .bp3-button-group.bp3-vertical:not(.bp3-minimal) > .bp3-button:not(:last-child){ margin-bottom:-1px; } .bp3-button-group.bp3-align-left .bp3-button{ text-align:left; } .bp3-dark .bp3-button-group:not(.bp3-minimal) > .bp3-popover-wrapper:not(:last-child) .bp3-button, .bp3-dark .bp3-button-group:not(.bp3-minimal) > .bp3-button:not(:last-child){ margin-right:1px; } .bp3-dark .bp3-button-group.bp3-vertical > .bp3-popover-wrapper:not(:last-child) .bp3-button, .bp3-dark .bp3-button-group.bp3-vertical > .bp3-button:not(:last-child){ margin-bottom:1px; } .bp3-callout{ font-size:14px; line-height:1.5; background-color:rgba(138, 155, 168, 0.15); border-radius:3px; padding:10px 12px 9px; position:relative; width:100%; } .bp3-callout[class*="bp3-icon-"]{ padding-left:40px; } .bp3-callout[class*="bp3-icon-"]::before{ font-family:"Icons20", sans-serif; font-size:20px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; color:#5c7080; left:10px; position:absolute; top:10px; } .bp3-callout.bp3-callout-icon{ padding-left:40px; } .bp3-callout.bp3-callout-icon > .bp3-icon:first-child{ color:#5c7080; left:10px; position:absolute; top:10px; } .bp3-callout .bp3-heading{ line-height:20px; margin-bottom:5px; margin-top:0; } .bp3-callout .bp3-heading:last-child{ margin-bottom:0; } .bp3-dark .bp3-callout{ background-color:rgba(138, 155, 168, 0.2); } .bp3-dark .bp3-callout[class*="bp3-icon-"]::before{ color:#a7b6c2; } .bp3-callout.bp3-intent-primary{ background-color:rgba(19, 124, 189, 0.15); } .bp3-callout.bp3-intent-primary[class*="bp3-icon-"]::before, .bp3-callout.bp3-intent-primary > .bp3-icon:first-child, .bp3-callout.bp3-intent-primary .bp3-heading{ color:#106ba3; } .bp3-dark .bp3-callout.bp3-intent-primary{ background-color:rgba(19, 124, 189, 0.25); } .bp3-dark .bp3-callout.bp3-intent-primary[class*="bp3-icon-"]::before, .bp3-dark .bp3-callout.bp3-intent-primary > .bp3-icon:first-child, .bp3-dark .bp3-callout.bp3-intent-primary .bp3-heading{ color:#48aff0; } .bp3-callout.bp3-intent-success{ background-color:rgba(15, 153, 96, 0.15); } .bp3-callout.bp3-intent-success[class*="bp3-icon-"]::before, .bp3-callout.bp3-intent-success > .bp3-icon:first-child, .bp3-callout.bp3-intent-success .bp3-heading{ color:#0d8050; } .bp3-dark .bp3-callout.bp3-intent-success{ background-color:rgba(15, 153, 96, 0.25); } .bp3-dark .bp3-callout.bp3-intent-success[class*="bp3-icon-"]::before, .bp3-dark .bp3-callout.bp3-intent-success > .bp3-icon:first-child, .bp3-dark .bp3-callout.bp3-intent-success .bp3-heading{ color:#3dcc91; } .bp3-callout.bp3-intent-warning{ background-color:rgba(217, 130, 43, 0.15); } .bp3-callout.bp3-intent-warning[class*="bp3-icon-"]::before, .bp3-callout.bp3-intent-warning > .bp3-icon:first-child, .bp3-callout.bp3-intent-warning .bp3-heading{ color:#bf7326; } .bp3-dark .bp3-callout.bp3-intent-warning{ background-color:rgba(217, 130, 43, 0.25); } .bp3-dark .bp3-callout.bp3-intent-warning[class*="bp3-icon-"]::before, .bp3-dark .bp3-callout.bp3-intent-warning > .bp3-icon:first-child, .bp3-dark .bp3-callout.bp3-intent-warning .bp3-heading{ color:#ffb366; } .bp3-callout.bp3-intent-danger{ background-color:rgba(219, 55, 55, 0.15); } .bp3-callout.bp3-intent-danger[class*="bp3-icon-"]::before, .bp3-callout.bp3-intent-danger > .bp3-icon:first-child, .bp3-callout.bp3-intent-danger .bp3-heading{ color:#c23030; } .bp3-dark .bp3-callout.bp3-intent-danger{ background-color:rgba(219, 55, 55, 0.25); } .bp3-dark .bp3-callout.bp3-intent-danger[class*="bp3-icon-"]::before, .bp3-dark .bp3-callout.bp3-intent-danger > .bp3-icon:first-child, .bp3-dark .bp3-callout.bp3-intent-danger .bp3-heading{ color:#ff7373; } .bp3-running-text .bp3-callout{ margin:20px 0; } .bp3-card{ background-color:#ffffff; border-radius:3px; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.15), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.15), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); padding:20px; -webkit-transition:-webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:-webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9), box-shadow 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9), box-shadow 200ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 200ms cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-card.bp3-dark, .bp3-dark .bp3-card{ background-color:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); } .bp3-elevation-0{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.15), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.15), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); } .bp3-elevation-0.bp3-dark, .bp3-dark .bp3-elevation-0{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), 0 0 0 rgba(16, 22, 26, 0), 0 0 0 rgba(16, 22, 26, 0); } .bp3-elevation-1{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-elevation-1.bp3-dark, .bp3-dark .bp3-elevation-1{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-elevation-2{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 1px 1px rgba(16, 22, 26, 0.2), 0 2px 6px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 1px 1px rgba(16, 22, 26, 0.2), 0 2px 6px rgba(16, 22, 26, 0.2); } .bp3-elevation-2.bp3-dark, .bp3-dark .bp3-elevation-2{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.4), 0 2px 6px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.4), 0 2px 6px rgba(16, 22, 26, 0.4); } .bp3-elevation-3{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); } .bp3-elevation-3.bp3-dark, .bp3-dark .bp3-elevation-3{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); } .bp3-elevation-4{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); } .bp3-elevation-4.bp3-dark, .bp3-dark .bp3-elevation-4{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); } .bp3-card.bp3-interactive:hover{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); cursor:pointer; } .bp3-card.bp3-interactive:hover.bp3-dark, .bp3-dark .bp3-card.bp3-interactive:hover{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); } .bp3-card.bp3-interactive:active{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); opacity:0.9; -webkit-transition-duration:0; transition-duration:0; } .bp3-card.bp3-interactive:active.bp3-dark, .bp3-dark .bp3-card.bp3-interactive:active{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-collapse{ height:0; overflow-y:hidden; -webkit-transition:height 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:height 200ms cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-collapse .bp3-collapse-body{ -webkit-transition:-webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:-webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-collapse .bp3-collapse-body[aria-hidden="true"]{ display:none; } .bp3-context-menu .bp3-popover-target{ display:block; } .bp3-context-menu-popover-target{ position:fixed; } .bp3-divider{ border-bottom:1px solid rgba(16, 22, 26, 0.15); border-right:1px solid rgba(16, 22, 26, 0.15); margin:5px; } .bp3-dark .bp3-divider{ border-color:rgba(16, 22, 26, 0.4); } .bp3-dialog-container{ opacity:1; -webkit-transform:scale(1); transform:scale(1); -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-pack:center; -ms-flex-pack:center; justify-content:center; min-height:100%; pointer-events:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; width:100%; } .bp3-dialog-container.bp3-overlay-enter > .bp3-dialog, .bp3-dialog-container.bp3-overlay-appear > .bp3-dialog{ opacity:0; -webkit-transform:scale(0.5); transform:scale(0.5); } .bp3-dialog-container.bp3-overlay-enter-active > .bp3-dialog, .bp3-dialog-container.bp3-overlay-appear-active > .bp3-dialog{ opacity:1; -webkit-transform:scale(1); transform:scale(1); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:300ms; transition-duration:300ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:opacity, transform; transition-property:opacity, transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); } .bp3-dialog-container.bp3-overlay-exit > .bp3-dialog{ opacity:1; -webkit-transform:scale(1); transform:scale(1); } .bp3-dialog-container.bp3-overlay-exit-active > .bp3-dialog{ opacity:0; -webkit-transform:scale(0.5); transform:scale(0.5); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:300ms; transition-duration:300ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:opacity, transform; transition-property:opacity, transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); } .bp3-dialog{ background:#ebf1f5; border-radius:6px; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; margin:30px 0; padding-bottom:20px; pointer-events:all; -webkit-user-select:text; -moz-user-select:text; -ms-user-select:text; user-select:text; width:500px; } .bp3-dialog:focus{ outline:0; } .bp3-dialog.bp3-dark, .bp3-dark .bp3-dialog{ background:#293742; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-dialog-header{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; background:#ffffff; border-radius:6px 6px 0 0; -webkit-box-shadow:0 1px 0 rgba(16, 22, 26, 0.15); box-shadow:0 1px 0 rgba(16, 22, 26, 0.15); display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; min-height:40px; padding-left:20px; padding-right:5px; z-index:30; } .bp3-dialog-header .bp3-icon-large, .bp3-dialog-header .bp3-icon{ color:#5c7080; -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; margin-right:10px; } .bp3-dialog-header .bp3-heading{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; line-height:inherit; margin:0; } .bp3-dialog-header .bp3-heading:last-child{ margin-right:20px; } .bp3-dark .bp3-dialog-header{ background:#30404d; -webkit-box-shadow:0 1px 0 rgba(16, 22, 26, 0.4); box-shadow:0 1px 0 rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-dialog-header .bp3-icon-large, .bp3-dark .bp3-dialog-header .bp3-icon{ color:#a7b6c2; } .bp3-dialog-body{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; line-height:18px; margin:20px; } .bp3-dialog-footer{ -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; margin:0 20px; } .bp3-dialog-footer-actions{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-pack:end; -ms-flex-pack:end; justify-content:flex-end; } .bp3-dialog-footer-actions .bp3-button{ margin-left:10px; } .bp3-multistep-dialog-panels{ display:-webkit-box; display:-ms-flexbox; display:flex; } .bp3-multistep-dialog-left-panel{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-flex:1; -ms-flex:1; flex:1; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; } .bp3-dark .bp3-multistep-dialog-left-panel{ background:#202b33; } .bp3-multistep-dialog-right-panel{ background-color:#f5f8fa; border-left:1px solid rgba(16, 22, 26, 0.15); border-radius:0 0 6px 0; -webkit-box-flex:3; -ms-flex:3; flex:3; min-width:0; } .bp3-dark .bp3-multistep-dialog-right-panel{ background-color:#293742; border-left:1px solid rgba(16, 22, 26, 0.4); } .bp3-multistep-dialog-footer{ background-color:#ffffff; border-radius:0 0 6px 0; border-top:1px solid rgba(16, 22, 26, 0.15); padding:10px; } .bp3-dark .bp3-multistep-dialog-footer{ background:#30404d; border-top:1px solid rgba(16, 22, 26, 0.4); } .bp3-dialog-step-container{ background-color:#f5f8fa; border-bottom:1px solid rgba(16, 22, 26, 0.15); } .bp3-dark .bp3-dialog-step-container{ background:#293742; border-bottom:1px solid rgba(16, 22, 26, 0.4); } .bp3-dialog-step-container.bp3-dialog-step-viewed{ background-color:#ffffff; } .bp3-dark .bp3-dialog-step-container.bp3-dialog-step-viewed{ background:#30404d; } .bp3-dialog-step{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; background-color:#f5f8fa; border-radius:6px; cursor:not-allowed; display:-webkit-box; display:-ms-flexbox; display:flex; margin:4px; padding:6px 14px; } .bp3-dark .bp3-dialog-step{ background:#293742; } .bp3-dialog-step-viewed .bp3-dialog-step{ background-color:#ffffff; cursor:pointer; } .bp3-dark .bp3-dialog-step-viewed .bp3-dialog-step{ background:#30404d; } .bp3-dialog-step:hover{ background-color:#f5f8fa; } .bp3-dark .bp3-dialog-step:hover{ background:#293742; } .bp3-dialog-step-icon{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; background-color:rgba(92, 112, 128, 0.6); border-radius:50%; color:#ffffff; display:-webkit-box; display:-ms-flexbox; display:flex; height:25px; -webkit-box-pack:center; -ms-flex-pack:center; justify-content:center; width:25px; } .bp3-dark .bp3-dialog-step-icon{ background-color:rgba(167, 182, 194, 0.6); } .bp3-active.bp3-dialog-step-viewed .bp3-dialog-step-icon{ background-color:#2b95d6; } .bp3-dialog-step-viewed .bp3-dialog-step-icon{ background-color:#8a9ba8; } .bp3-dialog-step-title{ color:rgba(92, 112, 128, 0.6); -webkit-box-flex:1; -ms-flex:1; flex:1; padding-left:10px; } .bp3-dark .bp3-dialog-step-title{ color:rgba(167, 182, 194, 0.6); } .bp3-active.bp3-dialog-step-viewed .bp3-dialog-step-title{ color:#2b95d6; } .bp3-dialog-step-viewed:not(.bp3-active) .bp3-dialog-step-title{ color:#182026; } .bp3-dark .bp3-dialog-step-viewed:not(.bp3-active) .bp3-dialog-step-title{ color:#f5f8fa; } .bp3-drawer{ background:#ffffff; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; margin:0; padding:0; } .bp3-drawer:focus{ outline:0; } .bp3-drawer.bp3-position-top{ height:50%; left:0; right:0; top:0; } .bp3-drawer.bp3-position-top.bp3-overlay-enter, .bp3-drawer.bp3-position-top.bp3-overlay-appear{ -webkit-transform:translateY(-100%); transform:translateY(-100%); } .bp3-drawer.bp3-position-top.bp3-overlay-enter-active, .bp3-drawer.bp3-position-top.bp3-overlay-appear-active{ -webkit-transform:translateY(0); transform:translateY(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-position-top.bp3-overlay-exit{ -webkit-transform:translateY(0); transform:translateY(0); } .bp3-drawer.bp3-position-top.bp3-overlay-exit-active{ -webkit-transform:translateY(-100%); transform:translateY(-100%); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-position-bottom{ bottom:0; height:50%; left:0; right:0; } .bp3-drawer.bp3-position-bottom.bp3-overlay-enter, .bp3-drawer.bp3-position-bottom.bp3-overlay-appear{ -webkit-transform:translateY(100%); transform:translateY(100%); } .bp3-drawer.bp3-position-bottom.bp3-overlay-enter-active, .bp3-drawer.bp3-position-bottom.bp3-overlay-appear-active{ -webkit-transform:translateY(0); transform:translateY(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-position-bottom.bp3-overlay-exit{ -webkit-transform:translateY(0); transform:translateY(0); } .bp3-drawer.bp3-position-bottom.bp3-overlay-exit-active{ -webkit-transform:translateY(100%); transform:translateY(100%); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-position-left{ bottom:0; left:0; top:0; width:50%; } .bp3-drawer.bp3-position-left.bp3-overlay-enter, .bp3-drawer.bp3-position-left.bp3-overlay-appear{ -webkit-transform:translateX(-100%); transform:translateX(-100%); } .bp3-drawer.bp3-position-left.bp3-overlay-enter-active, .bp3-drawer.bp3-position-left.bp3-overlay-appear-active{ -webkit-transform:translateX(0); transform:translateX(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-position-left.bp3-overlay-exit{ -webkit-transform:translateX(0); transform:translateX(0); } .bp3-drawer.bp3-position-left.bp3-overlay-exit-active{ -webkit-transform:translateX(-100%); transform:translateX(-100%); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-position-right{ bottom:0; right:0; top:0; width:50%; } .bp3-drawer.bp3-position-right.bp3-overlay-enter, .bp3-drawer.bp3-position-right.bp3-overlay-appear{ -webkit-transform:translateX(100%); transform:translateX(100%); } .bp3-drawer.bp3-position-right.bp3-overlay-enter-active, .bp3-drawer.bp3-position-right.bp3-overlay-appear-active{ -webkit-transform:translateX(0); transform:translateX(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-position-right.bp3-overlay-exit{ -webkit-transform:translateX(0); transform:translateX(0); } .bp3-drawer.bp3-position-right.bp3-overlay-exit-active{ -webkit-transform:translateX(100%); transform:translateX(100%); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right):not(.bp3-vertical){ bottom:0; right:0; top:0; width:50%; } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right):not(.bp3-vertical).bp3-overlay-enter, .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right):not(.bp3-vertical).bp3-overlay-appear{ -webkit-transform:translateX(100%); transform:translateX(100%); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right):not(.bp3-vertical).bp3-overlay-enter-active, .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right):not(.bp3-vertical).bp3-overlay-appear-active{ -webkit-transform:translateX(0); transform:translateX(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right):not(.bp3-vertical).bp3-overlay-exit{ -webkit-transform:translateX(0); transform:translateX(0); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right):not(.bp3-vertical).bp3-overlay-exit-active{ -webkit-transform:translateX(100%); transform:translateX(100%); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right).bp3-vertical{ bottom:0; height:50%; left:0; right:0; } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right).bp3-vertical.bp3-overlay-enter, .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right).bp3-vertical.bp3-overlay-appear{ -webkit-transform:translateY(100%); transform:translateY(100%); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right).bp3-vertical.bp3-overlay-enter-active, .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right).bp3-vertical.bp3-overlay-appear-active{ -webkit-transform:translateY(0); transform:translateY(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right).bp3-vertical.bp3-overlay-exit{ -webkit-transform:translateY(0); transform:translateY(0); } .bp3-drawer:not(.bp3-position-top):not(.bp3-position-bottom):not(.bp3-position-left):not( .bp3-position-right).bp3-vertical.bp3-overlay-exit-active{ -webkit-transform:translateY(100%); transform:translateY(100%); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-drawer.bp3-dark, .bp3-dark .bp3-drawer{ background:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-drawer-header{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; border-radius:0; -webkit-box-shadow:0 1px 0 rgba(16, 22, 26, 0.15); box-shadow:0 1px 0 rgba(16, 22, 26, 0.15); display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; min-height:40px; padding:5px; padding-left:20px; position:relative; } .bp3-drawer-header .bp3-icon-large, .bp3-drawer-header .bp3-icon{ color:#5c7080; -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; margin-right:10px; } .bp3-drawer-header .bp3-heading{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; line-height:inherit; margin:0; } .bp3-drawer-header .bp3-heading:last-child{ margin-right:20px; } .bp3-dark .bp3-drawer-header{ -webkit-box-shadow:0 1px 0 rgba(16, 22, 26, 0.4); box-shadow:0 1px 0 rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-drawer-header .bp3-icon-large, .bp3-dark .bp3-drawer-header .bp3-icon{ color:#a7b6c2; } .bp3-drawer-body{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; line-height:18px; overflow:auto; } .bp3-drawer-footer{ -webkit-box-shadow:inset 0 1px 0 rgba(16, 22, 26, 0.15); box-shadow:inset 0 1px 0 rgba(16, 22, 26, 0.15); -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; padding:10px 20px; position:relative; } .bp3-dark .bp3-drawer-footer{ -webkit-box-shadow:inset 0 1px 0 rgba(16, 22, 26, 0.4); box-shadow:inset 0 1px 0 rgba(16, 22, 26, 0.4); } .bp3-editable-text{ cursor:text; display:inline-block; max-width:100%; position:relative; vertical-align:top; white-space:nowrap; } .bp3-editable-text::before{ bottom:-3px; left:-3px; position:absolute; right:-3px; top:-3px; border-radius:3px; content:""; -webkit-transition:background-color 100ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:background-color 100ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:background-color 100ms cubic-bezier(0.4, 1, 0.75, 0.9), box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:background-color 100ms cubic-bezier(0.4, 1, 0.75, 0.9), box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-editable-text:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.15); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.15); } .bp3-editable-text.bp3-editable-text-editing::before{ background-color:#ffffff; -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-editable-text.bp3-disabled::before{ -webkit-box-shadow:none; box-shadow:none; } .bp3-editable-text.bp3-intent-primary .bp3-editable-text-input, .bp3-editable-text.bp3-intent-primary .bp3-editable-text-content{ color:#137cbd; } .bp3-editable-text.bp3-intent-primary:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(19, 124, 189, 0.4); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(19, 124, 189, 0.4); } .bp3-editable-text.bp3-intent-primary.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-editable-text.bp3-intent-success .bp3-editable-text-input, .bp3-editable-text.bp3-intent-success .bp3-editable-text-content{ color:#0f9960; } .bp3-editable-text.bp3-intent-success:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px rgba(15, 153, 96, 0.4); box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px rgba(15, 153, 96, 0.4); } .bp3-editable-text.bp3-intent-success.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-editable-text.bp3-intent-warning .bp3-editable-text-input, .bp3-editable-text.bp3-intent-warning .bp3-editable-text-content{ color:#d9822b; } .bp3-editable-text.bp3-intent-warning:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px rgba(217, 130, 43, 0.4); box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px rgba(217, 130, 43, 0.4); } .bp3-editable-text.bp3-intent-warning.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-editable-text.bp3-intent-danger .bp3-editable-text-input, .bp3-editable-text.bp3-intent-danger .bp3-editable-text-content{ color:#db3737; } .bp3-editable-text.bp3-intent-danger:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px rgba(219, 55, 55, 0.4); box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px rgba(219, 55, 55, 0.4); } .bp3-editable-text.bp3-intent-danger.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-editable-text:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(255, 255, 255, 0.15); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(255, 255, 255, 0.15); } .bp3-dark .bp3-editable-text.bp3-editable-text-editing::before{ background-color:rgba(16, 22, 26, 0.3); -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-editable-text.bp3-disabled::before{ -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-editable-text.bp3-intent-primary .bp3-editable-text-content{ color:#48aff0; } .bp3-dark .bp3-editable-text.bp3-intent-primary:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(72, 175, 240, 0), 0 0 0 0 rgba(72, 175, 240, 0), inset 0 0 0 1px rgba(72, 175, 240, 0.4); box-shadow:0 0 0 0 rgba(72, 175, 240, 0), 0 0 0 0 rgba(72, 175, 240, 0), inset 0 0 0 1px rgba(72, 175, 240, 0.4); } .bp3-dark .bp3-editable-text.bp3-intent-primary.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #48aff0, 0 0 0 3px rgba(72, 175, 240, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #48aff0, 0 0 0 3px rgba(72, 175, 240, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-editable-text.bp3-intent-success .bp3-editable-text-content{ color:#3dcc91; } .bp3-dark .bp3-editable-text.bp3-intent-success:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(61, 204, 145, 0), 0 0 0 0 rgba(61, 204, 145, 0), inset 0 0 0 1px rgba(61, 204, 145, 0.4); box-shadow:0 0 0 0 rgba(61, 204, 145, 0), 0 0 0 0 rgba(61, 204, 145, 0), inset 0 0 0 1px rgba(61, 204, 145, 0.4); } .bp3-dark .bp3-editable-text.bp3-intent-success.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #3dcc91, 0 0 0 3px rgba(61, 204, 145, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #3dcc91, 0 0 0 3px rgba(61, 204, 145, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-editable-text.bp3-intent-warning .bp3-editable-text-content{ color:#ffb366; } .bp3-dark .bp3-editable-text.bp3-intent-warning:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(255, 179, 102, 0), 0 0 0 0 rgba(255, 179, 102, 0), inset 0 0 0 1px rgba(255, 179, 102, 0.4); box-shadow:0 0 0 0 rgba(255, 179, 102, 0), 0 0 0 0 rgba(255, 179, 102, 0), inset 0 0 0 1px rgba(255, 179, 102, 0.4); } .bp3-dark .bp3-editable-text.bp3-intent-warning.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #ffb366, 0 0 0 3px rgba(255, 179, 102, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #ffb366, 0 0 0 3px rgba(255, 179, 102, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-editable-text.bp3-intent-danger .bp3-editable-text-content{ color:#ff7373; } .bp3-dark .bp3-editable-text.bp3-intent-danger:hover::before{ -webkit-box-shadow:0 0 0 0 rgba(255, 115, 115, 0), 0 0 0 0 rgba(255, 115, 115, 0), inset 0 0 0 1px rgba(255, 115, 115, 0.4); box-shadow:0 0 0 0 rgba(255, 115, 115, 0), 0 0 0 0 rgba(255, 115, 115, 0), inset 0 0 0 1px rgba(255, 115, 115, 0.4); } .bp3-dark .bp3-editable-text.bp3-intent-danger.bp3-editable-text-editing::before{ -webkit-box-shadow:0 0 0 1px #ff7373, 0 0 0 3px rgba(255, 115, 115, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #ff7373, 0 0 0 3px rgba(255, 115, 115, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-editable-text-input, .bp3-editable-text-content{ color:inherit; display:inherit; font:inherit; letter-spacing:inherit; max-width:inherit; min-width:inherit; position:relative; resize:none; text-transform:inherit; vertical-align:top; } .bp3-editable-text-input{ background:none; border:none; -webkit-box-shadow:none; box-shadow:none; padding:0; white-space:pre-wrap; width:100%; } .bp3-editable-text-input::-webkit-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-editable-text-input::-moz-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-editable-text-input:-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-editable-text-input::-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-editable-text-input::placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-editable-text-input:focus{ outline:none; } .bp3-editable-text-input::-ms-clear{ display:none; } .bp3-editable-text-content{ overflow:hidden; padding-right:2px; text-overflow:ellipsis; white-space:pre; } .bp3-editable-text-editing > .bp3-editable-text-content{ left:0; position:absolute; visibility:hidden; } .bp3-editable-text-placeholder > .bp3-editable-text-content{ color:rgba(92, 112, 128, 0.6); } .bp3-dark .bp3-editable-text-placeholder > .bp3-editable-text-content{ color:rgba(167, 182, 194, 0.6); } .bp3-editable-text.bp3-multiline{ display:block; } .bp3-editable-text.bp3-multiline .bp3-editable-text-content{ overflow:auto; white-space:pre-wrap; word-wrap:break-word; } .bp3-divider{ border-bottom:1px solid rgba(16, 22, 26, 0.15); border-right:1px solid rgba(16, 22, 26, 0.15); margin:5px; } .bp3-dark .bp3-divider{ border-color:rgba(16, 22, 26, 0.4); } .bp3-control-group{ -webkit-transform:translateZ(0); transform:translateZ(0); display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:stretch; -ms-flex-align:stretch; align-items:stretch; } .bp3-control-group > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-control-group > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-control-group .bp3-button, .bp3-control-group .bp3-html-select, .bp3-control-group .bp3-input, .bp3-control-group .bp3-select{ position:relative; } .bp3-control-group .bp3-input{ border-radius:inherit; z-index:2; } .bp3-control-group .bp3-input:focus{ border-radius:3px; z-index:14; } .bp3-control-group .bp3-input[class*="bp3-intent"]{ z-index:13; } .bp3-control-group .bp3-input[class*="bp3-intent"]:focus{ z-index:15; } .bp3-control-group .bp3-input[readonly], .bp3-control-group .bp3-input:disabled, .bp3-control-group .bp3-input.bp3-disabled{ z-index:1; } .bp3-control-group .bp3-input-group[class*="bp3-intent"] .bp3-input{ z-index:13; } .bp3-control-group .bp3-input-group[class*="bp3-intent"] .bp3-input:focus{ z-index:15; } .bp3-control-group .bp3-button, .bp3-control-group .bp3-html-select select, .bp3-control-group .bp3-select select{ -webkit-transform:translateZ(0); transform:translateZ(0); border-radius:inherit; z-index:4; } .bp3-control-group .bp3-button:focus, .bp3-control-group .bp3-html-select select:focus, .bp3-control-group .bp3-select select:focus{ z-index:5; } .bp3-control-group .bp3-button:hover, .bp3-control-group .bp3-html-select select:hover, .bp3-control-group .bp3-select select:hover{ z-index:6; } .bp3-control-group .bp3-button:active, .bp3-control-group .bp3-html-select select:active, .bp3-control-group .bp3-select select:active{ z-index:7; } .bp3-control-group .bp3-button[readonly], .bp3-control-group .bp3-button:disabled, .bp3-control-group .bp3-button.bp3-disabled, .bp3-control-group .bp3-html-select select[readonly], .bp3-control-group .bp3-html-select select:disabled, .bp3-control-group .bp3-html-select select.bp3-disabled, .bp3-control-group .bp3-select select[readonly], .bp3-control-group .bp3-select select:disabled, .bp3-control-group .bp3-select select.bp3-disabled{ z-index:3; } .bp3-control-group .bp3-button[class*="bp3-intent"], .bp3-control-group .bp3-html-select select[class*="bp3-intent"], .bp3-control-group .bp3-select select[class*="bp3-intent"]{ z-index:9; } .bp3-control-group .bp3-button[class*="bp3-intent"]:focus, .bp3-control-group .bp3-html-select select[class*="bp3-intent"]:focus, .bp3-control-group .bp3-select select[class*="bp3-intent"]:focus{ z-index:10; } .bp3-control-group .bp3-button[class*="bp3-intent"]:hover, .bp3-control-group .bp3-html-select select[class*="bp3-intent"]:hover, .bp3-control-group .bp3-select select[class*="bp3-intent"]:hover{ z-index:11; } .bp3-control-group .bp3-button[class*="bp3-intent"]:active, .bp3-control-group .bp3-html-select select[class*="bp3-intent"]:active, .bp3-control-group .bp3-select select[class*="bp3-intent"]:active{ z-index:12; } .bp3-control-group .bp3-button[class*="bp3-intent"][readonly], .bp3-control-group .bp3-button[class*="bp3-intent"]:disabled, .bp3-control-group .bp3-button[class*="bp3-intent"].bp3-disabled, .bp3-control-group .bp3-html-select select[class*="bp3-intent"][readonly], .bp3-control-group .bp3-html-select select[class*="bp3-intent"]:disabled, .bp3-control-group .bp3-html-select select[class*="bp3-intent"].bp3-disabled, .bp3-control-group .bp3-select select[class*="bp3-intent"][readonly], .bp3-control-group .bp3-select select[class*="bp3-intent"]:disabled, .bp3-control-group .bp3-select select[class*="bp3-intent"].bp3-disabled{ z-index:8; } .bp3-control-group .bp3-input-group > .bp3-icon, .bp3-control-group .bp3-input-group > .bp3-button, .bp3-control-group .bp3-input-group > .bp3-input-left-container, .bp3-control-group .bp3-input-group > .bp3-input-action{ z-index:16; } .bp3-control-group .bp3-select::after, .bp3-control-group .bp3-html-select::after, .bp3-control-group .bp3-select > .bp3-icon, .bp3-control-group .bp3-html-select > .bp3-icon{ z-index:17; } .bp3-control-group .bp3-select:focus-within{ z-index:5; } .bp3-control-group:not(.bp3-vertical) > *:not(.bp3-divider){ margin-right:-1px; } .bp3-control-group:not(.bp3-vertical) > .bp3-divider:not(:first-child){ margin-left:6px; } .bp3-dark .bp3-control-group:not(.bp3-vertical) > *:not(.bp3-divider){ margin-right:0; } .bp3-dark .bp3-control-group:not(.bp3-vertical) > .bp3-button + .bp3-button{ margin-left:1px; } .bp3-control-group .bp3-popover-wrapper, .bp3-control-group .bp3-popover-target{ border-radius:inherit; } .bp3-control-group > :first-child{ border-radius:3px 0 0 3px; } .bp3-control-group > :last-child{ border-radius:0 3px 3px 0; margin-right:0; } .bp3-control-group > :only-child{ border-radius:3px; margin-right:0; } .bp3-control-group .bp3-input-group .bp3-button{ border-radius:3px; } .bp3-control-group .bp3-numeric-input:not(:first-child) .bp3-input-group{ border-bottom-left-radius:0; border-top-left-radius:0; } .bp3-control-group.bp3-fill{ width:100%; } .bp3-control-group > .bp3-fill{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; } .bp3-control-group.bp3-fill > *:not(.bp3-fixed){ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; } .bp3-control-group.bp3-vertical{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; } .bp3-control-group.bp3-vertical > *{ margin-top:-1px; } .bp3-control-group.bp3-vertical > :first-child{ border-radius:3px 3px 0 0; margin-top:0; } .bp3-control-group.bp3-vertical > :last-child{ border-radius:0 0 3px 3px; } .bp3-control{ cursor:pointer; display:block; margin-bottom:10px; position:relative; text-transform:none; } .bp3-control input:checked ~ .bp3-control-indicator{ background-color:#137cbd; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.1)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); color:#ffffff; } .bp3-control:hover input:checked ~ .bp3-control-indicator{ background-color:#106ba3; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); } .bp3-control input:not(:disabled):active:checked ~ .bp3-control-indicator{ background:#0e5a8a; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-control input:disabled:checked ~ .bp3-control-indicator{ background:rgba(19, 124, 189, 0.5); -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-control input:checked ~ .bp3-control-indicator{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control:hover input:checked ~ .bp3-control-indicator{ background-color:#106ba3; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control input:not(:disabled):active:checked ~ .bp3-control-indicator{ background-color:#0e5a8a; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-control input:disabled:checked ~ .bp3-control-indicator{ background:rgba(14, 90, 138, 0.5); -webkit-box-shadow:none; box-shadow:none; } .bp3-control:not(.bp3-align-right){ padding-left:26px; } .bp3-control:not(.bp3-align-right) .bp3-control-indicator{ margin-left:-26px; } .bp3-control.bp3-align-right{ padding-right:26px; } .bp3-control.bp3-align-right .bp3-control-indicator{ margin-right:-26px; } .bp3-control.bp3-disabled{ color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-control.bp3-inline{ display:inline-block; margin-right:20px; } .bp3-control input{ left:0; opacity:0; position:absolute; top:0; z-index:-1; } .bp3-control .bp3-control-indicator{ background-clip:padding-box; background-color:#f5f8fa; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.8)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0)); border:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); cursor:pointer; display:inline-block; font-size:16px; height:1em; margin-right:10px; margin-top:-3px; position:relative; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; vertical-align:middle; width:1em; } .bp3-control .bp3-control-indicator::before{ content:""; display:block; height:1em; width:1em; } .bp3-control:hover .bp3-control-indicator{ background-color:#ebf1f5; } .bp3-control input:not(:disabled):active ~ .bp3-control-indicator{ background:#d8e1e8; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-control input:disabled ~ .bp3-control-indicator{ background:rgba(206, 217, 224, 0.5); -webkit-box-shadow:none; box-shadow:none; cursor:not-allowed; } .bp3-control input:focus ~ .bp3-control-indicator{ outline:rgba(19, 124, 189, 0.6) auto 2px; outline-offset:2px; -moz-outline-radius:6px; } .bp3-control.bp3-align-right .bp3-control-indicator{ float:right; margin-left:10px; margin-top:1px; } .bp3-control.bp3-large{ font-size:16px; } .bp3-control.bp3-large:not(.bp3-align-right){ padding-left:30px; } .bp3-control.bp3-large:not(.bp3-align-right) .bp3-control-indicator{ margin-left:-30px; } .bp3-control.bp3-large.bp3-align-right{ padding-right:30px; } .bp3-control.bp3-large.bp3-align-right .bp3-control-indicator{ margin-right:-30px; } .bp3-control.bp3-large .bp3-control-indicator{ font-size:20px; } .bp3-control.bp3-large.bp3-align-right .bp3-control-indicator{ margin-top:0; } .bp3-control.bp3-checkbox input:indeterminate ~ .bp3-control-indicator{ background-color:#137cbd; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.1)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); color:#ffffff; } .bp3-control.bp3-checkbox:hover input:indeterminate ~ .bp3-control-indicator{ background-color:#106ba3; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 -1px 0 rgba(16, 22, 26, 0.2); } .bp3-control.bp3-checkbox input:not(:disabled):active:indeterminate ~ .bp3-control-indicator{ background:#0e5a8a; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-control.bp3-checkbox input:disabled:indeterminate ~ .bp3-control-indicator{ background:rgba(19, 124, 189, 0.5); -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-control.bp3-checkbox input:indeterminate ~ .bp3-control-indicator{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control.bp3-checkbox:hover input:indeterminate ~ .bp3-control-indicator{ background-color:#106ba3; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control.bp3-checkbox input:not(:disabled):active:indeterminate ~ .bp3-control-indicator{ background-color:#0e5a8a; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-control.bp3-checkbox input:disabled:indeterminate ~ .bp3-control-indicator{ background:rgba(14, 90, 138, 0.5); -webkit-box-shadow:none; box-shadow:none; } .bp3-control.bp3-checkbox .bp3-control-indicator{ border-radius:3px; } .bp3-control.bp3-checkbox input:checked ~ .bp3-control-indicator::before{ background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill-rule='evenodd' clip-rule='evenodd' d='M12 5c-.28 0-.53.11-.71.29L7 9.59l-2.29-2.3a1.003 1.003 0 00-1.42 1.42l3 3c.18.18.43.29.71.29s.53-.11.71-.29l5-5A1.003 1.003 0 0012 5z' fill='white'/%3e%3c/svg%3e"); } .bp3-control.bp3-checkbox input:indeterminate ~ .bp3-control-indicator::before{ background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill-rule='evenodd' clip-rule='evenodd' d='M11 7H5c-.55 0-1 .45-1 1s.45 1 1 1h6c.55 0 1-.45 1-1s-.45-1-1-1z' fill='white'/%3e%3c/svg%3e"); } .bp3-control.bp3-radio .bp3-control-indicator{ border-radius:50%; } .bp3-control.bp3-radio input:checked ~ .bp3-control-indicator::before{ background-image:radial-gradient(#ffffff, #ffffff 28%, transparent 32%); } .bp3-control.bp3-radio input:checked:disabled ~ .bp3-control-indicator::before{ opacity:0.5; } .bp3-control.bp3-radio input:focus ~ .bp3-control-indicator{ -moz-outline-radius:16px; } .bp3-control.bp3-switch input ~ .bp3-control-indicator{ background:rgba(167, 182, 194, 0.5); } .bp3-control.bp3-switch:hover input ~ .bp3-control-indicator{ background:rgba(115, 134, 148, 0.5); } .bp3-control.bp3-switch input:not(:disabled):active ~ .bp3-control-indicator{ background:rgba(92, 112, 128, 0.5); } .bp3-control.bp3-switch input:disabled ~ .bp3-control-indicator{ background:rgba(206, 217, 224, 0.5); } .bp3-control.bp3-switch input:disabled ~ .bp3-control-indicator::before{ background:rgba(255, 255, 255, 0.8); } .bp3-control.bp3-switch input:checked ~ .bp3-control-indicator{ background:#137cbd; } .bp3-control.bp3-switch:hover input:checked ~ .bp3-control-indicator{ background:#106ba3; } .bp3-control.bp3-switch input:checked:not(:disabled):active ~ .bp3-control-indicator{ background:#0e5a8a; } .bp3-control.bp3-switch input:checked:disabled ~ .bp3-control-indicator{ background:rgba(19, 124, 189, 0.5); } .bp3-control.bp3-switch input:checked:disabled ~ .bp3-control-indicator::before{ background:rgba(255, 255, 255, 0.8); } .bp3-control.bp3-switch:not(.bp3-align-right){ padding-left:38px; } .bp3-control.bp3-switch:not(.bp3-align-right) .bp3-control-indicator{ margin-left:-38px; } .bp3-control.bp3-switch.bp3-align-right{ padding-right:38px; } .bp3-control.bp3-switch.bp3-align-right .bp3-control-indicator{ margin-right:-38px; } .bp3-control.bp3-switch .bp3-control-indicator{ border:none; border-radius:1.75em; -webkit-box-shadow:none !important; box-shadow:none !important; min-width:1.75em; -webkit-transition:background-color 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:background-color 100ms cubic-bezier(0.4, 1, 0.75, 0.9); width:auto; } .bp3-control.bp3-switch .bp3-control-indicator::before{ background:#ffffff; border-radius:50%; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.2); height:calc(1em - 4px); left:0; margin:2px; position:absolute; -webkit-transition:left 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:left 100ms cubic-bezier(0.4, 1, 0.75, 0.9); width:calc(1em - 4px); } .bp3-control.bp3-switch input:checked ~ .bp3-control-indicator::before{ left:calc(100% - 1em); } .bp3-control.bp3-switch.bp3-large:not(.bp3-align-right){ padding-left:45px; } .bp3-control.bp3-switch.bp3-large:not(.bp3-align-right) .bp3-control-indicator{ margin-left:-45px; } .bp3-control.bp3-switch.bp3-large.bp3-align-right{ padding-right:45px; } .bp3-control.bp3-switch.bp3-large.bp3-align-right .bp3-control-indicator{ margin-right:-45px; } .bp3-dark .bp3-control.bp3-switch input ~ .bp3-control-indicator{ background:rgba(16, 22, 26, 0.5); } .bp3-dark .bp3-control.bp3-switch:hover input ~ .bp3-control-indicator{ background:rgba(16, 22, 26, 0.7); } .bp3-dark .bp3-control.bp3-switch input:not(:disabled):active ~ .bp3-control-indicator{ background:rgba(16, 22, 26, 0.9); } .bp3-dark .bp3-control.bp3-switch input:disabled ~ .bp3-control-indicator{ background:rgba(57, 75, 89, 0.5); } .bp3-dark .bp3-control.bp3-switch input:disabled ~ .bp3-control-indicator::before{ background:rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control.bp3-switch input:checked ~ .bp3-control-indicator{ background:#137cbd; } .bp3-dark .bp3-control.bp3-switch:hover input:checked ~ .bp3-control-indicator{ background:#106ba3; } .bp3-dark .bp3-control.bp3-switch input:checked:not(:disabled):active ~ .bp3-control-indicator{ background:#0e5a8a; } .bp3-dark .bp3-control.bp3-switch input:checked:disabled ~ .bp3-control-indicator{ background:rgba(14, 90, 138, 0.5); } .bp3-dark .bp3-control.bp3-switch input:checked:disabled ~ .bp3-control-indicator::before{ background:rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control.bp3-switch .bp3-control-indicator::before{ background:#394b59; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control.bp3-switch input:checked ~ .bp3-control-indicator::before{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-control.bp3-switch .bp3-switch-inner-text{ font-size:0.7em; text-align:center; } .bp3-control.bp3-switch .bp3-control-indicator-child:first-child{ line-height:0; margin-left:0.5em; margin-right:1.2em; visibility:hidden; } .bp3-control.bp3-switch .bp3-control-indicator-child:last-child{ line-height:1em; margin-left:1.2em; margin-right:0.5em; visibility:visible; } .bp3-control.bp3-switch input:checked ~ .bp3-control-indicator .bp3-control-indicator-child:first-child{ line-height:1em; visibility:visible; } .bp3-control.bp3-switch input:checked ~ .bp3-control-indicator .bp3-control-indicator-child:last-child{ line-height:0; visibility:hidden; } .bp3-dark .bp3-control{ color:#f5f8fa; } .bp3-dark .bp3-control.bp3-disabled{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-control .bp3-control-indicator{ background-color:#394b59; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.05)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0)); -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-control:hover .bp3-control-indicator{ background-color:#30404d; } .bp3-dark .bp3-control input:not(:disabled):active ~ .bp3-control-indicator{ background:#202b33; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-control input:disabled ~ .bp3-control-indicator{ background:rgba(57, 75, 89, 0.5); -webkit-box-shadow:none; box-shadow:none; cursor:not-allowed; } .bp3-dark .bp3-control.bp3-checkbox input:disabled:checked ~ .bp3-control-indicator, .bp3-dark .bp3-control.bp3-checkbox input:disabled:indeterminate ~ .bp3-control-indicator{ color:rgba(167, 182, 194, 0.6); } .bp3-file-input{ cursor:pointer; display:inline-block; height:30px; position:relative; } .bp3-file-input input{ margin:0; min-width:200px; opacity:0; } .bp3-file-input input:disabled + .bp3-file-upload-input, .bp3-file-input input.bp3-disabled + .bp3-file-upload-input{ background:rgba(206, 217, 224, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; resize:none; } .bp3-file-input input:disabled + .bp3-file-upload-input::after, .bp3-file-input input.bp3-disabled + .bp3-file-upload-input::after{ background-color:rgba(206, 217, 224, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; outline:none; } .bp3-file-input input:disabled + .bp3-file-upload-input::after.bp3-active, .bp3-file-input input:disabled + .bp3-file-upload-input::after.bp3-active:hover, .bp3-file-input input.bp3-disabled + .bp3-file-upload-input::after.bp3-active, .bp3-file-input input.bp3-disabled + .bp3-file-upload-input::after.bp3-active:hover{ background:rgba(206, 217, 224, 0.7); } .bp3-dark .bp3-file-input input:disabled + .bp3-file-upload-input, .bp3-dark .bp3-file-input input.bp3-disabled + .bp3-file-upload-input{ background:rgba(57, 75, 89, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-input input:disabled + .bp3-file-upload-input::after, .bp3-dark .bp3-file-input input.bp3-disabled + .bp3-file-upload-input::after{ background-color:rgba(57, 75, 89, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-input input:disabled + .bp3-file-upload-input::after.bp3-active, .bp3-dark .bp3-file-input input.bp3-disabled + .bp3-file-upload-input::after.bp3-active{ background:rgba(57, 75, 89, 0.7); } .bp3-file-input.bp3-file-input-has-selection .bp3-file-upload-input{ color:#182026; } .bp3-dark .bp3-file-input.bp3-file-input-has-selection .bp3-file-upload-input{ color:#f5f8fa; } .bp3-file-input.bp3-fill{ width:100%; } .bp3-file-input.bp3-large, .bp3-large .bp3-file-input{ height:40px; } .bp3-file-input .bp3-file-upload-input-custom-text::after{ content:attr(bp3-button-text); } .bp3-file-upload-input{ -webkit-appearance:none; -moz-appearance:none; appearance:none; background:#ffffff; border:none; border-radius:3px; -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); color:#182026; font-size:14px; font-weight:400; height:30px; line-height:30px; outline:none; padding:0 10px; -webkit-transition:-webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:-webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); vertical-align:middle; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; color:rgba(92, 112, 128, 0.6); left:0; padding-right:80px; position:absolute; right:0; top:0; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; } .bp3-file-upload-input::-webkit-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-file-upload-input::-moz-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-file-upload-input:-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-file-upload-input::-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-file-upload-input::placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-file-upload-input:focus, .bp3-file-upload-input.bp3-active{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-file-upload-input[type="search"], .bp3-file-upload-input.bp3-round{ border-radius:30px; -webkit-box-sizing:border-box; box-sizing:border-box; padding-left:10px; } .bp3-file-upload-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.15); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.15); } .bp3-file-upload-input:disabled, .bp3-file-upload-input.bp3-disabled{ background:rgba(206, 217, 224, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; resize:none; } .bp3-file-upload-input::after{ background-color:#f5f8fa; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.8)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); color:#182026; min-height:24px; min-width:24px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; border-radius:3px; content:"Browse"; line-height:24px; margin:3px; position:absolute; right:0; text-align:center; top:0; width:70px; } .bp3-file-upload-input::after:hover{ background-clip:padding-box; background-color:#ebf1f5; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); } .bp3-file-upload-input::after:active, .bp3-file-upload-input::after.bp3-active{ background-color:#d8e1e8; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-file-upload-input::after:disabled, .bp3-file-upload-input::after.bp3-disabled{ background-color:rgba(206, 217, 224, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; outline:none; } .bp3-file-upload-input::after:disabled.bp3-active, .bp3-file-upload-input::after:disabled.bp3-active:hover, .bp3-file-upload-input::after.bp3-disabled.bp3-active, .bp3-file-upload-input::after.bp3-disabled.bp3-active:hover{ background:rgba(206, 217, 224, 0.7); } .bp3-file-upload-input:hover::after{ background-clip:padding-box; background-color:#ebf1f5; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); } .bp3-file-upload-input:active::after{ background-color:#d8e1e8; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-large .bp3-file-upload-input{ font-size:16px; height:40px; line-height:40px; padding-right:95px; } .bp3-large .bp3-file-upload-input[type="search"], .bp3-large .bp3-file-upload-input.bp3-round{ padding:0 15px; } .bp3-large .bp3-file-upload-input::after{ min-height:30px; min-width:30px; line-height:30px; margin:5px; width:85px; } .bp3-dark .bp3-file-upload-input{ background:rgba(16, 22, 26, 0.3); -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input::-webkit-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input::-moz-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input:-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input::-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input::placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input:focus{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-file-upload-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-file-upload-input:disabled, .bp3-dark .bp3-file-upload-input.bp3-disabled{ background:rgba(57, 75, 89, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input::after{ background-color:#394b59; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.05)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0)); -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-dark .bp3-file-upload-input::after:hover, .bp3-dark .bp3-file-upload-input::after:active, .bp3-dark .bp3-file-upload-input::after.bp3-active{ color:#f5f8fa; } .bp3-dark .bp3-file-upload-input::after:hover{ background-color:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-file-upload-input::after:active, .bp3-dark .bp3-file-upload-input::after.bp3-active{ background-color:#202b33; background-image:none; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-file-upload-input::after:disabled, .bp3-dark .bp3-file-upload-input::after.bp3-disabled{ background-color:rgba(57, 75, 89, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-file-upload-input::after:disabled.bp3-active, .bp3-dark .bp3-file-upload-input::after.bp3-disabled.bp3-active{ background:rgba(57, 75, 89, 0.7); } .bp3-dark .bp3-file-upload-input::after .bp3-button-spinner .bp3-spinner-head{ background:rgba(16, 22, 26, 0.5); stroke:#8a9ba8; } .bp3-dark .bp3-file-upload-input:hover::after{ background-color:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-file-upload-input:active::after{ background-color:#202b33; background-image:none; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-file-upload-input::after{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); } .bp3-form-group{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; margin:0 0 15px; } .bp3-form-group label.bp3-label{ margin-bottom:5px; } .bp3-form-group .bp3-control{ margin-top:7px; } .bp3-form-group .bp3-form-helper-text{ color:#5c7080; font-size:12px; margin-top:5px; } .bp3-form-group.bp3-intent-primary .bp3-form-helper-text{ color:#106ba3; } .bp3-form-group.bp3-intent-success .bp3-form-helper-text{ color:#0d8050; } .bp3-form-group.bp3-intent-warning .bp3-form-helper-text{ color:#bf7326; } .bp3-form-group.bp3-intent-danger .bp3-form-helper-text{ color:#c23030; } .bp3-form-group.bp3-inline{ -webkit-box-align:start; -ms-flex-align:start; align-items:flex-start; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; } .bp3-form-group.bp3-inline.bp3-large label.bp3-label{ line-height:40px; margin:0 10px 0 0; } .bp3-form-group.bp3-inline label.bp3-label{ line-height:30px; margin:0 10px 0 0; } .bp3-form-group.bp3-disabled .bp3-label, .bp3-form-group.bp3-disabled .bp3-text-muted, .bp3-form-group.bp3-disabled .bp3-form-helper-text{ color:rgba(92, 112, 128, 0.6) !important; } .bp3-dark .bp3-form-group.bp3-intent-primary .bp3-form-helper-text{ color:#48aff0; } .bp3-dark .bp3-form-group.bp3-intent-success .bp3-form-helper-text{ color:#3dcc91; } .bp3-dark .bp3-form-group.bp3-intent-warning .bp3-form-helper-text{ color:#ffb366; } .bp3-dark .bp3-form-group.bp3-intent-danger .bp3-form-helper-text{ color:#ff7373; } .bp3-dark .bp3-form-group .bp3-form-helper-text{ color:#a7b6c2; } .bp3-dark .bp3-form-group.bp3-disabled .bp3-label, .bp3-dark .bp3-form-group.bp3-disabled .bp3-text-muted, .bp3-dark .bp3-form-group.bp3-disabled .bp3-form-helper-text{ color:rgba(167, 182, 194, 0.6) !important; } .bp3-input-group{ display:block; position:relative; } .bp3-input-group .bp3-input{ position:relative; width:100%; } .bp3-input-group .bp3-input:not(:first-child){ padding-left:30px; } .bp3-input-group .bp3-input:not(:last-child){ padding-right:30px; } .bp3-input-group .bp3-input-action, .bp3-input-group > .bp3-input-left-container, .bp3-input-group > .bp3-button, .bp3-input-group > .bp3-icon{ position:absolute; top:0; } .bp3-input-group .bp3-input-action:first-child, .bp3-input-group > .bp3-input-left-container:first-child, .bp3-input-group > .bp3-button:first-child, .bp3-input-group > .bp3-icon:first-child{ left:0; } .bp3-input-group .bp3-input-action:last-child, .bp3-input-group > .bp3-input-left-container:last-child, .bp3-input-group > .bp3-button:last-child, .bp3-input-group > .bp3-icon:last-child{ right:0; } .bp3-input-group .bp3-button{ min-height:24px; min-width:24px; margin:3px; padding:0 7px; } .bp3-input-group .bp3-button:empty{ padding:0; } .bp3-input-group > .bp3-input-left-container, .bp3-input-group > .bp3-icon{ z-index:1; } .bp3-input-group > .bp3-input-left-container > .bp3-icon, .bp3-input-group > .bp3-icon{ color:#5c7080; } .bp3-input-group > .bp3-input-left-container > .bp3-icon:empty, .bp3-input-group > .bp3-icon:empty{ font-family:"Icons16", sans-serif; font-size:16px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; } .bp3-input-group > .bp3-input-left-container > .bp3-icon, .bp3-input-group > .bp3-icon, .bp3-input-group .bp3-input-action > .bp3-spinner{ margin:7px; } .bp3-input-group .bp3-tag{ margin:5px; } .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:not(:hover):not(:focus), .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:not(:hover):not(:focus){ color:#5c7080; } .bp3-dark .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:not(:hover):not(:focus), .bp3-dark .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:not(:hover):not(:focus){ color:#a7b6c2; } .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:not(:hover):not(:focus) .bp3-icon, .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:not(:hover):not(:focus) .bp3-icon-standard, .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:not(:hover):not(:focus) .bp3-icon-large, .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:not(:hover):not(:focus) .bp3-icon, .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:not(:hover):not(:focus) .bp3-icon-standard, .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:not(:hover):not(:focus) .bp3-icon-large{ color:#5c7080; } .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:disabled, .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:disabled{ color:rgba(92, 112, 128, 0.6) !important; } .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:disabled .bp3-icon, .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:disabled .bp3-icon-standard, .bp3-input-group .bp3-input:not(:focus) + .bp3-button.bp3-minimal:disabled .bp3-icon-large, .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:disabled .bp3-icon, .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:disabled .bp3-icon-standard, .bp3-input-group .bp3-input:not(:focus) + .bp3-input-action .bp3-button.bp3-minimal:disabled .bp3-icon-large{ color:rgba(92, 112, 128, 0.6) !important; } .bp3-input-group.bp3-disabled{ cursor:not-allowed; } .bp3-input-group.bp3-disabled .bp3-icon{ color:rgba(92, 112, 128, 0.6); } .bp3-input-group.bp3-large .bp3-button{ min-height:30px; min-width:30px; margin:5px; } .bp3-input-group.bp3-large > .bp3-input-left-container > .bp3-icon, .bp3-input-group.bp3-large > .bp3-icon, .bp3-input-group.bp3-large .bp3-input-action > .bp3-spinner{ margin:12px; } .bp3-input-group.bp3-large .bp3-input{ font-size:16px; height:40px; line-height:40px; } .bp3-input-group.bp3-large .bp3-input[type="search"], .bp3-input-group.bp3-large .bp3-input.bp3-round{ padding:0 15px; } .bp3-input-group.bp3-large .bp3-input:not(:first-child){ padding-left:40px; } .bp3-input-group.bp3-large .bp3-input:not(:last-child){ padding-right:40px; } .bp3-input-group.bp3-small .bp3-button{ min-height:20px; min-width:20px; margin:2px; } .bp3-input-group.bp3-small .bp3-tag{ min-height:20px; min-width:20px; margin:2px; } .bp3-input-group.bp3-small > .bp3-input-left-container > .bp3-icon, .bp3-input-group.bp3-small > .bp3-icon, .bp3-input-group.bp3-small .bp3-input-action > .bp3-spinner{ margin:4px; } .bp3-input-group.bp3-small .bp3-input{ font-size:12px; height:24px; line-height:24px; padding-left:8px; padding-right:8px; } .bp3-input-group.bp3-small .bp3-input[type="search"], .bp3-input-group.bp3-small .bp3-input.bp3-round{ padding:0 12px; } .bp3-input-group.bp3-small .bp3-input:not(:first-child){ padding-left:24px; } .bp3-input-group.bp3-small .bp3-input:not(:last-child){ padding-right:24px; } .bp3-input-group.bp3-fill{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; width:100%; } .bp3-input-group.bp3-round .bp3-button, .bp3-input-group.bp3-round .bp3-input, .bp3-input-group.bp3-round .bp3-tag{ border-radius:30px; } .bp3-dark .bp3-input-group .bp3-icon{ color:#a7b6c2; } .bp3-dark .bp3-input-group.bp3-disabled .bp3-icon{ color:rgba(167, 182, 194, 0.6); } .bp3-input-group.bp3-intent-primary .bp3-input{ -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px #137cbd, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px #137cbd, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-primary .bp3-input:focus{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-primary .bp3-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #137cbd; box-shadow:inset 0 0 0 1px #137cbd; } .bp3-input-group.bp3-intent-primary .bp3-input:disabled, .bp3-input-group.bp3-intent-primary .bp3-input.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input-group.bp3-intent-primary > .bp3-icon{ color:#106ba3; } .bp3-dark .bp3-input-group.bp3-intent-primary > .bp3-icon{ color:#48aff0; } .bp3-input-group.bp3-intent-success .bp3-input{ -webkit-box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px #0f9960, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px #0f9960, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-success .bp3-input:focus{ -webkit-box-shadow:0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-success .bp3-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #0f9960; box-shadow:inset 0 0 0 1px #0f9960; } .bp3-input-group.bp3-intent-success .bp3-input:disabled, .bp3-input-group.bp3-intent-success .bp3-input.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input-group.bp3-intent-success > .bp3-icon{ color:#0d8050; } .bp3-dark .bp3-input-group.bp3-intent-success > .bp3-icon{ color:#3dcc91; } .bp3-input-group.bp3-intent-warning .bp3-input{ -webkit-box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px #d9822b, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px #d9822b, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-warning .bp3-input:focus{ -webkit-box-shadow:0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-warning .bp3-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #d9822b; box-shadow:inset 0 0 0 1px #d9822b; } .bp3-input-group.bp3-intent-warning .bp3-input:disabled, .bp3-input-group.bp3-intent-warning .bp3-input.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input-group.bp3-intent-warning > .bp3-icon{ color:#bf7326; } .bp3-dark .bp3-input-group.bp3-intent-warning > .bp3-icon{ color:#ffb366; } .bp3-input-group.bp3-intent-danger .bp3-input{ -webkit-box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px #db3737, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px #db3737, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-danger .bp3-input:focus{ -webkit-box-shadow:0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input-group.bp3-intent-danger .bp3-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #db3737; box-shadow:inset 0 0 0 1px #db3737; } .bp3-input-group.bp3-intent-danger .bp3-input:disabled, .bp3-input-group.bp3-intent-danger .bp3-input.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input-group.bp3-intent-danger > .bp3-icon{ color:#c23030; } .bp3-dark .bp3-input-group.bp3-intent-danger > .bp3-icon{ color:#ff7373; } .bp3-input{ -webkit-appearance:none; -moz-appearance:none; appearance:none; background:#ffffff; border:none; border-radius:3px; -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); color:#182026; font-size:14px; font-weight:400; height:30px; line-height:30px; outline:none; padding:0 10px; -webkit-transition:-webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:-webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-box-shadow 100ms cubic-bezier(0.4, 1, 0.75, 0.9); vertical-align:middle; } .bp3-input::-webkit-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input::-moz-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input:-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input::-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input::placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input:focus, .bp3-input.bp3-active{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input[type="search"], .bp3-input.bp3-round{ border-radius:30px; -webkit-box-sizing:border-box; box-sizing:border-box; padding-left:10px; } .bp3-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.15); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.15); } .bp3-input:disabled, .bp3-input.bp3-disabled{ background:rgba(206, 217, 224, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; resize:none; } .bp3-input.bp3-large{ font-size:16px; height:40px; line-height:40px; } .bp3-input.bp3-large[type="search"], .bp3-input.bp3-large.bp3-round{ padding:0 15px; } .bp3-input.bp3-small{ font-size:12px; height:24px; line-height:24px; padding-left:8px; padding-right:8px; } .bp3-input.bp3-small[type="search"], .bp3-input.bp3-small.bp3-round{ padding:0 12px; } .bp3-input.bp3-fill{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; width:100%; } .bp3-dark .bp3-input{ background:rgba(16, 22, 26, 0.3); -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-dark .bp3-input::-webkit-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-input::-moz-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-input:-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-input::-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-input::placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-input:focus{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input:disabled, .bp3-dark .bp3-input.bp3-disabled{ background:rgba(57, 75, 89, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-input.bp3-intent-primary{ -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px #137cbd, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px #137cbd, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-primary:focus{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-primary[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #137cbd; box-shadow:inset 0 0 0 1px #137cbd; } .bp3-input.bp3-intent-primary:disabled, .bp3-input.bp3-intent-primary.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-input.bp3-intent-primary{ -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px #137cbd, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px #137cbd, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-primary:focus{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-primary[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #137cbd; box-shadow:inset 0 0 0 1px #137cbd; } .bp3-dark .bp3-input.bp3-intent-primary:disabled, .bp3-dark .bp3-input.bp3-intent-primary.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input.bp3-intent-success{ -webkit-box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px #0f9960, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px #0f9960, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-success:focus{ -webkit-box-shadow:0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-success[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #0f9960; box-shadow:inset 0 0 0 1px #0f9960; } .bp3-input.bp3-intent-success:disabled, .bp3-input.bp3-intent-success.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-input.bp3-intent-success{ -webkit-box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px #0f9960, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), 0 0 0 0 rgba(15, 153, 96, 0), inset 0 0 0 1px #0f9960, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-success:focus{ -webkit-box-shadow:0 0 0 1px #0f9960, 0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #0f9960, 0 0 0 1px #0f9960, 0 0 0 3px rgba(15, 153, 96, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-success[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #0f9960; box-shadow:inset 0 0 0 1px #0f9960; } .bp3-dark .bp3-input.bp3-intent-success:disabled, .bp3-dark .bp3-input.bp3-intent-success.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input.bp3-intent-warning{ -webkit-box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px #d9822b, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px #d9822b, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-warning:focus{ -webkit-box-shadow:0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-warning[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #d9822b; box-shadow:inset 0 0 0 1px #d9822b; } .bp3-input.bp3-intent-warning:disabled, .bp3-input.bp3-intent-warning.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-input.bp3-intent-warning{ -webkit-box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px #d9822b, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), 0 0 0 0 rgba(217, 130, 43, 0), inset 0 0 0 1px #d9822b, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-warning:focus{ -webkit-box-shadow:0 0 0 1px #d9822b, 0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #d9822b, 0 0 0 1px #d9822b, 0 0 0 3px rgba(217, 130, 43, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-warning[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #d9822b; box-shadow:inset 0 0 0 1px #d9822b; } .bp3-dark .bp3-input.bp3-intent-warning:disabled, .bp3-dark .bp3-input.bp3-intent-warning.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input.bp3-intent-danger{ -webkit-box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px #db3737, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px #db3737, inset 0 0 0 1px rgba(16, 22, 26, 0.15), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-danger:focus{ -webkit-box-shadow:0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-input.bp3-intent-danger[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #db3737; box-shadow:inset 0 0 0 1px #db3737; } .bp3-input.bp3-intent-danger:disabled, .bp3-input.bp3-intent-danger.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-input.bp3-intent-danger{ -webkit-box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px #db3737, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), 0 0 0 0 rgba(219, 55, 55, 0), inset 0 0 0 1px #db3737, inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-danger:focus{ -webkit-box-shadow:0 0 0 1px #db3737, 0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #db3737, 0 0 0 1px #db3737, 0 0 0 3px rgba(219, 55, 55, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-input.bp3-intent-danger[readonly]{ -webkit-box-shadow:inset 0 0 0 1px #db3737; box-shadow:inset 0 0 0 1px #db3737; } .bp3-dark .bp3-input.bp3-intent-danger:disabled, .bp3-dark .bp3-input.bp3-intent-danger.bp3-disabled{ -webkit-box-shadow:none; box-shadow:none; } .bp3-input::-ms-clear{ display:none; } textarea.bp3-input{ max-width:100%; padding:10px; } textarea.bp3-input, textarea.bp3-input.bp3-large, textarea.bp3-input.bp3-small{ height:auto; line-height:inherit; } textarea.bp3-input.bp3-small{ padding:8px; } .bp3-dark textarea.bp3-input{ background:rgba(16, 22, 26, 0.3); -webkit-box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), 0 0 0 0 rgba(19, 124, 189, 0), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-dark textarea.bp3-input::-webkit-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark textarea.bp3-input::-moz-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark textarea.bp3-input:-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark textarea.bp3-input::-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark textarea.bp3-input::placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark textarea.bp3-input:focus{ -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark textarea.bp3-input[readonly]{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark textarea.bp3-input:disabled, .bp3-dark textarea.bp3-input.bp3-disabled{ background:rgba(57, 75, 89, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } label.bp3-label{ display:block; margin-bottom:15px; margin-top:0; } label.bp3-label .bp3-html-select, label.bp3-label .bp3-input, label.bp3-label .bp3-select, label.bp3-label .bp3-slider, label.bp3-label .bp3-popover-wrapper{ display:block; margin-top:5px; text-transform:none; } label.bp3-label .bp3-button-group{ margin-top:5px; } label.bp3-label .bp3-select select, label.bp3-label .bp3-html-select select{ font-weight:400; vertical-align:top; width:100%; } label.bp3-label.bp3-disabled, label.bp3-label.bp3-disabled .bp3-text-muted{ color:rgba(92, 112, 128, 0.6); } label.bp3-label.bp3-inline{ line-height:30px; } label.bp3-label.bp3-inline .bp3-html-select, label.bp3-label.bp3-inline .bp3-input, label.bp3-label.bp3-inline .bp3-input-group, label.bp3-label.bp3-inline .bp3-select, label.bp3-label.bp3-inline .bp3-popover-wrapper{ display:inline-block; margin:0 0 0 5px; vertical-align:top; } label.bp3-label.bp3-inline .bp3-button-group{ margin:0 0 0 5px; } label.bp3-label.bp3-inline .bp3-input-group .bp3-input{ margin-left:0; } label.bp3-label.bp3-inline.bp3-large{ line-height:40px; } label.bp3-label:not(.bp3-inline) .bp3-popover-target{ display:block; } .bp3-dark label.bp3-label{ color:#f5f8fa; } .bp3-dark label.bp3-label.bp3-disabled, .bp3-dark label.bp3-label.bp3-disabled .bp3-text-muted{ color:rgba(167, 182, 194, 0.6); } .bp3-numeric-input .bp3-button-group.bp3-vertical > .bp3-button{ -webkit-box-flex:1; -ms-flex:1 1 14px; flex:1 1 14px; min-height:0; padding:0; width:30px; } .bp3-numeric-input .bp3-button-group.bp3-vertical > .bp3-button:first-child{ border-radius:0 3px 0 0; } .bp3-numeric-input .bp3-button-group.bp3-vertical > .bp3-button:last-child{ border-radius:0 0 3px 0; } .bp3-numeric-input .bp3-button-group.bp3-vertical:first-child > .bp3-button:first-child{ border-radius:3px 0 0 0; } .bp3-numeric-input .bp3-button-group.bp3-vertical:first-child > .bp3-button:last-child{ border-radius:0 0 0 3px; } .bp3-numeric-input.bp3-large .bp3-button-group.bp3-vertical > .bp3-button{ width:40px; } form{ display:block; } .bp3-html-select select, .bp3-select select{ display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:center; -ms-flex-align:center; align-items:center; border:none; border-radius:3px; cursor:pointer; font-size:14px; -webkit-box-pack:center; -ms-flex-pack:center; justify-content:center; padding:5px 10px; text-align:left; vertical-align:middle; background-color:#f5f8fa; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.8)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); color:#182026; -moz-appearance:none; -webkit-appearance:none; border-radius:3px; height:30px; padding:0 25px 0 10px; width:100%; } .bp3-html-select select > *, .bp3-select select > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-html-select select > .bp3-fill, .bp3-select select > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-html-select select::before, .bp3-select select::before, .bp3-html-select select > *, .bp3-select select > *{ margin-right:7px; } .bp3-html-select select:empty::before, .bp3-select select:empty::before, .bp3-html-select select > :last-child, .bp3-select select > :last-child{ margin-right:0; } .bp3-html-select select:hover, .bp3-select select:hover{ background-clip:padding-box; background-color:#ebf1f5; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); } .bp3-html-select select:active, .bp3-select select:active, .bp3-html-select select.bp3-active, .bp3-select select.bp3-active{ background-color:#d8e1e8; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-html-select select:disabled, .bp3-select select:disabled, .bp3-html-select select.bp3-disabled, .bp3-select select.bp3-disabled{ background-color:rgba(206, 217, 224, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; outline:none; } .bp3-html-select select:disabled.bp3-active, .bp3-select select:disabled.bp3-active, .bp3-html-select select:disabled.bp3-active:hover, .bp3-select select:disabled.bp3-active:hover, .bp3-html-select select.bp3-disabled.bp3-active, .bp3-select select.bp3-disabled.bp3-active, .bp3-html-select select.bp3-disabled.bp3-active:hover, .bp3-select select.bp3-disabled.bp3-active:hover{ background:rgba(206, 217, 224, 0.7); } .bp3-html-select.bp3-minimal select, .bp3-select.bp3-minimal select{ background:none; -webkit-box-shadow:none; box-shadow:none; } .bp3-html-select.bp3-minimal select:hover, .bp3-select.bp3-minimal select:hover{ background:rgba(167, 182, 194, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; text-decoration:none; } .bp3-html-select.bp3-minimal select:active, .bp3-select.bp3-minimal select:active, .bp3-html-select.bp3-minimal select.bp3-active, .bp3-select.bp3-minimal select.bp3-active{ background:rgba(115, 134, 148, 0.3); -webkit-box-shadow:none; box-shadow:none; color:#182026; } .bp3-html-select.bp3-minimal select:disabled, .bp3-select.bp3-minimal select:disabled, .bp3-html-select.bp3-minimal select:disabled:hover, .bp3-select.bp3-minimal select:disabled:hover, .bp3-html-select.bp3-minimal select.bp3-disabled, .bp3-select.bp3-minimal select.bp3-disabled, .bp3-html-select.bp3-minimal select.bp3-disabled:hover, .bp3-select.bp3-minimal select.bp3-disabled:hover{ background:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-html-select.bp3-minimal select:disabled.bp3-active, .bp3-select.bp3-minimal select:disabled.bp3-active, .bp3-html-select.bp3-minimal select:disabled:hover.bp3-active, .bp3-select.bp3-minimal select:disabled:hover.bp3-active, .bp3-html-select.bp3-minimal select.bp3-disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-disabled.bp3-active, .bp3-html-select.bp3-minimal select.bp3-disabled:hover.bp3-active, .bp3-select.bp3-minimal select.bp3-disabled:hover.bp3-active{ background:rgba(115, 134, 148, 0.3); } .bp3-dark .bp3-html-select.bp3-minimal select, .bp3-html-select.bp3-minimal .bp3-dark select, .bp3-dark .bp3-select.bp3-minimal select, .bp3-select.bp3-minimal .bp3-dark select{ background:none; -webkit-box-shadow:none; box-shadow:none; color:inherit; } .bp3-dark .bp3-html-select.bp3-minimal select:hover, .bp3-html-select.bp3-minimal .bp3-dark select:hover, .bp3-dark .bp3-select.bp3-minimal select:hover, .bp3-select.bp3-minimal .bp3-dark select:hover, .bp3-dark .bp3-html-select.bp3-minimal select:active, .bp3-html-select.bp3-minimal .bp3-dark select:active, .bp3-dark .bp3-select.bp3-minimal select:active, .bp3-select.bp3-minimal .bp3-dark select:active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-html-select.bp3-minimal select:hover, .bp3-html-select.bp3-minimal .bp3-dark select:hover, .bp3-dark .bp3-select.bp3-minimal select:hover, .bp3-select.bp3-minimal .bp3-dark select:hover{ background:rgba(138, 155, 168, 0.15); } .bp3-dark .bp3-html-select.bp3-minimal select:active, .bp3-html-select.bp3-minimal .bp3-dark select:active, .bp3-dark .bp3-select.bp3-minimal select:active, .bp3-select.bp3-minimal .bp3-dark select:active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-active{ background:rgba(138, 155, 168, 0.3); color:#f5f8fa; } .bp3-dark .bp3-html-select.bp3-minimal select:disabled, .bp3-html-select.bp3-minimal .bp3-dark select:disabled, .bp3-dark .bp3-select.bp3-minimal select:disabled, .bp3-select.bp3-minimal .bp3-dark select:disabled, .bp3-dark .bp3-html-select.bp3-minimal select:disabled:hover, .bp3-html-select.bp3-minimal .bp3-dark select:disabled:hover, .bp3-dark .bp3-select.bp3-minimal select:disabled:hover, .bp3-select.bp3-minimal .bp3-dark select:disabled:hover, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-disabled, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-disabled:hover, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-disabled:hover, .bp3-dark .bp3-select.bp3-minimal select.bp3-disabled:hover, .bp3-select.bp3-minimal .bp3-dark select.bp3-disabled:hover{ background:none; color:rgba(167, 182, 194, 0.6); cursor:not-allowed; } .bp3-dark .bp3-html-select.bp3-minimal select:disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select:disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select:disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select:disabled.bp3-active, .bp3-dark .bp3-html-select.bp3-minimal select:disabled:hover.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select:disabled:hover.bp3-active, .bp3-dark .bp3-select.bp3-minimal select:disabled:hover.bp3-active, .bp3-select.bp3-minimal .bp3-dark select:disabled:hover.bp3-active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-disabled.bp3-active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-disabled:hover.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-disabled:hover.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-disabled:hover.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-disabled:hover.bp3-active{ background:rgba(138, 155, 168, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-primary, .bp3-select.bp3-minimal select.bp3-intent-primary{ color:#106ba3; } .bp3-html-select.bp3-minimal select.bp3-intent-primary:hover, .bp3-select.bp3-minimal select.bp3-intent-primary:hover, .bp3-html-select.bp3-minimal select.bp3-intent-primary:active, .bp3-select.bp3-minimal select.bp3-intent-primary:active, .bp3-html-select.bp3-minimal select.bp3-intent-primary.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-primary.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#106ba3; } .bp3-html-select.bp3-minimal select.bp3-intent-primary:hover, .bp3-select.bp3-minimal select.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.15); color:#106ba3; } .bp3-html-select.bp3-minimal select.bp3-intent-primary:active, .bp3-select.bp3-minimal select.bp3-intent-primary:active, .bp3-html-select.bp3-minimal select.bp3-intent-primary.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#106ba3; } .bp3-html-select.bp3-minimal select.bp3-intent-primary:disabled, .bp3-select.bp3-minimal select.bp3-intent-primary:disabled, .bp3-html-select.bp3-minimal select.bp3-intent-primary.bp3-disabled, .bp3-select.bp3-minimal select.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(16, 107, 163, 0.5); } .bp3-html-select.bp3-minimal select.bp3-intent-primary:disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-primary:disabled.bp3-active, .bp3-html-select.bp3-minimal select.bp3-intent-primary.bp3-disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-primary .bp3-button-spinner .bp3-spinner-head, .bp3-select.bp3-minimal select.bp3-intent-primary .bp3-button-spinner .bp3-spinner-head{ stroke:#106ba3; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary{ color:#48aff0; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary:hover, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary:hover, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary:hover, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary:hover{ background:rgba(19, 124, 189, 0.2); color:#48aff0; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary:active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary:active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary:active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary:active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary.bp3-active{ background:rgba(19, 124, 189, 0.3); color:#48aff0; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary:disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary:disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary:disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary:disabled, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary.bp3-disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary.bp3-disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary.bp3-disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary.bp3-disabled{ background:none; color:rgba(72, 175, 240, 0.5); } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary:disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary:disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary:disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary:disabled.bp3-active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-primary.bp3-disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-primary.bp3-disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-primary.bp3-disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-primary.bp3-disabled.bp3-active{ background:rgba(19, 124, 189, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-success, .bp3-select.bp3-minimal select.bp3-intent-success{ color:#0d8050; } .bp3-html-select.bp3-minimal select.bp3-intent-success:hover, .bp3-select.bp3-minimal select.bp3-intent-success:hover, .bp3-html-select.bp3-minimal select.bp3-intent-success:active, .bp3-select.bp3-minimal select.bp3-intent-success:active, .bp3-html-select.bp3-minimal select.bp3-intent-success.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-success.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#0d8050; } .bp3-html-select.bp3-minimal select.bp3-intent-success:hover, .bp3-select.bp3-minimal select.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.15); color:#0d8050; } .bp3-html-select.bp3-minimal select.bp3-intent-success:active, .bp3-select.bp3-minimal select.bp3-intent-success:active, .bp3-html-select.bp3-minimal select.bp3-intent-success.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#0d8050; } .bp3-html-select.bp3-minimal select.bp3-intent-success:disabled, .bp3-select.bp3-minimal select.bp3-intent-success:disabled, .bp3-html-select.bp3-minimal select.bp3-intent-success.bp3-disabled, .bp3-select.bp3-minimal select.bp3-intent-success.bp3-disabled{ background:none; color:rgba(13, 128, 80, 0.5); } .bp3-html-select.bp3-minimal select.bp3-intent-success:disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-success:disabled.bp3-active, .bp3-html-select.bp3-minimal select.bp3-intent-success.bp3-disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-success .bp3-button-spinner .bp3-spinner-head, .bp3-select.bp3-minimal select.bp3-intent-success .bp3-button-spinner .bp3-spinner-head{ stroke:#0d8050; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success{ color:#3dcc91; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success:hover, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success:hover, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success:hover, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success:hover{ background:rgba(15, 153, 96, 0.2); color:#3dcc91; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success:active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success:active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success:active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success:active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success.bp3-active{ background:rgba(15, 153, 96, 0.3); color:#3dcc91; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success:disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success:disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success:disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success:disabled, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success.bp3-disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success.bp3-disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success.bp3-disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success.bp3-disabled{ background:none; color:rgba(61, 204, 145, 0.5); } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success:disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success:disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success:disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success:disabled.bp3-active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-success.bp3-disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-success.bp3-disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-success.bp3-disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-success.bp3-disabled.bp3-active{ background:rgba(15, 153, 96, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-warning, .bp3-select.bp3-minimal select.bp3-intent-warning{ color:#bf7326; } .bp3-html-select.bp3-minimal select.bp3-intent-warning:hover, .bp3-select.bp3-minimal select.bp3-intent-warning:hover, .bp3-html-select.bp3-minimal select.bp3-intent-warning:active, .bp3-select.bp3-minimal select.bp3-intent-warning:active, .bp3-html-select.bp3-minimal select.bp3-intent-warning.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-warning.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#bf7326; } .bp3-html-select.bp3-minimal select.bp3-intent-warning:hover, .bp3-select.bp3-minimal select.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.15); color:#bf7326; } .bp3-html-select.bp3-minimal select.bp3-intent-warning:active, .bp3-select.bp3-minimal select.bp3-intent-warning:active, .bp3-html-select.bp3-minimal select.bp3-intent-warning.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#bf7326; } .bp3-html-select.bp3-minimal select.bp3-intent-warning:disabled, .bp3-select.bp3-minimal select.bp3-intent-warning:disabled, .bp3-html-select.bp3-minimal select.bp3-intent-warning.bp3-disabled, .bp3-select.bp3-minimal select.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(191, 115, 38, 0.5); } .bp3-html-select.bp3-minimal select.bp3-intent-warning:disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-warning:disabled.bp3-active, .bp3-html-select.bp3-minimal select.bp3-intent-warning.bp3-disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-warning .bp3-button-spinner .bp3-spinner-head, .bp3-select.bp3-minimal select.bp3-intent-warning .bp3-button-spinner .bp3-spinner-head{ stroke:#bf7326; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning{ color:#ffb366; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning:hover, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning:hover, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning:hover, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning:hover{ background:rgba(217, 130, 43, 0.2); color:#ffb366; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning:active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning:active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning:active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning:active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning.bp3-active{ background:rgba(217, 130, 43, 0.3); color:#ffb366; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning:disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning:disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning:disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning:disabled, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning.bp3-disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning.bp3-disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning.bp3-disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning.bp3-disabled{ background:none; color:rgba(255, 179, 102, 0.5); } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning:disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning:disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning:disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning:disabled.bp3-active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-warning.bp3-disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-warning.bp3-disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-warning.bp3-disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-warning.bp3-disabled.bp3-active{ background:rgba(217, 130, 43, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-danger, .bp3-select.bp3-minimal select.bp3-intent-danger{ color:#c23030; } .bp3-html-select.bp3-minimal select.bp3-intent-danger:hover, .bp3-select.bp3-minimal select.bp3-intent-danger:hover, .bp3-html-select.bp3-minimal select.bp3-intent-danger:active, .bp3-select.bp3-minimal select.bp3-intent-danger:active, .bp3-html-select.bp3-minimal select.bp3-intent-danger.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-danger.bp3-active{ background:none; -webkit-box-shadow:none; box-shadow:none; color:#c23030; } .bp3-html-select.bp3-minimal select.bp3-intent-danger:hover, .bp3-select.bp3-minimal select.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.15); color:#c23030; } .bp3-html-select.bp3-minimal select.bp3-intent-danger:active, .bp3-select.bp3-minimal select.bp3-intent-danger:active, .bp3-html-select.bp3-minimal select.bp3-intent-danger.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#c23030; } .bp3-html-select.bp3-minimal select.bp3-intent-danger:disabled, .bp3-select.bp3-minimal select.bp3-intent-danger:disabled, .bp3-html-select.bp3-minimal select.bp3-intent-danger.bp3-disabled, .bp3-select.bp3-minimal select.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(194, 48, 48, 0.5); } .bp3-html-select.bp3-minimal select.bp3-intent-danger:disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-danger:disabled.bp3-active, .bp3-html-select.bp3-minimal select.bp3-intent-danger.bp3-disabled.bp3-active, .bp3-select.bp3-minimal select.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-html-select.bp3-minimal select.bp3-intent-danger .bp3-button-spinner .bp3-spinner-head, .bp3-select.bp3-minimal select.bp3-intent-danger .bp3-button-spinner .bp3-spinner-head{ stroke:#c23030; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger{ color:#ff7373; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger:hover, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger:hover, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger:hover, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger:hover{ background:rgba(219, 55, 55, 0.2); color:#ff7373; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger:active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger:active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger:active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger:active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger.bp3-active{ background:rgba(219, 55, 55, 0.3); color:#ff7373; } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger:disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger:disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger:disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger:disabled, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger.bp3-disabled, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger.bp3-disabled, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger.bp3-disabled, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger.bp3-disabled{ background:none; color:rgba(255, 115, 115, 0.5); } .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger:disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger:disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger:disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger:disabled.bp3-active, .bp3-dark .bp3-html-select.bp3-minimal select.bp3-intent-danger.bp3-disabled.bp3-active, .bp3-html-select.bp3-minimal .bp3-dark select.bp3-intent-danger.bp3-disabled.bp3-active, .bp3-dark .bp3-select.bp3-minimal select.bp3-intent-danger.bp3-disabled.bp3-active, .bp3-select.bp3-minimal .bp3-dark select.bp3-intent-danger.bp3-disabled.bp3-active{ background:rgba(219, 55, 55, 0.3); } .bp3-html-select.bp3-large select, .bp3-select.bp3-large select{ font-size:16px; height:40px; padding-right:35px; } .bp3-dark .bp3-html-select select, .bp3-dark .bp3-select select{ background-color:#394b59; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.05)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0)); -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-dark .bp3-html-select select:hover, .bp3-dark .bp3-select select:hover, .bp3-dark .bp3-html-select select:active, .bp3-dark .bp3-select select:active, .bp3-dark .bp3-html-select select.bp3-active, .bp3-dark .bp3-select select.bp3-active{ color:#f5f8fa; } .bp3-dark .bp3-html-select select:hover, .bp3-dark .bp3-select select:hover{ background-color:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-html-select select:active, .bp3-dark .bp3-select select:active, .bp3-dark .bp3-html-select select.bp3-active, .bp3-dark .bp3-select select.bp3-active{ background-color:#202b33; background-image:none; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-html-select select:disabled, .bp3-dark .bp3-select select:disabled, .bp3-dark .bp3-html-select select.bp3-disabled, .bp3-dark .bp3-select select.bp3-disabled{ background-color:rgba(57, 75, 89, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-html-select select:disabled.bp3-active, .bp3-dark .bp3-select select:disabled.bp3-active, .bp3-dark .bp3-html-select select.bp3-disabled.bp3-active, .bp3-dark .bp3-select select.bp3-disabled.bp3-active{ background:rgba(57, 75, 89, 0.7); } .bp3-dark .bp3-html-select select .bp3-button-spinner .bp3-spinner-head, .bp3-dark .bp3-select select .bp3-button-spinner .bp3-spinner-head{ background:rgba(16, 22, 26, 0.5); stroke:#8a9ba8; } .bp3-html-select select:disabled, .bp3-select select:disabled{ background-color:rgba(206, 217, 224, 0.5); -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-html-select .bp3-icon, .bp3-select .bp3-icon, .bp3-select::after{ color:#5c7080; pointer-events:none; position:absolute; right:7px; top:7px; } .bp3-html-select .bp3-disabled.bp3-icon, .bp3-select .bp3-disabled.bp3-icon, .bp3-disabled.bp3-select::after{ color:rgba(92, 112, 128, 0.6); } .bp3-html-select, .bp3-select{ display:inline-block; letter-spacing:normal; position:relative; vertical-align:middle; } .bp3-html-select select::-ms-expand, .bp3-select select::-ms-expand{ display:none; } .bp3-html-select .bp3-icon, .bp3-select .bp3-icon{ color:#5c7080; } .bp3-html-select .bp3-icon:hover, .bp3-select .bp3-icon:hover{ color:#182026; } .bp3-dark .bp3-html-select .bp3-icon, .bp3-dark .bp3-select .bp3-icon{ color:#a7b6c2; } .bp3-dark .bp3-html-select .bp3-icon:hover, .bp3-dark .bp3-select .bp3-icon:hover{ color:#f5f8fa; } .bp3-html-select.bp3-large::after, .bp3-html-select.bp3-large .bp3-icon, .bp3-select.bp3-large::after, .bp3-select.bp3-large .bp3-icon{ right:12px; top:12px; } .bp3-html-select.bp3-fill, .bp3-html-select.bp3-fill select, .bp3-select.bp3-fill, .bp3-select.bp3-fill select{ width:100%; } .bp3-dark .bp3-html-select option, .bp3-dark .bp3-select option{ background-color:#30404d; color:#f5f8fa; } .bp3-dark .bp3-html-select option:disabled, .bp3-dark .bp3-select option:disabled{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-html-select::after, .bp3-dark .bp3-select::after{ color:#a7b6c2; } .bp3-select::after{ font-family:"Icons16", sans-serif; font-size:16px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; content:""; } .bp3-running-text table, table.bp3-html-table{ border-spacing:0; font-size:14px; } .bp3-running-text table th, table.bp3-html-table th, .bp3-running-text table td, table.bp3-html-table td{ padding:11px; text-align:left; vertical-align:top; } .bp3-running-text table th, table.bp3-html-table th{ color:#182026; font-weight:600; } .bp3-running-text table td, table.bp3-html-table td{ color:#182026; } .bp3-running-text table tbody tr:first-child th, table.bp3-html-table tbody tr:first-child th, .bp3-running-text table tbody tr:first-child td, table.bp3-html-table tbody tr:first-child td, .bp3-running-text table tfoot tr:first-child th, table.bp3-html-table tfoot tr:first-child th, .bp3-running-text table tfoot tr:first-child td, table.bp3-html-table tfoot tr:first-child td{ -webkit-box-shadow:inset 0 1px 0 0 rgba(16, 22, 26, 0.15); box-shadow:inset 0 1px 0 0 rgba(16, 22, 26, 0.15); } .bp3-dark .bp3-running-text table th, .bp3-running-text .bp3-dark table th, .bp3-dark table.bp3-html-table th{ color:#f5f8fa; } .bp3-dark .bp3-running-text table td, .bp3-running-text .bp3-dark table td, .bp3-dark table.bp3-html-table td{ color:#f5f8fa; } .bp3-dark .bp3-running-text table tbody tr:first-child th, .bp3-running-text .bp3-dark table tbody tr:first-child th, .bp3-dark table.bp3-html-table tbody tr:first-child th, .bp3-dark .bp3-running-text table tbody tr:first-child td, .bp3-running-text .bp3-dark table tbody tr:first-child td, .bp3-dark table.bp3-html-table tbody tr:first-child td, .bp3-dark .bp3-running-text table tfoot tr:first-child th, .bp3-running-text .bp3-dark table tfoot tr:first-child th, .bp3-dark table.bp3-html-table tfoot tr:first-child th, .bp3-dark .bp3-running-text table tfoot tr:first-child td, .bp3-running-text .bp3-dark table tfoot tr:first-child td, .bp3-dark table.bp3-html-table tfoot tr:first-child td{ -webkit-box-shadow:inset 0 1px 0 0 rgba(255, 255, 255, 0.15); box-shadow:inset 0 1px 0 0 rgba(255, 255, 255, 0.15); } table.bp3-html-table.bp3-html-table-condensed th, table.bp3-html-table.bp3-html-table-condensed td, table.bp3-html-table.bp3-small th, table.bp3-html-table.bp3-small td{ padding-bottom:6px; padding-top:6px; } table.bp3-html-table.bp3-html-table-striped tbody tr:nth-child(odd) td{ background:rgba(191, 204, 214, 0.15); } table.bp3-html-table.bp3-html-table-bordered th:not(:first-child){ -webkit-box-shadow:inset 1px 0 0 0 rgba(16, 22, 26, 0.15); box-shadow:inset 1px 0 0 0 rgba(16, 22, 26, 0.15); } table.bp3-html-table.bp3-html-table-bordered tbody tr td, table.bp3-html-table.bp3-html-table-bordered tfoot tr td{ -webkit-box-shadow:inset 0 1px 0 0 rgba(16, 22, 26, 0.15); box-shadow:inset 0 1px 0 0 rgba(16, 22, 26, 0.15); } table.bp3-html-table.bp3-html-table-bordered tbody tr td:not(:first-child), table.bp3-html-table.bp3-html-table-bordered tfoot tr td:not(:first-child){ -webkit-box-shadow:inset 1px 1px 0 0 rgba(16, 22, 26, 0.15); box-shadow:inset 1px 1px 0 0 rgba(16, 22, 26, 0.15); } table.bp3-html-table.bp3-html-table-bordered.bp3-html-table-striped tbody tr:not(:first-child) td{ -webkit-box-shadow:none; box-shadow:none; } table.bp3-html-table.bp3-html-table-bordered.bp3-html-table-striped tbody tr:not(:first-child) td:not(:first-child){ -webkit-box-shadow:inset 1px 0 0 0 rgba(16, 22, 26, 0.15); box-shadow:inset 1px 0 0 0 rgba(16, 22, 26, 0.15); } table.bp3-html-table.bp3-interactive tbody tr:hover td{ background-color:rgba(191, 204, 214, 0.3); cursor:pointer; } table.bp3-html-table.bp3-interactive tbody tr:active td{ background-color:rgba(191, 204, 214, 0.4); } .bp3-dark table.bp3-html-table{ } .bp3-dark table.bp3-html-table.bp3-html-table-striped tbody tr:nth-child(odd) td{ background:rgba(92, 112, 128, 0.15); } .bp3-dark table.bp3-html-table.bp3-html-table-bordered th:not(:first-child){ -webkit-box-shadow:inset 1px 0 0 0 rgba(255, 255, 255, 0.15); box-shadow:inset 1px 0 0 0 rgba(255, 255, 255, 0.15); } .bp3-dark table.bp3-html-table.bp3-html-table-bordered tbody tr td, .bp3-dark table.bp3-html-table.bp3-html-table-bordered tfoot tr td{ -webkit-box-shadow:inset 0 1px 0 0 rgba(255, 255, 255, 0.15); box-shadow:inset 0 1px 0 0 rgba(255, 255, 255, 0.15); } .bp3-dark table.bp3-html-table.bp3-html-table-bordered tbody tr td:not(:first-child), .bp3-dark table.bp3-html-table.bp3-html-table-bordered tfoot tr td:not(:first-child){ -webkit-box-shadow:inset 1px 1px 0 0 rgba(255, 255, 255, 0.15); box-shadow:inset 1px 1px 0 0 rgba(255, 255, 255, 0.15); } .bp3-dark table.bp3-html-table.bp3-html-table-bordered.bp3-html-table-striped tbody tr:not(:first-child) td{ -webkit-box-shadow:inset 1px 0 0 0 rgba(255, 255, 255, 0.15); box-shadow:inset 1px 0 0 0 rgba(255, 255, 255, 0.15); } .bp3-dark table.bp3-html-table.bp3-html-table-bordered.bp3-html-table-striped tbody tr:not(:first-child) td:first-child{ -webkit-box-shadow:none; box-shadow:none; } .bp3-dark table.bp3-html-table.bp3-interactive tbody tr:hover td{ background-color:rgba(92, 112, 128, 0.3); cursor:pointer; } .bp3-dark table.bp3-html-table.bp3-interactive tbody tr:active td{ background-color:rgba(92, 112, 128, 0.4); } .bp3-key-combo{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:center; -ms-flex-align:center; align-items:center; } .bp3-key-combo > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-key-combo > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-key-combo::before, .bp3-key-combo > *{ margin-right:5px; } .bp3-key-combo:empty::before, .bp3-key-combo > :last-child{ margin-right:0; } .bp3-hotkey-dialog{ padding-bottom:0; top:40px; } .bp3-hotkey-dialog .bp3-dialog-body{ margin:0; padding:0; } .bp3-hotkey-dialog .bp3-hotkey-label{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; } .bp3-hotkey-column{ margin:auto; max-height:80vh; overflow-y:auto; padding:30px; } .bp3-hotkey-column .bp3-heading{ margin-bottom:20px; } .bp3-hotkey-column .bp3-heading:not(:first-child){ margin-top:40px; } .bp3-hotkey{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-pack:justify; -ms-flex-pack:justify; justify-content:space-between; margin-left:0; margin-right:0; } .bp3-hotkey:not(:last-child){ margin-bottom:10px; } .bp3-icon{ display:inline-block; -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; vertical-align:text-bottom; } .bp3-icon:not(:empty)::before{ content:"" !important; content:unset !important; } .bp3-icon > svg{ display:block; } .bp3-icon > svg:not([fill]){ fill:currentColor; } .bp3-icon.bp3-intent-primary, .bp3-icon-standard.bp3-intent-primary, .bp3-icon-large.bp3-intent-primary{ color:#106ba3; } .bp3-dark .bp3-icon.bp3-intent-primary, .bp3-dark .bp3-icon-standard.bp3-intent-primary, .bp3-dark .bp3-icon-large.bp3-intent-primary{ color:#48aff0; } .bp3-icon.bp3-intent-success, .bp3-icon-standard.bp3-intent-success, .bp3-icon-large.bp3-intent-success{ color:#0d8050; } .bp3-dark .bp3-icon.bp3-intent-success, .bp3-dark .bp3-icon-standard.bp3-intent-success, .bp3-dark .bp3-icon-large.bp3-intent-success{ color:#3dcc91; } .bp3-icon.bp3-intent-warning, .bp3-icon-standard.bp3-intent-warning, .bp3-icon-large.bp3-intent-warning{ color:#bf7326; } .bp3-dark .bp3-icon.bp3-intent-warning, .bp3-dark .bp3-icon-standard.bp3-intent-warning, .bp3-dark .bp3-icon-large.bp3-intent-warning{ color:#ffb366; } .bp3-icon.bp3-intent-danger, .bp3-icon-standard.bp3-intent-danger, .bp3-icon-large.bp3-intent-danger{ color:#c23030; } .bp3-dark .bp3-icon.bp3-intent-danger, .bp3-dark .bp3-icon-standard.bp3-intent-danger, .bp3-dark .bp3-icon-large.bp3-intent-danger{ color:#ff7373; } span.bp3-icon-standard{ font-family:"Icons16", sans-serif; font-size:16px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; display:inline-block; } span.bp3-icon-large{ font-family:"Icons20", sans-serif; font-size:20px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; display:inline-block; } span.bp3-icon:empty{ font-family:"Icons20"; font-size:inherit; font-style:normal; font-weight:400; line-height:1; } span.bp3-icon:empty::before{ -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; } .bp3-icon-add::before{ content:""; } .bp3-icon-add-column-left::before{ content:""; } .bp3-icon-add-column-right::before{ content:""; } .bp3-icon-add-row-bottom::before{ content:""; } .bp3-icon-add-row-top::before{ content:""; } .bp3-icon-add-to-artifact::before{ content:""; } .bp3-icon-add-to-folder::before{ content:""; } .bp3-icon-airplane::before{ content:""; } .bp3-icon-align-center::before{ content:""; } .bp3-icon-align-justify::before{ content:""; } .bp3-icon-align-left::before{ content:""; } .bp3-icon-align-right::before{ content:""; } .bp3-icon-alignment-bottom::before{ content:""; } .bp3-icon-alignment-horizontal-center::before{ content:""; } .bp3-icon-alignment-left::before{ content:""; } .bp3-icon-alignment-right::before{ content:""; } .bp3-icon-alignment-top::before{ content:""; } .bp3-icon-alignment-vertical-center::before{ content:""; } .bp3-icon-annotation::before{ content:""; } .bp3-icon-application::before{ content:""; } .bp3-icon-applications::before{ content:""; } .bp3-icon-archive::before{ content:""; } .bp3-icon-arrow-bottom-left::before{ content:"↙"; } .bp3-icon-arrow-bottom-right::before{ content:"↘"; } .bp3-icon-arrow-down::before{ content:"↓"; } .bp3-icon-arrow-left::before{ content:"←"; } .bp3-icon-arrow-right::before{ content:"→"; } .bp3-icon-arrow-top-left::before{ content:"↖"; } .bp3-icon-arrow-top-right::before{ content:"↗"; } .bp3-icon-arrow-up::before{ content:"↑"; } .bp3-icon-arrows-horizontal::before{ content:"↔"; } .bp3-icon-arrows-vertical::before{ content:"↕"; } .bp3-icon-asterisk::before{ content:"*"; } .bp3-icon-automatic-updates::before{ content:""; } .bp3-icon-badge::before{ content:""; } .bp3-icon-ban-circle::before{ content:""; } .bp3-icon-bank-account::before{ content:""; } .bp3-icon-barcode::before{ content:""; } .bp3-icon-blank::before{ content:""; } .bp3-icon-blocked-person::before{ content:""; } .bp3-icon-bold::before{ content:""; } .bp3-icon-book::before{ content:""; } .bp3-icon-bookmark::before{ content:""; } .bp3-icon-box::before{ content:""; } .bp3-icon-briefcase::before{ content:""; } .bp3-icon-bring-data::before{ content:""; } .bp3-icon-build::before{ content:""; } .bp3-icon-calculator::before{ content:""; } .bp3-icon-calendar::before{ content:""; } .bp3-icon-camera::before{ content:""; } .bp3-icon-caret-down::before{ content:"⌄"; } .bp3-icon-caret-left::before{ content:"〈"; } .bp3-icon-caret-right::before{ content:"〉"; } .bp3-icon-caret-up::before{ content:"⌃"; } .bp3-icon-cell-tower::before{ content:""; } .bp3-icon-changes::before{ content:""; } .bp3-icon-chart::before{ content:""; } .bp3-icon-chat::before{ content:""; } .bp3-icon-chevron-backward::before{ content:""; } .bp3-icon-chevron-down::before{ content:""; } .bp3-icon-chevron-forward::before{ content:""; } .bp3-icon-chevron-left::before{ content:""; } .bp3-icon-chevron-right::before{ content:""; } .bp3-icon-chevron-up::before{ content:""; } .bp3-icon-circle::before{ content:""; } .bp3-icon-circle-arrow-down::before{ content:""; } .bp3-icon-circle-arrow-left::before{ content:""; } .bp3-icon-circle-arrow-right::before{ content:""; } .bp3-icon-circle-arrow-up::before{ content:""; } .bp3-icon-citation::before{ content:""; } .bp3-icon-clean::before{ content:""; } .bp3-icon-clipboard::before{ content:""; } .bp3-icon-cloud::before{ content:"☁"; } .bp3-icon-cloud-download::before{ content:""; } .bp3-icon-cloud-upload::before{ content:""; } .bp3-icon-code::before{ content:""; } .bp3-icon-code-block::before{ content:""; } .bp3-icon-cog::before{ content:""; } .bp3-icon-collapse-all::before{ content:""; } .bp3-icon-column-layout::before{ content:""; } .bp3-icon-comment::before{ content:""; } .bp3-icon-comparison::before{ content:""; } .bp3-icon-compass::before{ content:""; } .bp3-icon-compressed::before{ content:""; } .bp3-icon-confirm::before{ content:""; } .bp3-icon-console::before{ content:""; } .bp3-icon-contrast::before{ content:""; } .bp3-icon-control::before{ content:""; } .bp3-icon-credit-card::before{ content:""; } .bp3-icon-cross::before{ content:"✗"; } .bp3-icon-crown::before{ content:""; } .bp3-icon-cube::before{ content:""; } .bp3-icon-cube-add::before{ content:""; } .bp3-icon-cube-remove::before{ content:""; } .bp3-icon-curved-range-chart::before{ content:""; } .bp3-icon-cut::before{ content:""; } .bp3-icon-dashboard::before{ content:""; } .bp3-icon-data-lineage::before{ content:""; } .bp3-icon-database::before{ content:""; } .bp3-icon-delete::before{ content:""; } .bp3-icon-delta::before{ content:"Δ"; } .bp3-icon-derive-column::before{ content:""; } .bp3-icon-desktop::before{ content:""; } .bp3-icon-diagnosis::before{ content:""; } .bp3-icon-diagram-tree::before{ content:""; } .bp3-icon-direction-left::before{ content:""; } .bp3-icon-direction-right::before{ content:""; } .bp3-icon-disable::before{ content:""; } .bp3-icon-document::before{ content:""; } .bp3-icon-document-open::before{ content:""; } .bp3-icon-document-share::before{ content:""; } .bp3-icon-dollar::before{ content:"$"; } .bp3-icon-dot::before{ content:"•"; } .bp3-icon-double-caret-horizontal::before{ content:""; } .bp3-icon-double-caret-vertical::before{ content:""; } .bp3-icon-double-chevron-down::before{ content:""; } .bp3-icon-double-chevron-left::before{ content:""; } .bp3-icon-double-chevron-right::before{ content:""; } .bp3-icon-double-chevron-up::before{ content:""; } .bp3-icon-doughnut-chart::before{ content:""; } .bp3-icon-download::before{ content:""; } .bp3-icon-drag-handle-horizontal::before{ content:""; } .bp3-icon-drag-handle-vertical::before{ content:""; } .bp3-icon-draw::before{ content:""; } .bp3-icon-drive-time::before{ content:""; } .bp3-icon-duplicate::before{ content:""; } .bp3-icon-edit::before{ content:"✎"; } .bp3-icon-eject::before{ content:"⏏"; } .bp3-icon-endorsed::before{ content:""; } .bp3-icon-envelope::before{ content:"✉"; } .bp3-icon-equals::before{ content:""; } .bp3-icon-eraser::before{ content:""; } .bp3-icon-error::before{ content:""; } .bp3-icon-euro::before{ content:"€"; } .bp3-icon-exchange::before{ content:""; } .bp3-icon-exclude-row::before{ content:""; } .bp3-icon-expand-all::before{ content:""; } .bp3-icon-export::before{ content:""; } .bp3-icon-eye-off::before{ content:""; } .bp3-icon-eye-on::before{ content:""; } .bp3-icon-eye-open::before{ content:""; } .bp3-icon-fast-backward::before{ content:""; } .bp3-icon-fast-forward::before{ content:""; } .bp3-icon-feed::before{ content:""; } .bp3-icon-feed-subscribed::before{ content:""; } .bp3-icon-film::before{ content:""; } .bp3-icon-filter::before{ content:""; } .bp3-icon-filter-keep::before{ content:""; } .bp3-icon-filter-list::before{ content:""; } .bp3-icon-filter-open::before{ content:""; } .bp3-icon-filter-remove::before{ content:""; } .bp3-icon-flag::before{ content:"⚑"; } .bp3-icon-flame::before{ content:""; } .bp3-icon-flash::before{ content:""; } .bp3-icon-floppy-disk::before{ content:""; } .bp3-icon-flow-branch::before{ content:""; } .bp3-icon-flow-end::before{ content:""; } .bp3-icon-flow-linear::before{ content:""; } .bp3-icon-flow-review::before{ content:""; } .bp3-icon-flow-review-branch::before{ content:""; } .bp3-icon-flows::before{ content:""; } .bp3-icon-folder-close::before{ content:""; } .bp3-icon-folder-new::before{ content:""; } .bp3-icon-folder-open::before{ content:""; } .bp3-icon-folder-shared::before{ content:""; } .bp3-icon-folder-shared-open::before{ content:""; } .bp3-icon-follower::before{ content:""; } .bp3-icon-following::before{ content:""; } .bp3-icon-font::before{ content:""; } .bp3-icon-fork::before{ content:""; } .bp3-icon-form::before{ content:""; } .bp3-icon-full-circle::before{ content:""; } .bp3-icon-full-stacked-chart::before{ content:""; } .bp3-icon-fullscreen::before{ content:""; } .bp3-icon-function::before{ content:""; } .bp3-icon-gantt-chart::before{ content:""; } .bp3-icon-geolocation::before{ content:""; } .bp3-icon-geosearch::before{ content:""; } .bp3-icon-git-branch::before{ content:""; } .bp3-icon-git-commit::before{ content:""; } .bp3-icon-git-merge::before{ content:""; } .bp3-icon-git-new-branch::before{ content:""; } .bp3-icon-git-pull::before{ content:""; } .bp3-icon-git-push::before{ content:""; } .bp3-icon-git-repo::before{ content:""; } .bp3-icon-glass::before{ content:""; } .bp3-icon-globe::before{ content:""; } .bp3-icon-globe-network::before{ content:""; } .bp3-icon-graph::before{ content:""; } .bp3-icon-graph-remove::before{ content:""; } .bp3-icon-greater-than::before{ content:""; } .bp3-icon-greater-than-or-equal-to::before{ content:""; } .bp3-icon-grid::before{ content:""; } .bp3-icon-grid-view::before{ content:""; } .bp3-icon-group-objects::before{ content:""; } .bp3-icon-grouped-bar-chart::before{ content:""; } .bp3-icon-hand::before{ content:""; } .bp3-icon-hand-down::before{ content:""; } .bp3-icon-hand-left::before{ content:""; } .bp3-icon-hand-right::before{ content:""; } .bp3-icon-hand-up::before{ content:""; } .bp3-icon-header::before{ content:""; } .bp3-icon-header-one::before{ content:""; } .bp3-icon-header-two::before{ content:""; } .bp3-icon-headset::before{ content:""; } .bp3-icon-heart::before{ content:"♥"; } .bp3-icon-heart-broken::before{ content:""; } .bp3-icon-heat-grid::before{ content:""; } .bp3-icon-heatmap::before{ content:""; } .bp3-icon-help::before{ content:"?"; } .bp3-icon-helper-management::before{ content:""; } .bp3-icon-highlight::before{ content:""; } .bp3-icon-history::before{ content:""; } .bp3-icon-home::before{ content:"⌂"; } .bp3-icon-horizontal-bar-chart::before{ content:""; } .bp3-icon-horizontal-bar-chart-asc::before{ content:""; } .bp3-icon-horizontal-bar-chart-desc::before{ content:""; } .bp3-icon-horizontal-distribution::before{ content:""; } .bp3-icon-id-number::before{ content:""; } .bp3-icon-image-rotate-left::before{ content:""; } .bp3-icon-image-rotate-right::before{ content:""; } .bp3-icon-import::before{ content:""; } .bp3-icon-inbox::before{ content:""; } .bp3-icon-inbox-filtered::before{ content:""; } .bp3-icon-inbox-geo::before{ content:""; } .bp3-icon-inbox-search::before{ content:""; } .bp3-icon-inbox-update::before{ content:""; } .bp3-icon-info-sign::before{ content:"ℹ"; } .bp3-icon-inheritance::before{ content:""; } .bp3-icon-inner-join::before{ content:""; } .bp3-icon-insert::before{ content:""; } .bp3-icon-intersection::before{ content:""; } .bp3-icon-ip-address::before{ content:""; } .bp3-icon-issue::before{ content:""; } .bp3-icon-issue-closed::before{ content:""; } .bp3-icon-issue-new::before{ content:""; } .bp3-icon-italic::before{ content:""; } .bp3-icon-join-table::before{ content:""; } .bp3-icon-key::before{ content:""; } .bp3-icon-key-backspace::before{ content:""; } .bp3-icon-key-command::before{ content:""; } .bp3-icon-key-control::before{ content:""; } .bp3-icon-key-delete::before{ content:""; } .bp3-icon-key-enter::before{ content:""; } .bp3-icon-key-escape::before{ content:""; } .bp3-icon-key-option::before{ content:""; } .bp3-icon-key-shift::before{ content:""; } .bp3-icon-key-tab::before{ content:""; } .bp3-icon-known-vehicle::before{ content:""; } .bp3-icon-lab-test::before{ content:""; } .bp3-icon-label::before{ content:""; } .bp3-icon-layer::before{ content:""; } .bp3-icon-layers::before{ content:""; } .bp3-icon-layout::before{ content:""; } .bp3-icon-layout-auto::before{ content:""; } .bp3-icon-layout-balloon::before{ content:""; } .bp3-icon-layout-circle::before{ content:""; } .bp3-icon-layout-grid::before{ content:""; } .bp3-icon-layout-group-by::before{ content:""; } .bp3-icon-layout-hierarchy::before{ content:""; } .bp3-icon-layout-linear::before{ content:""; } .bp3-icon-layout-skew-grid::before{ content:""; } .bp3-icon-layout-sorted-clusters::before{ content:""; } .bp3-icon-learning::before{ content:""; } .bp3-icon-left-join::before{ content:""; } .bp3-icon-less-than::before{ content:""; } .bp3-icon-less-than-or-equal-to::before{ content:""; } .bp3-icon-lifesaver::before{ content:""; } .bp3-icon-lightbulb::before{ content:""; } .bp3-icon-link::before{ content:""; } .bp3-icon-list::before{ content:"☰"; } .bp3-icon-list-columns::before{ content:""; } .bp3-icon-list-detail-view::before{ content:""; } .bp3-icon-locate::before{ content:""; } .bp3-icon-lock::before{ content:""; } .bp3-icon-log-in::before{ content:""; } .bp3-icon-log-out::before{ content:""; } .bp3-icon-manual::before{ content:""; } .bp3-icon-manually-entered-data::before{ content:""; } .bp3-icon-map::before{ content:""; } .bp3-icon-map-create::before{ content:""; } .bp3-icon-map-marker::before{ content:""; } .bp3-icon-maximize::before{ content:""; } .bp3-icon-media::before{ content:""; } .bp3-icon-menu::before{ content:""; } .bp3-icon-menu-closed::before{ content:""; } .bp3-icon-menu-open::before{ content:""; } .bp3-icon-merge-columns::before{ content:""; } .bp3-icon-merge-links::before{ content:""; } .bp3-icon-minimize::before{ content:""; } .bp3-icon-minus::before{ content:"−"; } .bp3-icon-mobile-phone::before{ content:""; } .bp3-icon-mobile-video::before{ content:""; } .bp3-icon-moon::before{ content:""; } .bp3-icon-more::before{ content:""; } .bp3-icon-mountain::before{ content:""; } .bp3-icon-move::before{ content:""; } .bp3-icon-mugshot::before{ content:""; } .bp3-icon-multi-select::before{ content:""; } .bp3-icon-music::before{ content:""; } .bp3-icon-new-drawing::before{ content:""; } .bp3-icon-new-grid-item::before{ content:""; } .bp3-icon-new-layer::before{ content:""; } .bp3-icon-new-layers::before{ content:""; } .bp3-icon-new-link::before{ content:""; } .bp3-icon-new-object::before{ content:""; } .bp3-icon-new-person::before{ content:""; } .bp3-icon-new-prescription::before{ content:""; } .bp3-icon-new-text-box::before{ content:""; } .bp3-icon-ninja::before{ content:""; } .bp3-icon-not-equal-to::before{ content:""; } .bp3-icon-notifications::before{ content:""; } .bp3-icon-notifications-updated::before{ content:""; } .bp3-icon-numbered-list::before{ content:""; } .bp3-icon-numerical::before{ content:""; } .bp3-icon-office::before{ content:""; } .bp3-icon-offline::before{ content:""; } .bp3-icon-oil-field::before{ content:""; } .bp3-icon-one-column::before{ content:""; } .bp3-icon-outdated::before{ content:""; } .bp3-icon-page-layout::before{ content:""; } .bp3-icon-panel-stats::before{ content:""; } .bp3-icon-panel-table::before{ content:""; } .bp3-icon-paperclip::before{ content:""; } .bp3-icon-paragraph::before{ content:""; } .bp3-icon-path::before{ content:""; } .bp3-icon-path-search::before{ content:""; } .bp3-icon-pause::before{ content:""; } .bp3-icon-people::before{ content:""; } .bp3-icon-percentage::before{ content:""; } .bp3-icon-person::before{ content:""; } .bp3-icon-phone::before{ content:"☎"; } .bp3-icon-pie-chart::before{ content:""; } .bp3-icon-pin::before{ content:""; } .bp3-icon-pivot::before{ content:""; } .bp3-icon-pivot-table::before{ content:""; } .bp3-icon-play::before{ content:""; } .bp3-icon-plus::before{ content:"+"; } .bp3-icon-polygon-filter::before{ content:""; } .bp3-icon-power::before{ content:""; } .bp3-icon-predictive-analysis::before{ content:""; } .bp3-icon-prescription::before{ content:""; } .bp3-icon-presentation::before{ content:""; } .bp3-icon-print::before{ content:"⎙"; } .bp3-icon-projects::before{ content:""; } .bp3-icon-properties::before{ content:""; } .bp3-icon-property::before{ content:""; } .bp3-icon-publish-function::before{ content:""; } .bp3-icon-pulse::before{ content:""; } .bp3-icon-random::before{ content:""; } .bp3-icon-record::before{ content:""; } .bp3-icon-redo::before{ content:""; } .bp3-icon-refresh::before{ content:""; } .bp3-icon-regression-chart::before{ content:""; } .bp3-icon-remove::before{ content:""; } .bp3-icon-remove-column::before{ content:""; } .bp3-icon-remove-column-left::before{ content:""; } .bp3-icon-remove-column-right::before{ content:""; } .bp3-icon-remove-row-bottom::before{ content:""; } .bp3-icon-remove-row-top::before{ content:""; } .bp3-icon-repeat::before{ content:""; } .bp3-icon-reset::before{ content:""; } .bp3-icon-resolve::before{ content:""; } .bp3-icon-rig::before{ content:""; } .bp3-icon-right-join::before{ content:""; } .bp3-icon-ring::before{ content:""; } .bp3-icon-rotate-document::before{ content:""; } .bp3-icon-rotate-page::before{ content:""; } .bp3-icon-satellite::before{ content:""; } .bp3-icon-saved::before{ content:""; } .bp3-icon-scatter-plot::before{ content:""; } .bp3-icon-search::before{ content:""; } .bp3-icon-search-around::before{ content:""; } .bp3-icon-search-template::before{ content:""; } .bp3-icon-search-text::before{ content:""; } .bp3-icon-segmented-control::before{ content:""; } .bp3-icon-select::before{ content:""; } .bp3-icon-selection::before{ content:"⦿"; } .bp3-icon-send-to::before{ content:""; } .bp3-icon-send-to-graph::before{ content:""; } .bp3-icon-send-to-map::before{ content:""; } .bp3-icon-series-add::before{ content:""; } .bp3-icon-series-configuration::before{ content:""; } .bp3-icon-series-derived::before{ content:""; } .bp3-icon-series-filtered::before{ content:""; } .bp3-icon-series-search::before{ content:""; } .bp3-icon-settings::before{ content:""; } .bp3-icon-share::before{ content:""; } .bp3-icon-shield::before{ content:""; } .bp3-icon-shop::before{ content:""; } .bp3-icon-shopping-cart::before{ content:""; } .bp3-icon-signal-search::before{ content:""; } .bp3-icon-sim-card::before{ content:""; } .bp3-icon-slash::before{ content:""; } .bp3-icon-small-cross::before{ content:""; } .bp3-icon-small-minus::before{ content:""; } .bp3-icon-small-plus::before{ content:""; } .bp3-icon-small-tick::before{ content:""; } .bp3-icon-snowflake::before{ content:""; } .bp3-icon-social-media::before{ content:""; } .bp3-icon-sort::before{ content:""; } .bp3-icon-sort-alphabetical::before{ content:""; } .bp3-icon-sort-alphabetical-desc::before{ content:""; } .bp3-icon-sort-asc::before{ content:""; } .bp3-icon-sort-desc::before{ content:""; } .bp3-icon-sort-numerical::before{ content:""; } .bp3-icon-sort-numerical-desc::before{ content:""; } .bp3-icon-split-columns::before{ content:""; } .bp3-icon-square::before{ content:""; } .bp3-icon-stacked-chart::before{ content:""; } .bp3-icon-star::before{ content:"★"; } .bp3-icon-star-empty::before{ content:"☆"; } .bp3-icon-step-backward::before{ content:""; } .bp3-icon-step-chart::before{ content:""; } .bp3-icon-step-forward::before{ content:""; } .bp3-icon-stop::before{ content:""; } .bp3-icon-stopwatch::before{ content:""; } .bp3-icon-strikethrough::before{ content:""; } .bp3-icon-style::before{ content:""; } .bp3-icon-swap-horizontal::before{ content:""; } .bp3-icon-swap-vertical::before{ content:""; } .bp3-icon-symbol-circle::before{ content:""; } .bp3-icon-symbol-cross::before{ content:""; } .bp3-icon-symbol-diamond::before{ content:""; } .bp3-icon-symbol-square::before{ content:""; } .bp3-icon-symbol-triangle-down::before{ content:""; } .bp3-icon-symbol-triangle-up::before{ content:""; } .bp3-icon-tag::before{ content:""; } .bp3-icon-take-action::before{ content:""; } .bp3-icon-taxi::before{ content:""; } .bp3-icon-text-highlight::before{ content:""; } .bp3-icon-th::before{ content:""; } .bp3-icon-th-derived::before{ content:""; } .bp3-icon-th-disconnect::before{ content:""; } .bp3-icon-th-filtered::before{ content:""; } .bp3-icon-th-list::before{ content:""; } .bp3-icon-thumbs-down::before{ content:""; } .bp3-icon-thumbs-up::before{ content:""; } .bp3-icon-tick::before{ content:"✓"; } .bp3-icon-tick-circle::before{ content:""; } .bp3-icon-time::before{ content:"⏲"; } .bp3-icon-timeline-area-chart::before{ content:""; } .bp3-icon-timeline-bar-chart::before{ content:""; } .bp3-icon-timeline-events::before{ content:""; } .bp3-icon-timeline-line-chart::before{ content:""; } .bp3-icon-tint::before{ content:""; } .bp3-icon-torch::before{ content:""; } .bp3-icon-tractor::before{ content:""; } .bp3-icon-train::before{ content:""; } .bp3-icon-translate::before{ content:""; } .bp3-icon-trash::before{ content:""; } .bp3-icon-tree::before{ content:""; } .bp3-icon-trending-down::before{ content:""; } .bp3-icon-trending-up::before{ content:""; } .bp3-icon-truck::before{ content:""; } .bp3-icon-two-columns::before{ content:""; } .bp3-icon-unarchive::before{ content:""; } .bp3-icon-underline::before{ content:"⎁"; } .bp3-icon-undo::before{ content:"⎌"; } .bp3-icon-ungroup-objects::before{ content:""; } .bp3-icon-unknown-vehicle::before{ content:""; } .bp3-icon-unlock::before{ content:""; } .bp3-icon-unpin::before{ content:""; } .bp3-icon-unresolve::before{ content:""; } .bp3-icon-updated::before{ content:""; } .bp3-icon-upload::before{ content:""; } .bp3-icon-user::before{ content:""; } .bp3-icon-variable::before{ content:""; } .bp3-icon-vertical-bar-chart-asc::before{ content:""; } .bp3-icon-vertical-bar-chart-desc::before{ content:""; } .bp3-icon-vertical-distribution::before{ content:""; } .bp3-icon-video::before{ content:""; } .bp3-icon-volume-down::before{ content:""; } .bp3-icon-volume-off::before{ content:""; } .bp3-icon-volume-up::before{ content:""; } .bp3-icon-walk::before{ content:""; } .bp3-icon-warning-sign::before{ content:""; } .bp3-icon-waterfall-chart::before{ content:""; } .bp3-icon-widget::before{ content:""; } .bp3-icon-widget-button::before{ content:""; } .bp3-icon-widget-footer::before{ content:""; } .bp3-icon-widget-header::before{ content:""; } .bp3-icon-wrench::before{ content:""; } .bp3-icon-zoom-in::before{ content:""; } .bp3-icon-zoom-out::before{ content:""; } .bp3-icon-zoom-to-fit::before{ content:""; } .bp3-submenu > .bp3-popover-wrapper{ display:block; } .bp3-submenu .bp3-popover-target{ display:block; } .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-menu-item{ } .bp3-submenu.bp3-popover{ -webkit-box-shadow:none; box-shadow:none; padding:0 5px; } .bp3-submenu.bp3-popover > .bp3-popover-content{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-submenu.bp3-popover, .bp3-submenu.bp3-popover.bp3-dark{ -webkit-box-shadow:none; box-shadow:none; } .bp3-dark .bp3-submenu.bp3-popover > .bp3-popover-content, .bp3-submenu.bp3-popover.bp3-dark > .bp3-popover-content{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); } .bp3-menu{ background:#ffffff; border-radius:3px; color:#182026; list-style:none; margin:0; min-width:180px; padding:5px; text-align:left; } .bp3-menu-divider{ border-top:1px solid rgba(16, 22, 26, 0.15); display:block; margin:5px; } .bp3-dark .bp3-menu-divider{ border-top-color:rgba(255, 255, 255, 0.15); } .bp3-menu-item{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:start; -ms-flex-align:start; align-items:flex-start; border-radius:2px; color:inherit; line-height:20px; padding:5px 7px; text-decoration:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; } .bp3-menu-item > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-menu-item > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-menu-item::before, .bp3-menu-item > *{ margin-right:7px; } .bp3-menu-item:empty::before, .bp3-menu-item > :last-child{ margin-right:0; } .bp3-menu-item > .bp3-fill{ word-break:break-word; } .bp3-menu-item:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-menu-item{ background-color:rgba(167, 182, 194, 0.3); cursor:pointer; text-decoration:none; } .bp3-menu-item.bp3-disabled{ background-color:inherit; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-dark .bp3-menu-item{ color:inherit; } .bp3-dark .bp3-menu-item:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-menu-item{ background-color:rgba(138, 155, 168, 0.15); color:inherit; } .bp3-dark .bp3-menu-item.bp3-disabled{ background-color:inherit; color:rgba(167, 182, 194, 0.6); } .bp3-menu-item.bp3-intent-primary{ color:#106ba3; } .bp3-menu-item.bp3-intent-primary .bp3-icon{ color:inherit; } .bp3-menu-item.bp3-intent-primary::before, .bp3-menu-item.bp3-intent-primary::after, .bp3-menu-item.bp3-intent-primary .bp3-menu-item-label{ color:#106ba3; } .bp3-menu-item.bp3-intent-primary:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item, .bp3-menu-item.bp3-intent-primary.bp3-active{ background-color:#137cbd; } .bp3-menu-item.bp3-intent-primary:active{ background-color:#106ba3; } .bp3-menu-item.bp3-intent-primary:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item, .bp3-menu-item.bp3-intent-primary:hover::before, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item::before, .bp3-menu-item.bp3-intent-primary:hover::after, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item::after, .bp3-menu-item.bp3-intent-primary:hover .bp3-menu-item-label, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item .bp3-menu-item-label, .bp3-menu-item.bp3-intent-primary:active, .bp3-menu-item.bp3-intent-primary:active::before, .bp3-menu-item.bp3-intent-primary:active::after, .bp3-menu-item.bp3-intent-primary:active .bp3-menu-item-label, .bp3-menu-item.bp3-intent-primary.bp3-active, .bp3-menu-item.bp3-intent-primary.bp3-active::before, .bp3-menu-item.bp3-intent-primary.bp3-active::after, .bp3-menu-item.bp3-intent-primary.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-menu-item.bp3-intent-success{ color:#0d8050; } .bp3-menu-item.bp3-intent-success .bp3-icon{ color:inherit; } .bp3-menu-item.bp3-intent-success::before, .bp3-menu-item.bp3-intent-success::after, .bp3-menu-item.bp3-intent-success .bp3-menu-item-label{ color:#0d8050; } .bp3-menu-item.bp3-intent-success:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item, .bp3-menu-item.bp3-intent-success.bp3-active{ background-color:#0f9960; } .bp3-menu-item.bp3-intent-success:active{ background-color:#0d8050; } .bp3-menu-item.bp3-intent-success:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item, .bp3-menu-item.bp3-intent-success:hover::before, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item::before, .bp3-menu-item.bp3-intent-success:hover::after, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item::after, .bp3-menu-item.bp3-intent-success:hover .bp3-menu-item-label, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item .bp3-menu-item-label, .bp3-menu-item.bp3-intent-success:active, .bp3-menu-item.bp3-intent-success:active::before, .bp3-menu-item.bp3-intent-success:active::after, .bp3-menu-item.bp3-intent-success:active .bp3-menu-item-label, .bp3-menu-item.bp3-intent-success.bp3-active, .bp3-menu-item.bp3-intent-success.bp3-active::before, .bp3-menu-item.bp3-intent-success.bp3-active::after, .bp3-menu-item.bp3-intent-success.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-menu-item.bp3-intent-warning{ color:#bf7326; } .bp3-menu-item.bp3-intent-warning .bp3-icon{ color:inherit; } .bp3-menu-item.bp3-intent-warning::before, .bp3-menu-item.bp3-intent-warning::after, .bp3-menu-item.bp3-intent-warning .bp3-menu-item-label{ color:#bf7326; } .bp3-menu-item.bp3-intent-warning:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item, .bp3-menu-item.bp3-intent-warning.bp3-active{ background-color:#d9822b; } .bp3-menu-item.bp3-intent-warning:active{ background-color:#bf7326; } .bp3-menu-item.bp3-intent-warning:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item, .bp3-menu-item.bp3-intent-warning:hover::before, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item::before, .bp3-menu-item.bp3-intent-warning:hover::after, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item::after, .bp3-menu-item.bp3-intent-warning:hover .bp3-menu-item-label, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item .bp3-menu-item-label, .bp3-menu-item.bp3-intent-warning:active, .bp3-menu-item.bp3-intent-warning:active::before, .bp3-menu-item.bp3-intent-warning:active::after, .bp3-menu-item.bp3-intent-warning:active .bp3-menu-item-label, .bp3-menu-item.bp3-intent-warning.bp3-active, .bp3-menu-item.bp3-intent-warning.bp3-active::before, .bp3-menu-item.bp3-intent-warning.bp3-active::after, .bp3-menu-item.bp3-intent-warning.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-menu-item.bp3-intent-danger{ color:#c23030; } .bp3-menu-item.bp3-intent-danger .bp3-icon{ color:inherit; } .bp3-menu-item.bp3-intent-danger::before, .bp3-menu-item.bp3-intent-danger::after, .bp3-menu-item.bp3-intent-danger .bp3-menu-item-label{ color:#c23030; } .bp3-menu-item.bp3-intent-danger:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item, .bp3-menu-item.bp3-intent-danger.bp3-active{ background-color:#db3737; } .bp3-menu-item.bp3-intent-danger:active{ background-color:#c23030; } .bp3-menu-item.bp3-intent-danger:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item, .bp3-menu-item.bp3-intent-danger:hover::before, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item::before, .bp3-menu-item.bp3-intent-danger:hover::after, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item::after, .bp3-menu-item.bp3-intent-danger:hover .bp3-menu-item-label, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item .bp3-menu-item-label, .bp3-menu-item.bp3-intent-danger:active, .bp3-menu-item.bp3-intent-danger:active::before, .bp3-menu-item.bp3-intent-danger:active::after, .bp3-menu-item.bp3-intent-danger:active .bp3-menu-item-label, .bp3-menu-item.bp3-intent-danger.bp3-active, .bp3-menu-item.bp3-intent-danger.bp3-active::before, .bp3-menu-item.bp3-intent-danger.bp3-active::after, .bp3-menu-item.bp3-intent-danger.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-menu-item::before{ font-family:"Icons16", sans-serif; font-size:16px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; margin-right:7px; } .bp3-menu-item::before, .bp3-menu-item > .bp3-icon{ color:#5c7080; margin-top:2px; } .bp3-menu-item .bp3-menu-item-label{ color:#5c7080; } .bp3-menu-item:hover, .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-menu-item{ color:inherit; } .bp3-menu-item.bp3-active, .bp3-menu-item:active{ background-color:rgba(115, 134, 148, 0.3); } .bp3-menu-item.bp3-disabled{ background-color:inherit !important; color:rgba(92, 112, 128, 0.6) !important; cursor:not-allowed !important; outline:none !important; } .bp3-menu-item.bp3-disabled::before, .bp3-menu-item.bp3-disabled > .bp3-icon, .bp3-menu-item.bp3-disabled .bp3-menu-item-label{ color:rgba(92, 112, 128, 0.6) !important; } .bp3-large .bp3-menu-item{ font-size:16px; line-height:22px; padding:9px 7px; } .bp3-large .bp3-menu-item .bp3-icon{ margin-top:3px; } .bp3-large .bp3-menu-item::before{ font-family:"Icons20", sans-serif; font-size:20px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; margin-right:10px; margin-top:1px; } button.bp3-menu-item{ background:none; border:none; text-align:left; width:100%; } .bp3-menu-header{ border-top:1px solid rgba(16, 22, 26, 0.15); display:block; margin:5px; cursor:default; padding-left:2px; } .bp3-dark .bp3-menu-header{ border-top-color:rgba(255, 255, 255, 0.15); } .bp3-menu-header:first-of-type{ border-top:none; } .bp3-menu-header > h6{ color:#182026; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; line-height:17px; margin:0; padding:10px 7px 0 1px; } .bp3-dark .bp3-menu-header > h6{ color:#f5f8fa; } .bp3-menu-header:first-of-type > h6{ padding-top:0; } .bp3-large .bp3-menu-header > h6{ font-size:18px; padding-bottom:5px; padding-top:15px; } .bp3-large .bp3-menu-header:first-of-type > h6{ padding-top:0; } .bp3-dark .bp3-menu{ background:#30404d; color:#f5f8fa; } .bp3-dark .bp3-menu-item{ } .bp3-dark .bp3-menu-item.bp3-intent-primary{ color:#48aff0; } .bp3-dark .bp3-menu-item.bp3-intent-primary .bp3-icon{ color:inherit; } .bp3-dark .bp3-menu-item.bp3-intent-primary::before, .bp3-dark .bp3-menu-item.bp3-intent-primary::after, .bp3-dark .bp3-menu-item.bp3-intent-primary .bp3-menu-item-label{ color:#48aff0; } .bp3-dark .bp3-menu-item.bp3-intent-primary:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-primary.bp3-active{ background-color:#137cbd; } .bp3-dark .bp3-menu-item.bp3-intent-primary:active{ background-color:#106ba3; } .bp3-dark .bp3-menu-item.bp3-intent-primary:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-primary:hover::before, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item::before, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item::before, .bp3-dark .bp3-menu-item.bp3-intent-primary:hover::after, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item::after, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item::after, .bp3-dark .bp3-menu-item.bp3-intent-primary:hover .bp3-menu-item-label, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item .bp3-menu-item-label, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-primary.bp3-menu-item .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-primary:active, .bp3-dark .bp3-menu-item.bp3-intent-primary:active::before, .bp3-dark .bp3-menu-item.bp3-intent-primary:active::after, .bp3-dark .bp3-menu-item.bp3-intent-primary:active .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-primary.bp3-active, .bp3-dark .bp3-menu-item.bp3-intent-primary.bp3-active::before, .bp3-dark .bp3-menu-item.bp3-intent-primary.bp3-active::after, .bp3-dark .bp3-menu-item.bp3-intent-primary.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-dark .bp3-menu-item.bp3-intent-success{ color:#3dcc91; } .bp3-dark .bp3-menu-item.bp3-intent-success .bp3-icon{ color:inherit; } .bp3-dark .bp3-menu-item.bp3-intent-success::before, .bp3-dark .bp3-menu-item.bp3-intent-success::after, .bp3-dark .bp3-menu-item.bp3-intent-success .bp3-menu-item-label{ color:#3dcc91; } .bp3-dark .bp3-menu-item.bp3-intent-success:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-success.bp3-active{ background-color:#0f9960; } .bp3-dark .bp3-menu-item.bp3-intent-success:active{ background-color:#0d8050; } .bp3-dark .bp3-menu-item.bp3-intent-success:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-success:hover::before, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item::before, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item::before, .bp3-dark .bp3-menu-item.bp3-intent-success:hover::after, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item::after, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item::after, .bp3-dark .bp3-menu-item.bp3-intent-success:hover .bp3-menu-item-label, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item .bp3-menu-item-label, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-success.bp3-menu-item .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-success:active, .bp3-dark .bp3-menu-item.bp3-intent-success:active::before, .bp3-dark .bp3-menu-item.bp3-intent-success:active::after, .bp3-dark .bp3-menu-item.bp3-intent-success:active .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-success.bp3-active, .bp3-dark .bp3-menu-item.bp3-intent-success.bp3-active::before, .bp3-dark .bp3-menu-item.bp3-intent-success.bp3-active::after, .bp3-dark .bp3-menu-item.bp3-intent-success.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-dark .bp3-menu-item.bp3-intent-warning{ color:#ffb366; } .bp3-dark .bp3-menu-item.bp3-intent-warning .bp3-icon{ color:inherit; } .bp3-dark .bp3-menu-item.bp3-intent-warning::before, .bp3-dark .bp3-menu-item.bp3-intent-warning::after, .bp3-dark .bp3-menu-item.bp3-intent-warning .bp3-menu-item-label{ color:#ffb366; } .bp3-dark .bp3-menu-item.bp3-intent-warning:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-warning.bp3-active{ background-color:#d9822b; } .bp3-dark .bp3-menu-item.bp3-intent-warning:active{ background-color:#bf7326; } .bp3-dark .bp3-menu-item.bp3-intent-warning:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-warning:hover::before, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item::before, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item::before, .bp3-dark .bp3-menu-item.bp3-intent-warning:hover::after, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item::after, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item::after, .bp3-dark .bp3-menu-item.bp3-intent-warning:hover .bp3-menu-item-label, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item .bp3-menu-item-label, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-warning.bp3-menu-item .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-warning:active, .bp3-dark .bp3-menu-item.bp3-intent-warning:active::before, .bp3-dark .bp3-menu-item.bp3-intent-warning:active::after, .bp3-dark .bp3-menu-item.bp3-intent-warning:active .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-warning.bp3-active, .bp3-dark .bp3-menu-item.bp3-intent-warning.bp3-active::before, .bp3-dark .bp3-menu-item.bp3-intent-warning.bp3-active::after, .bp3-dark .bp3-menu-item.bp3-intent-warning.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-dark .bp3-menu-item.bp3-intent-danger{ color:#ff7373; } .bp3-dark .bp3-menu-item.bp3-intent-danger .bp3-icon{ color:inherit; } .bp3-dark .bp3-menu-item.bp3-intent-danger::before, .bp3-dark .bp3-menu-item.bp3-intent-danger::after, .bp3-dark .bp3-menu-item.bp3-intent-danger .bp3-menu-item-label{ color:#ff7373; } .bp3-dark .bp3-menu-item.bp3-intent-danger:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-danger.bp3-active{ background-color:#db3737; } .bp3-dark .bp3-menu-item.bp3-intent-danger:active{ background-color:#c23030; } .bp3-dark .bp3-menu-item.bp3-intent-danger:hover, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item, .bp3-dark .bp3-menu-item.bp3-intent-danger:hover::before, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item::before, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item::before, .bp3-dark .bp3-menu-item.bp3-intent-danger:hover::after, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item::after, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item::after, .bp3-dark .bp3-menu-item.bp3-intent-danger:hover .bp3-menu-item-label, .bp3-dark .bp3-submenu .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item .bp3-menu-item-label, .bp3-submenu .bp3-dark .bp3-popover-target.bp3-popover-open > .bp3-intent-danger.bp3-menu-item .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-danger:active, .bp3-dark .bp3-menu-item.bp3-intent-danger:active::before, .bp3-dark .bp3-menu-item.bp3-intent-danger:active::after, .bp3-dark .bp3-menu-item.bp3-intent-danger:active .bp3-menu-item-label, .bp3-dark .bp3-menu-item.bp3-intent-danger.bp3-active, .bp3-dark .bp3-menu-item.bp3-intent-danger.bp3-active::before, .bp3-dark .bp3-menu-item.bp3-intent-danger.bp3-active::after, .bp3-dark .bp3-menu-item.bp3-intent-danger.bp3-active .bp3-menu-item-label{ color:#ffffff; } .bp3-dark .bp3-menu-item::before, .bp3-dark .bp3-menu-item > .bp3-icon{ color:#a7b6c2; } .bp3-dark .bp3-menu-item .bp3-menu-item-label{ color:#a7b6c2; } .bp3-dark .bp3-menu-item.bp3-active, .bp3-dark .bp3-menu-item:active{ background-color:rgba(138, 155, 168, 0.3); } .bp3-dark .bp3-menu-item.bp3-disabled{ color:rgba(167, 182, 194, 0.6) !important; } .bp3-dark .bp3-menu-item.bp3-disabled::before, .bp3-dark .bp3-menu-item.bp3-disabled > .bp3-icon, .bp3-dark .bp3-menu-item.bp3-disabled .bp3-menu-item-label{ color:rgba(167, 182, 194, 0.6) !important; } .bp3-dark .bp3-menu-divider, .bp3-dark .bp3-menu-header{ border-color:rgba(255, 255, 255, 0.15); } .bp3-dark .bp3-menu-header > h6{ color:#f5f8fa; } .bp3-label .bp3-menu{ margin-top:5px; } .bp3-navbar{ background-color:#ffffff; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.2); height:50px; padding:0 15px; position:relative; width:100%; z-index:10; } .bp3-navbar.bp3-dark, .bp3-dark .bp3-navbar{ background-color:#394b59; } .bp3-navbar.bp3-dark{ -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-navbar{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 0 0 rgba(16, 22, 26, 0), 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-navbar.bp3-fixed-top{ left:0; position:fixed; right:0; top:0; } .bp3-navbar-heading{ font-size:16px; margin-right:15px; } .bp3-navbar-group{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box; display:-ms-flexbox; display:flex; height:50px; } .bp3-navbar-group.bp3-align-left{ float:left; } .bp3-navbar-group.bp3-align-right{ float:right; } .bp3-navbar-divider{ border-left:1px solid rgba(16, 22, 26, 0.15); height:20px; margin:0 10px; } .bp3-dark .bp3-navbar-divider{ border-left-color:rgba(255, 255, 255, 0.15); } .bp3-non-ideal-state{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; -webkit-box-align:center; -ms-flex-align:center; align-items:center; height:100%; -webkit-box-pack:center; -ms-flex-pack:center; justify-content:center; text-align:center; width:100%; } .bp3-non-ideal-state > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-non-ideal-state > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-non-ideal-state::before, .bp3-non-ideal-state > *{ margin-bottom:20px; } .bp3-non-ideal-state:empty::before, .bp3-non-ideal-state > :last-child{ margin-bottom:0; } .bp3-non-ideal-state > *{ max-width:400px; } .bp3-non-ideal-state-visual{ color:rgba(92, 112, 128, 0.6); font-size:60px; } .bp3-dark .bp3-non-ideal-state-visual{ color:rgba(167, 182, 194, 0.6); } .bp3-overflow-list{ display:-webkit-box; display:-ms-flexbox; display:flex; -ms-flex-wrap:nowrap; flex-wrap:nowrap; min-width:0; } .bp3-overflow-list-spacer{ -ms-flex-negative:1; flex-shrink:1; width:1px; } body.bp3-overlay-open{ overflow:hidden; } .bp3-overlay{ bottom:0; left:0; position:static; right:0; top:0; z-index:20; } .bp3-overlay:not(.bp3-overlay-open){ pointer-events:none; } .bp3-overlay.bp3-overlay-container{ overflow:hidden; position:fixed; } .bp3-overlay.bp3-overlay-container.bp3-overlay-inline{ position:absolute; } .bp3-overlay.bp3-overlay-scroll-container{ overflow:auto; position:fixed; } .bp3-overlay.bp3-overlay-scroll-container.bp3-overlay-inline{ position:absolute; } .bp3-overlay.bp3-overlay-inline{ display:inline; overflow:visible; } .bp3-overlay-content{ position:fixed; z-index:20; } .bp3-overlay-inline .bp3-overlay-content, .bp3-overlay-scroll-container .bp3-overlay-content{ position:absolute; } .bp3-overlay-backdrop{ bottom:0; left:0; position:fixed; right:0; top:0; opacity:1; background-color:rgba(16, 22, 26, 0.7); overflow:auto; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; z-index:20; } .bp3-overlay-backdrop.bp3-overlay-enter, .bp3-overlay-backdrop.bp3-overlay-appear{ opacity:0; } .bp3-overlay-backdrop.bp3-overlay-enter-active, .bp3-overlay-backdrop.bp3-overlay-appear-active{ opacity:1; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:opacity; transition-property:opacity; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-overlay-backdrop.bp3-overlay-exit{ opacity:1; } .bp3-overlay-backdrop.bp3-overlay-exit-active{ opacity:0; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:opacity; transition-property:opacity; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-overlay-backdrop:focus{ outline:none; } .bp3-overlay-inline .bp3-overlay-backdrop{ position:absolute; } .bp3-panel-stack{ overflow:hidden; position:relative; } .bp3-panel-stack-header{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; -webkit-box-shadow:0 1px rgba(16, 22, 26, 0.15); box-shadow:0 1px rgba(16, 22, 26, 0.15); display:-webkit-box; display:-ms-flexbox; display:flex; -ms-flex-negative:0; flex-shrink:0; height:30px; z-index:1; } .bp3-dark .bp3-panel-stack-header{ -webkit-box-shadow:0 1px rgba(255, 255, 255, 0.15); box-shadow:0 1px rgba(255, 255, 255, 0.15); } .bp3-panel-stack-header > span{ -webkit-box-align:stretch; -ms-flex-align:stretch; align-items:stretch; display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-flex:1; -ms-flex:1; flex:1; } .bp3-panel-stack-header .bp3-heading{ margin:0 5px; } .bp3-button.bp3-panel-stack-header-back{ margin-left:5px; padding-left:0; white-space:nowrap; } .bp3-button.bp3-panel-stack-header-back .bp3-icon{ margin:0 2px; } .bp3-panel-stack-view{ bottom:0; left:0; position:absolute; right:0; top:0; background-color:#ffffff; border-right:1px solid rgba(16, 22, 26, 0.15); display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; margin-right:-1px; overflow-y:auto; z-index:1; } .bp3-dark .bp3-panel-stack-view{ background-color:#30404d; } .bp3-panel-stack-view:nth-last-child(n + 4){ display:none; } .bp3-panel-stack-push .bp3-panel-stack-enter, .bp3-panel-stack-push .bp3-panel-stack-appear{ -webkit-transform:translateX(100%); transform:translateX(100%); opacity:0; } .bp3-panel-stack-push .bp3-panel-stack-enter-active, .bp3-panel-stack-push .bp3-panel-stack-appear-active{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-panel-stack-push .bp3-panel-stack-exit{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; } .bp3-panel-stack-push .bp3-panel-stack-exit-active{ -webkit-transform:translateX(-50%); transform:translateX(-50%); opacity:0; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-panel-stack-pop .bp3-panel-stack-enter, .bp3-panel-stack-pop .bp3-panel-stack-appear{ -webkit-transform:translateX(-50%); transform:translateX(-50%); opacity:0; } .bp3-panel-stack-pop .bp3-panel-stack-enter-active, .bp3-panel-stack-pop .bp3-panel-stack-appear-active{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-panel-stack-pop .bp3-panel-stack-exit{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; } .bp3-panel-stack-pop .bp3-panel-stack-exit-active{ -webkit-transform:translateX(100%); transform:translateX(100%); opacity:0; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-panel-stack2{ overflow:hidden; position:relative; } .bp3-panel-stack2-header{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; -webkit-box-shadow:0 1px rgba(16, 22, 26, 0.15); box-shadow:0 1px rgba(16, 22, 26, 0.15); display:-webkit-box; display:-ms-flexbox; display:flex; -ms-flex-negative:0; flex-shrink:0; height:30px; z-index:1; } .bp3-dark .bp3-panel-stack2-header{ -webkit-box-shadow:0 1px rgba(255, 255, 255, 0.15); box-shadow:0 1px rgba(255, 255, 255, 0.15); } .bp3-panel-stack2-header > span{ -webkit-box-align:stretch; -ms-flex-align:stretch; align-items:stretch; display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-flex:1; -ms-flex:1; flex:1; } .bp3-panel-stack2-header .bp3-heading{ margin:0 5px; } .bp3-button.bp3-panel-stack2-header-back{ margin-left:5px; padding-left:0; white-space:nowrap; } .bp3-button.bp3-panel-stack2-header-back .bp3-icon{ margin:0 2px; } .bp3-panel-stack2-view{ bottom:0; left:0; position:absolute; right:0; top:0; background-color:#ffffff; border-right:1px solid rgba(16, 22, 26, 0.15); display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; margin-right:-1px; overflow-y:auto; z-index:1; } .bp3-dark .bp3-panel-stack2-view{ background-color:#30404d; } .bp3-panel-stack2-view:nth-last-child(n + 4){ display:none; } .bp3-panel-stack2-push .bp3-panel-stack2-enter, .bp3-panel-stack2-push .bp3-panel-stack2-appear{ -webkit-transform:translateX(100%); transform:translateX(100%); opacity:0; } .bp3-panel-stack2-push .bp3-panel-stack2-enter-active, .bp3-panel-stack2-push .bp3-panel-stack2-appear-active{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-panel-stack2-push .bp3-panel-stack2-exit{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; } .bp3-panel-stack2-push .bp3-panel-stack2-exit-active{ -webkit-transform:translateX(-50%); transform:translateX(-50%); opacity:0; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-panel-stack2-pop .bp3-panel-stack2-enter, .bp3-panel-stack2-pop .bp3-panel-stack2-appear{ -webkit-transform:translateX(-50%); transform:translateX(-50%); opacity:0; } .bp3-panel-stack2-pop .bp3-panel-stack2-enter-active, .bp3-panel-stack2-pop .bp3-panel-stack2-appear-active{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-panel-stack2-pop .bp3-panel-stack2-exit{ -webkit-transform:translate(0%); transform:translate(0%); opacity:1; } .bp3-panel-stack2-pop .bp3-panel-stack2-exit-active{ -webkit-transform:translateX(100%); transform:translateX(100%); opacity:0; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:400ms; transition-duration:400ms; -webkit-transition-property:opacity, -webkit-transform; transition-property:opacity, -webkit-transform; transition-property:transform, opacity; transition-property:transform, opacity, -webkit-transform; -webkit-transition-timing-function:ease; transition-timing-function:ease; } .bp3-popover{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); -webkit-transform:scale(1); transform:scale(1); border-radius:3px; display:inline-block; z-index:20; } .bp3-popover .bp3-popover-arrow{ height:30px; position:absolute; width:30px; } .bp3-popover .bp3-popover-arrow::before{ height:20px; margin:5px; width:20px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-top > .bp3-popover{ margin-bottom:17px; margin-top:-17px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-top > .bp3-popover > .bp3-popover-arrow{ bottom:-11px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-top > .bp3-popover > .bp3-popover-arrow svg{ -webkit-transform:rotate(-90deg); transform:rotate(-90deg); } .bp3-tether-element-attached-left.bp3-tether-target-attached-right > .bp3-popover{ margin-left:17px; } .bp3-tether-element-attached-left.bp3-tether-target-attached-right > .bp3-popover > .bp3-popover-arrow{ left:-11px; } .bp3-tether-element-attached-left.bp3-tether-target-attached-right > .bp3-popover > .bp3-popover-arrow svg{ -webkit-transform:rotate(0); transform:rotate(0); } .bp3-tether-element-attached-top.bp3-tether-target-attached-bottom > .bp3-popover{ margin-top:17px; } .bp3-tether-element-attached-top.bp3-tether-target-attached-bottom > .bp3-popover > .bp3-popover-arrow{ top:-11px; } .bp3-tether-element-attached-top.bp3-tether-target-attached-bottom > .bp3-popover > .bp3-popover-arrow svg{ -webkit-transform:rotate(90deg); transform:rotate(90deg); } .bp3-tether-element-attached-right.bp3-tether-target-attached-left > .bp3-popover{ margin-left:-17px; margin-right:17px; } .bp3-tether-element-attached-right.bp3-tether-target-attached-left > .bp3-popover > .bp3-popover-arrow{ right:-11px; } .bp3-tether-element-attached-right.bp3-tether-target-attached-left > .bp3-popover > .bp3-popover-arrow svg{ -webkit-transform:rotate(180deg); transform:rotate(180deg); } .bp3-tether-element-attached-middle > .bp3-popover > .bp3-popover-arrow{ top:50%; -webkit-transform:translateY(-50%); transform:translateY(-50%); } .bp3-tether-element-attached-center > .bp3-popover > .bp3-popover-arrow{ right:50%; -webkit-transform:translateX(50%); transform:translateX(50%); } .bp3-tether-element-attached-top.bp3-tether-target-attached-top > .bp3-popover > .bp3-popover-arrow{ top:-0.3934px; } .bp3-tether-element-attached-right.bp3-tether-target-attached-right > .bp3-popover > .bp3-popover-arrow{ right:-0.3934px; } .bp3-tether-element-attached-left.bp3-tether-target-attached-left > .bp3-popover > .bp3-popover-arrow{ left:-0.3934px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-bottom > .bp3-popover > .bp3-popover-arrow{ bottom:-0.3934px; } .bp3-tether-element-attached-top.bp3-tether-element-attached-left > .bp3-popover{ -webkit-transform-origin:top left; transform-origin:top left; } .bp3-tether-element-attached-top.bp3-tether-element-attached-center > .bp3-popover{ -webkit-transform-origin:top center; transform-origin:top center; } .bp3-tether-element-attached-top.bp3-tether-element-attached-right > .bp3-popover{ -webkit-transform-origin:top right; transform-origin:top right; } .bp3-tether-element-attached-middle.bp3-tether-element-attached-left > .bp3-popover{ -webkit-transform-origin:center left; transform-origin:center left; } .bp3-tether-element-attached-middle.bp3-tether-element-attached-center > .bp3-popover{ -webkit-transform-origin:center center; transform-origin:center center; } .bp3-tether-element-attached-middle.bp3-tether-element-attached-right > .bp3-popover{ -webkit-transform-origin:center right; transform-origin:center right; } .bp3-tether-element-attached-bottom.bp3-tether-element-attached-left > .bp3-popover{ -webkit-transform-origin:bottom left; transform-origin:bottom left; } .bp3-tether-element-attached-bottom.bp3-tether-element-attached-center > .bp3-popover{ -webkit-transform-origin:bottom center; transform-origin:bottom center; } .bp3-tether-element-attached-bottom.bp3-tether-element-attached-right > .bp3-popover{ -webkit-transform-origin:bottom right; transform-origin:bottom right; } .bp3-popover .bp3-popover-content{ background:#ffffff; color:inherit; } .bp3-popover .bp3-popover-arrow::before{ -webkit-box-shadow:1px 1px 6px rgba(16, 22, 26, 0.2); box-shadow:1px 1px 6px rgba(16, 22, 26, 0.2); } .bp3-popover .bp3-popover-arrow-border{ fill:#10161a; fill-opacity:0.1; } .bp3-popover .bp3-popover-arrow-fill{ fill:#ffffff; } .bp3-popover-enter > .bp3-popover, .bp3-popover-appear > .bp3-popover{ -webkit-transform:scale(0.3); transform:scale(0.3); } .bp3-popover-enter-active > .bp3-popover, .bp3-popover-appear-active > .bp3-popover{ -webkit-transform:scale(1); transform:scale(1); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:300ms; transition-duration:300ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); } .bp3-popover-exit > .bp3-popover{ -webkit-transform:scale(1); transform:scale(1); } .bp3-popover-exit-active > .bp3-popover{ -webkit-transform:scale(0.3); transform:scale(0.3); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:300ms; transition-duration:300ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); } .bp3-popover .bp3-popover-content{ border-radius:3px; position:relative; } .bp3-popover.bp3-popover-content-sizing .bp3-popover-content{ max-width:350px; padding:20px; } .bp3-popover-target + .bp3-overlay .bp3-popover.bp3-popover-content-sizing{ width:350px; } .bp3-popover.bp3-minimal{ margin:0 !important; } .bp3-popover.bp3-minimal .bp3-popover-arrow{ display:none; } .bp3-popover.bp3-minimal.bp3-popover{ -webkit-transform:scale(1); transform:scale(1); } .bp3-popover-enter > .bp3-popover.bp3-minimal.bp3-popover, .bp3-popover-appear > .bp3-popover.bp3-minimal.bp3-popover{ -webkit-transform:scale(1); transform:scale(1); } .bp3-popover-enter-active > .bp3-popover.bp3-minimal.bp3-popover, .bp3-popover-appear-active > .bp3-popover.bp3-minimal.bp3-popover{ -webkit-transform:scale(1); transform:scale(1); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-popover-exit > .bp3-popover.bp3-minimal.bp3-popover{ -webkit-transform:scale(1); transform:scale(1); } .bp3-popover-exit-active > .bp3-popover.bp3-minimal.bp3-popover{ -webkit-transform:scale(1); transform:scale(1); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-popover.bp3-dark, .bp3-dark .bp3-popover{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); } .bp3-popover.bp3-dark .bp3-popover-content, .bp3-dark .bp3-popover .bp3-popover-content{ background:#30404d; color:inherit; } .bp3-popover.bp3-dark .bp3-popover-arrow::before, .bp3-dark .bp3-popover .bp3-popover-arrow::before{ -webkit-box-shadow:1px 1px 6px rgba(16, 22, 26, 0.4); box-shadow:1px 1px 6px rgba(16, 22, 26, 0.4); } .bp3-popover.bp3-dark .bp3-popover-arrow-border, .bp3-dark .bp3-popover .bp3-popover-arrow-border{ fill:#10161a; fill-opacity:0.2; } .bp3-popover.bp3-dark .bp3-popover-arrow-fill, .bp3-dark .bp3-popover .bp3-popover-arrow-fill{ fill:#30404d; } .bp3-popover-arrow::before{ border-radius:2px; content:""; display:block; position:absolute; -webkit-transform:rotate(45deg); transform:rotate(45deg); } .bp3-tether-pinned .bp3-popover-arrow{ display:none; } .bp3-popover-backdrop{ background:rgba(255, 255, 255, 0); } .bp3-transition-container{ opacity:1; display:-webkit-box; display:-ms-flexbox; display:flex; z-index:20; } .bp3-transition-container.bp3-popover-enter, .bp3-transition-container.bp3-popover-appear{ opacity:0; } .bp3-transition-container.bp3-popover-enter-active, .bp3-transition-container.bp3-popover-appear-active{ opacity:1; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:opacity; transition-property:opacity; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-transition-container.bp3-popover-exit{ opacity:1; } .bp3-transition-container.bp3-popover-exit-active{ opacity:0; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:opacity; transition-property:opacity; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-transition-container:focus{ outline:none; } .bp3-transition-container.bp3-popover-leave .bp3-popover-content{ pointer-events:none; } .bp3-transition-container[data-x-out-of-boundaries]{ display:none; } span.bp3-popover-target{ display:inline-block; } .bp3-popover-wrapper.bp3-fill{ width:100%; } .bp3-portal{ left:0; position:absolute; right:0; top:0; } @-webkit-keyframes linear-progress-bar-stripes{ from{ background-position:0 0; } to{ background-position:30px 0; } } @keyframes linear-progress-bar-stripes{ from{ background-position:0 0; } to{ background-position:30px 0; } } .bp3-progress-bar{ background:rgba(92, 112, 128, 0.2); border-radius:40px; display:block; height:8px; overflow:hidden; position:relative; width:100%; } .bp3-progress-bar .bp3-progress-meter{ background:linear-gradient(-45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%); background-color:rgba(92, 112, 128, 0.8); background-size:30px 30px; border-radius:40px; height:100%; position:absolute; -webkit-transition:width 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:width 200ms cubic-bezier(0.4, 1, 0.75, 0.9); width:100%; } .bp3-progress-bar:not(.bp3-no-animation):not(.bp3-no-stripes) .bp3-progress-meter{ animation:linear-progress-bar-stripes 300ms linear infinite reverse; } .bp3-progress-bar.bp3-no-stripes .bp3-progress-meter{ background-image:none; } .bp3-dark .bp3-progress-bar{ background:rgba(16, 22, 26, 0.5); } .bp3-dark .bp3-progress-bar .bp3-progress-meter{ background-color:#8a9ba8; } .bp3-progress-bar.bp3-intent-primary .bp3-progress-meter{ background-color:#137cbd; } .bp3-progress-bar.bp3-intent-success .bp3-progress-meter{ background-color:#0f9960; } .bp3-progress-bar.bp3-intent-warning .bp3-progress-meter{ background-color:#d9822b; } .bp3-progress-bar.bp3-intent-danger .bp3-progress-meter{ background-color:#db3737; } @-webkit-keyframes skeleton-glow{ from{ background:rgba(206, 217, 224, 0.2); border-color:rgba(206, 217, 224, 0.2); } to{ background:rgba(92, 112, 128, 0.2); border-color:rgba(92, 112, 128, 0.2); } } @keyframes skeleton-glow{ from{ background:rgba(206, 217, 224, 0.2); border-color:rgba(206, 217, 224, 0.2); } to{ background:rgba(92, 112, 128, 0.2); border-color:rgba(92, 112, 128, 0.2); } } .bp3-skeleton{ -webkit-animation:1000ms linear infinite alternate skeleton-glow; animation:1000ms linear infinite alternate skeleton-glow; background:rgba(206, 217, 224, 0.2); background-clip:padding-box !important; border-color:rgba(206, 217, 224, 0.2) !important; border-radius:2px; -webkit-box-shadow:none !important; box-shadow:none !important; color:transparent !important; cursor:default; pointer-events:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; } .bp3-skeleton::before, .bp3-skeleton::after, .bp3-skeleton *{ visibility:hidden !important; } .bp3-slider{ height:40px; min-width:150px; width:100%; cursor:default; outline:none; position:relative; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; } .bp3-slider:hover{ cursor:pointer; } .bp3-slider:active{ cursor:-webkit-grabbing; cursor:grabbing; } .bp3-slider.bp3-disabled{ cursor:not-allowed; opacity:0.5; } .bp3-slider.bp3-slider-unlabeled{ height:16px; } .bp3-slider-track, .bp3-slider-progress{ height:6px; left:0; right:0; top:5px; position:absolute; } .bp3-slider-track{ border-radius:3px; overflow:hidden; } .bp3-slider-progress{ background:rgba(92, 112, 128, 0.2); } .bp3-dark .bp3-slider-progress{ background:rgba(16, 22, 26, 0.5); } .bp3-slider-progress.bp3-intent-primary{ background-color:#137cbd; } .bp3-slider-progress.bp3-intent-success{ background-color:#0f9960; } .bp3-slider-progress.bp3-intent-warning{ background-color:#d9822b; } .bp3-slider-progress.bp3-intent-danger{ background-color:#db3737; } .bp3-slider-handle{ background-color:#f5f8fa; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.8)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0)); -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); color:#182026; border-radius:3px; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.2); cursor:pointer; height:16px; left:0; position:absolute; top:0; width:16px; } .bp3-slider-handle:hover{ background-clip:padding-box; background-color:#ebf1f5; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); } .bp3-slider-handle:active, .bp3-slider-handle.bp3-active{ background-color:#d8e1e8; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-slider-handle:disabled, .bp3-slider-handle.bp3-disabled{ background-color:rgba(206, 217, 224, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; outline:none; } .bp3-slider-handle:disabled.bp3-active, .bp3-slider-handle:disabled.bp3-active:hover, .bp3-slider-handle.bp3-disabled.bp3-active, .bp3-slider-handle.bp3-disabled.bp3-active:hover{ background:rgba(206, 217, 224, 0.7); } .bp3-slider-handle:focus{ z-index:1; } .bp3-slider-handle:hover{ background-clip:padding-box; background-color:#ebf1f5; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1); -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 1px 1px rgba(16, 22, 26, 0.2); cursor:-webkit-grab; cursor:grab; z-index:2; } .bp3-slider-handle.bp3-active{ background-color:#d8e1e8; background-image:none; -webkit-box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 2px rgba(16, 22, 26, 0.2); -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 1px rgba(16, 22, 26, 0.1); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 1px 1px rgba(16, 22, 26, 0.1); cursor:-webkit-grabbing; cursor:grabbing; } .bp3-disabled .bp3-slider-handle{ background:#bfccd6; -webkit-box-shadow:none; box-shadow:none; pointer-events:none; } .bp3-dark .bp3-slider-handle{ background-color:#394b59; background-image:-webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0.05)), to(rgba(255, 255, 255, 0))); background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0)); -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); color:#f5f8fa; } .bp3-dark .bp3-slider-handle:hover, .bp3-dark .bp3-slider-handle:active, .bp3-dark .bp3-slider-handle.bp3-active{ color:#f5f8fa; } .bp3-dark .bp3-slider-handle:hover{ background-color:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-slider-handle:active, .bp3-dark .bp3-slider-handle.bp3-active{ background-color:#202b33; background-image:none; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.6), inset 0 1px 2px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-slider-handle:disabled, .bp3-dark .bp3-slider-handle.bp3-disabled{ background-color:rgba(57, 75, 89, 0.5); background-image:none; -webkit-box-shadow:none; box-shadow:none; color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-slider-handle:disabled.bp3-active, .bp3-dark .bp3-slider-handle.bp3-disabled.bp3-active{ background:rgba(57, 75, 89, 0.7); } .bp3-dark .bp3-slider-handle .bp3-button-spinner .bp3-spinner-head{ background:rgba(16, 22, 26, 0.5); stroke:#8a9ba8; } .bp3-dark .bp3-slider-handle, .bp3-dark .bp3-slider-handle:hover{ background-color:#394b59; } .bp3-dark .bp3-slider-handle.bp3-active{ background-color:#293742; } .bp3-dark .bp3-disabled .bp3-slider-handle{ background:#5c7080; border-color:#5c7080; -webkit-box-shadow:none; box-shadow:none; } .bp3-slider-handle .bp3-slider-label{ background:#394b59; border-radius:3px; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); color:#f5f8fa; margin-left:8px; } .bp3-dark .bp3-slider-handle .bp3-slider-label{ background:#e1e8ed; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); color:#394b59; } .bp3-disabled .bp3-slider-handle .bp3-slider-label{ -webkit-box-shadow:none; box-shadow:none; } .bp3-slider-handle.bp3-start, .bp3-slider-handle.bp3-end{ width:8px; } .bp3-slider-handle.bp3-start{ border-bottom-right-radius:0; border-top-right-radius:0; } .bp3-slider-handle.bp3-end{ border-bottom-left-radius:0; border-top-left-radius:0; margin-left:8px; } .bp3-slider-handle.bp3-end .bp3-slider-label{ margin-left:0; } .bp3-slider-label{ -webkit-transform:translate(-50%, 20px); transform:translate(-50%, 20px); display:inline-block; font-size:12px; line-height:1; padding:2px 5px; position:absolute; vertical-align:top; } .bp3-slider.bp3-vertical{ height:150px; min-width:40px; width:40px; } .bp3-slider.bp3-vertical .bp3-slider-track, .bp3-slider.bp3-vertical .bp3-slider-progress{ bottom:0; height:auto; left:5px; top:0; width:6px; } .bp3-slider.bp3-vertical .bp3-slider-progress{ top:auto; } .bp3-slider.bp3-vertical .bp3-slider-label{ -webkit-transform:translate(20px, 50%); transform:translate(20px, 50%); } .bp3-slider.bp3-vertical .bp3-slider-handle{ top:auto; } .bp3-slider.bp3-vertical .bp3-slider-handle .bp3-slider-label{ margin-left:0; margin-top:-8px; } .bp3-slider.bp3-vertical .bp3-slider-handle.bp3-end, .bp3-slider.bp3-vertical .bp3-slider-handle.bp3-start{ height:8px; margin-left:0; width:16px; } .bp3-slider.bp3-vertical .bp3-slider-handle.bp3-start{ border-bottom-right-radius:3px; border-top-left-radius:0; } .bp3-slider.bp3-vertical .bp3-slider-handle.bp3-start .bp3-slider-label{ -webkit-transform:translate(20px); transform:translate(20px); } .bp3-slider.bp3-vertical .bp3-slider-handle.bp3-end{ border-bottom-left-radius:0; border-bottom-right-radius:0; border-top-left-radius:3px; margin-bottom:8px; } @-webkit-keyframes pt-spinner-animation{ from{ -webkit-transform:rotate(0deg); transform:rotate(0deg); } to{ -webkit-transform:rotate(360deg); transform:rotate(360deg); } } @keyframes pt-spinner-animation{ from{ -webkit-transform:rotate(0deg); transform:rotate(0deg); } to{ -webkit-transform:rotate(360deg); transform:rotate(360deg); } } .bp3-spinner{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-pack:center; -ms-flex-pack:center; justify-content:center; overflow:visible; vertical-align:middle; } .bp3-spinner svg{ display:block; } .bp3-spinner path{ fill-opacity:0; } .bp3-spinner .bp3-spinner-head{ stroke:rgba(92, 112, 128, 0.8); stroke-linecap:round; -webkit-transform-origin:center; transform-origin:center; -webkit-transition:stroke-dashoffset 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:stroke-dashoffset 200ms cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-spinner .bp3-spinner-track{ stroke:rgba(92, 112, 128, 0.2); } .bp3-spinner-animation{ -webkit-animation:pt-spinner-animation 500ms linear infinite; animation:pt-spinner-animation 500ms linear infinite; } .bp3-no-spin > .bp3-spinner-animation{ -webkit-animation:none; animation:none; } .bp3-dark .bp3-spinner .bp3-spinner-head{ stroke:#8a9ba8; } .bp3-dark .bp3-spinner .bp3-spinner-track{ stroke:rgba(16, 22, 26, 0.5); } .bp3-spinner.bp3-intent-primary .bp3-spinner-head{ stroke:#137cbd; } .bp3-spinner.bp3-intent-success .bp3-spinner-head{ stroke:#0f9960; } .bp3-spinner.bp3-intent-warning .bp3-spinner-head{ stroke:#d9822b; } .bp3-spinner.bp3-intent-danger .bp3-spinner-head{ stroke:#db3737; } .bp3-tabs.bp3-vertical{ display:-webkit-box; display:-ms-flexbox; display:flex; } .bp3-tabs.bp3-vertical > .bp3-tab-list{ -webkit-box-align:start; -ms-flex-align:start; align-items:flex-start; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; } .bp3-tabs.bp3-vertical > .bp3-tab-list .bp3-tab{ border-radius:3px; padding:0 10px; width:100%; } .bp3-tabs.bp3-vertical > .bp3-tab-list .bp3-tab[aria-selected="true"]{ background-color:rgba(19, 124, 189, 0.2); -webkit-box-shadow:none; box-shadow:none; } .bp3-tabs.bp3-vertical > .bp3-tab-list .bp3-tab-indicator-wrapper .bp3-tab-indicator{ background-color:rgba(19, 124, 189, 0.2); border-radius:3px; bottom:0; height:auto; left:0; right:0; top:0; } .bp3-tabs.bp3-vertical > .bp3-tab-panel{ margin-top:0; padding-left:20px; } .bp3-tab-list{ -webkit-box-align:end; -ms-flex-align:end; align-items:flex-end; border:none; display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; list-style:none; margin:0; padding:0; position:relative; } .bp3-tab-list > *:not(:last-child){ margin-right:20px; } .bp3-tab{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; color:#182026; cursor:pointer; -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; font-size:14px; line-height:30px; max-width:100%; position:relative; vertical-align:top; } .bp3-tab a{ color:inherit; display:block; text-decoration:none; } .bp3-tab-indicator-wrapper ~ .bp3-tab{ background-color:transparent !important; -webkit-box-shadow:none !important; box-shadow:none !important; } .bp3-tab[aria-disabled="true"]{ color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-tab[aria-selected="true"]{ border-radius:0; -webkit-box-shadow:inset 0 -3px 0 #106ba3; box-shadow:inset 0 -3px 0 #106ba3; } .bp3-tab[aria-selected="true"], .bp3-tab:not([aria-disabled="true"]):hover{ color:#106ba3; } .bp3-tab:focus{ -moz-outline-radius:0; } .bp3-large > .bp3-tab{ font-size:16px; line-height:40px; } .bp3-tab-panel{ margin-top:20px; } .bp3-tab-panel[aria-hidden="true"]{ display:none; } .bp3-tab-indicator-wrapper{ left:0; pointer-events:none; position:absolute; top:0; -webkit-transform:translateX(0), translateY(0); transform:translateX(0), translateY(0); -webkit-transition:height, width, -webkit-transform; transition:height, width, -webkit-transform; transition:height, transform, width; transition:height, transform, width, -webkit-transform; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-tab-indicator-wrapper .bp3-tab-indicator{ background-color:#106ba3; bottom:0; height:3px; left:0; position:absolute; right:0; } .bp3-tab-indicator-wrapper.bp3-no-animation{ -webkit-transition:none; transition:none; } .bp3-dark .bp3-tab{ color:#f5f8fa; } .bp3-dark .bp3-tab[aria-disabled="true"]{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-tab[aria-selected="true"]{ -webkit-box-shadow:inset 0 -3px 0 #48aff0; box-shadow:inset 0 -3px 0 #48aff0; } .bp3-dark .bp3-tab[aria-selected="true"], .bp3-dark .bp3-tab:not([aria-disabled="true"]):hover{ color:#48aff0; } .bp3-dark .bp3-tab-indicator{ background-color:#48aff0; } .bp3-flex-expander{ -webkit-box-flex:1; -ms-flex:1 1; flex:1 1; } .bp3-tag{ display:-webkit-inline-box; display:-ms-inline-flexbox; display:inline-flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:center; -ms-flex-align:center; align-items:center; background-color:#5c7080; border:none; border-radius:3px; -webkit-box-shadow:none; box-shadow:none; color:#f5f8fa; font-size:12px; line-height:16px; max-width:100%; min-height:20px; min-width:20px; padding:2px 6px; position:relative; } .bp3-tag.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-interactive:hover{ background-color:rgba(92, 112, 128, 0.85); } .bp3-tag.bp3-interactive.bp3-active, .bp3-tag.bp3-interactive:active{ background-color:rgba(92, 112, 128, 0.7); } .bp3-tag > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-tag > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-tag::before, .bp3-tag > *{ margin-right:4px; } .bp3-tag:empty::before, .bp3-tag > :last-child{ margin-right:0; } .bp3-tag:focus{ outline:rgba(19, 124, 189, 0.6) auto 2px; outline-offset:0; -moz-outline-radius:6px; } .bp3-tag.bp3-round{ border-radius:30px; padding-left:8px; padding-right:8px; } .bp3-dark .bp3-tag{ background-color:#bfccd6; color:#182026; } .bp3-dark .bp3-tag.bp3-interactive{ cursor:pointer; } .bp3-dark .bp3-tag.bp3-interactive:hover{ background-color:rgba(191, 204, 214, 0.85); } .bp3-dark .bp3-tag.bp3-interactive.bp3-active, .bp3-dark .bp3-tag.bp3-interactive:active{ background-color:rgba(191, 204, 214, 0.7); } .bp3-dark .bp3-tag > .bp3-icon, .bp3-dark .bp3-tag .bp3-icon-standard, .bp3-dark .bp3-tag .bp3-icon-large{ fill:currentColor; } .bp3-tag > .bp3-icon, .bp3-tag .bp3-icon-standard, .bp3-tag .bp3-icon-large{ fill:#ffffff; } .bp3-tag.bp3-large, .bp3-large .bp3-tag{ font-size:14px; line-height:20px; min-height:30px; min-width:30px; padding:5px 10px; } .bp3-tag.bp3-large::before, .bp3-tag.bp3-large > *, .bp3-large .bp3-tag::before, .bp3-large .bp3-tag > *{ margin-right:7px; } .bp3-tag.bp3-large:empty::before, .bp3-tag.bp3-large > :last-child, .bp3-large .bp3-tag:empty::before, .bp3-large .bp3-tag > :last-child{ margin-right:0; } .bp3-tag.bp3-large.bp3-round, .bp3-large .bp3-tag.bp3-round{ padding-left:12px; padding-right:12px; } .bp3-tag.bp3-intent-primary{ background:#137cbd; color:#ffffff; } .bp3-tag.bp3-intent-primary.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-intent-primary.bp3-interactive:hover{ background-color:rgba(19, 124, 189, 0.85); } .bp3-tag.bp3-intent-primary.bp3-interactive.bp3-active, .bp3-tag.bp3-intent-primary.bp3-interactive:active{ background-color:rgba(19, 124, 189, 0.7); } .bp3-tag.bp3-intent-success{ background:#0f9960; color:#ffffff; } .bp3-tag.bp3-intent-success.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-intent-success.bp3-interactive:hover{ background-color:rgba(15, 153, 96, 0.85); } .bp3-tag.bp3-intent-success.bp3-interactive.bp3-active, .bp3-tag.bp3-intent-success.bp3-interactive:active{ background-color:rgba(15, 153, 96, 0.7); } .bp3-tag.bp3-intent-warning{ background:#d9822b; color:#ffffff; } .bp3-tag.bp3-intent-warning.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-intent-warning.bp3-interactive:hover{ background-color:rgba(217, 130, 43, 0.85); } .bp3-tag.bp3-intent-warning.bp3-interactive.bp3-active, .bp3-tag.bp3-intent-warning.bp3-interactive:active{ background-color:rgba(217, 130, 43, 0.7); } .bp3-tag.bp3-intent-danger{ background:#db3737; color:#ffffff; } .bp3-tag.bp3-intent-danger.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-intent-danger.bp3-interactive:hover{ background-color:rgba(219, 55, 55, 0.85); } .bp3-tag.bp3-intent-danger.bp3-interactive.bp3-active, .bp3-tag.bp3-intent-danger.bp3-interactive:active{ background-color:rgba(219, 55, 55, 0.7); } .bp3-tag.bp3-fill{ display:-webkit-box; display:-ms-flexbox; display:flex; width:100%; } .bp3-tag.bp3-minimal > .bp3-icon, .bp3-tag.bp3-minimal .bp3-icon-standard, .bp3-tag.bp3-minimal .bp3-icon-large{ fill:#5c7080; } .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]){ background-color:rgba(138, 155, 168, 0.2); color:#182026; } .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive:hover{ background-color:rgba(92, 112, 128, 0.3); } .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive.bp3-active, .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive:active{ background-color:rgba(92, 112, 128, 0.4); } .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]){ color:#f5f8fa; } .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive{ cursor:pointer; } .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive:hover{ background-color:rgba(191, 204, 214, 0.3); } .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive.bp3-active, .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]).bp3-interactive:active{ background-color:rgba(191, 204, 214, 0.4); } .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]) > .bp3-icon, .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]) .bp3-icon-standard, .bp3-dark .bp3-tag.bp3-minimal:not([class*="bp3-intent-"]) .bp3-icon-large{ fill:#a7b6c2; } .bp3-tag.bp3-minimal.bp3-intent-primary{ background-color:rgba(19, 124, 189, 0.15); color:#106ba3; } .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive:hover{ background-color:rgba(19, 124, 189, 0.25); } .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive.bp3-active, .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive:active{ background-color:rgba(19, 124, 189, 0.35); } .bp3-tag.bp3-minimal.bp3-intent-primary > .bp3-icon, .bp3-tag.bp3-minimal.bp3-intent-primary .bp3-icon-standard, .bp3-tag.bp3-minimal.bp3-intent-primary .bp3-icon-large{ fill:#137cbd; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-primary{ background-color:rgba(19, 124, 189, 0.25); color:#48aff0; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive{ cursor:pointer; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive:hover{ background-color:rgba(19, 124, 189, 0.35); } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive.bp3-active, .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-primary.bp3-interactive:active{ background-color:rgba(19, 124, 189, 0.45); } .bp3-tag.bp3-minimal.bp3-intent-success{ background-color:rgba(15, 153, 96, 0.15); color:#0d8050; } .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive:hover{ background-color:rgba(15, 153, 96, 0.25); } .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive.bp3-active, .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive:active{ background-color:rgba(15, 153, 96, 0.35); } .bp3-tag.bp3-minimal.bp3-intent-success > .bp3-icon, .bp3-tag.bp3-minimal.bp3-intent-success .bp3-icon-standard, .bp3-tag.bp3-minimal.bp3-intent-success .bp3-icon-large{ fill:#0f9960; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-success{ background-color:rgba(15, 153, 96, 0.25); color:#3dcc91; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive{ cursor:pointer; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive:hover{ background-color:rgba(15, 153, 96, 0.35); } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive.bp3-active, .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-success.bp3-interactive:active{ background-color:rgba(15, 153, 96, 0.45); } .bp3-tag.bp3-minimal.bp3-intent-warning{ background-color:rgba(217, 130, 43, 0.15); color:#bf7326; } .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive:hover{ background-color:rgba(217, 130, 43, 0.25); } .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive.bp3-active, .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive:active{ background-color:rgba(217, 130, 43, 0.35); } .bp3-tag.bp3-minimal.bp3-intent-warning > .bp3-icon, .bp3-tag.bp3-minimal.bp3-intent-warning .bp3-icon-standard, .bp3-tag.bp3-minimal.bp3-intent-warning .bp3-icon-large{ fill:#d9822b; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-warning{ background-color:rgba(217, 130, 43, 0.25); color:#ffb366; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive{ cursor:pointer; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive:hover{ background-color:rgba(217, 130, 43, 0.35); } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive.bp3-active, .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-warning.bp3-interactive:active{ background-color:rgba(217, 130, 43, 0.45); } .bp3-tag.bp3-minimal.bp3-intent-danger{ background-color:rgba(219, 55, 55, 0.15); color:#c23030; } .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive{ cursor:pointer; } .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive:hover{ background-color:rgba(219, 55, 55, 0.25); } .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive.bp3-active, .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive:active{ background-color:rgba(219, 55, 55, 0.35); } .bp3-tag.bp3-minimal.bp3-intent-danger > .bp3-icon, .bp3-tag.bp3-minimal.bp3-intent-danger .bp3-icon-standard, .bp3-tag.bp3-minimal.bp3-intent-danger .bp3-icon-large{ fill:#db3737; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-danger{ background-color:rgba(219, 55, 55, 0.25); color:#ff7373; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive{ cursor:pointer; } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive:hover{ background-color:rgba(219, 55, 55, 0.35); } .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive.bp3-active, .bp3-dark .bp3-tag.bp3-minimal.bp3-intent-danger.bp3-interactive:active{ background-color:rgba(219, 55, 55, 0.45); } .bp3-tag-remove{ background:none; border:none; color:inherit; cursor:pointer; display:-webkit-box; display:-ms-flexbox; display:flex; margin-bottom:-2px; margin-right:-6px !important; margin-top:-2px; opacity:0.5; padding:2px; padding-left:0; } .bp3-tag-remove:hover{ background:none; opacity:0.8; text-decoration:none; } .bp3-tag-remove:active{ opacity:1; } .bp3-tag-remove:empty::before{ font-family:"Icons16", sans-serif; font-size:16px; font-style:normal; font-weight:400; line-height:1; -moz-osx-font-smoothing:grayscale; -webkit-font-smoothing:antialiased; content:""; } .bp3-large .bp3-tag-remove{ margin-right:-10px !important; padding:0 5px 0 0; } .bp3-large .bp3-tag-remove:empty::before{ font-family:"Icons20", sans-serif; font-size:20px; font-style:normal; font-weight:400; line-height:1; } .bp3-tag-input{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:start; -ms-flex-align:start; align-items:flex-start; cursor:text; height:auto; line-height:inherit; min-height:30px; padding-left:5px; padding-right:0; } .bp3-tag-input > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-tag-input > .bp3-tag-input-values{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-tag-input .bp3-tag-input-icon{ color:#5c7080; margin-left:2px; margin-right:7px; margin-top:7px; } .bp3-tag-input .bp3-tag-input-values{ display:-webkit-box; display:-ms-flexbox; display:flex; -webkit-box-orient:horizontal; -webkit-box-direction:normal; -ms-flex-direction:row; flex-direction:row; -webkit-box-align:center; -ms-flex-align:center; align-items:center; -ms-flex-item-align:stretch; align-self:stretch; -ms-flex-wrap:wrap; flex-wrap:wrap; margin-right:7px; margin-top:5px; min-width:0; } .bp3-tag-input .bp3-tag-input-values > *{ -webkit-box-flex:0; -ms-flex-positive:0; flex-grow:0; -ms-flex-negative:0; flex-shrink:0; } .bp3-tag-input .bp3-tag-input-values > .bp3-fill{ -webkit-box-flex:1; -ms-flex-positive:1; flex-grow:1; -ms-flex-negative:1; flex-shrink:1; } .bp3-tag-input .bp3-tag-input-values::before, .bp3-tag-input .bp3-tag-input-values > *{ margin-right:5px; } .bp3-tag-input .bp3-tag-input-values:empty::before, .bp3-tag-input .bp3-tag-input-values > :last-child{ margin-right:0; } .bp3-tag-input .bp3-tag-input-values:first-child .bp3-input-ghost:first-child{ padding-left:5px; } .bp3-tag-input .bp3-tag-input-values > *{ margin-bottom:5px; } .bp3-tag-input .bp3-tag{ overflow-wrap:break-word; } .bp3-tag-input .bp3-tag.bp3-active{ outline:rgba(19, 124, 189, 0.6) auto 2px; outline-offset:0; -moz-outline-radius:6px; } .bp3-tag-input .bp3-input-ghost{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; line-height:20px; width:80px; } .bp3-tag-input .bp3-input-ghost:disabled, .bp3-tag-input .bp3-input-ghost.bp3-disabled{ cursor:not-allowed; } .bp3-tag-input .bp3-button, .bp3-tag-input .bp3-spinner{ margin:3px; margin-left:0; } .bp3-tag-input .bp3-button{ min-height:24px; min-width:24px; padding:0 7px; } .bp3-tag-input.bp3-large{ height:auto; min-height:40px; } .bp3-tag-input.bp3-large::before, .bp3-tag-input.bp3-large > *{ margin-right:10px; } .bp3-tag-input.bp3-large:empty::before, .bp3-tag-input.bp3-large > :last-child{ margin-right:0; } .bp3-tag-input.bp3-large .bp3-tag-input-icon{ margin-left:5px; margin-top:10px; } .bp3-tag-input.bp3-large .bp3-input-ghost{ line-height:30px; } .bp3-tag-input.bp3-large .bp3-button{ min-height:30px; min-width:30px; padding:5px 10px; margin:5px; margin-left:0; } .bp3-tag-input.bp3-large .bp3-spinner{ margin:8px; margin-left:0; } .bp3-tag-input.bp3-active{ background-color:#ffffff; -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-tag-input.bp3-active.bp3-intent-primary{ -webkit-box-shadow:0 0 0 1px #106ba3, 0 0 0 3px rgba(16, 107, 163, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #106ba3, 0 0 0 3px rgba(16, 107, 163, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-tag-input.bp3-active.bp3-intent-success{ -webkit-box-shadow:0 0 0 1px #0d8050, 0 0 0 3px rgba(13, 128, 80, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #0d8050, 0 0 0 3px rgba(13, 128, 80, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-tag-input.bp3-active.bp3-intent-warning{ -webkit-box-shadow:0 0 0 1px #bf7326, 0 0 0 3px rgba(191, 115, 38, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #bf7326, 0 0 0 3px rgba(191, 115, 38, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-tag-input.bp3-active.bp3-intent-danger{ -webkit-box-shadow:0 0 0 1px #c23030, 0 0 0 3px rgba(194, 48, 48, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px #c23030, 0 0 0 3px rgba(194, 48, 48, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.2); } .bp3-dark .bp3-tag-input .bp3-tag-input-icon, .bp3-tag-input.bp3-dark .bp3-tag-input-icon{ color:#a7b6c2; } .bp3-dark .bp3-tag-input .bp3-input-ghost, .bp3-tag-input.bp3-dark .bp3-input-ghost{ color:#f5f8fa; } .bp3-dark .bp3-tag-input .bp3-input-ghost::-webkit-input-placeholder, .bp3-tag-input.bp3-dark .bp3-input-ghost::-webkit-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-tag-input .bp3-input-ghost::-moz-placeholder, .bp3-tag-input.bp3-dark .bp3-input-ghost::-moz-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-tag-input .bp3-input-ghost:-ms-input-placeholder, .bp3-tag-input.bp3-dark .bp3-input-ghost:-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-tag-input .bp3-input-ghost::-ms-input-placeholder, .bp3-tag-input.bp3-dark .bp3-input-ghost::-ms-input-placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-tag-input .bp3-input-ghost::placeholder, .bp3-tag-input.bp3-dark .bp3-input-ghost::placeholder{ color:rgba(167, 182, 194, 0.6); } .bp3-dark .bp3-tag-input.bp3-active, .bp3-tag-input.bp3-dark.bp3-active{ background-color:rgba(16, 22, 26, 0.3); -webkit-box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #137cbd, 0 0 0 1px #137cbd, 0 0 0 3px rgba(19, 124, 189, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-tag-input.bp3-active.bp3-intent-primary, .bp3-tag-input.bp3-dark.bp3-active.bp3-intent-primary{ -webkit-box-shadow:0 0 0 1px #106ba3, 0 0 0 3px rgba(16, 107, 163, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #106ba3, 0 0 0 3px rgba(16, 107, 163, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-tag-input.bp3-active.bp3-intent-success, .bp3-tag-input.bp3-dark.bp3-active.bp3-intent-success{ -webkit-box-shadow:0 0 0 1px #0d8050, 0 0 0 3px rgba(13, 128, 80, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #0d8050, 0 0 0 3px rgba(13, 128, 80, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-tag-input.bp3-active.bp3-intent-warning, .bp3-tag-input.bp3-dark.bp3-active.bp3-intent-warning{ -webkit-box-shadow:0 0 0 1px #bf7326, 0 0 0 3px rgba(191, 115, 38, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #bf7326, 0 0 0 3px rgba(191, 115, 38, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-dark .bp3-tag-input.bp3-active.bp3-intent-danger, .bp3-tag-input.bp3-dark.bp3-active.bp3-intent-danger{ -webkit-box-shadow:0 0 0 1px #c23030, 0 0 0 3px rgba(194, 48, 48, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px #c23030, 0 0 0 3px rgba(194, 48, 48, 0.3), inset 0 0 0 1px rgba(16, 22, 26, 0.3), inset 0 1px 1px rgba(16, 22, 26, 0.4); } .bp3-input-ghost{ background:none; border:none; -webkit-box-shadow:none; box-shadow:none; padding:0; } .bp3-input-ghost::-webkit-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input-ghost::-moz-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input-ghost:-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input-ghost::-ms-input-placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input-ghost::placeholder{ color:rgba(92, 112, 128, 0.6); opacity:1; } .bp3-input-ghost:focus{ outline:none !important; } .bp3-toast{ -webkit-box-align:start; -ms-flex-align:start; align-items:flex-start; background-color:#ffffff; border-radius:3px; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); display:-webkit-box; display:-ms-flexbox; display:flex; margin:20px 0 0; max-width:500px; min-width:300px; pointer-events:all; position:relative !important; } .bp3-toast.bp3-toast-enter, .bp3-toast.bp3-toast-appear{ -webkit-transform:translateY(-40px); transform:translateY(-40px); } .bp3-toast.bp3-toast-enter-active, .bp3-toast.bp3-toast-appear-active{ -webkit-transform:translateY(0); transform:translateY(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:300ms; transition-duration:300ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); } .bp3-toast.bp3-toast-enter ~ .bp3-toast, .bp3-toast.bp3-toast-appear ~ .bp3-toast{ -webkit-transform:translateY(-40px); transform:translateY(-40px); } .bp3-toast.bp3-toast-enter-active ~ .bp3-toast, .bp3-toast.bp3-toast-appear-active ~ .bp3-toast{ -webkit-transform:translateY(0); transform:translateY(0); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:300ms; transition-duration:300ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); transition-timing-function:cubic-bezier(0.54, 1.12, 0.38, 1.11); } .bp3-toast.bp3-toast-exit{ opacity:1; -webkit-filter:blur(0); filter:blur(0); } .bp3-toast.bp3-toast-exit-active{ opacity:0; -webkit-filter:blur(10px); filter:blur(10px); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:300ms; transition-duration:300ms; -webkit-transition-property:opacity, -webkit-filter; transition-property:opacity, -webkit-filter; transition-property:opacity, filter; transition-property:opacity, filter, -webkit-filter; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-toast.bp3-toast-exit ~ .bp3-toast{ -webkit-transform:translateY(0); transform:translateY(0); } .bp3-toast.bp3-toast-exit-active ~ .bp3-toast{ -webkit-transform:translateY(-40px); transform:translateY(-40px); -webkit-transition-delay:50ms; transition-delay:50ms; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-toast .bp3-button-group{ -webkit-box-flex:0; -ms-flex:0 0 auto; flex:0 0 auto; padding:5px; padding-left:0; } .bp3-toast > .bp3-icon{ color:#5c7080; margin:12px; margin-right:0; } .bp3-toast.bp3-dark, .bp3-dark .bp3-toast{ background-color:#394b59; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); } .bp3-toast.bp3-dark > .bp3-icon, .bp3-dark .bp3-toast > .bp3-icon{ color:#a7b6c2; } .bp3-toast[class*="bp3-intent-"] a{ color:rgba(255, 255, 255, 0.7); } .bp3-toast[class*="bp3-intent-"] a:hover{ color:#ffffff; } .bp3-toast[class*="bp3-intent-"] > .bp3-icon{ color:#ffffff; } .bp3-toast[class*="bp3-intent-"] .bp3-button, .bp3-toast[class*="bp3-intent-"] .bp3-button::before, .bp3-toast[class*="bp3-intent-"] .bp3-button .bp3-icon, .bp3-toast[class*="bp3-intent-"] .bp3-button:active{ color:rgba(255, 255, 255, 0.7) !important; } .bp3-toast[class*="bp3-intent-"] .bp3-button:focus{ outline-color:rgba(255, 255, 255, 0.5); } .bp3-toast[class*="bp3-intent-"] .bp3-button:hover{ background-color:rgba(255, 255, 255, 0.15) !important; color:#ffffff !important; } .bp3-toast[class*="bp3-intent-"] .bp3-button:active{ background-color:rgba(255, 255, 255, 0.3) !important; color:#ffffff !important; } .bp3-toast[class*="bp3-intent-"] .bp3-button::after{ background:rgba(255, 255, 255, 0.3) !important; } .bp3-toast.bp3-intent-primary{ background-color:#137cbd; color:#ffffff; } .bp3-toast.bp3-intent-success{ background-color:#0f9960; color:#ffffff; } .bp3-toast.bp3-intent-warning{ background-color:#d9822b; color:#ffffff; } .bp3-toast.bp3-intent-danger{ background-color:#db3737; color:#ffffff; } .bp3-toast-message{ -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; padding:11px; word-break:break-word; } .bp3-toast-container{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box !important; display:-ms-flexbox !important; display:flex !important; -webkit-box-orient:vertical; -webkit-box-direction:normal; -ms-flex-direction:column; flex-direction:column; left:0; overflow:hidden; padding:0 20px 20px; pointer-events:none; right:0; z-index:40; } .bp3-toast-container.bp3-toast-container-in-portal{ position:fixed; } .bp3-toast-container.bp3-toast-container-inline{ position:absolute; } .bp3-toast-container.bp3-toast-container-top{ top:0; } .bp3-toast-container.bp3-toast-container-bottom{ bottom:0; -webkit-box-orient:vertical; -webkit-box-direction:reverse; -ms-flex-direction:column-reverse; flex-direction:column-reverse; top:auto; } .bp3-toast-container.bp3-toast-container-left{ -webkit-box-align:start; -ms-flex-align:start; align-items:flex-start; } .bp3-toast-container.bp3-toast-container-right{ -webkit-box-align:end; -ms-flex-align:end; align-items:flex-end; } .bp3-toast-container-bottom .bp3-toast.bp3-toast-enter:not(.bp3-toast-enter-active), .bp3-toast-container-bottom .bp3-toast.bp3-toast-enter:not(.bp3-toast-enter-active) ~ .bp3-toast, .bp3-toast-container-bottom .bp3-toast.bp3-toast-appear:not(.bp3-toast-appear-active), .bp3-toast-container-bottom .bp3-toast.bp3-toast-appear:not(.bp3-toast-appear-active) ~ .bp3-toast, .bp3-toast-container-bottom .bp3-toast.bp3-toast-exit-active ~ .bp3-toast, .bp3-toast-container-bottom .bp3-toast.bp3-toast-leave-active ~ .bp3-toast{ -webkit-transform:translateY(60px); transform:translateY(60px); } .bp3-tooltip{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 2px 4px rgba(16, 22, 26, 0.2), 0 8px 24px rgba(16, 22, 26, 0.2); -webkit-transform:scale(1); transform:scale(1); } .bp3-tooltip .bp3-popover-arrow{ height:22px; position:absolute; width:22px; } .bp3-tooltip .bp3-popover-arrow::before{ height:14px; margin:4px; width:14px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-top > .bp3-tooltip{ margin-bottom:11px; margin-top:-11px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-top > .bp3-tooltip > .bp3-popover-arrow{ bottom:-8px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-top > .bp3-tooltip > .bp3-popover-arrow svg{ -webkit-transform:rotate(-90deg); transform:rotate(-90deg); } .bp3-tether-element-attached-left.bp3-tether-target-attached-right > .bp3-tooltip{ margin-left:11px; } .bp3-tether-element-attached-left.bp3-tether-target-attached-right > .bp3-tooltip > .bp3-popover-arrow{ left:-8px; } .bp3-tether-element-attached-left.bp3-tether-target-attached-right > .bp3-tooltip > .bp3-popover-arrow svg{ -webkit-transform:rotate(0); transform:rotate(0); } .bp3-tether-element-attached-top.bp3-tether-target-attached-bottom > .bp3-tooltip{ margin-top:11px; } .bp3-tether-element-attached-top.bp3-tether-target-attached-bottom > .bp3-tooltip > .bp3-popover-arrow{ top:-8px; } .bp3-tether-element-attached-top.bp3-tether-target-attached-bottom > .bp3-tooltip > .bp3-popover-arrow svg{ -webkit-transform:rotate(90deg); transform:rotate(90deg); } .bp3-tether-element-attached-right.bp3-tether-target-attached-left > .bp3-tooltip{ margin-left:-11px; margin-right:11px; } .bp3-tether-element-attached-right.bp3-tether-target-attached-left > .bp3-tooltip > .bp3-popover-arrow{ right:-8px; } .bp3-tether-element-attached-right.bp3-tether-target-attached-left > .bp3-tooltip > .bp3-popover-arrow svg{ -webkit-transform:rotate(180deg); transform:rotate(180deg); } .bp3-tether-element-attached-middle > .bp3-tooltip > .bp3-popover-arrow{ top:50%; -webkit-transform:translateY(-50%); transform:translateY(-50%); } .bp3-tether-element-attached-center > .bp3-tooltip > .bp3-popover-arrow{ right:50%; -webkit-transform:translateX(50%); transform:translateX(50%); } .bp3-tether-element-attached-top.bp3-tether-target-attached-top > .bp3-tooltip > .bp3-popover-arrow{ top:-0.22183px; } .bp3-tether-element-attached-right.bp3-tether-target-attached-right > .bp3-tooltip > .bp3-popover-arrow{ right:-0.22183px; } .bp3-tether-element-attached-left.bp3-tether-target-attached-left > .bp3-tooltip > .bp3-popover-arrow{ left:-0.22183px; } .bp3-tether-element-attached-bottom.bp3-tether-target-attached-bottom > .bp3-tooltip > .bp3-popover-arrow{ bottom:-0.22183px; } .bp3-tether-element-attached-top.bp3-tether-element-attached-left > .bp3-tooltip{ -webkit-transform-origin:top left; transform-origin:top left; } .bp3-tether-element-attached-top.bp3-tether-element-attached-center > .bp3-tooltip{ -webkit-transform-origin:top center; transform-origin:top center; } .bp3-tether-element-attached-top.bp3-tether-element-attached-right > .bp3-tooltip{ -webkit-transform-origin:top right; transform-origin:top right; } .bp3-tether-element-attached-middle.bp3-tether-element-attached-left > .bp3-tooltip{ -webkit-transform-origin:center left; transform-origin:center left; } .bp3-tether-element-attached-middle.bp3-tether-element-attached-center > .bp3-tooltip{ -webkit-transform-origin:center center; transform-origin:center center; } .bp3-tether-element-attached-middle.bp3-tether-element-attached-right > .bp3-tooltip{ -webkit-transform-origin:center right; transform-origin:center right; } .bp3-tether-element-attached-bottom.bp3-tether-element-attached-left > .bp3-tooltip{ -webkit-transform-origin:bottom left; transform-origin:bottom left; } .bp3-tether-element-attached-bottom.bp3-tether-element-attached-center > .bp3-tooltip{ -webkit-transform-origin:bottom center; transform-origin:bottom center; } .bp3-tether-element-attached-bottom.bp3-tether-element-attached-right > .bp3-tooltip{ -webkit-transform-origin:bottom right; transform-origin:bottom right; } .bp3-tooltip .bp3-popover-content{ background:#394b59; color:#f5f8fa; } .bp3-tooltip .bp3-popover-arrow::before{ -webkit-box-shadow:1px 1px 6px rgba(16, 22, 26, 0.2); box-shadow:1px 1px 6px rgba(16, 22, 26, 0.2); } .bp3-tooltip .bp3-popover-arrow-border{ fill:#10161a; fill-opacity:0.1; } .bp3-tooltip .bp3-popover-arrow-fill{ fill:#394b59; } .bp3-popover-enter > .bp3-tooltip, .bp3-popover-appear > .bp3-tooltip{ -webkit-transform:scale(0.8); transform:scale(0.8); } .bp3-popover-enter-active > .bp3-tooltip, .bp3-popover-appear-active > .bp3-tooltip{ -webkit-transform:scale(1); transform:scale(1); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-popover-exit > .bp3-tooltip{ -webkit-transform:scale(1); transform:scale(1); } .bp3-popover-exit-active > .bp3-tooltip{ -webkit-transform:scale(0.8); transform:scale(0.8); -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:100ms; transition-duration:100ms; -webkit-transition-property:-webkit-transform; transition-property:-webkit-transform; transition-property:transform; transition-property:transform, -webkit-transform; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-tooltip .bp3-popover-content{ padding:10px 12px; } .bp3-tooltip.bp3-dark, .bp3-dark .bp3-tooltip{ -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 2px 4px rgba(16, 22, 26, 0.4), 0 8px 24px rgba(16, 22, 26, 0.4); } .bp3-tooltip.bp3-dark .bp3-popover-content, .bp3-dark .bp3-tooltip .bp3-popover-content{ background:#e1e8ed; color:#394b59; } .bp3-tooltip.bp3-dark .bp3-popover-arrow::before, .bp3-dark .bp3-tooltip .bp3-popover-arrow::before{ -webkit-box-shadow:1px 1px 6px rgba(16, 22, 26, 0.4); box-shadow:1px 1px 6px rgba(16, 22, 26, 0.4); } .bp3-tooltip.bp3-dark .bp3-popover-arrow-border, .bp3-dark .bp3-tooltip .bp3-popover-arrow-border{ fill:#10161a; fill-opacity:0.2; } .bp3-tooltip.bp3-dark .bp3-popover-arrow-fill, .bp3-dark .bp3-tooltip .bp3-popover-arrow-fill{ fill:#e1e8ed; } .bp3-tooltip.bp3-intent-primary .bp3-popover-content{ background:#137cbd; color:#ffffff; } .bp3-tooltip.bp3-intent-primary .bp3-popover-arrow-fill{ fill:#137cbd; } .bp3-tooltip.bp3-intent-success .bp3-popover-content{ background:#0f9960; color:#ffffff; } .bp3-tooltip.bp3-intent-success .bp3-popover-arrow-fill{ fill:#0f9960; } .bp3-tooltip.bp3-intent-warning .bp3-popover-content{ background:#d9822b; color:#ffffff; } .bp3-tooltip.bp3-intent-warning .bp3-popover-arrow-fill{ fill:#d9822b; } .bp3-tooltip.bp3-intent-danger .bp3-popover-content{ background:#db3737; color:#ffffff; } .bp3-tooltip.bp3-intent-danger .bp3-popover-arrow-fill{ fill:#db3737; } .bp3-tooltip-indicator{ border-bottom:dotted 1px; cursor:help; } .bp3-tree .bp3-icon, .bp3-tree .bp3-icon-standard, .bp3-tree .bp3-icon-large{ color:#5c7080; } .bp3-tree .bp3-icon.bp3-intent-primary, .bp3-tree .bp3-icon-standard.bp3-intent-primary, .bp3-tree .bp3-icon-large.bp3-intent-primary{ color:#137cbd; } .bp3-tree .bp3-icon.bp3-intent-success, .bp3-tree .bp3-icon-standard.bp3-intent-success, .bp3-tree .bp3-icon-large.bp3-intent-success{ color:#0f9960; } .bp3-tree .bp3-icon.bp3-intent-warning, .bp3-tree .bp3-icon-standard.bp3-intent-warning, .bp3-tree .bp3-icon-large.bp3-intent-warning{ color:#d9822b; } .bp3-tree .bp3-icon.bp3-intent-danger, .bp3-tree .bp3-icon-standard.bp3-intent-danger, .bp3-tree .bp3-icon-large.bp3-intent-danger{ color:#db3737; } .bp3-tree-node-list{ list-style:none; margin:0; padding-left:0; } .bp3-tree-root{ background-color:transparent; cursor:default; padding-left:0; position:relative; } .bp3-tree-node-content-0{ padding-left:0px; } .bp3-tree-node-content-1{ padding-left:23px; } .bp3-tree-node-content-2{ padding-left:46px; } .bp3-tree-node-content-3{ padding-left:69px; } .bp3-tree-node-content-4{ padding-left:92px; } .bp3-tree-node-content-5{ padding-left:115px; } .bp3-tree-node-content-6{ padding-left:138px; } .bp3-tree-node-content-7{ padding-left:161px; } .bp3-tree-node-content-8{ padding-left:184px; } .bp3-tree-node-content-9{ padding-left:207px; } .bp3-tree-node-content-10{ padding-left:230px; } .bp3-tree-node-content-11{ padding-left:253px; } .bp3-tree-node-content-12{ padding-left:276px; } .bp3-tree-node-content-13{ padding-left:299px; } .bp3-tree-node-content-14{ padding-left:322px; } .bp3-tree-node-content-15{ padding-left:345px; } .bp3-tree-node-content-16{ padding-left:368px; } .bp3-tree-node-content-17{ padding-left:391px; } .bp3-tree-node-content-18{ padding-left:414px; } .bp3-tree-node-content-19{ padding-left:437px; } .bp3-tree-node-content-20{ padding-left:460px; } .bp3-tree-node-content{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box; display:-ms-flexbox; display:flex; height:30px; padding-right:5px; width:100%; } .bp3-tree-node-content:hover{ background-color:rgba(191, 204, 214, 0.4); } .bp3-tree-node-caret, .bp3-tree-node-caret-none{ min-width:30px; } .bp3-tree-node-caret{ color:#5c7080; cursor:pointer; padding:7px; -webkit-transform:rotate(0deg); transform:rotate(0deg); -webkit-transition:-webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:-webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); transition:transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9), -webkit-transform 200ms cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-tree-node-caret:hover{ color:#182026; } .bp3-dark .bp3-tree-node-caret{ color:#a7b6c2; } .bp3-dark .bp3-tree-node-caret:hover{ color:#f5f8fa; } .bp3-tree-node-caret.bp3-tree-node-caret-open{ -webkit-transform:rotate(90deg); transform:rotate(90deg); } .bp3-tree-node-caret.bp3-icon-standard::before{ content:""; } .bp3-tree-node-icon{ margin-right:7px; position:relative; } .bp3-tree-node-label{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; word-wrap:normal; -webkit-box-flex:1; -ms-flex:1 1 auto; flex:1 1 auto; position:relative; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; } .bp3-tree-node-label span{ display:inline; } .bp3-tree-node-secondary-label{ padding:0 5px; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; } .bp3-tree-node-secondary-label .bp3-popover-wrapper, .bp3-tree-node-secondary-label .bp3-popover-target{ -webkit-box-align:center; -ms-flex-align:center; align-items:center; display:-webkit-box; display:-ms-flexbox; display:flex; } .bp3-tree-node.bp3-disabled .bp3-tree-node-content{ background-color:inherit; color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-tree-node.bp3-disabled .bp3-tree-node-caret, .bp3-tree-node.bp3-disabled .bp3-tree-node-icon{ color:rgba(92, 112, 128, 0.6); cursor:not-allowed; } .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content{ background-color:#137cbd; } .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content, .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content .bp3-icon, .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content .bp3-icon-standard, .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content .bp3-icon-large{ color:#ffffff; } .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content .bp3-tree-node-caret::before{ color:rgba(255, 255, 255, 0.7); } .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content .bp3-tree-node-caret:hover::before{ color:#ffffff; } .bp3-dark .bp3-tree-node-content:hover{ background-color:rgba(92, 112, 128, 0.3); } .bp3-dark .bp3-tree .bp3-icon, .bp3-dark .bp3-tree .bp3-icon-standard, .bp3-dark .bp3-tree .bp3-icon-large{ color:#a7b6c2; } .bp3-dark .bp3-tree .bp3-icon.bp3-intent-primary, .bp3-dark .bp3-tree .bp3-icon-standard.bp3-intent-primary, .bp3-dark .bp3-tree .bp3-icon-large.bp3-intent-primary{ color:#137cbd; } .bp3-dark .bp3-tree .bp3-icon.bp3-intent-success, .bp3-dark .bp3-tree .bp3-icon-standard.bp3-intent-success, .bp3-dark .bp3-tree .bp3-icon-large.bp3-intent-success{ color:#0f9960; } .bp3-dark .bp3-tree .bp3-icon.bp3-intent-warning, .bp3-dark .bp3-tree .bp3-icon-standard.bp3-intent-warning, .bp3-dark .bp3-tree .bp3-icon-large.bp3-intent-warning{ color:#d9822b; } .bp3-dark .bp3-tree .bp3-icon.bp3-intent-danger, .bp3-dark .bp3-tree .bp3-icon-standard.bp3-intent-danger, .bp3-dark .bp3-tree .bp3-icon-large.bp3-intent-danger{ color:#db3737; } .bp3-dark .bp3-tree-node.bp3-tree-node-selected > .bp3-tree-node-content{ background-color:#137cbd; } .bp3-omnibar{ -webkit-filter:blur(0); filter:blur(0); opacity:1; background-color:#ffffff; border-radius:3px; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.1), 0 4px 8px rgba(16, 22, 26, 0.2), 0 18px 46px 6px rgba(16, 22, 26, 0.2); left:calc(50% - 250px); top:20vh; width:500px; z-index:21; } .bp3-omnibar.bp3-overlay-enter, .bp3-omnibar.bp3-overlay-appear{ -webkit-filter:blur(20px); filter:blur(20px); opacity:0.2; } .bp3-omnibar.bp3-overlay-enter-active, .bp3-omnibar.bp3-overlay-appear-active{ -webkit-filter:blur(0); filter:blur(0); opacity:1; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:opacity, -webkit-filter; transition-property:opacity, -webkit-filter; transition-property:filter, opacity; transition-property:filter, opacity, -webkit-filter; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-omnibar.bp3-overlay-exit{ -webkit-filter:blur(0); filter:blur(0); opacity:1; } .bp3-omnibar.bp3-overlay-exit-active{ -webkit-filter:blur(20px); filter:blur(20px); opacity:0.2; -webkit-transition-delay:0; transition-delay:0; -webkit-transition-duration:200ms; transition-duration:200ms; -webkit-transition-property:opacity, -webkit-filter; transition-property:opacity, -webkit-filter; transition-property:filter, opacity; transition-property:filter, opacity, -webkit-filter; -webkit-transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); transition-timing-function:cubic-bezier(0.4, 1, 0.75, 0.9); } .bp3-omnibar .bp3-input{ background-color:transparent; border-radius:0; } .bp3-omnibar .bp3-input, .bp3-omnibar .bp3-input:focus{ -webkit-box-shadow:none; box-shadow:none; } .bp3-omnibar .bp3-menu{ background-color:transparent; border-radius:0; -webkit-box-shadow:inset 0 1px 0 rgba(16, 22, 26, 0.15); box-shadow:inset 0 1px 0 rgba(16, 22, 26, 0.15); max-height:calc(60vh - 40px); overflow:auto; } .bp3-omnibar .bp3-menu:empty{ display:none; } .bp3-dark .bp3-omnibar, .bp3-omnibar.bp3-dark{ background-color:#30404d; -webkit-box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); box-shadow:0 0 0 1px rgba(16, 22, 26, 0.2), 0 4px 8px rgba(16, 22, 26, 0.4), 0 18px 46px 6px rgba(16, 22, 26, 0.4); } .bp3-omnibar-overlay .bp3-overlay-backdrop{ background-color:rgba(16, 22, 26, 0.2); } .bp3-select-popover .bp3-popover-content{ padding:5px; } .bp3-select-popover .bp3-input-group{ margin-bottom:0; } .bp3-select-popover .bp3-menu{ max-height:300px; max-width:400px; overflow:auto; padding:0; } .bp3-select-popover .bp3-menu:not(:first-child){ padding-top:5px; } .bp3-multi-select{ min-width:150px; } .bp3-multi-select-popover .bp3-menu{ max-height:300px; max-width:400px; overflow:auto; } .bp3-select-popover .bp3-popover-content{ padding:5px; } .bp3-select-popover .bp3-input-group{ margin-bottom:0; } .bp3-select-popover .bp3-menu{ max-height:300px; max-width:400px; overflow:auto; padding:0; } .bp3-select-popover .bp3-menu:not(:first-child){ padding-top:5px; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /* This file was auto-generated by ensureUiComponents() in @jupyterlab/buildutils */ /** * (DEPRECATED) Support for consuming icons as CSS background images */ /* Icons urls */ :root { --jp-icon-add: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTE5IDEzaC02djZoLTJ2LTZINXYtMmg2VjVoMnY2aDZ2MnoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-bug: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIj4KICAgIDxwYXRoIGQ9Ik0yMCA4aC0yLjgxYy0uNDUtLjc4LTEuMDctMS40NS0xLjgyLTEuOTZMMTcgNC40MSAxNS41OSAzbC0yLjE3IDIuMTdDMTIuOTYgNS4wNiAxMi40OSA1IDEyIDVjLS40OSAwLS45Ni4wNi0xLjQxLjE3TDguNDEgMyA3IDQuNDFsMS42MiAxLjYzQzcuODggNi41NSA3LjI2IDcuMjIgNi44MSA4SDR2MmgyLjA5Yy0uMDUuMzMtLjA5LjY2LS4wOSAxdjFINHYyaDJ2MWMwIC4zNC4wNC42Ny4wOSAxSDR2MmgyLjgxYzEuMDQgMS43OSAyLjk3IDMgNS4xOSAzczQuMTUtMS4yMSA1LjE5LTNIMjB2LTJoLTIuMDljLjA1LS4zMy4wOS0uNjYuMDktMXYtMWgydi0yaC0ydi0xYzAtLjM0LS4wNC0uNjctLjA5LTFIMjBWOHptLTYgOGgtNHYtMmg0djJ6bTAtNGgtNHYtMmg0djJ6Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-build: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTE0LjkgMTcuNDVDMTYuMjUgMTcuNDUgMTcuMzUgMTYuMzUgMTcuMzUgMTVDMTcuMzUgMTMuNjUgMTYuMjUgMTIuNTUgMTQuOSAxMi41NUMxMy41NCAxMi41NSAxMi40NSAxMy42NSAxMi40NSAxNUMxMi40NSAxNi4zNSAxMy41NCAxNy40NSAxNC45IDE3LjQ1Wk0yMC4xIDE1LjY4TDIxLjU4IDE2Ljg0QzIxLjcxIDE2Ljk1IDIxLjc1IDE3LjEzIDIxLjY2IDE3LjI5TDIwLjI2IDE5LjcxQzIwLjE3IDE5Ljg2IDIwIDE5LjkyIDE5LjgzIDE5Ljg2TDE4LjA5IDE5LjE2QzE3LjczIDE5LjQ0IDE3LjMzIDE5LjY3IDE2LjkxIDE5Ljg1TDE2LjY0IDIxLjdDMTYuNjIgMjEuODcgMTYuNDcgMjIgMTYuMyAyMkgxMy41QzEzLjMyIDIyIDEzLjE4IDIxLjg3IDEzLjE1IDIxLjdMMTIuODkgMTkuODVDMTIuNDYgMTkuNjcgMTIuMDcgMTkuNDQgMTEuNzEgMTkuMTZMOS45NjAwMiAxOS44NkM5LjgxMDAyIDE5LjkyIDkuNjIwMDIgMTkuODYgOS41NDAwMiAxOS43MUw4LjE0MDAyIDE3LjI5QzguMDUwMDIgMTcuMTMgOC4wOTAwMiAxNi45NSA4LjIyMDAyIDE2Ljg0TDkuNzAwMDIgMTUuNjhMOS42NTAwMSAxNUw5LjcwMDAyIDE0LjMxTDguMjIwMDIgMTMuMTZDOC4wOTAwMiAxMy4wNSA4LjA1MDAyIDEyLjg2IDguMTQwMDIgMTIuNzFMOS41NDAwMiAxMC4yOUM5LjYyMDAyIDEwLjEzIDkuODEwMDIgMTAuMDcgOS45NjAwMiAxMC4xM0wxMS43MSAxMC44NEMxMi4wNyAxMC41NiAxMi40NiAxMC4zMiAxMi44OSAxMC4xNUwxMy4xNSA4LjI4OTk4QzEzLjE4IDguMTI5OTggMTMuMzIgNy45OTk5OCAxMy41IDcuOTk5OThIMTYuM0MxNi40NyA3Ljk5OTk4IDE2LjYyIDguMTI5OTggMTYuNjQgOC4yODk5OEwxNi45MSAxMC4xNUMxNy4zMyAxMC4zMiAxNy43MyAxMC41NiAxOC4wOSAxMC44NEwxOS44MyAxMC4xM0MyMCAxMC4wNyAyMC4xNyAxMC4xMyAyMC4yNiAxMC4yOUwyMS42NiAxMi43MUMyMS43NSAxMi44NiAyMS43MSAxMy4wNSAyMS41OCAxMy4xNkwyMC4xIDE0LjMxTDIwLjE1IDE1TDIwLjEgMTUuNjhaIi8+CiAgICA8cGF0aCBkPSJNNy4zMjk2NiA3LjQ0NDU0QzguMDgzMSA3LjAwOTU0IDguMzM5MzIgNi4wNTMzMiA3LjkwNDMyIDUuMjk5ODhDNy40NjkzMiA0LjU0NjQzIDYuNTA4MSA0LjI4MTU2IDUuNzU0NjYgNC43MTY1NkM1LjM5MTc2IDQuOTI2MDggNS4xMjY5NSA1LjI3MTE4IDUuMDE4NDkgNS42NzU5NEM0LjkxMDA0IDYuMDgwNzEgNC45NjY4MiA2LjUxMTk4IDUuMTc2MzQgNi44NzQ4OEM1LjYxMTM0IDcuNjI4MzIgNi41NzYyMiA3Ljg3OTU0IDcuMzI5NjYgNy40NDQ1NFpNOS42NTcxOCA0Ljc5NTkzTDEwLjg2NzIgNC45NTE3OUMxMC45NjI4IDQuOTc3NDEgMTEuMDQwMiA1LjA3MTMzIDExLjAzODIgNS4xODc5M0wxMS4wMzg4IDYuOTg4OTNDMTEuMDQ1NSA3LjEwMDU0IDEwLjk2MTYgNy4xOTUxOCAxMC44NTUgNy4yMTA1NEw5LjY2MDAxIDcuMzgwODNMOS4yMzkxNSA4LjEzMTg4TDkuNjY5NjEgOS4yNTc0NUM5LjcwNzI5IDkuMzYyNzEgOS42NjkzNCA5LjQ3Njk5IDkuNTc0MDggOS41MzE5OUw4LjAxNTIzIDEwLjQzMkM3LjkxMTMxIDEwLjQ5MiA3Ljc5MzM3IDEwLjQ2NzcgNy43MjEwNSAxMC4zODI0TDYuOTg3NDggOS40MzE4OEw2LjEwOTMxIDkuNDMwODNMNS4zNDcwNCAxMC4zOTA1QzUuMjg5MDkgMTAuNDcwMiA1LjE3MzgzIDEwLjQ5MDUgNS4wNzE4NyAxMC40MzM5TDMuNTEyNDUgOS41MzI5M0MzLjQxMDQ5IDkuNDc2MzMgMy4zNzY0NyA5LjM1NzQxIDMuNDEwNzUgOS4yNTY3OUwzLjg2MzQ3IDguMTQwOTNMMy42MTc0OSA3Ljc3NDg4TDMuNDIzNDcgNy4zNzg4M0wyLjIzMDc1IDcuMjEyOTdDMi4xMjY0NyA3LjE5MjM1IDIuMDQwNDkgNy4xMDM0MiAyLjA0MjQ1IDYuOTg2ODJMMi4wNDE4NyA1LjE4NTgyQzIuMDQzODMgNS4wNjkyMiAyLjExOTA5IDQuOTc5NTggMi4yMTcwNCA0Ljk2OTIyTDMuNDIwNjUgNC43OTM5M0wzLjg2NzQ5IDQuMDI3ODhMMy40MTEwNSAyLjkxNzMxQzMuMzczMzcgMi44MTIwNCAzLjQxMTMxIDIuNjk3NzYgMy41MTUyMyAyLjYzNzc2TDUuMDc0MDggMS43Mzc3NkM1LjE2OTM0IDEuNjgyNzYgNS4yODcyOSAxLjcwNzA0IDUuMzU5NjEgMS43OTIzMUw2LjExOTE1IDIuNzI3ODhMNi45ODAwMSAyLjczODkzTDcuNzI0OTYgMS43ODkyMkM3Ljc5MTU2IDEuNzA0NTggNy45MTU0OCAxLjY3OTIyIDguMDA4NzkgMS43NDA4Mkw5LjU2ODIxIDIuNjQxODJDOS42NzAxNyAyLjY5ODQyIDkuNzEyODUgMi44MTIzNCA5LjY4NzIzIDIuOTA3OTdMOS4yMTcxOCA0LjAzMzgzTDkuNDYzMTYgNC4zOTk4OEw5LjY1NzE4IDQuNzk1OTNaIi8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-caret-down-empty-thin: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIwIDIwIj4KCTxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iPgoJCTxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iOS45LDEzLjYgMy42LDcuNCA0LjQsNi42IDkuOSwxMi4yIDE1LjQsNi43IDE2LjEsNy40ICIvPgoJPC9nPgo8L3N2Zz4K); --jp-icon-caret-down-empty: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDE4IDE4Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiIHNoYXBlLXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIj4KICAgIDxwYXRoIGQ9Ik01LjIsNS45TDksOS43bDMuOC0zLjhsMS4yLDEuMmwtNC45LDVsLTQuOS01TDUuMiw1Ljl6Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-caret-down: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDE4IDE4Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiIHNoYXBlLXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIj4KICAgIDxwYXRoIGQ9Ik01LjIsNy41TDksMTEuMmwzLjgtMy44SDUuMnoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-caret-left: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDE4IDE4Ij4KCTxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iPgoJCTxwYXRoIGQ9Ik0xMC44LDEyLjhMNy4xLDlsMy44LTMuOGwwLDcuNkgxMC44eiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-caret-right: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDE4IDE4Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiIHNoYXBlLXJlbmRlcmluZz0iZ2VvbWV0cmljUHJlY2lzaW9uIj4KICAgIDxwYXRoIGQ9Ik03LjIsNS4yTDEwLjksOWwtMy44LDMuOFY1LjJINy4yeiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-caret-up-empty-thin: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIwIDIwIj4KCTxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iPgoJCTxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iMTUuNCwxMy4zIDkuOSw3LjcgNC40LDEzLjIgMy42LDEyLjUgOS45LDYuMyAxNi4xLDEyLjYgIi8+Cgk8L2c+Cjwvc3ZnPgo=); --jp-icon-caret-up: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDE4IDE4Ij4KCTxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iPgoJCTxwYXRoIGQ9Ik01LjIsMTAuNUw5LDYuOGwzLjgsMy44SDUuMnoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-case-sensitive: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIwIDIwIj4KICA8ZyBjbGFzcz0ianAtaWNvbjIiIGZpbGw9IiM0MTQxNDEiPgogICAgPHJlY3QgeD0iMiIgeT0iMiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+CiAgPC9nPgogIDxnIGNsYXNzPSJqcC1pY29uLWFjY2VudDIiIGZpbGw9IiNGRkYiPgogICAgPHBhdGggZD0iTTcuNiw4aDAuOWwzLjUsOGgtMS4xTDEwLDE0SDZsLTAuOSwySDRMNy42LDh6IE04LDkuMUw2LjQsMTNoMy4yTDgsOS4xeiIvPgogICAgPHBhdGggZD0iTTE2LjYsOS44Yy0wLjIsMC4xLTAuNCwwLjEtMC43LDAuMWMtMC4yLDAtMC40LTAuMS0wLjYtMC4yYy0wLjEtMC4xLTAuMi0wLjQtMC4yLTAuNyBjLTAuMywwLjMtMC42LDAuNS0wLjksMC43Yy0wLjMsMC4xLTAuNywwLjItMS4xLDAuMmMtMC4zLDAtMC41LDAtMC43LTAuMWMtMC4yLTAuMS0wLjQtMC4yLTAuNi0wLjNjLTAuMi0wLjEtMC4zLTAuMy0wLjQtMC41IGMtMC4xLTAuMi0wLjEtMC40LTAuMS0wLjdjMC0wLjMsMC4xLTAuNiwwLjItMC44YzAuMS0wLjIsMC4zLTAuNCwwLjQtMC41QzEyLDcsMTIuMiw2LjksMTIuNSw2LjhjMC4yLTAuMSwwLjUtMC4xLDAuNy0wLjIgYzAuMy0wLjEsMC41LTAuMSwwLjctMC4xYzAuMiwwLDAuNC0wLjEsMC42LTAuMWMwLjIsMCwwLjMtMC4xLDAuNC0wLjJjMC4xLTAuMSwwLjItMC4yLDAuMi0wLjRjMC0xLTEuMS0xLTEuMy0xIGMtMC40LDAtMS40LDAtMS40LDEuMmgtMC45YzAtMC40LDAuMS0wLjcsMC4yLTFjMC4xLTAuMiwwLjMtMC40LDAuNS0wLjZjMC4yLTAuMiwwLjUtMC4zLDAuOC0wLjNDMTMuMyw0LDEzLjYsNCwxMy45LDQgYzAuMywwLDAuNSwwLDAuOCwwLjFjMC4zLDAsMC41LDAuMSwwLjcsMC4yYzAuMiwwLjEsMC40LDAuMywwLjUsMC41QzE2LDUsMTYsNS4yLDE2LDUuNnYyLjljMCwwLjIsMCwwLjQsMCwwLjUgYzAsMC4xLDAuMSwwLjIsMC4zLDAuMmMwLjEsMCwwLjIsMCwwLjMsMFY5Ljh6IE0xNS4yLDYuOWMtMS4yLDAuNi0zLjEsMC4yLTMuMSwxLjRjMCwxLjQsMy4xLDEsMy4xLTAuNVY2Ljl6Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-check: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIj4KICAgIDxwYXRoIGQ9Ik05IDE2LjE3TDQuODMgMTJsLTEuNDIgMS40MUw5IDE5IDIxIDdsLTEuNDEtMS40MXoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-circle-empty: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTEyIDJDNi40NyAyIDIgNi40NyAyIDEyczQuNDcgMTAgMTAgMTAgMTAtNC40NyAxMC0xMFMxNy41MyAyIDEyIDJ6bTAgMThjLTQuNDEgMC04LTMuNTktOC04czMuNTktOCA4LTggOCAzLjU5IDggOC0zLjU5IDgtOCA4eiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-circle: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTggMTgiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPGNpcmNsZSBjeD0iOSIgY3k9IjkiIHI9IjgiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-clear: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8bWFzayBpZD0iZG9udXRIb2xlIj4KICAgIDxyZWN0IHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0id2hpdGUiIC8+CiAgICA8Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSI4IiBmaWxsPSJibGFjayIvPgogIDwvbWFzaz4KCiAgPGcgY2xhc3M9ImpwLWljb24zIiBmaWxsPSIjNjE2MTYxIj4KICAgIDxyZWN0IGhlaWdodD0iMTgiIHdpZHRoPSIyIiB4PSIxMSIgeT0iMyIgdHJhbnNmb3JtPSJyb3RhdGUoMzE1LCAxMiwgMTIpIi8+CiAgICA8Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIxMCIgbWFzaz0idXJsKCNkb251dEhvbGUpIi8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-close: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbi1ub25lIGpwLWljb24tc2VsZWN0YWJsZS1pbnZlcnNlIGpwLWljb24zLWhvdmVyIiBmaWxsPSJub25lIj4KICAgIDxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjExIi8+CiAgPC9nPgoKICA8ZyBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIGpwLWljb24tYWNjZW50Mi1ob3ZlciIgZmlsbD0iIzYxNjE2MSI+CiAgICA8cGF0aCBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyeiIvPgogIDwvZz4KCiAgPGcgY2xhc3M9ImpwLWljb24tbm9uZSBqcC1pY29uLWJ1c3kiIGZpbGw9Im5vbmUiPgogICAgPGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iNyIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-code: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHZpZXdCb3g9IjAgMCAyOCAyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KCTxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CgkJPHBhdGggZD0iTTExLjQgMTguNkw2LjggMTRMMTEuNCA5LjRMMTAgOEw0IDE0TDEwIDIwTDExLjQgMTguNlpNMTYuNiAxOC42TDIxLjIgMTRMMTYuNiA5LjRMMTggOEwyNCAxNEwxOCAyMEwxNi42IDE4LjZWMTguNloiLz4KCTwvZz4KPC9zdmc+Cg==); --jp-icon-console: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIwMCAyMDAiPgogIDxnIGNsYXNzPSJqcC1pY29uLWJyYW5kMSBqcC1pY29uLXNlbGVjdGFibGUiIGZpbGw9IiMwMjg4RDEiPgogICAgPHBhdGggZD0iTTIwIDE5LjhoMTYwdjE1OS45SDIweiIvPgogIDwvZz4KICA8ZyBjbGFzcz0ianAtaWNvbi1zZWxlY3RhYmxlLWludmVyc2UiIGZpbGw9IiNmZmYiPgogICAgPHBhdGggZD0iTTEwNSAxMjcuM2g0MHYxMi44aC00MHpNNTEuMSA3N0w3NCA5OS45bC0yMy4zIDIzLjMgMTAuNSAxMC41IDIzLjMtMjMuM0w5NSA5OS45IDg0LjUgODkuNCA2MS42IDY2LjV6Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-copy: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTggMTgiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTExLjksMUgzLjJDMi40LDEsMS43LDEuNywxLjcsMi41djEwLjJoMS41VjIuNWg4LjdWMXogTTE0LjEsMy45aC04Yy0wLjgsMC0xLjUsMC43LTEuNSwxLjV2MTAuMmMwLDAuOCwwLjcsMS41LDEuNSwxLjVoOCBjMC44LDAsMS41LTAuNywxLjUtMS41VjUuNEMxNS41LDQuNiwxNC45LDMuOSwxNC4xLDMuOXogTTE0LjEsMTUuNWgtOFY1LjRoOFYxNS41eiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-copyright: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCI+CiAgPGcgY2xhc3M9ImpwLWljb24zIiBmaWxsPSIjNjE2MTYxIj4KICAgIDxwYXRoIGQ9Ik0xMS44OCw5LjE0YzEuMjgsMC4wNiwxLjYxLDEuMTUsMS42MywxLjY2aDEuNzljLTAuMDgtMS45OC0xLjQ5LTMuMTktMy40NS0zLjE5QzkuNjQsNy42MSw4LDksOCwxMi4xNCBjMCwxLjk0LDAuOTMsNC4yNCwzLjg0LDQuMjRjMi4yMiwwLDMuNDEtMS42NSwzLjQ0LTIuOTVoLTEuNzljLTAuMDMsMC41OS0wLjQ1LDEuMzgtMS42MywxLjQ0QzEwLjU1LDE0LjgzLDEwLDEzLjgxLDEwLDEyLjE0IEMxMCw5LjI1LDExLjI4LDkuMTYsMTEuODgsOS4xNHogTTEyLDJDNi40OCwyLDIsNi40OCwyLDEyczQuNDgsMTAsMTAsMTBzMTAtNC40OCwxMC0xMFMxNy41MiwyLDEyLDJ6IE0xMiwyMGMtNC40MSwwLTgtMy41OS04LTggczMuNTktOCw4LThzOCwzLjU5LDgsOFMxNi40MSwyMCwxMiwyMHoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-cut: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTkuNjQgNy42NGMuMjMtLjUuMzYtMS4wNS4zNi0xLjY0IDAtMi4yMS0xLjc5LTQtNC00UzIgMy43OSAyIDZzMS43OSA0IDQgNGMuNTkgMCAxLjE0LS4xMyAxLjY0LS4zNkwxMCAxMmwtMi4zNiAyLjM2QzcuMTQgMTQuMTMgNi41OSAxNCA2IDE0Yy0yLjIxIDAtNCAxLjc5LTQgNHMxLjc5IDQgNCA0IDQtMS43OSA0LTRjMC0uNTktLjEzLTEuMTQtLjM2LTEuNjRMMTIgMTRsNyA3aDN2LTFMOS42NCA3LjY0ek02IDhjLTEuMSAwLTItLjg5LTItMnMuOS0yIDItMiAyIC44OSAyIDItLjkgMi0yIDJ6bTAgMTJjLTEuMSAwLTItLjg5LTItMnMuOS0yIDItMiAyIC44OSAyIDItLjkgMi0yIDJ6bTYtNy41Yy0uMjggMC0uNS0uMjItLjUtLjVzLjIyLS41LjUtLjUuNS4yMi41LjUtLjIyLjUtLjUuNXpNMTkgM2wtNiA2IDIgMiA3LTdWM3oiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-download: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTE5IDloLTRWM0g5djZINWw3IDcgNy03ek01IDE4djJoMTR2LTJINXoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-edit: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTMgMTcuMjVWMjFoMy43NUwxNy44MSA5Ljk0bC0zLjc1LTMuNzVMMyAxNy4yNXpNMjAuNzEgNy4wNGMuMzktLjM5LjM5LTEuMDIgMC0xLjQxbC0yLjM0LTIuMzRjLS4zOS0uMzktMS4wMi0uMzktMS40MSAwbC0xLjgzIDEuODMgMy43NSAzLjc1IDEuODMtMS44M3oiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-ellipses: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPGNpcmNsZSBjeD0iNSIgY3k9IjEyIiByPSIyIi8+CiAgICA8Y2lyY2xlIGN4PSIxMiIgY3k9IjEyIiByPSIyIi8+CiAgICA8Y2lyY2xlIGN4PSIxOSIgY3k9IjEyIiByPSIyIi8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-extension: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTIwLjUgMTFIMTlWN2MwLTEuMS0uOS0yLTItMmgtNFYzLjVDMTMgMi4xMiAxMS44OCAxIDEwLjUgMVM4IDIuMTIgOCAzLjVWNUg0Yy0xLjEgMC0xLjk5LjktMS45OSAydjMuOEgzLjVjMS40OSAwIDIuNyAxLjIxIDIuNyAyLjdzLTEuMjEgMi43LTIuNyAyLjdIMlYyMGMwIDEuMS45IDIgMiAyaDMuOHYtMS41YzAtMS40OSAxLjIxLTIuNyAyLjctMi43IDEuNDkgMCAyLjcgMS4yMSAyLjcgMi43VjIySDE3YzEuMSAwIDItLjkgMi0ydi00aDEuNWMxLjM4IDAgMi41LTEuMTIgMi41LTIuNVMyMS44OCAxMSAyMC41IDExeiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-fast-forward: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTQgMThsOC41LTZMNCA2djEyem05LTEydjEybDguNS02TDEzIDZ6Ii8+CiAgICA8L2c+Cjwvc3ZnPgo=); --jp-icon-file-upload: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTkgMTZoNnYtNmg0bC03LTctNyA3aDR6bS00IDJoMTR2Mkg1eiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-file: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8cGF0aCBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIiBkPSJNMTkuMyA4LjJsLTUuNS01LjVjLS4zLS4zLS43LS41LTEuMi0uNUgzLjljLS44LjEtMS42LjktMS42IDEuOHYxNC4xYzAgLjkuNyAxLjYgMS42IDEuNmgxNC4yYy45IDAgMS42LS43IDEuNi0xLjZWOS40Yy4xLS41LS4xLS45LS40LTEuMnptLTUuOC0zLjNsMy40IDMuNmgtMy40VjQuOXptMy45IDEyLjdINC43Yy0uMSAwLS4yIDAtLjItLjJWNC43YzAtLjIuMS0uMy4yLS4zaDcuMnY0LjRzMCAuOC4zIDEuMWMuMy4zIDEuMS4zIDEuMS4zaDQuM3Y3LjJzLS4xLjItLjIuMnoiLz4KPC9zdmc+Cg==); --jp-icon-filter-list: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTEwIDE4aDR2LTJoLTR2MnpNMyA2djJoMThWNkgzem0zIDdoMTJ2LTJINnYyeiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-folder: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIiBkPSJNMTAgNEg0Yy0xLjEgMC0xLjk5LjktMS45OSAyTDIgMThjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY4YzAtMS4xLS45LTItMi0yaC04bC0yLTJ6Ii8+Cjwvc3ZnPgo=); --jp-icon-html5: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDUxMiA1MTIiPgogIDxwYXRoIGNsYXNzPSJqcC1pY29uMCBqcC1pY29uLXNlbGVjdGFibGUiIGZpbGw9IiMwMDAiIGQ9Ik0xMDguNCAwaDIzdjIyLjhoMjEuMlYwaDIzdjY5aC0yM1Y0NmgtMjF2MjNoLTIzLjJNMjA2IDIzaC0yMC4zVjBoNjMuN3YyM0gyMjl2NDZoLTIzbTUzLjUtNjloMjQuMWwxNC44IDI0LjNMMzEzLjIgMGgyNC4xdjY5aC0yM1YzNC44bC0xNi4xIDI0LjgtMTYuMS0yNC44VjY5aC0yMi42bTg5LjItNjloMjN2NDYuMmgzMi42VjY5aC01NS42Ii8+CiAgPHBhdGggY2xhc3M9ImpwLWljb24tc2VsZWN0YWJsZSIgZmlsbD0iI2U0NGQyNiIgZD0iTTEwNy42IDQ3MWwtMzMtMzcwLjRoMzYyLjhsLTMzIDM3MC4yTDI1NS43IDUxMiIvPgogIDxwYXRoIGNsYXNzPSJqcC1pY29uLXNlbGVjdGFibGUiIGZpbGw9IiNmMTY1MjkiIGQ9Ik0yNTYgNDgwLjVWMTMxaDE0OC4zTDM3NiA0NDciLz4KICA8cGF0aCBjbGFzcz0ianAtaWNvbi1zZWxlY3RhYmxlLWludmVyc2UiIGZpbGw9IiNlYmViZWIiIGQ9Ik0xNDIgMTc2LjNoMTE0djQ1LjRoLTY0LjJsNC4yIDQ2LjVoNjB2NDUuM0gxNTQuNG0yIDIyLjhIMjAybDMuMiAzNi4zIDUwLjggMTMuNnY0Ny40bC05My4yLTI2Ii8+CiAgPHBhdGggY2xhc3M9ImpwLWljb24tc2VsZWN0YWJsZS1pbnZlcnNlIiBmaWxsPSIjZmZmIiBkPSJNMzY5LjYgMTc2LjNIMjU1Ljh2NDUuNGgxMDkuNm0tNC4xIDQ2LjVIMjU1Ljh2NDUuNGg1NmwtNS4zIDU5LTUwLjcgMTMuNnY0Ny4ybDkzLTI1LjgiLz4KPC9zdmc+Cg==); --jp-icon-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8cGF0aCBjbGFzcz0ianAtaWNvbi1icmFuZDQganAtaWNvbi1zZWxlY3RhYmxlLWludmVyc2UiIGZpbGw9IiNGRkYiIGQ9Ik0yLjIgMi4yaDE3LjV2MTcuNUgyLjJ6Ii8+CiAgPHBhdGggY2xhc3M9ImpwLWljb24tYnJhbmQwIGpwLWljb24tc2VsZWN0YWJsZSIgZmlsbD0iIzNGNTFCNSIgZD0iTTIuMiAyLjJ2MTcuNWgxNy41bC4xLTE3LjVIMi4yem0xMi4xIDIuMmMxLjIgMCAyLjIgMSAyLjIgMi4ycy0xIDIuMi0yLjIgMi4yLTIuMi0xLTIuMi0yLjIgMS0yLjIgMi4yLTIuMnpNNC40IDE3LjZsMy4zLTguOCAzLjMgNi42IDIuMi0zLjIgNC40IDUuNEg0LjR6Ii8+Cjwvc3ZnPgo=); --jp-icon-inspector: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIiBkPSJNMjAgNEg0Yy0xLjEgMC0xLjk5LjktMS45OSAyTDIgMThjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY2YzAtMS4xLS45LTItMi0yem0tNSAxNEg0di00aDExdjR6bTAtNUg0VjloMTF2NHptNSA1aC00VjloNHY5eiIvPgo8L3N2Zz4K); --jp-icon-json: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8ZyBjbGFzcz0ianAtaWNvbi13YXJuMSBqcC1pY29uLXNlbGVjdGFibGUiIGZpbGw9IiNGOUE4MjUiPgogICAgPHBhdGggZD0iTTIwLjIgMTEuOGMtMS42IDAtMS43LjUtMS43IDEgMCAuNC4xLjkuMSAxLjMuMS41LjEuOS4xIDEuMyAwIDEuNy0xLjQgMi4zLTMuNSAyLjNoLS45di0xLjloLjVjMS4xIDAgMS40IDAgMS40LS44IDAtLjMgMC0uNi0uMS0xIDAtLjQtLjEtLjgtLjEtMS4yIDAtMS4zIDAtMS44IDEuMy0yLTEuMy0uMi0xLjMtLjctMS4zLTIgMC0uNC4xLS44LjEtMS4yLjEtLjQuMS0uNy4xLTEgMC0uOC0uNC0uNy0xLjQtLjhoLS41VjQuMWguOWMyLjIgMCAzLjUuNyAzLjUgMi4zIDAgLjQtLjEuOS0uMSAxLjMtLjEuNS0uMS45LS4xIDEuMyAwIC41LjIgMSAxLjcgMXYxLjh6TTEuOCAxMC4xYzEuNiAwIDEuNy0uNSAxLjctMSAwLS40LS4xLS45LS4xLTEuMy0uMS0uNS0uMS0uOS0uMS0xLjMgMC0xLjYgMS40LTIuMyAzLjUtMi4zaC45djEuOWgtLjVjLTEgMC0xLjQgMC0xLjQuOCAwIC4zIDAgLjYuMSAxIDAgLjIuMS42LjEgMSAwIDEuMyAwIDEuOC0xLjMgMkM2IDExLjIgNiAxMS43IDYgMTNjMCAuNC0uMS44LS4xIDEuMi0uMS4zLS4xLjctLjEgMSAwIC44LjMuOCAxLjQuOGguNXYxLjloLS45Yy0yLjEgMC0zLjUtLjYtMy41LTIuMyAwLS40LjEtLjkuMS0xLjMuMS0uNS4xLS45LjEtMS4zIDAtLjUtLjItMS0xLjctMXYtMS45eiIvPgogICAgPGNpcmNsZSBjeD0iMTEiIGN5PSIxMy44IiByPSIyLjEiLz4KICAgIDxjaXJjbGUgY3g9IjExIiBjeT0iOC4yIiByPSIyLjEiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-julia: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDMyNSAzMDAiPgogIDxnIGNsYXNzPSJqcC1icmFuZDAganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjY2IzYzMzIj4KICAgIDxwYXRoIGQ9Ik0gMTUwLjg5ODQzOCAyMjUgQyAxNTAuODk4NDM4IDI2Ni40MjE4NzUgMTE3LjMyMDMxMiAzMDAgNzUuODk4NDM4IDMwMCBDIDM0LjQ3NjU2MiAzMDAgMC44OTg0MzggMjY2LjQyMTg3NSAwLjg5ODQzOCAyMjUgQyAwLjg5ODQzOCAxODMuNTc4MTI1IDM0LjQ3NjU2MiAxNTAgNzUuODk4NDM4IDE1MCBDIDExNy4zMjAzMTIgMTUwIDE1MC44OTg0MzggMTgzLjU3ODEyNSAxNTAuODk4NDM4IDIyNSIvPgogIDwvZz4KICA8ZyBjbGFzcz0ianAtYnJhbmQwIGpwLWljb24tc2VsZWN0YWJsZSIgZmlsbD0iIzM4OTgyNiI+CiAgICA8cGF0aCBkPSJNIDIzNy41IDc1IEMgMjM3LjUgMTE2LjQyMTg3NSAyMDMuOTIxODc1IDE1MCAxNjIuNSAxNTAgQyAxMjEuMDc4MTI1IDE1MCA4Ny41IDExNi40MjE4NzUgODcuNSA3NSBDIDg3LjUgMzMuNTc4MTI1IDEyMS4wNzgxMjUgMCAxNjIuNSAwIEMgMjAzLjkyMTg3NSAwIDIzNy41IDMzLjU3ODEyNSAyMzcuNSA3NSIvPgogIDwvZz4KICA8ZyBjbGFzcz0ianAtYnJhbmQwIGpwLWljb24tc2VsZWN0YWJsZSIgZmlsbD0iIzk1NThiMiI+CiAgICA8cGF0aCBkPSJNIDMyNC4xMDE1NjIgMjI1IEMgMzI0LjEwMTU2MiAyNjYuNDIxODc1IDI5MC41MjM0MzggMzAwIDI0OS4xMDE1NjIgMzAwIEMgMjA3LjY3OTY4OCAzMDAgMTc0LjEwMTU2MiAyNjYuNDIxODc1IDE3NC4xMDE1NjIgMjI1IEMgMTc0LjEwMTU2MiAxODMuNTc4MTI1IDIwNy42Nzk2ODggMTUwIDI0OS4xMDE1NjIgMTUwIEMgMjkwLjUyMzQzOCAxNTAgMzI0LjEwMTU2MiAxODMuNTc4MTI1IDMyNC4xMDE1NjIgMjI1Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-jupyter-favicon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUyIiBoZWlnaHQ9IjE2NSIgdmlld0JveD0iMCAwIDE1MiAxNjUiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbi13YXJuMCIgZmlsbD0iI0YzNzcyNiI+CiAgICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLjA3ODk0NywgMTEwLjU4MjkyNykiIGQ9Ik03NS45NDIyODQyLDI5LjU4MDQ1NjEgQzQzLjMwMjM5NDcsMjkuNTgwNDU2MSAxNC43OTY3ODMyLDE3LjY1MzQ2MzQgMCwwIEM1LjUxMDgzMjExLDE1Ljg0MDY4MjkgMTUuNzgxNTM4OSwyOS41NjY3NzMyIDI5LjM5MDQ5NDcsMzkuMjc4NDE3MSBDNDIuOTk5Nyw0OC45ODk4NTM3IDU5LjI3MzcsNTQuMjA2NzgwNSA3NS45NjA1Nzg5LDU0LjIwNjc4MDUgQzkyLjY0NzQ1NzksNTQuMjA2NzgwNSAxMDguOTIxNDU4LDQ4Ljk4OTg1MzcgMTIyLjUzMDY2MywzOS4yNzg0MTcxIEMxMzYuMTM5NDUzLDI5LjU2Njc3MzIgMTQ2LjQxMDI4NCwxNS44NDA2ODI5IDE1MS45MjExNTgsMCBDMTM3LjA4Nzg2OCwxNy42NTM0NjM0IDEwOC41ODI1ODksMjkuNTgwNDU2MSA3NS45NDIyODQyLDI5LjU4MDQ1NjEgTDc1Ljk0MjI4NDIsMjkuNTgwNDU2MSBaIiAvPgogICAgPHBhdGggdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMzczNjgsIDAuNzA0ODc4KSIgZD0iTTc1Ljk3ODQ1NzksMjQuNjI2NDA3MyBDMTA4LjYxODc2MywyNC42MjY0MDczIDEzNy4xMjQ0NTgsMzYuNTUzNDQxNSAxNTEuOTIxMTU4LDU0LjIwNjc4MDUgQzE0Ni40MTAyODQsMzguMzY2MjIyIDEzNi4xMzk0NTMsMjQuNjQwMTMxNyAxMjIuNTMwNjYzLDE0LjkyODQ4NzggQzEwOC45MjE0NTgsNS4yMTY4NDM5IDkyLjY0NzQ1NzksMCA3NS45NjA1Nzg5LDAgQzU5LjI3MzcsMCA0Mi45OTk3LDUuMjE2ODQzOSAyOS4zOTA0OTQ3LDE0LjkyODQ4NzggQzE1Ljc4MTUzODksMjQuNjQwMTMxNyA1LjUxMDgzMjExLDM4LjM2NjIyMiAwLDU0LjIwNjc4MDUgQzE0LjgzMzA4MTYsMzYuNTg5OTI5MyA0My4zMzg1Njg0LDI0LjYyNjQwNzMgNzUuOTc4NDU3OSwyNC42MjY0MDczIEw3NS45Nzg0NTc5LDI0LjYyNjQwNzMgWiIgLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-jupyter: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzkiIGhlaWdodD0iNTEiIHZpZXdCb3g9IjAgMCAzOSA1MSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTYzOCAtMjI4MSkiPgogICAgPGcgY2xhc3M9ImpwLWljb24td2FybjAiIGZpbGw9IiNGMzc3MjYiPgogICAgICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjM5Ljc0IDIzMTEuOTgpIiBkPSJNIDE4LjI2NDYgNy4xMzQxMUMgMTAuNDE0NSA3LjEzNDExIDMuNTU4NzIgNC4yNTc2IDAgMEMgMS4zMjUzOSAzLjgyMDQgMy43OTU1NiA3LjEzMDgxIDcuMDY4NiA5LjQ3MzAzQyAxMC4zNDE3IDExLjgxNTIgMTQuMjU1NyAxMy4wNzM0IDE4LjI2OSAxMy4wNzM0QyAyMi4yODIzIDEzLjA3MzQgMjYuMTk2MyAxMS44MTUyIDI5LjQ2OTQgOS40NzMwM0MgMzIuNzQyNCA3LjEzMDgxIDM1LjIxMjYgMy44MjA0IDM2LjUzOCAwQyAzMi45NzA1IDQuMjU3NiAyNi4xMTQ4IDcuMTM0MTEgMTguMjY0NiA3LjEzNDExWiIvPgogICAgICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjM5LjczIDIyODUuNDgpIiBkPSJNIDE4LjI3MzMgNS45MzkzMUMgMjYuMTIzNSA1LjkzOTMxIDMyLjk3OTMgOC44MTU4MyAzNi41MzggMTMuMDczNEMgMzUuMjEyNiA5LjI1MzAzIDMyLjc0MjQgNS45NDI2MiAyOS40Njk0IDMuNjAwNEMgMjYuMTk2MyAxLjI1ODE4IDIyLjI4MjMgMCAxOC4yNjkgMEMgMTQuMjU1NyAwIDEwLjM0MTcgMS4yNTgxOCA3LjA2ODYgMy42MDA0QyAzLjc5NTU2IDUuOTQyNjIgMS4zMjUzOSA5LjI1MzAzIDAgMTMuMDczNEMgMy41Njc0NSA4LjgyNDYzIDEwLjQyMzIgNS45MzkzMSAxOC4yNzMzIDUuOTM5MzFaIi8+CiAgICA8L2c+CiAgICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjY5LjMgMjI4MS4zMSkiIGQ9Ik0gNS44OTM1MyAyLjg0NEMgNS45MTg4OSAzLjQzMTY1IDUuNzcwODUgNC4wMTM2NyA1LjQ2ODE1IDQuNTE2NDVDIDUuMTY1NDUgNS4wMTkyMiA0LjcyMTY4IDUuNDIwMTUgNC4xOTI5OSA1LjY2ODUxQyAzLjY2NDMgNS45MTY4OCAzLjA3NDQ0IDYuMDAxNTEgMi40OTgwNSA1LjkxMTcxQyAxLjkyMTY2IDUuODIxOSAxLjM4NDYzIDUuNTYxNyAwLjk1NDg5OCA1LjE2NDAxQyAwLjUyNTE3IDQuNzY2MzMgMC4yMjIwNTYgNC4yNDkwMyAwLjA4MzkwMzcgMy42Nzc1N0MgLTAuMDU0MjQ4MyAzLjEwNjExIC0wLjAyMTIzIDIuNTA2MTcgMC4xNzg3ODEgMS45NTM2NEMgMC4zNzg3OTMgMS40MDExIDAuNzM2ODA5IDAuOTIwODE3IDEuMjA3NTQgMC41NzM1MzhDIDEuNjc4MjYgMC4yMjYyNTkgMi4yNDA1NSAwLjAyNzU5MTkgMi44MjMyNiAwLjAwMjY3MjI5QyAzLjYwMzg5IC0wLjAzMDcxMTUgNC4zNjU3MyAwLjI0OTc4OSA0Ljk0MTQyIDAuNzgyNTUxQyA1LjUxNzExIDEuMzE1MzEgNS44NTk1NiAyLjA1Njc2IDUuODkzNTMgMi44NDRaIi8+CiAgICAgIDxwYXRoIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE2MzkuOCAyMzIzLjgxKSIgZD0iTSA3LjQyNzg5IDMuNTgzMzhDIDcuNDYwMDggNC4zMjQzIDcuMjczNTUgNS4wNTgxOSA2Ljg5MTkzIDUuNjkyMTNDIDYuNTEwMzEgNi4zMjYwNyA1Ljk1MDc1IDYuODMxNTYgNS4yODQxMSA3LjE0NDZDIDQuNjE3NDcgNy40NTc2MyAzLjg3MzcxIDcuNTY0MTQgMy4xNDcwMiA3LjQ1MDYzQyAyLjQyMDMyIDcuMzM3MTIgMS43NDMzNiA3LjAwODcgMS4yMDE4NCA2LjUwNjk1QyAwLjY2MDMyOCA2LjAwNTIgMC4yNzg2MSA1LjM1MjY4IDAuMTA1MDE3IDQuNjMyMDJDIC0wLjA2ODU3NTcgMy45MTEzNSAtMC4wMjYyMzYxIDMuMTU0OTQgMC4yMjY2NzUgMi40NTg1NkMgMC40Nzk1ODcgMS43NjIxNyAwLjkzMTY5NyAxLjE1NzEzIDEuNTI1NzYgMC43MjAwMzNDIDIuMTE5ODMgMC4yODI5MzUgMi44MjkxNCAwLjAzMzQzOTUgMy41NjM4OSAwLjAwMzEzMzQ0QyA0LjU0NjY3IC0wLjAzNzQwMzMgNS41MDUyOSAwLjMxNjcwNiA2LjIyOTYxIDAuOTg3ODM1QyA2Ljk1MzkzIDEuNjU4OTYgNy4zODQ4NCAyLjU5MjM1IDcuNDI3ODkgMy41ODMzOEwgNy40Mjc4OSAzLjU4MzM4WiIvPgogICAgICA8cGF0aCB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjM4LjM2IDIyODYuMDYpIiBkPSJNIDIuMjc0NzEgNC4zOTYyOUMgMS44NDM2MyA0LjQxNTA4IDEuNDE2NzEgNC4zMDQ0NSAxLjA0Nzk5IDQuMDc4NDNDIDAuNjc5MjY4IDMuODUyNCAwLjM4NTMyOCAzLjUyMTE0IDAuMjAzMzcxIDMuMTI2NTZDIDAuMDIxNDEzNiAyLjczMTk4IC0wLjA0MDM3OTggMi4yOTE4MyAwLjAyNTgxMTYgMS44NjE4MUMgMC4wOTIwMDMxIDEuNDMxOCAwLjI4MzIwNCAxLjAzMTI2IDAuNTc1MjEzIDAuNzEwODgzQyAwLjg2NzIyMiAwLjM5MDUxIDEuMjQ2OTEgMC4xNjQ3MDggMS42NjYyMiAwLjA2MjA1OTJDIDIuMDg1NTMgLTAuMDQwNTg5NyAyLjUyNTYxIC0wLjAxNTQ3MTQgMi45MzA3NiAwLjEzNDIzNUMgMy4zMzU5MSAwLjI4Mzk0MSAzLjY4NzkyIDAuNTUxNTA1IDMuOTQyMjIgMC45MDMwNkMgNC4xOTY1MiAxLjI1NDYyIDQuMzQxNjkgMS42NzQzNiA0LjM1OTM1IDIuMTA5MTZDIDQuMzgyOTkgMi42OTEwNyA0LjE3Njc4IDMuMjU4NjkgMy43ODU5NyAzLjY4NzQ2QyAzLjM5NTE2IDQuMTE2MjQgMi44NTE2NiA0LjM3MTE2IDIuMjc0NzEgNC4zOTYyOUwgMi4yNzQ3MSA0LjM5NjI5WiIvPgogICAgPC9nPgogIDwvZz4+Cjwvc3ZnPgo=); --jp-icon-jupyterlab-wordmark: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMDAiIHZpZXdCb3g9IjAgMCAxODYwLjggNDc1Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjIiIGZpbGw9IiM0RTRFNEUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ4MC4xMzY0MDEsIDY0LjI3MTQ5MykiPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDU4Ljg3NTU2NikiPgogICAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLjA4NzYwMywgMC4xNDAyOTQpIj4KICAgICAgICA8cGF0aCBkPSJNLTQyNi45LDE2OS44YzAsNDguNy0zLjcsNjQuNy0xMy42LDc2LjRjLTEwLjgsMTAtMjUsMTUuNS0zOS43LDE1LjVsMy43LDI5IGMyMi44LDAuMyw0NC44LTcuOSw2MS45LTIzLjFjMTcuOC0xOC41LDI0LTQ0LjEsMjQtODMuM1YwSC00Mjd2MTcwLjFMLTQyNi45LDE2OS44TC00MjYuOSwxNjkuOHoiLz4KICAgICAgPC9nPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTU1LjA0NTI5NiwgNTYuODM3MTA0KSI+CiAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEuNTYyNDUzLCAxLjc5OTg0MikiPgogICAgICAgIDxwYXRoIGQ9Ik0tMzEyLDE0OGMwLDIxLDAsMzkuNSwxLjcsNTUuNGgtMzEuOGwtMi4xLTMzLjNoLTAuOGMtNi43LDExLjYtMTYuNCwyMS4zLTI4LDI3LjkgYy0xMS42LDYuNi0yNC44LDEwLTM4LjIsOS44Yy0zMS40LDAtNjktMTcuNy02OS04OVYwaDM2LjR2MTEyLjdjMCwzOC43LDExLjYsNjQuNyw0NC42LDY0LjdjMTAuMy0wLjIsMjAuNC0zLjUsMjguOS05LjQgYzguNS01LjksMTUuMS0xNC4zLDE4LjktMjMuOWMyLjItNi4xLDMuMy0xMi41LDMuMy0xOC45VjAuMmgzNi40VjE0OEgtMzEyTC0zMTIsMTQ4eiIvPgogICAgICA8L2c+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzOTAuMDEzMzIyLCA1My40Nzk2MzgpIj4KICAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMS43MDY0NTgsIDAuMjMxNDI1KSI+CiAgICAgICAgPHBhdGggZD0iTS00NzguNiw3MS40YzAtMjYtMC44LTQ3LTEuNy02Ni43aDMyLjdsMS43LDM0LjhoMC44YzcuMS0xMi41LDE3LjUtMjIuOCwzMC4xLTI5LjcgYzEyLjUtNywyNi43LTEwLjMsNDEtOS44YzQ4LjMsMCw4NC43LDQxLjcsODQuNywxMDMuM2MwLDczLjEtNDMuNywxMDkuMi05MSwxMDkuMmMtMTIuMSwwLjUtMjQuMi0yLjItMzUtNy44IGMtMTAuOC01LjYtMTkuOS0xMy45LTI2LjYtMjQuMmgtMC44VjI5MWgtMzZ2LTIyMEwtNDc4LjYsNzEuNEwtNDc4LjYsNzEuNHogTS00NDIuNiwxMjUuNmMwLjEsNS4xLDAuNiwxMC4xLDEuNywxNS4xIGMzLDEyLjMsOS45LDIzLjMsMTkuOCwzMS4xYzkuOSw3LjgsMjIuMSwxMi4xLDM0LjcsMTIuMWMzOC41LDAsNjAuNy0zMS45LDYwLjctNzguNWMwLTQwLjctMjEuMS03NS42LTU5LjUtNzUuNiBjLTEyLjksMC40LTI1LjMsNS4xLTM1LjMsMTMuNGMtOS45LDguMy0xNi45LDE5LjctMTkuNiwzMi40Yy0xLjUsNC45LTIuMywxMC0yLjUsMTUuMVYxMjUuNkwtNDQyLjYsMTI1LjZMLTQ0Mi42LDEyNS42eiIvPgogICAgICA8L2c+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MDYuNzQwNzI2LCA1Ni44MzcxMDQpIj4KICAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC43NTEyMjYsIDEuOTg5Mjk5KSI+CiAgICAgICAgPHBhdGggZD0iTS00NDAuOCwwbDQzLjcsMTIwLjFjNC41LDEzLjQsOS41LDI5LjQsMTIuOCw0MS43aDAuOGMzLjctMTIuMiw3LjktMjcuNywxMi44LTQyLjQgbDM5LjctMTE5LjJoMzguNUwtMzQ2LjksMTQ1Yy0yNiw2OS43LTQzLjcsMTA1LjQtNjguNiwxMjcuMmMtMTIuNSwxMS43LTI3LjksMjAtNDQuNiwyMy45bC05LjEtMzEuMSBjMTEuNy0zLjksMjIuNS0xMC4xLDMxLjgtMTguMWMxMy4yLTExLjEsMjMuNy0yNS4yLDMwLjYtNDEuMmMxLjUtMi44LDIuNS01LjcsMi45LTguOGMtMC4zLTMuMy0xLjItNi42LTIuNS05LjdMLTQ4MC4yLDAuMSBoMzkuN0wtNDQwLjgsMEwtNDQwLjgsMHoiLz4KICAgICAgPC9nPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoODIyLjc0ODEwNCwgMC4wMDAwMDApIj4KICAgICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMS40NjQwNTAsIDAuMzc4OTE0KSI+CiAgICAgICAgPHBhdGggZD0iTS00MTMuNywwdjU4LjNoNTJ2MjguMmgtNTJWMTk2YzAsMjUsNywzOS41LDI3LjMsMzkuNWM3LjEsMC4xLDE0LjItMC43LDIxLjEtMi41IGwxLjcsMjcuN2MtMTAuMywzLjctMjEuMyw1LjQtMzIuMiw1Yy03LjMsMC40LTE0LjYtMC43LTIxLjMtMy40Yy02LjgtMi43LTEyLjktNi44LTE3LjktMTIuMWMtMTAuMy0xMC45LTE0LjEtMjktMTQuMS01Mi45IFY4Ni41aC0zMVY1OC4zaDMxVjkuNkwtNDEzLjcsMEwtNDEzLjcsMHoiLz4KICAgICAgPC9nPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOTc0LjQzMzI4NiwgNTMuNDc5NjM4KSI+CiAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuOTkwMDM0LCAwLjYxMDMzOSkiPgogICAgICAgIDxwYXRoIGQ9Ik0tNDQ1LjgsMTEzYzAuOCw1MCwzMi4yLDcwLjYsNjguNiw3MC42YzE5LDAuNiwzNy45LTMsNTUuMy0xMC41bDYuMiwyNi40IGMtMjAuOSw4LjktNDMuNSwxMy4xLTY2LjIsMTIuNmMtNjEuNSwwLTk4LjMtNDEuMi05OC4zLTEwMi41Qy00ODAuMiw0OC4yLTQ0NC43LDAtMzg2LjUsMGM2NS4yLDAsODIuNyw1OC4zLDgyLjcsOTUuNyBjLTAuMSw1LjgtMC41LDExLjUtMS4yLDE3LjJoLTE0MC42SC00NDUuOEwtNDQ1LjgsMTEzeiBNLTMzOS4yLDg2LjZjMC40LTIzLjUtOS41LTYwLjEtNTAuNC02MC4xIGMtMzYuOCwwLTUyLjgsMzQuNC01NS43LDYwLjFILTMzOS4yTC0zMzkuMiw4Ni42TC0zMzkuMiw4Ni42eiIvPgogICAgICA8L2c+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjAxLjk2MTA1OCwgNTMuNDc5NjM4KSI+CiAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEuMTc5NjQwLCAwLjcwNTA2OCkiPgogICAgICAgIDxwYXRoIGQ9Ik0tNDc4LjYsNjhjMC0yMy45LTAuNC00NC41LTEuNy02My40aDMxLjhsMS4yLDM5LjloMS43YzkuMS0yNy4zLDMxLTQ0LjUsNTUuMy00NC41IGMzLjUtMC4xLDcsMC40LDEwLjMsMS4ydjM0LjhjLTQuMS0wLjktOC4yLTEuMy0xMi40LTEuMmMtMjUuNiwwLTQzLjcsMTkuNy00OC43LDQ3LjRjLTEsNS43LTEuNiwxMS41LTEuNywxNy4ydjEwOC4zaC0zNlY2OCBMLTQ3OC42LDY4eiIvPgogICAgICA8L2c+CiAgICA8L2c+CiAgPC9nPgoKICA8ZyBjbGFzcz0ianAtaWNvbi13YXJuMCIgZmlsbD0iI0YzNzcyNiI+CiAgICA8cGF0aCBkPSJNMTM1Mi4zLDMyNi4yaDM3VjI4aC0zN1YzMjYuMnogTTE2MDQuOCwzMjYuMmMtMi41LTEzLjktMy40LTMxLjEtMy40LTQ4Ljd2LTc2IGMwLTQwLjctMTUuMS04My4xLTc3LjMtODMuMWMtMjUuNiwwLTUwLDcuMS02Ni44LDE4LjFsOC40LDI0LjRjMTQuMy05LjIsMzQtMTUuMSw1My0xNS4xYzQxLjYsMCw0Ni4yLDMwLjIsNDYuMiw0N3Y0LjIgYy03OC42LTAuNC0xMjIuMywyNi41LTEyMi4zLDc1LjZjMCwyOS40LDIxLDU4LjQsNjIuMiw1OC40YzI5LDAsNTAuOS0xNC4zLDYyLjItMzAuMmgxLjNsMi45LDI1LjZIMTYwNC44eiBNMTU2NS43LDI1Ny43IGMwLDMuOC0wLjgsOC0yLjEsMTEuOGMtNS45LDE3LjItMjIuNywzNC00OS4yLDM0Yy0xOC45LDAtMzQuOS0xMS4zLTM0LjktMzUuM2MwLTM5LjUsNDUuOC00Ni42LDg2LjItNDUuOFYyNTcuN3ogTTE2OTguNSwzMjYuMiBsMS43LTMzLjZoMS4zYzE1LjEsMjYuOSwzOC43LDM4LjIsNjguMSwzOC4yYzQ1LjQsMCw5MS4yLTM2LjEsOTEuMi0xMDguOGMwLjQtNjEuNy0zNS4zLTEwMy43LTg1LjctMTAzLjcgYy0zMi44LDAtNTYuMywxNC43LTY5LjMsMzcuNGgtMC44VjI4aC0zNi42djI0NS43YzAsMTguMS0wLjgsMzguNi0xLjcsNTIuNUgxNjk4LjV6IE0xNzA0LjgsMjA4LjJjMC01LjksMS4zLTEwLjksMi4xLTE1LjEgYzcuNi0yOC4xLDMxLjEtNDUuNCw1Ni4zLTQ1LjRjMzkuNSwwLDYwLjUsMzQuOSw2MC41LDc1LjZjMCw0Ni42LTIzLjEsNzguMS02MS44LDc4LjFjLTI2LjksMC00OC4zLTE3LjYtNTUuNS00My4zIGMtMC44LTQuMi0xLjctOC44LTEuNy0xMy40VjIwOC4yeiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-kernel: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICAgIDxwYXRoIGNsYXNzPSJqcC1pY29uMiIgZmlsbD0iIzYxNjE2MSIgZD0iTTE1IDlIOXY2aDZWOXptLTIgNGgtMnYtMmgydjJ6bTgtMlY5aC0yVjdjMC0xLjEtLjktMi0yLTJoLTJWM2gtMnYyaC0yVjNIOXYySDdjLTEuMSAwLTIgLjktMiAydjJIM3YyaDJ2MkgzdjJoMnYyYzAgMS4xLjkgMiAyIDJoMnYyaDJ2LTJoMnYyaDJ2LTJoMmMxLjEgMCAyLS45IDItMnYtMmgydi0yaC0ydi0yaDJ6bS00IDZIN1Y3aDEwdjEweiIvPgo8L3N2Zz4K); --jp-icon-keyboard: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIiBkPSJNMjAgNUg0Yy0xLjEgMC0xLjk5LjktMS45OSAyTDIgMTdjMCAxLjEuOSAyIDIgMmgxNmMxLjEgMCAyLS45IDItMlY3YzAtMS4xLS45LTItMi0yem0tOSAzaDJ2MmgtMlY4em0wIDNoMnYyaC0ydi0yek04IDhoMnYySDhWOHptMCAzaDJ2Mkg4di0yem0tMSAySDV2LTJoMnYyem0wLTNINVY4aDJ2MnptOSA3SDh2LTJoOHYyem0wLTRoLTJ2LTJoMnYyem0wLTNoLTJWOGgydjJ6bTMgM2gtMnYtMmgydjJ6bTAtM2gtMlY4aDJ2MnoiLz4KPC9zdmc+Cg==); --jp-icon-launcher: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIiBkPSJNMTkgMTlINVY1aDdWM0g1YTIgMiAwIDAwLTIgMnYxNGEyIDIgMCAwMDIgMmgxNGMxLjEgMCAyLS45IDItMnYtN2gtMnY3ek0xNCAzdjJoMy41OWwtOS44MyA5LjgzIDEuNDEgMS40MUwxOSA2LjQxVjEwaDJWM2gtN3oiLz4KPC9zdmc+Cg==); --jp-icon-line-form: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICAgIDxwYXRoIGZpbGw9IndoaXRlIiBkPSJNNS44OCA0LjEyTDEzLjc2IDEybC03Ljg4IDcuODhMOCAyMmwxMC0xMEw4IDJ6Ii8+Cjwvc3ZnPgo=); --jp-icon-link: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTMuOSAxMmMwLTEuNzEgMS4zOS0zLjEgMy4xLTMuMWg0VjdIN2MtMi43NiAwLTUgMi4yNC01IDVzMi4yNCA1IDUgNWg0di0xLjlIN2MtMS43MSAwLTMuMS0xLjM5LTMuMS0zLjF6TTggMTNoOHYtMkg4djJ6bTktNmgtNHYxLjloNGMxLjcxIDAgMy4xIDEuMzkgMy4xIDMuMXMtMS4zOSAzLjEtMy4xIDMuMWgtNFYxN2g0YzIuNzYgMCA1LTIuMjQgNS01cy0yLjI0LTUtNS01eiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-list: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICAgIDxwYXRoIGNsYXNzPSJqcC1pY29uMiBqcC1pY29uLXNlbGVjdGFibGUiIGZpbGw9IiM2MTYxNjEiIGQ9Ik0xOSA1djE0SDVWNWgxNG0xLjEtMkgzLjljLS41IDAtLjkuNC0uOS45djE2LjJjMCAuNC40LjkuOS45aDE2LjJjLjQgMCAuOS0uNS45LS45VjMuOWMwLS41LS41LS45LS45LS45ek0xMSA3aDZ2MmgtNlY3em0wIDRoNnYyaC02di0yem0wIDRoNnYyaC02ek03IDdoMnYySDd6bTAgNGgydjJIN3ptMCA0aDJ2Mkg3eiIvPgo8L3N2Zz4=); --jp-icon-listings-info: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MC45NzggNTAuOTc4IiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MC45NzggNTAuOTc4OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+Cgk8Zz4KCQk8cGF0aCBzdHlsZT0iZmlsbDojMDEwMDAyOyIgZD0iTTQzLjUyLDcuNDU4QzM4LjcxMSwyLjY0OCwzMi4zMDcsMCwyNS40ODksMEMxOC42NywwLDEyLjI2NiwyLjY0OCw3LjQ1OCw3LjQ1OAoJCQljLTkuOTQzLDkuOTQxLTkuOTQzLDI2LjExOSwwLDM2LjA2MmM0LjgwOSw0LjgwOSwxMS4yMTIsNy40NTYsMTguMDMxLDcuNDU4YzAsMCwwLjAwMSwwLDAuMDAyLDAKCQkJYzYuODE2LDAsMTMuMjIxLTIuNjQ4LDE4LjAyOS03LjQ1OGM0LjgwOS00LjgwOSw3LjQ1Ny0xMS4yMTIsNy40NTctMTguMDNDNTAuOTc3LDE4LjY3LDQ4LjMyOCwxMi4yNjYsNDMuNTIsNy40NTh6CgkJCSBNNDIuMTA2LDQyLjEwNWMtNC40MzIsNC40MzEtMTAuMzMyLDYuODcyLTE2LjYxNSw2Ljg3MmgtMC4wMDJjLTYuMjg1LTAuMDAxLTEyLjE4Ny0yLjQ0MS0xNi42MTctNi44NzIKCQkJYy05LjE2Mi05LjE2My05LjE2Mi0yNC4wNzEsMC0zMy4yMzNDMTMuMzAzLDQuNDQsMTkuMjA0LDIsMjUuNDg5LDJjNi4yODQsMCwxMi4xODYsMi40NCwxNi42MTcsNi44NzIKCQkJYzQuNDMxLDQuNDMxLDYuODcxLDEwLjMzMiw2Ljg3MSwxNi42MTdDNDguOTc3LDMxLjc3Miw0Ni41MzYsMzcuNjc1LDQyLjEwNiw0Mi4xMDV6Ii8+CgkJPHBhdGggc3R5bGU9ImZpbGw6IzAxMDAwMjsiIGQ9Ik0yMy41NzgsMzIuMjE4Yy0wLjAyMy0xLjczNCwwLjE0My0zLjA1OSwwLjQ5Ni0zLjk3MmMwLjM1My0wLjkxMywxLjExLTEuOTk3LDIuMjcyLTMuMjUzCgkJCWMwLjQ2OC0wLjUzNiwwLjkyMy0xLjA2MiwxLjM2Ny0xLjU3NWMwLjYyNi0wLjc1MywxLjEwNC0xLjQ3OCwxLjQzNi0yLjE3NWMwLjMzMS0wLjcwNywwLjQ5NS0xLjU0MSwwLjQ5NS0yLjUKCQkJYzAtMS4wOTYtMC4yNi0yLjA4OC0wLjc3OS0yLjk3OWMtMC41NjUtMC44NzktMS41MDEtMS4zMzYtMi44MDYtMS4zNjljLTEuODAyLDAuMDU3LTIuOTg1LDAuNjY3LTMuNTUsMS44MzIKCQkJYy0wLjMwMSwwLjUzNS0wLjUwMywxLjE0MS0wLjYwNywxLjgxNGMtMC4xMzksMC43MDctMC4yMDcsMS40MzItMC4yMDcsMi4xNzRoLTIuOTM3Yy0wLjA5MS0yLjIwOCwwLjQwNy00LjExNCwxLjQ5My01LjcxOQoJCQljMS4wNjItMS42NCwyLjg1NS0yLjQ4MSw1LjM3OC0yLjUyN2MyLjE2LDAuMDIzLDMuODc0LDAuNjA4LDUuMTQxLDEuNzU4YzEuMjc4LDEuMTYsMS45MjksMi43NjQsMS45NSw0LjgxMQoJCQljMCwxLjE0Mi0wLjEzNywyLjExMS0wLjQxLDIuOTExYy0wLjMwOSwwLjg0NS0wLjczMSwxLjU5My0xLjI2OCwyLjI0M2MtMC40OTIsMC42NS0xLjA2OCwxLjMxOC0xLjczLDIuMDAyCgkJCWMtMC42NSwwLjY5Ny0xLjMxMywxLjQ3OS0xLjk4NywyLjM0NmMtMC4yMzksMC4zNzctMC40MjksMC43NzctMC41NjUsMS4xOTljLTAuMTYsMC45NTktMC4yMTcsMS45NTEtMC4xNzEsMi45NzkKCQkJQzI2LjU4OSwzMi4yMTgsMjMuNTc4LDMyLjIxOCwyMy41NzgsMzIuMjE4eiBNMjMuNTc4LDM4LjIydi0zLjQ4NGgzLjA3NnYzLjQ4NEgyMy41Nzh6Ii8+Cgk8L2c+Cjwvc3ZnPgo=); --jp-icon-markdown: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8cGF0aCBjbGFzcz0ianAtaWNvbi1jb250cmFzdDAganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjN0IxRkEyIiBkPSJNNSAxNC45aDEybC02LjEgNnptOS40LTYuOGMwLTEuMy0uMS0yLjktLjEtNC41LS40IDEuNC0uOSAyLjktMS4zIDQuM2wtMS4zIDQuM2gtMkw4LjUgNy45Yy0uNC0xLjMtLjctMi45LTEtNC4zLS4xIDEuNi0uMSAzLjItLjIgNC42TDcgMTIuNEg0LjhsLjctMTFoMy4zTDEwIDVjLjQgMS4yLjcgMi43IDEgMy45LjMtMS4yLjctMi42IDEtMy45bDEuMi0zLjdoMy4zbC42IDExaC0yLjRsLS4zLTQuMnoiLz4KPC9zdmc+Cg==); --jp-icon-new-folder: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTIwIDZoLThsLTItMkg0Yy0xLjExIDAtMS45OS44OS0xLjk5IDJMMiAxOGMwIDEuMTEuODkgMiAyIDJoMTZjMS4xMSAwIDItLjg5IDItMlY4YzAtMS4xMS0uODktMi0yLTJ6bS0xIDhoLTN2M2gtMnYtM2gtM3YtMmgzVjloMnYzaDN2MnoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-not-trusted: url(data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI1IDI1Ij4KICAgIDxwYXRoIGNsYXNzPSJqcC1pY29uMiIgc3Ryb2tlPSIjMzMzMzMzIiBzdHJva2Utd2lkdGg9IjIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMgMykiIGQ9Ik0xLjg2MDk0IDExLjQ0MDlDMC44MjY0NDggOC43NzAyNyAwLjg2Mzc3OSA2LjA1NzY0IDEuMjQ5MDcgNC4xOTkzMkMyLjQ4MjA2IDMuOTMzNDcgNC4wODA2OCAzLjQwMzQ3IDUuNjAxMDIgMi44NDQ5QzcuMjM1NDkgMi4yNDQ0IDguODU2NjYgMS41ODE1IDkuOTg3NiAxLjA5NTM5QzExLjA1OTcgMS41ODM0MSAxMi42MDk0IDIuMjQ0NCAxNC4yMTggMi44NDMzOUMxNS43NTAzIDMuNDEzOTQgMTcuMzk5NSAzLjk1MjU4IDE4Ljc1MzkgNC4yMTM4NUMxOS4xMzY0IDYuMDcxNzcgMTkuMTcwOSA4Ljc3NzIyIDE4LjEzOSAxMS40NDA5QzE3LjAzMDMgMTQuMzAzMiAxNC42NjY4IDE3LjE4NDQgOS45OTk5OSAxOC45MzU0QzUuMzMzMTkgMTcuMTg0NCAyLjk2OTY4IDE0LjMwMzIgMS44NjA5NCAxMS40NDA5WiIvPgogICAgPHBhdGggY2xhc3M9ImpwLWljb24yIiBzdHJva2U9IiMzMzMzMzMiIHN0cm9rZS13aWR0aD0iMiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOS4zMTU5MiA5LjMyMDMxKSIgZD0iTTcuMzY4NDIgMEwwIDcuMzY0NzkiLz4KICAgIDxwYXRoIGNsYXNzPSJqcC1pY29uMiIgc3Ryb2tlPSIjMzMzMzMzIiBzdHJva2Utd2lkdGg9IjIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDkuMzE1OTIgMTYuNjgzNikgc2NhbGUoMSAtMSkiIGQ9Ik03LjM2ODQyIDBMMCA3LjM2NDc5Ii8+Cjwvc3ZnPgo=); --jp-icon-notebook: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8ZyBjbGFzcz0ianAtaWNvbi13YXJuMCBqcC1pY29uLXNlbGVjdGFibGUiIGZpbGw9IiNFRjZDMDAiPgogICAgPHBhdGggZD0iTTE4LjcgMy4zdjE1LjRIMy4zVjMuM2gxNS40bTEuNS0xLjVIMS44djE4LjNoMTguM2wuMS0xOC4zeiIvPgogICAgPHBhdGggZD0iTTE2LjUgMTYuNWwtNS40LTQuMy01LjYgNC4zdi0xMWgxMXoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-numbering: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjIiIHZpZXdCb3g9IjAgMCAyOCAyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KCTxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CgkJPHBhdGggZD0iTTQgMTlINlYxOS41SDVWMjAuNUg2VjIxSDRWMjJIN1YxOEg0VjE5Wk01IDEwSDZWNkg0VjdINVYxMFpNNCAxM0g1LjhMNCAxNS4xVjE2SDdWMTVINS4yTDcgMTIuOVYxMkg0VjEzWk05IDdWOUgyM1Y3SDlaTTkgMjFIMjNWMTlIOVYyMVpNOSAxNUgyM1YxM0g5VjE1WiIvPgoJPC9nPgo8L3N2Zz4K); --jp-icon-offline-bolt: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTEyIDIuMDJjLTUuNTEgMC05Ljk4IDQuNDctOS45OCA5Ljk4czQuNDcgOS45OCA5Ljk4IDkuOTggOS45OC00LjQ3IDkuOTgtOS45OFMxNy41MSAyLjAyIDEyIDIuMDJ6TTExLjQ4IDIwdi02LjI2SDhMMTMgNHY2LjI2aDMuMzVMMTEuNDggMjB6Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-palette: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTE4IDEzVjIwSDRWNkg5LjAyQzkuMDcgNS4yOSA5LjI0IDQuNjIgOS41IDRINEMyLjkgNCAyIDQuOSAyIDZWMjBDMiAyMS4xIDIuOSAyMiA0IDIySDE4QzE5LjEgMjIgMjAgMjEuMSAyMCAyMFYxNUwxOCAxM1pNMTkuMyA4Ljg5QzE5Ljc0IDguMTkgMjAgNy4zOCAyMCA2LjVDMjAgNC4wMSAxNy45OSAyIDE1LjUgMkMxMy4wMSAyIDExIDQuMDEgMTEgNi41QzExIDguOTkgMTMuMDEgMTEgMTUuNDkgMTFDMTYuMzcgMTEgMTcuMTkgMTAuNzQgMTcuODggMTAuM0wyMSAxMy40MkwyMi40MiAxMkwxOS4zIDguODlaTTE1LjUgOUMxNC4xMiA5IDEzIDcuODggMTMgNi41QzEzIDUuMTIgMTQuMTIgNCAxNS41IDRDMTYuODggNCAxOCA1LjEyIDE4IDYuNUMxOCA3Ljg4IDE2Ljg4IDkgMTUuNSA5WiIvPgogICAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00IDZIOS4wMTg5NEM5LjAwNjM5IDYuMTY1MDIgOSA2LjMzMTc2IDkgNi41QzkgOC44MTU3NyAxMC4yMTEgMTAuODQ4NyAxMi4wMzQzIDEySDlWMTRIMTZWMTIuOTgxMUMxNi41NzAzIDEyLjkzNzcgMTcuMTIgMTIuODIwNyAxNy42Mzk2IDEyLjYzOTZMMTggMTNWMjBINFY2Wk04IDhINlYxMEg4VjhaTTYgMTJIOFYxNEg2VjEyWk04IDE2SDZWMThIOFYxNlpNOSAxNkgxNlYxOEg5VjE2WiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-paste: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTE5IDJoLTQuMThDMTQuNC44NCAxMy4zIDAgMTIgMGMtMS4zIDAtMi40Ljg0LTIuODIgMkg1Yy0xLjEgMC0yIC45LTIgMnYxNmMwIDEuMS45IDIgMiAyaDE0YzEuMSAwIDItLjkgMi0yVjRjMC0xLjEtLjktMi0yLTJ6bS03IDBjLjU1IDAgMSAuNDUgMSAxcy0uNDUgMS0xIDEtMS0uNDUtMS0xIC40NS0xIDEtMXptNyAxOEg1VjRoMnYzaDEwVjRoMnYxNnoiLz4KICAgIDwvZz4KPC9zdmc+Cg==); --jp-icon-pdf: url(data:image/svg+xml;base64,PHN2ZwogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMiAyMiIgd2lkdGg9IjE2Ij4KICAgIDxwYXRoIHRyYW5zZm9ybT0icm90YXRlKDQ1KSIgY2xhc3M9ImpwLWljb24tc2VsZWN0YWJsZSIgZmlsbD0iI0ZGMkEyQSIKICAgICAgIGQ9Im0gMjIuMzQ0MzY5LC0zLjAxNjM2NDIgaCA1LjYzODYwNCB2IDEuNTc5MjQzMyBoIC0zLjU0OTIyNyB2IDEuNTA4NjkyOTkgaCAzLjMzNzU3NiBWIDEuNjUwODE1NCBoIC0zLjMzNzU3NiB2IDMuNDM1MjYxMyBoIC0yLjA4OTM3NyB6IG0gLTcuMTM2NDQ0LDEuNTc5MjQzMyB2IDQuOTQzOTU0MyBoIDAuNzQ4OTIgcSAxLjI4MDc2MSwwIDEuOTUzNzAzLC0wLjYzNDk1MzUgMC42NzgzNjksLTAuNjM0OTUzNSAwLjY3ODM2OSwtMS44NDUxNjQxIDAsLTEuMjA0NzgzNTUgLTAuNjcyOTQyLC0xLjgzNDMxMDExIC0wLjY3Mjk0MiwtMC42Mjk1MjY1OSAtMS45NTkxMywtMC42Mjk1MjY1OSB6IG0gLTIuMDg5Mzc3LC0xLjU3OTI0MzMgaCAyLjIwMzM0MyBxIDEuODQ1MTY0LDAgMi43NDYwMzksMC4yNjU5MjA3IDAuOTA2MzAxLDAuMjYwNDkzNyAxLjU1MjEwOCwwLjg5MDAyMDMgMC41Njk4MywwLjU0ODEyMjMgMC44NDY2MDUsMS4yNjQ0ODAwNiAwLjI3Njc3NCwwLjcxNjM1NzgxIDAuMjc2Nzc0LDEuNjIyNjU4OTQgMCwwLjkxNzE1NTEgLTAuMjc2Nzc0LDEuNjM4OTM5OSAtMC4yNzY3NzUsMC43MTYzNTc4IC0wLjg0NjYwNSwxLjI2NDQ4IC0wLjY1MTIzNCwwLjYyOTUyNjYgLTEuNTYyOTYyLDAuODk1NDQ3MyAtMC45MTE3MjgsMC4yNjA0OTM3IC0yLjczNTE4NSwwLjI2MDQ5MzcgaCAtMi4yMDMzNDMgeiBtIC04LjE0NTg1NjUsMCBoIDMuNDY3ODIzIHEgMS41NDY2ODE2LDAgMi4zNzE1Nzg1LDAuNjg5MjIzIDAuODMwMzI0LDAuNjgzNzk2MSAwLjgzMDMyNCwxLjk1MzcwMzE0IDAsMS4yNzUzMzM5NyAtMC44MzAzMjQsMS45NjQ1NTcwNiBRIDkuOTg3MTk2MSwyLjI3NDkxNSA4LjQ0MDUxNDUsMi4yNzQ5MTUgSCA3LjA2MjA2ODQgViA1LjA4NjA3NjcgSCA0Ljk3MjY5MTUgWiBtIDIuMDg5Mzc2OSwxLjUxNDExOTkgdiAyLjI2MzAzOTQzIGggMS4xNTU5NDEgcSAwLjYwNzgxODgsMCAwLjkzODg2MjksLTAuMjkzMDU1NDcgMC4zMzEwNDQxLC0wLjI5ODQ4MjQxIDAuMzMxMDQ0MSwtMC44NDExNzc3MiAwLC0wLjU0MjY5NTMxIC0wLjMzMTA0NDEsLTAuODM1NzUwNzQgLTAuMzMxMDQ0MSwtMC4yOTMwNTU1IC0wLjkzODg2MjksLTAuMjkzMDU1NSB6IgovPgo8L3N2Zz4K); --jp-icon-python: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8ZyBjbGFzcz0ianAtaWNvbi1icmFuZDAganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjMEQ0N0ExIj4KICAgIDxwYXRoIGQ9Ik0xMS4xIDYuOVY1LjhINi45YzAtLjUgMC0xLjMuMi0xLjYuNC0uNy44LTEuMSAxLjctMS40IDEuNy0uMyAyLjUtLjMgMy45LS4xIDEgLjEgMS45LjkgMS45IDEuOXY0LjJjMCAuNS0uOSAxLjYtMiAxLjZIOC44Yy0xLjUgMC0yLjQgMS40LTIuNCAyLjh2Mi4ySDQuN0MzLjUgMTUuMSAzIDE0IDMgMTMuMVY5Yy0uMS0xIC42LTIgMS44LTIgMS41LS4xIDYuMy0uMSA2LjMtLjF6Ii8+CiAgICA8cGF0aCBkPSJNMTAuOSAxNS4xdjEuMWg0LjJjMCAuNSAwIDEuMy0uMiAxLjYtLjQuNy0uOCAxLjEtMS43IDEuNC0xLjcuMy0yLjUuMy0zLjkuMS0xLS4xLTEuOS0uOS0xLjktMS45di00LjJjMC0uNS45LTEuNiAyLTEuNmgzLjhjMS41IDAgMi40LTEuNCAyLjQtMi44VjYuNmgxLjdDMTguNSA2LjkgMTkgOCAxOSA4LjlWMTNjMCAxLS43IDIuMS0xLjkgMi4xaC02LjJ6Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-r-kernel: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8cGF0aCBjbGFzcz0ianAtaWNvbi1jb250cmFzdDMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjMjE5NkYzIiBkPSJNNC40IDIuNWMxLjItLjEgMi45LS4zIDQuOS0uMyAyLjUgMCA0LjEuNCA1LjIgMS4zIDEgLjcgMS41IDEuOSAxLjUgMy41IDAgMi0xLjQgMy41LTIuOSA0LjEgMS4yLjQgMS43IDEuNiAyLjIgMyAuNiAxLjkgMSAzLjkgMS4zIDQuNmgtMy44Yy0uMy0uNC0uOC0xLjctMS4yLTMuN3MtMS4yLTIuNi0yLjYtMi42aC0uOXY2LjRINC40VjIuNXptMy43IDYuOWgxLjRjMS45IDAgMi45LS45IDIuOS0yLjNzLTEtMi4zLTIuOC0yLjNjLS43IDAtMS4zIDAtMS42LjJ2NC41aC4xdi0uMXoiLz4KPC9zdmc+Cg==); --jp-icon-react: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMTUwIDE1MCA1NDEuOSAyOTUuMyI+CiAgPGcgY2xhc3M9ImpwLWljb24tYnJhbmQyIGpwLWljb24tc2VsZWN0YWJsZSIgZmlsbD0iIzYxREFGQiI+CiAgICA8cGF0aCBkPSJNNjY2LjMgMjk2LjVjMC0zMi41LTQwLjctNjMuMy0xMDMuMS04Mi40IDE0LjQtNjMuNiA4LTExNC4yLTIwLjItMTMwLjQtNi41LTMuOC0xNC4xLTUuNi0yMi40LTUuNnYyMi4zYzQuNiAwIDguMy45IDExLjQgMi42IDEzLjYgNy44IDE5LjUgMzcuNSAxNC45IDc1LjctMS4xIDkuNC0yLjkgMTkuMy01LjEgMjkuNC0xOS42LTQuOC00MS04LjUtNjMuNS0xMC45LTEzLjUtMTguNS0yNy41LTM1LjMtNDEuNi01MCAzMi42LTMwLjMgNjMuMi00Ni45IDg0LTQ2LjlWNzhjLTI3LjUgMC02My41IDE5LjYtOTkuOSA1My42LTM2LjQtMzMuOC03Mi40LTUzLjItOTkuOS01My4ydjIyLjNjMjAuNyAwIDUxLjQgMTYuNSA4NCA0Ni42LTE0IDE0LjctMjggMzEuNC00MS4zIDQ5LjktMjIuNiAyLjQtNDQgNi4xLTYzLjYgMTEtMi4zLTEwLTQtMTkuNy01LjItMjktNC43LTM4LjIgMS4xLTY3LjkgMTQuNi03NS44IDMtMS44IDYuOS0yLjYgMTEuNS0yLjZWNzguNWMtOC40IDAtMTYgMS44LTIyLjYgNS42LTI4LjEgMTYuMi0zNC40IDY2LjctMTkuOSAxMzAuMS02Mi4yIDE5LjItMTAyLjcgNDkuOS0xMDIuNyA4Mi4zIDAgMzIuNSA0MC43IDYzLjMgMTAzLjEgODIuNC0xNC40IDYzLjYtOCAxMTQuMiAyMC4yIDEzMC40IDYuNSAzLjggMTQuMSA1LjYgMjIuNSA1LjYgMjcuNSAwIDYzLjUtMTkuNiA5OS45LTUzLjYgMzYuNCAzMy44IDcyLjQgNTMuMiA5OS45IDUzLjIgOC40IDAgMTYtMS44IDIyLjYtNS42IDI4LjEtMTYuMiAzNC40LTY2LjcgMTkuOS0xMzAuMSA2Mi0xOS4xIDEwMi41LTQ5LjkgMTAyLjUtODIuM3ptLTEzMC4yLTY2LjdjLTMuNyAxMi45LTguMyAyNi4yLTEzLjUgMzkuNS00LjEtOC04LjQtMTYtMTMuMS0yNC00LjYtOC05LjUtMTUuOC0xNC40LTIzLjQgMTQuMiAyLjEgMjcuOSA0LjcgNDEgNy45em0tNDUuOCAxMDYuNWMtNy44IDEzLjUtMTUuOCAyNi4zLTI0LjEgMzguMi0xNC45IDEuMy0zMCAyLTQ1LjIgMi0xNS4xIDAtMzAuMi0uNy00NS0xLjktOC4zLTExLjktMTYuNC0yNC42LTI0LjItMzgtNy42LTEzLjEtMTQuNS0yNi40LTIwLjgtMzkuOCA2LjItMTMuNCAxMy4yLTI2LjggMjAuNy0zOS45IDcuOC0xMy41IDE1LjgtMjYuMyAyNC4xLTM4LjIgMTQuOS0xLjMgMzAtMiA0NS4yLTIgMTUuMSAwIDMwLjIuNyA0NSAxLjkgOC4zIDExLjkgMTYuNCAyNC42IDI0LjIgMzggNy42IDEzLjEgMTQuNSAyNi40IDIwLjggMzkuOC02LjMgMTMuNC0xMy4yIDI2LjgtMjAuNyAzOS45em0zMi4zLTEzYzUuNCAxMy40IDEwIDI2LjggMTMuOCAzOS44LTEzLjEgMy4yLTI2LjkgNS45LTQxLjIgOCA0LjktNy43IDkuOC0xNS42IDE0LjQtMjMuNyA0LjYtOCA4LjktMTYuMSAxMy0yNC4xek00MjEuMiA0MzBjLTkuMy05LjYtMTguNi0yMC4zLTI3LjgtMzIgOSAuNCAxOC4yLjcgMjcuNS43IDkuNCAwIDE4LjctLjIgMjcuOC0uNy05IDExLjctMTguMyAyMi40LTI3LjUgMzJ6bS03NC40LTU4LjljLTE0LjItMi4xLTI3LjktNC43LTQxLTcuOSAzLjctMTIuOSA4LjMtMjYuMiAxMy41LTM5LjUgNC4xIDggOC40IDE2IDEzLjEgMjQgNC43IDggOS41IDE1LjggMTQuNCAyMy40ek00MjAuNyAxNjNjOS4zIDkuNiAxOC42IDIwLjMgMjcuOCAzMi05LS40LTE4LjItLjctMjcuNS0uNy05LjQgMC0xOC43LjItMjcuOC43IDktMTEuNyAxOC4zLTIyLjQgMjcuNS0zMnptLTc0IDU4LjljLTQuOSA3LjctOS44IDE1LjYtMTQuNCAyMy43LTQuNiA4LTguOSAxNi0xMyAyNC01LjQtMTMuNC0xMC0yNi44LTEzLjgtMzkuOCAxMy4xLTMuMSAyNi45LTUuOCA0MS4yLTcuOXptLTkwLjUgMTI1LjJjLTM1LjQtMTUuMS01OC4zLTM0LjktNTguMy01MC42IDAtMTUuNyAyMi45LTM1LjYgNTguMy01MC42IDguNi0zLjcgMTgtNyAyNy43LTEwLjEgNS43IDE5LjYgMTMuMiA0MCAyMi41IDYwLjktOS4yIDIwLjgtMTYuNiA0MS4xLTIyLjIgNjAuNi05LjktMy4xLTE5LjMtNi41LTI4LTEwLjJ6TTMxMCA0OTBjLTEzLjYtNy44LTE5LjUtMzcuNS0xNC45LTc1LjcgMS4xLTkuNCAyLjktMTkuMyA1LjEtMjkuNCAxOS42IDQuOCA0MSA4LjUgNjMuNSAxMC45IDEzLjUgMTguNSAyNy41IDM1LjMgNDEuNiA1MC0zMi42IDMwLjMtNjMuMiA0Ni45LTg0IDQ2LjktNC41LS4xLTguMy0xLTExLjMtMi43em0yMzcuMi03Ni4yYzQuNyAzOC4yLTEuMSA2Ny45LTE0LjYgNzUuOC0zIDEuOC02LjkgMi42LTExLjUgMi42LTIwLjcgMC01MS40LTE2LjUtODQtNDYuNiAxNC0xNC43IDI4LTMxLjQgNDEuMy00OS45IDIyLjYtMi40IDQ0LTYuMSA2My42LTExIDIuMyAxMC4xIDQuMSAxOS44IDUuMiAyOS4xem0zOC41LTY2LjdjLTguNiAzLjctMTggNy0yNy43IDEwLjEtNS43LTE5LjYtMTMuMi00MC0yMi41LTYwLjkgOS4yLTIwLjggMTYuNi00MS4xIDIyLjItNjAuNiA5LjkgMy4xIDE5LjMgNi41IDI4LjEgMTAuMiAzNS40IDE1LjEgNTguMyAzNC45IDU4LjMgNTAuNi0uMSAxNS43LTIzIDM1LjYtNTguNCA1MC42ek0zMjAuOCA3OC40eiIvPgogICAgPGNpcmNsZSBjeD0iNDIwLjkiIGN5PSIyOTYuNSIgcj0iNDUuNyIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-redo: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjE2Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTE4LjQgMTAuNkMxNi41NSA4Ljk5IDE0LjE1IDggMTEuNSA4Yy00LjY1IDAtOC41OCAzLjAzLTkuOTYgNy4yMkwzLjkgMTZjMS4wNS0zLjE5IDQuMDUtNS41IDcuNi01LjUgMS45NSAwIDMuNzMuNzIgNS4xMiAxLjg4TDEzIDE2aDlWN2wtMy42IDMuNnoiLz4KICA8L2c+Cjwvc3ZnPgo=); --jp-icon-refresh: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDE4IDE4Ij4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTkgMTMuNWMtMi40OSAwLTQuNS0yLjAxLTQuNS00LjVTNi41MSA0LjUgOSA0LjVjMS4yNCAwIDIuMzYuNTIgMy4xNyAxLjMzTDEwIDhoNVYzbC0xLjc2IDEuNzZDMTIuMTUgMy42OCAxMC42NiAzIDkgMyA1LjY5IDMgMy4wMSA1LjY5IDMuMDEgOVM1LjY5IDE1IDkgMTVjMi45NyAwIDUuNDMtMi4xNiA1LjktNWgtMS41MmMtLjQ2IDItMi4yNCAzLjUtNC4zOCAzLjV6Ii8+CiAgICA8L2c+Cjwvc3ZnPgo=); --jp-icon-regex: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIwIDIwIj4KICA8ZyBjbGFzcz0ianAtaWNvbjIiIGZpbGw9IiM0MTQxNDEiPgogICAgPHJlY3QgeD0iMiIgeT0iMiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2Ii8+CiAgPC9nPgoKICA8ZyBjbGFzcz0ianAtaWNvbi1hY2NlbnQyIiBmaWxsPSIjRkZGIj4KICAgIDxjaXJjbGUgY2xhc3M9InN0MiIgY3g9IjUuNSIgY3k9IjE0LjUiIHI9IjEuNSIvPgogICAgPHJlY3QgeD0iMTIiIHk9IjQiIGNsYXNzPSJzdDIiIHdpZHRoPSIxIiBoZWlnaHQ9IjgiLz4KICAgIDxyZWN0IHg9IjguNSIgeT0iNy41IiB0cmFuc2Zvcm09Im1hdHJpeCgwLjg2NiAtMC41IDAuNSAwLjg2NiAtMi4zMjU1IDcuMzIxOSkiIGNsYXNzPSJzdDIiIHdpZHRoPSI4IiBoZWlnaHQ9IjEiLz4KICAgIDxyZWN0IHg9IjEyIiB5PSI0IiB0cmFuc2Zvcm09Im1hdHJpeCgwLjUgLTAuODY2IDAuODY2IDAuNSAtMC42Nzc5IDE0LjgyNTIpIiBjbGFzcz0ic3QyIiB3aWR0aD0iMSIgaGVpZ2h0PSI4Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-run: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTggNXYxNGwxMS03eiIvPgogICAgPC9nPgo8L3N2Zz4K); --jp-icon-running: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDUxMiA1MTIiPgogIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICA8cGF0aCBkPSJNMjU2IDhDMTE5IDggOCAxMTkgOCAyNTZzMTExIDI0OCAyNDggMjQ4IDI0OC0xMTEgMjQ4LTI0OFMzOTMgOCAyNTYgOHptOTYgMzI4YzAgOC44LTcuMiAxNi0xNiAxNkgxNzZjLTguOCAwLTE2LTcuMi0xNi0xNlYxNzZjMC04LjggNy4yLTE2IDE2LTE2aDE2MGM4LjggMCAxNiA3LjIgMTYgMTZ2MTYweiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-save: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTE3IDNINWMtMS4xMSAwLTIgLjktMiAydjE0YzAgMS4xLjg5IDIgMiAyaDE0YzEuMSAwIDItLjkgMi0yVjdsLTQtNHptLTUgMTZjLTEuNjYgMC0zLTEuMzQtMy0zczEuMzQtMyAzLTMgMyAxLjM0IDMgMy0xLjM0IDMtMyAzem0zLTEwSDVWNWgxMHY0eiIvPgogICAgPC9nPgo8L3N2Zz4K); --jp-icon-search: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTggMTgiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTEyLjEsMTAuOWgtMC43bC0wLjItMC4yYzAuOC0wLjksMS4zLTIuMiwxLjMtMy41YzAtMy0yLjQtNS40LTUuNC01LjRTMS44LDQuMiwxLjgsNy4xczIuNCw1LjQsNS40LDUuNCBjMS4zLDAsMi41LTAuNSwzLjUtMS4zbDAuMiwwLjJ2MC43bDQuMSw0LjFsMS4yLTEuMkwxMi4xLDEwLjl6IE03LjEsMTAuOWMtMi4xLDAtMy43LTEuNy0zLjctMy43czEuNy0zLjcsMy43LTMuN3MzLjcsMS43LDMuNywzLjcgUzkuMiwxMC45LDcuMSwxMC45eiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-settings: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIiBkPSJNMTkuNDMgMTIuOThjLjA0LS4zMi4wNy0uNjQuMDctLjk4cy0uMDMtLjY2LS4wNy0uOThsMi4xMS0xLjY1Yy4xOS0uMTUuMjQtLjQyLjEyLS42NGwtMi0zLjQ2Yy0uMTItLjIyLS4zOS0uMy0uNjEtLjIybC0yLjQ5IDFjLS41Mi0uNC0xLjA4LS43My0xLjY5LS45OGwtLjM4LTIuNjVBLjQ4OC40ODggMCAwMDE0IDJoLTRjLS4yNSAwLS40Ni4xOC0uNDkuNDJsLS4zOCAyLjY1Yy0uNjEuMjUtMS4xNy41OS0xLjY5Ljk4bC0yLjQ5LTFjLS4yMy0uMDktLjQ5IDAtLjYxLjIybC0yIDMuNDZjLS4xMy4yMi0uMDcuNDkuMTIuNjRsMi4xMSAxLjY1Yy0uMDQuMzItLjA3LjY1LS4wNy45OHMuMDMuNjYuMDcuOThsLTIuMTEgMS42NWMtLjE5LjE1LS4yNC40Mi0uMTIuNjRsMiAzLjQ2Yy4xMi4yMi4zOS4zLjYxLjIybDIuNDktMWMuNTIuNCAxLjA4LjczIDEuNjkuOThsLjM4IDIuNjVjLjAzLjI0LjI0LjQyLjQ5LjQyaDRjLjI1IDAgLjQ2LS4xOC40OS0uNDJsLjM4LTIuNjVjLjYxLS4yNSAxLjE3LS41OSAxLjY5LS45OGwyLjQ5IDFjLjIzLjA5LjQ5IDAgLjYxLS4yMmwyLTMuNDZjLjEyLS4yMi4wNy0uNDktLjEyLS42NGwtMi4xMS0xLjY1ek0xMiAxNS41Yy0xLjkzIDAtMy41LTEuNTctMy41LTMuNXMxLjU3LTMuNSAzLjUtMy41IDMuNSAxLjU3IDMuNSAzLjUtMS41NyAzLjUtMy41IDMuNXoiLz4KPC9zdmc+Cg==); --jp-icon-spreadsheet: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8cGF0aCBjbGFzcz0ianAtaWNvbi1jb250cmFzdDEganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNENBRjUwIiBkPSJNMi4yIDIuMnYxNy42aDE3LjZWMi4ySDIuMnptMTUuNCA3LjdoLTUuNVY0LjRoNS41djUuNXpNOS45IDQuNHY1LjVINC40VjQuNGg1LjV6bS01LjUgNy43aDUuNXY1LjVINC40di01LjV6bTcuNyA1LjV2LTUuNWg1LjV2NS41aC01LjV6Ii8+Cjwvc3ZnPgo=); --jp-icon-stop: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgogICAgICAgIDxwYXRoIGQ9Ik02IDZoMTJ2MTJINnoiLz4KICAgIDwvZz4KPC9zdmc+Cg==); --jp-icon-tab: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTIxIDNIM2MtMS4xIDAtMiAuOS0yIDJ2MTRjMCAxLjEuOSAyIDIgMmgxOGMxLjEgMCAyLS45IDItMlY1YzAtMS4xLS45LTItMi0yem0wIDE2SDNWNWgxMHY0aDh2MTB6Ii8+CiAgPC9nPgo8L3N2Zz4K); --jp-icon-table-rows: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgogICAgICAgIDxwYXRoIGQ9Ik0yMSw4SDNWNGgxOFY4eiBNMjEsMTBIM3Y0aDE4VjEweiBNMjEsMTZIM3Y0aDE4VjE2eiIvPgogICAgPC9nPgo8L3N2Zz4=); --jp-icon-tag: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjgiIGhlaWdodD0iMjgiIHZpZXdCb3g9IjAgMCA0MyAyOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KCTxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CgkJPHBhdGggZD0iTTI4LjgzMzIgMTIuMzM0TDMyLjk5OTggMTYuNTAwN0wzNy4xNjY1IDEyLjMzNEgyOC44MzMyWiIvPgoJCTxwYXRoIGQ9Ik0xNi4yMDk1IDIxLjYxMDRDMTUuNjg3MyAyMi4xMjk5IDE0Ljg0NDMgMjIuMTI5OSAxNC4zMjQ4IDIxLjYxMDRMNi45ODI5IDE0LjcyNDVDNi41NzI0IDE0LjMzOTQgNi4wODMxMyAxMy42MDk4IDYuMDQ3ODYgMTMuMDQ4MkM1Ljk1MzQ3IDExLjUyODggNi4wMjAwMiA4LjYxOTQ0IDYuMDY2MjEgNy4wNzY5NUM2LjA4MjgxIDYuNTE0NzcgNi41NTU0OCA2LjA0MzQ3IDcuMTE4MDQgNi4wMzA1NUM5LjA4ODYzIDUuOTg0NzMgMTMuMjYzOCA1LjkzNTc5IDEzLjY1MTggNi4zMjQyNUwyMS43MzY5IDEzLjYzOUMyMi4yNTYgMTQuMTU4NSAyMS43ODUxIDE1LjQ3MjQgMjEuMjYyIDE1Ljk5NDZMMTYuMjA5NSAyMS42MTA0Wk05Ljc3NTg1IDguMjY1QzkuMzM1NTEgNy44MjU2NiA4LjYyMzUxIDcuODI1NjYgOC4xODI4IDguMjY1QzcuNzQzNDYgOC43MDU3MSA3Ljc0MzQ2IDkuNDE3MzMgOC4xODI4IDkuODU2NjdDOC42MjM4MiAxMC4yOTY0IDkuMzM1ODIgMTAuMjk2NCA5Ljc3NTg1IDkuODU2NjdDMTAuMjE1NiA5LjQxNzMzIDEwLjIxNTYgOC43MDUzMyA5Ljc3NTg1IDguMjY1WiIvPgoJPC9nPgo8L3N2Zz4K); --jp-icon-terminal: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0IiA+CiAgICA8cmVjdCBjbGFzcz0ianAtaWNvbjIganAtaWNvbi1zZWxlY3RhYmxlIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIgMikiIGZpbGw9IiMzMzMzMzMiLz4KICAgIDxwYXRoIGNsYXNzPSJqcC1pY29uLWFjY2VudDIganAtaWNvbi1zZWxlY3RhYmxlLWludmVyc2UiIGQ9Ik01LjA1NjY0IDguNzYxNzJDNS4wNTY2NCA4LjU5NzY2IDUuMDMxMjUgOC40NTMxMiA0Ljk4MDQ3IDguMzI4MTJDNC45MzM1OSA4LjE5OTIyIDQuODU1NDcgOC4wODIwMyA0Ljc0NjA5IDcuOTc2NTZDNC42NDA2MiA3Ljg3MTA5IDQuNSA3Ljc3NTM5IDQuMzI0MjIgNy42ODk0NUM0LjE1MjM0IDcuNTk5NjEgMy45NDMzNiA3LjUxMTcyIDMuNjk3MjcgNy40MjU3OEMzLjMwMjczIDcuMjg1MTYgMi45NDMzNiA3LjEzNjcyIDIuNjE5MTQgNi45ODA0N0MyLjI5NDkyIDYuODI0MjIgMi4wMTc1OCA2LjY0MjU4IDEuNzg3MTEgNi40MzU1NUMxLjU2MDU1IDYuMjI4NTIgMS4zODQ3NyA1Ljk4ODI4IDEuMjU5NzcgNS43MTQ4NEMxLjEzNDc3IDUuNDM3NSAxLjA3MjI3IDUuMTA5MzggMS4wNzIyNyA0LjczMDQ3QzEuMDcyMjcgNC4zOTg0NCAxLjEyODkxIDQuMDk1NyAxLjI0MjE5IDMuODIyMjdDMS4zNTU0NyAzLjU0NDkyIDEuNTE1NjIgMy4zMDQ2OSAxLjcyMjY2IDMuMTAxNTZDMS45Mjk2OSAyLjg5ODQ0IDIuMTc5NjkgMi43MzQzNyAyLjQ3MjY2IDIuNjA5MzhDMi43NjU2MiAyLjQ4NDM4IDMuMDkxOCAyLjQwNDMgMy40NTExNyAyLjM2OTE0VjEuMTA5MzhINC4zODg2N1YyLjM4MDg2QzQuNzQwMjMgMi40Mjc3MyA1LjA1NjY0IDIuNTIzNDQgNS4zMzc4OSAyLjY2Nzk3QzUuNjE5MTQgMi44MTI1IDUuODU3NDIgMy4wMDE5NSA2LjA1MjczIDMuMjM2MzNDNi4yNTE5NSAzLjQ2NjggNi40MDQzIDMuNzQwMjMgNi41MDk3NyA0LjA1NjY0QzYuNjE5MTQgNC4zNjkxNCA2LjY3MzgzIDQuNzIwNyA2LjY3MzgzIDUuMTExMzNINS4wNDQ5MkM1LjA0NDkyIDQuNjM4NjcgNC45Mzc1IDQuMjgxMjUgNC43MjI2NiA0LjAzOTA2QzQuNTA3ODEgMy43OTI5NyA0LjIxNjggMy42Njk5MiAzLjg0OTYxIDMuNjY5OTJDMy42NTAzOSAzLjY2OTkyIDMuNDc2NTYgMy42OTcyNyAzLjMyODEyIDMuNzUxOTVDMy4xODM1OSAzLjgwMjczIDMuMDY0NDUgMy44NzY5NSAyLjk3MDcgMy45NzQ2MUMyLjg3Njk1IDQuMDY4MzYgMi44MDY2NCA0LjE3OTY5IDIuNzU5NzcgNC4zMDg1OUMyLjcxNjggNC40Mzc1IDIuNjk1MzEgNC41NzgxMiAyLjY5NTMxIDQuNzMwNDdDMi42OTUzMSA0Ljg4MjgxIDIuNzE2OCA1LjAxOTUzIDIuNzU5NzcgNS4xNDA2MkMyLjgwNjY0IDUuMjU3ODEgMi44ODI4MSA1LjM2NzE5IDIuOTg4MjggNS40Njg3NUMzLjA5NzY2IDUuNTcwMzEgMy4yNDAyMyA1LjY2Nzk3IDMuNDE2MDIgNS43NjE3MkMzLjU5MTggNS44NTE1NiAzLjgxMDU1IDUuOTQzMzYgNC4wNzIyNyA2LjAzNzExQzQuNDY2OCA2LjE4NTU1IDQuODI0MjIgNi4zMzk4NCA1LjE0NDUzIDYuNUM1LjQ2NDg0IDYuNjU2MjUgNS43MzgyOCA2LjgzOTg0IDUuOTY0ODQgNy4wNTA3OEM2LjE5NTMxIDcuMjU3ODEgNi4zNzEwOSA3LjUgNi40OTIxOSA3Ljc3NzM0QzYuNjE3MTkgOC4wNTA3OCA2LjY3OTY5IDguMzc1IDYuNjc5NjkgOC43NUM2LjY3OTY5IDkuMDkzNzUgNi42MjMwNSA5LjQwNDMgNi41MDk3NyA5LjY4MTY0QzYuMzk2NDggOS45NTUwOCA2LjIzNDM4IDEwLjE5MTQgNi4wMjM0NCAxMC4zOTA2QzUuODEyNSAxMC41ODk4IDUuNTU4NTkgMTAuNzUgNS4yNjE3MiAxMC44NzExQzQuOTY0ODQgMTAuOTg4MyA0LjYzMjgxIDExLjA2NDUgNC4yNjU2MiAxMS4wOTk2VjEyLjI0OEgzLjMzMzk4VjExLjA5OTZDMy4wMDE5NSAxMS4wNjg0IDIuNjc5NjkgMTAuOTk2MSAyLjM2NzE5IDEwLjg4MjhDMi4wNTQ2OSAxMC43NjU2IDEuNzc3MzQgMTAuNTk3NyAxLjUzNTE2IDEwLjM3ODlDMS4yOTY4OCAxMC4xNjAyIDEuMTA1NDcgOS44ODQ3NyAwLjk2MDkzOCA5LjU1MjczQzAuODE2NDA2IDkuMjE2OCAwLjc0NDE0MSA4LjgxNDQ1IDAuNzQ0MTQxIDguMzQ1N0gyLjM3ODkxQzIuMzc4OTEgOC42MjY5NSAyLjQxOTkyIDguODYzMjggMi41MDE5NSA5LjA1NDY5QzIuNTgzOTggOS4yNDIxOSAyLjY4OTQ1IDkuMzkyNTggMi44MTgzNiA5LjUwNTg2QzIuOTUxMTcgOS42MTUyMyAzLjEwMTU2IDkuNjkzMzYgMy4yNjk1MyA5Ljc0MDIzQzMuNDM3NSA5Ljc4NzExIDMuNjA5MzggOS44MTA1NSAzLjc4NTE2IDkuODEwNTVDNC4yMDMxMiA5LjgxMDU1IDQuNTE5NTMgOS43MTI4OSA0LjczNDM4IDkuNTE3NThDNC45NDkyMiA5LjMyMjI3IDUuMDU2NjQgOS4wNzAzMSA1LjA1NjY0IDguNzYxNzJaTTEzLjQxOCAxMi4yNzE1SDguMDc0MjJWMTFIMTMuNDE4VjEyLjI3MTVaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzLjk1MjY0IDYpIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K); --jp-icon-text-editor: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8cGF0aCBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIiBkPSJNMTUgMTVIM3YyaDEydi0yem0wLThIM3YyaDEyVjd6TTMgMTNoMTh2LTJIM3Yyem0wIDhoMTh2LTJIM3Yyek0zIDN2MmgxOFYzSDN6Ii8+Cjwvc3ZnPgo=); --jp-icon-toc: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij4KICA8ZyBjbGFzcz0ianAtaWNvbjMganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjNjE2MTYxIj4KICAgIDxwYXRoIGQ9Ik03LDVIMjFWN0g3VjVNNywxM1YxMUgyMVYxM0g3TTQsNC41QTEuNSwxLjUgMCAwLDEgNS41LDZBMS41LDEuNSAwIDAsMSA0LDcuNUExLjUsMS41IDAgMCwxIDIuNSw2QTEuNSwxLjUgMCAwLDEgNCw0LjVNNCwxMC41QTEuNSwxLjUgMCAwLDEgNS41LDEyQTEuNSwxLjUgMCAwLDEgNCwxMy41QTEuNSwxLjUgMCAwLDEgMi41LDEyQTEuNSwxLjUgMCAwLDEgNCwxMC41TTcsMTlWMTdIMjFWMTlIN000LDE2LjVBMS41LDEuNSAwIDAsMSA1LjUsMThBMS41LDEuNSAwIDAsMSA0LDE5LjVBMS41LDEuNSAwIDAsMSAyLjUsMThBMS41LDEuNSAwIDAsMSA0LDE2LjVaIiAvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-tree-view: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGNsYXNzPSJqcC1pY29uMyIgZmlsbD0iIzYxNjE2MSI+CiAgICAgICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPgogICAgICAgIDxwYXRoIGQ9Ik0yMiAxMVYzaC03djNIOVYzSDJ2OGg3VjhoMnYxMGg0djNoN3YtOGgtN3YzaC0yVjhoMnYzeiIvPgogICAgPC9nPgo8L3N2Zz4=); --jp-icon-trusted: url(data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDI0IDI1Ij4KICAgIDxwYXRoIGNsYXNzPSJqcC1pY29uMiIgc3Ryb2tlPSIjMzMzMzMzIiBzdHJva2Utd2lkdGg9IjIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIgMykiIGQ9Ik0xLjg2MDk0IDExLjQ0MDlDMC44MjY0NDggOC43NzAyNyAwLjg2Mzc3OSA2LjA1NzY0IDEuMjQ5MDcgNC4xOTkzMkMyLjQ4MjA2IDMuOTMzNDcgNC4wODA2OCAzLjQwMzQ3IDUuNjAxMDIgMi44NDQ5QzcuMjM1NDkgMi4yNDQ0IDguODU2NjYgMS41ODE1IDkuOTg3NiAxLjA5NTM5QzExLjA1OTcgMS41ODM0MSAxMi42MDk0IDIuMjQ0NCAxNC4yMTggMi44NDMzOUMxNS43NTAzIDMuNDEzOTQgMTcuMzk5NSAzLjk1MjU4IDE4Ljc1MzkgNC4yMTM4NUMxOS4xMzY0IDYuMDcxNzcgMTkuMTcwOSA4Ljc3NzIyIDE4LjEzOSAxMS40NDA5QzE3LjAzMDMgMTQuMzAzMiAxNC42NjY4IDE3LjE4NDQgOS45OTk5OSAxOC45MzU0QzUuMzMzMiAxNy4xODQ0IDIuOTY5NjggMTQuMzAzMiAxLjg2MDk0IDExLjQ0MDlaIi8+CiAgICA8cGF0aCBjbGFzcz0ianAtaWNvbjIiIGZpbGw9IiMzMzMzMzMiIHN0cm9rZT0iIzMzMzMzMyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoOCA5Ljg2NzE5KSIgZD0iTTIuODYwMTUgNC44NjUzNUwwLjcyNjU0OSAyLjk5OTU5TDAgMy42MzA0NUwyLjg2MDE1IDYuMTMxNTdMOCAwLjYzMDg3Mkw3LjI3ODU3IDBMMi44NjAxNSA0Ljg2NTM1WiIvPgo8L3N2Zz4K); --jp-icon-undo: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHdpZHRoPSIxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZyBjbGFzcz0ianAtaWNvbjMiIGZpbGw9IiM2MTYxNjEiPgogICAgPHBhdGggZD0iTTEyLjUgOGMtMi42NSAwLTUuMDUuOTktNi45IDIuNkwyIDd2OWg5bC0zLjYyLTMuNjJjMS4zOS0xLjE2IDMuMTYtMS44OCA1LjEyLTEuODggMy41NCAwIDYuNTUgMi4zMSA3LjYgNS41bDIuMzctLjc4QzIxLjA4IDExLjAzIDE3LjE1IDggMTIuNSA4eiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-vega: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8ZyBjbGFzcz0ianAtaWNvbjEganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjMjEyMTIxIj4KICAgIDxwYXRoIGQ9Ik0xMC42IDUuNGwyLjItMy4ySDIuMnY3LjNsNC02LjZ6Ii8+CiAgICA8cGF0aCBkPSJNMTUuOCAyLjJsLTQuNCA2LjZMNyA2LjNsLTQuOCA4djUuNWgxNy42VjIuMmgtNHptLTcgMTUuNEg1LjV2LTQuNGgzLjN2NC40em00LjQgMEg5LjhWOS44aDMuNHY3Ljh6bTQuNCAwaC0zLjRWNi41aDMuNHYxMS4xeiIvPgogIDwvZz4KPC9zdmc+Cg==); --jp-icon-yaml: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgdmlld0JveD0iMCAwIDIyIDIyIj4KICA8ZyBjbGFzcz0ianAtaWNvbi1jb250cmFzdDIganAtaWNvbi1zZWxlY3RhYmxlIiBmaWxsPSIjRDgxQjYwIj4KICAgIDxwYXRoIGQ9Ik03LjIgMTguNnYtNS40TDMgNS42aDMuM2wxLjQgMy4xYy4zLjkuNiAxLjYgMSAyLjUuMy0uOC42LTEuNiAxLTIuNWwxLjQtMy4xaDMuNGwtNC40IDcuNnY1LjVsLTIuOS0uMXoiLz4KICAgIDxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjE3LjYiIGN5PSIxNi41IiByPSIyLjEiLz4KICAgIDxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjE3LjYiIGN5PSIxMSIgcj0iMi4xIi8+CiAgPC9nPgo8L3N2Zz4K); } /* Icon CSS class declarations */ .jp-AddIcon { background-image: var(--jp-icon-add); } .jp-BugIcon { background-image: var(--jp-icon-bug); } .jp-BuildIcon { background-image: var(--jp-icon-build); } .jp-CaretDownEmptyIcon { background-image: var(--jp-icon-caret-down-empty); } .jp-CaretDownEmptyThinIcon { background-image: var(--jp-icon-caret-down-empty-thin); } .jp-CaretDownIcon { background-image: var(--jp-icon-caret-down); } .jp-CaretLeftIcon { background-image: var(--jp-icon-caret-left); } .jp-CaretRightIcon { background-image: var(--jp-icon-caret-right); } .jp-CaretUpEmptyThinIcon { background-image: var(--jp-icon-caret-up-empty-thin); } .jp-CaretUpIcon { background-image: var(--jp-icon-caret-up); } .jp-CaseSensitiveIcon { background-image: var(--jp-icon-case-sensitive); } .jp-CheckIcon { background-image: var(--jp-icon-check); } .jp-CircleEmptyIcon { background-image: var(--jp-icon-circle-empty); } .jp-CircleIcon { background-image: var(--jp-icon-circle); } .jp-ClearIcon { background-image: var(--jp-icon-clear); } .jp-CloseIcon { background-image: var(--jp-icon-close); } .jp-CodeIcon { background-image: var(--jp-icon-code); } .jp-ConsoleIcon { background-image: var(--jp-icon-console); } .jp-CopyIcon { background-image: var(--jp-icon-copy); } .jp-CopyrightIcon { background-image: var(--jp-icon-copyright); } .jp-CutIcon { background-image: var(--jp-icon-cut); } .jp-DownloadIcon { background-image: var(--jp-icon-download); } .jp-EditIcon { background-image: var(--jp-icon-edit); } .jp-EllipsesIcon { background-image: var(--jp-icon-ellipses); } .jp-ExtensionIcon { background-image: var(--jp-icon-extension); } .jp-FastForwardIcon { background-image: var(--jp-icon-fast-forward); } .jp-FileIcon { background-image: var(--jp-icon-file); } .jp-FileUploadIcon { background-image: var(--jp-icon-file-upload); } .jp-FilterListIcon { background-image: var(--jp-icon-filter-list); } .jp-FolderIcon { background-image: var(--jp-icon-folder); } .jp-Html5Icon { background-image: var(--jp-icon-html5); } .jp-ImageIcon { background-image: var(--jp-icon-image); } .jp-InspectorIcon { background-image: var(--jp-icon-inspector); } .jp-JsonIcon { background-image: var(--jp-icon-json); } .jp-JuliaIcon { background-image: var(--jp-icon-julia); } .jp-JupyterFaviconIcon { background-image: var(--jp-icon-jupyter-favicon); } .jp-JupyterIcon { background-image: var(--jp-icon-jupyter); } .jp-JupyterlabWordmarkIcon { background-image: var(--jp-icon-jupyterlab-wordmark); } .jp-KernelIcon { background-image: var(--jp-icon-kernel); } .jp-KeyboardIcon { background-image: var(--jp-icon-keyboard); } .jp-LauncherIcon { background-image: var(--jp-icon-launcher); } .jp-LineFormIcon { background-image: var(--jp-icon-line-form); } .jp-LinkIcon { background-image: var(--jp-icon-link); } .jp-ListIcon { background-image: var(--jp-icon-list); } .jp-ListingsInfoIcon { background-image: var(--jp-icon-listings-info); } .jp-MarkdownIcon { background-image: var(--jp-icon-markdown); } .jp-NewFolderIcon { background-image: var(--jp-icon-new-folder); } .jp-NotTrustedIcon { background-image: var(--jp-icon-not-trusted); } .jp-NotebookIcon { background-image: var(--jp-icon-notebook); } .jp-NumberingIcon { background-image: var(--jp-icon-numbering); } .jp-OfflineBoltIcon { background-image: var(--jp-icon-offline-bolt); } .jp-PaletteIcon { background-image: var(--jp-icon-palette); } .jp-PasteIcon { background-image: var(--jp-icon-paste); } .jp-PdfIcon { background-image: var(--jp-icon-pdf); } .jp-PythonIcon { background-image: var(--jp-icon-python); } .jp-RKernelIcon { background-image: var(--jp-icon-r-kernel); } .jp-ReactIcon { background-image: var(--jp-icon-react); } .jp-RedoIcon { background-image: var(--jp-icon-redo); } .jp-RefreshIcon { background-image: var(--jp-icon-refresh); } .jp-RegexIcon { background-image: var(--jp-icon-regex); } .jp-RunIcon { background-image: var(--jp-icon-run); } .jp-RunningIcon { background-image: var(--jp-icon-running); } .jp-SaveIcon { background-image: var(--jp-icon-save); } .jp-SearchIcon { background-image: var(--jp-icon-search); } .jp-SettingsIcon { background-image: var(--jp-icon-settings); } .jp-SpreadsheetIcon { background-image: var(--jp-icon-spreadsheet); } .jp-StopIcon { background-image: var(--jp-icon-stop); } .jp-TabIcon { background-image: var(--jp-icon-tab); } .jp-TableRowsIcon { background-image: var(--jp-icon-table-rows); } .jp-TagIcon { background-image: var(--jp-icon-tag); } .jp-TerminalIcon { background-image: var(--jp-icon-terminal); } .jp-TextEditorIcon { background-image: var(--jp-icon-text-editor); } .jp-TocIcon { background-image: var(--jp-icon-toc); } .jp-TreeViewIcon { background-image: var(--jp-icon-tree-view); } .jp-TrustedIcon { background-image: var(--jp-icon-trusted); } .jp-UndoIcon { background-image: var(--jp-icon-undo); } .jp-VegaIcon { background-image: var(--jp-icon-vega); } .jp-YamlIcon { background-image: var(--jp-icon-yaml); } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /** * (DEPRECATED) Support for consuming icons as CSS background images */ .jp-Icon, .jp-MaterialIcon { background-position: center; background-repeat: no-repeat; background-size: 16px; min-width: 16px; min-height: 16px; } .jp-Icon-cover { background-position: center; background-repeat: no-repeat; background-size: cover; } /** * (DEPRECATED) Support for specific CSS icon sizes */ .jp-Icon-16 { background-size: 16px; min-width: 16px; min-height: 16px; } .jp-Icon-18 { background-size: 18px; min-width: 18px; min-height: 18px; } .jp-Icon-20 { background-size: 20px; min-width: 20px; min-height: 20px; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /** * Support for icons as inline SVG HTMLElements */ /* recolor the primary elements of an icon */ .jp-icon0[fill] { fill: var(--jp-inverse-layout-color0); } .jp-icon1[fill] { fill: var(--jp-inverse-layout-color1); } .jp-icon2[fill] { fill: var(--jp-inverse-layout-color2); } .jp-icon3[fill] { fill: var(--jp-inverse-layout-color3); } .jp-icon4[fill] { fill: var(--jp-inverse-layout-color4); } .jp-icon0[stroke] { stroke: var(--jp-inverse-layout-color0); } .jp-icon1[stroke] { stroke: var(--jp-inverse-layout-color1); } .jp-icon2[stroke] { stroke: var(--jp-inverse-layout-color2); } .jp-icon3[stroke] { stroke: var(--jp-inverse-layout-color3); } .jp-icon4[stroke] { stroke: var(--jp-inverse-layout-color4); } /* recolor the accent elements of an icon */ .jp-icon-accent0[fill] { fill: var(--jp-layout-color0); } .jp-icon-accent1[fill] { fill: var(--jp-layout-color1); } .jp-icon-accent2[fill] { fill: var(--jp-layout-color2); } .jp-icon-accent3[fill] { fill: var(--jp-layout-color3); } .jp-icon-accent4[fill] { fill: var(--jp-layout-color4); } .jp-icon-accent0[stroke] { stroke: var(--jp-layout-color0); } .jp-icon-accent1[stroke] { stroke: var(--jp-layout-color1); } .jp-icon-accent2[stroke] { stroke: var(--jp-layout-color2); } .jp-icon-accent3[stroke] { stroke: var(--jp-layout-color3); } .jp-icon-accent4[stroke] { stroke: var(--jp-layout-color4); } /* set the color of an icon to transparent */ .jp-icon-none[fill] { fill: none; } .jp-icon-none[stroke] { stroke: none; } /* brand icon colors. Same for light and dark */ .jp-icon-brand0[fill] { fill: var(--jp-brand-color0); } .jp-icon-brand1[fill] { fill: var(--jp-brand-color1); } .jp-icon-brand2[fill] { fill: var(--jp-brand-color2); } .jp-icon-brand3[fill] { fill: var(--jp-brand-color3); } .jp-icon-brand4[fill] { fill: var(--jp-brand-color4); } .jp-icon-brand0[stroke] { stroke: var(--jp-brand-color0); } .jp-icon-brand1[stroke] { stroke: var(--jp-brand-color1); } .jp-icon-brand2[stroke] { stroke: var(--jp-brand-color2); } .jp-icon-brand3[stroke] { stroke: var(--jp-brand-color3); } .jp-icon-brand4[stroke] { stroke: var(--jp-brand-color4); } /* warn icon colors. Same for light and dark */ .jp-icon-warn0[fill] { fill: var(--jp-warn-color0); } .jp-icon-warn1[fill] { fill: var(--jp-warn-color1); } .jp-icon-warn2[fill] { fill: var(--jp-warn-color2); } .jp-icon-warn3[fill] { fill: var(--jp-warn-color3); } .jp-icon-warn0[stroke] { stroke: var(--jp-warn-color0); } .jp-icon-warn1[stroke] { stroke: var(--jp-warn-color1); } .jp-icon-warn2[stroke] { stroke: var(--jp-warn-color2); } .jp-icon-warn3[stroke] { stroke: var(--jp-warn-color3); } /* icon colors that contrast well with each other and most backgrounds */ .jp-icon-contrast0[fill] { fill: var(--jp-icon-contrast-color0); } .jp-icon-contrast1[fill] { fill: var(--jp-icon-contrast-color1); } .jp-icon-contrast2[fill] { fill: var(--jp-icon-contrast-color2); } .jp-icon-contrast3[fill] { fill: var(--jp-icon-contrast-color3); } .jp-icon-contrast0[stroke] { stroke: var(--jp-icon-contrast-color0); } .jp-icon-contrast1[stroke] { stroke: var(--jp-icon-contrast-color1); } .jp-icon-contrast2[stroke] { stroke: var(--jp-icon-contrast-color2); } .jp-icon-contrast3[stroke] { stroke: var(--jp-icon-contrast-color3); } /* CSS for icons in selected items in the settings editor */ #setting-editor .jp-PluginList .jp-mod-selected .jp-icon-selectable[fill] { fill: #fff; } #setting-editor .jp-PluginList .jp-mod-selected .jp-icon-selectable-inverse[fill] { fill: var(--jp-brand-color1); } /* CSS for icons in selected filebrowser listing items */ .jp-DirListing-item.jp-mod-selected .jp-icon-selectable[fill] { fill: #fff; } .jp-DirListing-item.jp-mod-selected .jp-icon-selectable-inverse[fill] { fill: var(--jp-brand-color1); } /* CSS for icons in selected tabs in the sidebar tab manager */ #tab-manager .lm-TabBar-tab.jp-mod-active .jp-icon-selectable[fill] { fill: #fff; } #tab-manager .lm-TabBar-tab.jp-mod-active .jp-icon-selectable-inverse[fill] { fill: var(--jp-brand-color1); } #tab-manager .lm-TabBar-tab.jp-mod-active .jp-icon-hover :hover .jp-icon-selectable[fill] { fill: var(--jp-brand-color1); } #tab-manager .lm-TabBar-tab.jp-mod-active .jp-icon-hover :hover .jp-icon-selectable-inverse[fill] { fill: #fff; } /** * TODO: come up with non css-hack solution for showing the busy icon on top * of the close icon * CSS for complex behavior of close icon of tabs in the sidebar tab manager */ #tab-manager .lm-TabBar-tab.jp-mod-dirty > .lm-TabBar-tabCloseIcon > :not(:hover) > .jp-icon3[fill] { fill: none; } #tab-manager .lm-TabBar-tab.jp-mod-dirty > .lm-TabBar-tabCloseIcon > :not(:hover) > .jp-icon-busy[fill] { fill: var(--jp-inverse-layout-color3); } #tab-manager .lm-TabBar-tab.jp-mod-dirty.jp-mod-active > .lm-TabBar-tabCloseIcon > :not(:hover) > .jp-icon-busy[fill] { fill: #fff; } /** * TODO: come up with non css-hack solution for showing the busy icon on top * of the close icon * CSS for complex behavior of close icon of tabs in the main area tabbar */ .lm-DockPanel-tabBar .lm-TabBar-tab.lm-mod-closable.jp-mod-dirty > .lm-TabBar-tabCloseIcon > :not(:hover) > .jp-icon3[fill] { fill: none; } .lm-DockPanel-tabBar .lm-TabBar-tab.lm-mod-closable.jp-mod-dirty > .lm-TabBar-tabCloseIcon > :not(:hover) > .jp-icon-busy[fill] { fill: var(--jp-inverse-layout-color3); } /* CSS for icons in status bar */ #jp-main-statusbar .jp-mod-selected .jp-icon-selectable[fill] { fill: #fff; } #jp-main-statusbar .jp-mod-selected .jp-icon-selectable-inverse[fill] { fill: var(--jp-brand-color1); } /* special handling for splash icon CSS. While the theme CSS reloads during splash, the splash icon can loose theming. To prevent that, we set a default for its color variable */ :root { --jp-warn-color0: var(--md-orange-700); } /* not sure what to do with this one, used in filebrowser listing */ .jp-DragIcon { margin-right: 4px; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /** * Support for alt colors for icons as inline SVG HTMLElements */ /* alt recolor the primary elements of an icon */ .jp-icon-alt .jp-icon0[fill] { fill: var(--jp-layout-color0); } .jp-icon-alt .jp-icon1[fill] { fill: var(--jp-layout-color1); } .jp-icon-alt .jp-icon2[fill] { fill: var(--jp-layout-color2); } .jp-icon-alt .jp-icon3[fill] { fill: var(--jp-layout-color3); } .jp-icon-alt .jp-icon4[fill] { fill: var(--jp-layout-color4); } .jp-icon-alt .jp-icon0[stroke] { stroke: var(--jp-layout-color0); } .jp-icon-alt .jp-icon1[stroke] { stroke: var(--jp-layout-color1); } .jp-icon-alt .jp-icon2[stroke] { stroke: var(--jp-layout-color2); } .jp-icon-alt .jp-icon3[stroke] { stroke: var(--jp-layout-color3); } .jp-icon-alt .jp-icon4[stroke] { stroke: var(--jp-layout-color4); } /* alt recolor the accent elements of an icon */ .jp-icon-alt .jp-icon-accent0[fill] { fill: var(--jp-inverse-layout-color0); } .jp-icon-alt .jp-icon-accent1[fill] { fill: var(--jp-inverse-layout-color1); } .jp-icon-alt .jp-icon-accent2[fill] { fill: var(--jp-inverse-layout-color2); } .jp-icon-alt .jp-icon-accent3[fill] { fill: var(--jp-inverse-layout-color3); } .jp-icon-alt .jp-icon-accent4[fill] { fill: var(--jp-inverse-layout-color4); } .jp-icon-alt .jp-icon-accent0[stroke] { stroke: var(--jp-inverse-layout-color0); } .jp-icon-alt .jp-icon-accent1[stroke] { stroke: var(--jp-inverse-layout-color1); } .jp-icon-alt .jp-icon-accent2[stroke] { stroke: var(--jp-inverse-layout-color2); } .jp-icon-alt .jp-icon-accent3[stroke] { stroke: var(--jp-inverse-layout-color3); } .jp-icon-alt .jp-icon-accent4[stroke] { stroke: var(--jp-inverse-layout-color4); } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-icon-hoverShow:not(:hover) svg { display: none !important; } /** * Support for hover colors for icons as inline SVG HTMLElements */ /** * regular colors */ /* recolor the primary elements of an icon */ .jp-icon-hover :hover .jp-icon0-hover[fill] { fill: var(--jp-inverse-layout-color0); } .jp-icon-hover :hover .jp-icon1-hover[fill] { fill: var(--jp-inverse-layout-color1); } .jp-icon-hover :hover .jp-icon2-hover[fill] { fill: var(--jp-inverse-layout-color2); } .jp-icon-hover :hover .jp-icon3-hover[fill] { fill: var(--jp-inverse-layout-color3); } .jp-icon-hover :hover .jp-icon4-hover[fill] { fill: var(--jp-inverse-layout-color4); } .jp-icon-hover :hover .jp-icon0-hover[stroke] { stroke: var(--jp-inverse-layout-color0); } .jp-icon-hover :hover .jp-icon1-hover[stroke] { stroke: var(--jp-inverse-layout-color1); } .jp-icon-hover :hover .jp-icon2-hover[stroke] { stroke: var(--jp-inverse-layout-color2); } .jp-icon-hover :hover .jp-icon3-hover[stroke] { stroke: var(--jp-inverse-layout-color3); } .jp-icon-hover :hover .jp-icon4-hover[stroke] { stroke: var(--jp-inverse-layout-color4); } /* recolor the accent elements of an icon */ .jp-icon-hover :hover .jp-icon-accent0-hover[fill] { fill: var(--jp-layout-color0); } .jp-icon-hover :hover .jp-icon-accent1-hover[fill] { fill: var(--jp-layout-color1); } .jp-icon-hover :hover .jp-icon-accent2-hover[fill] { fill: var(--jp-layout-color2); } .jp-icon-hover :hover .jp-icon-accent3-hover[fill] { fill: var(--jp-layout-color3); } .jp-icon-hover :hover .jp-icon-accent4-hover[fill] { fill: var(--jp-layout-color4); } .jp-icon-hover :hover .jp-icon-accent0-hover[stroke] { stroke: var(--jp-layout-color0); } .jp-icon-hover :hover .jp-icon-accent1-hover[stroke] { stroke: var(--jp-layout-color1); } .jp-icon-hover :hover .jp-icon-accent2-hover[stroke] { stroke: var(--jp-layout-color2); } .jp-icon-hover :hover .jp-icon-accent3-hover[stroke] { stroke: var(--jp-layout-color3); } .jp-icon-hover :hover .jp-icon-accent4-hover[stroke] { stroke: var(--jp-layout-color4); } /* set the color of an icon to transparent */ .jp-icon-hover :hover .jp-icon-none-hover[fill] { fill: none; } .jp-icon-hover :hover .jp-icon-none-hover[stroke] { stroke: none; } /** * inverse colors */ /* inverse recolor the primary elements of an icon */ .jp-icon-hover.jp-icon-alt :hover .jp-icon0-hover[fill] { fill: var(--jp-layout-color0); } .jp-icon-hover.jp-icon-alt :hover .jp-icon1-hover[fill] { fill: var(--jp-layout-color1); } .jp-icon-hover.jp-icon-alt :hover .jp-icon2-hover[fill] { fill: var(--jp-layout-color2); } .jp-icon-hover.jp-icon-alt :hover .jp-icon3-hover[fill] { fill: var(--jp-layout-color3); } .jp-icon-hover.jp-icon-alt :hover .jp-icon4-hover[fill] { fill: var(--jp-layout-color4); } .jp-icon-hover.jp-icon-alt :hover .jp-icon0-hover[stroke] { stroke: var(--jp-layout-color0); } .jp-icon-hover.jp-icon-alt :hover .jp-icon1-hover[stroke] { stroke: var(--jp-layout-color1); } .jp-icon-hover.jp-icon-alt :hover .jp-icon2-hover[stroke] { stroke: var(--jp-layout-color2); } .jp-icon-hover.jp-icon-alt :hover .jp-icon3-hover[stroke] { stroke: var(--jp-layout-color3); } .jp-icon-hover.jp-icon-alt :hover .jp-icon4-hover[stroke] { stroke: var(--jp-layout-color4); } /* inverse recolor the accent elements of an icon */ .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent0-hover[fill] { fill: var(--jp-inverse-layout-color0); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent1-hover[fill] { fill: var(--jp-inverse-layout-color1); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent2-hover[fill] { fill: var(--jp-inverse-layout-color2); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent3-hover[fill] { fill: var(--jp-inverse-layout-color3); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent4-hover[fill] { fill: var(--jp-inverse-layout-color4); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent0-hover[stroke] { stroke: var(--jp-inverse-layout-color0); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent1-hover[stroke] { stroke: var(--jp-inverse-layout-color1); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent2-hover[stroke] { stroke: var(--jp-inverse-layout-color2); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent3-hover[stroke] { stroke: var(--jp-inverse-layout-color3); } .jp-icon-hover.jp-icon-alt :hover .jp-icon-accent4-hover[stroke] { stroke: var(--jp-inverse-layout-color4); } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-switch { display: flex; align-items: center; padding-left: 4px; padding-right: 4px; font-size: var(--jp-ui-font-size1); background-color: transparent; color: var(--jp-ui-font-color1); border: none; height: 20px; } .jp-switch:hover { background-color: var(--jp-layout-color2); } .jp-switch-label { margin-right: 5px; } .jp-switch-track { cursor: pointer; background-color: var(--jp-border-color1); -webkit-transition: 0.4s; transition: 0.4s; border-radius: 34px; height: 16px; width: 35px; position: relative; } .jp-switch-track::before { content: ''; position: absolute; height: 10px; width: 10px; margin: 3px; left: 0px; background-color: var(--jp-ui-inverse-font-color1); -webkit-transition: 0.4s; transition: 0.4s; border-radius: 50%; } .jp-switch[aria-checked='true'] .jp-switch-track { background-color: var(--jp-warn-color0); } .jp-switch[aria-checked='true'] .jp-switch-track::before { /* track width (35) - margins (3 + 3) - thumb width (10) */ left: 19px; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /* Sibling imports */ /* Override Blueprint's _reset.scss styles */ html { box-sizing: unset; } *, *::before, *::after { box-sizing: unset; } body { color: unset; font-family: var(--jp-ui-font-family); } p { margin-top: unset; margin-bottom: unset; } small { font-size: unset; } strong { font-weight: unset; } /* Override Blueprint's _typography.scss styles */ a { text-decoration: unset; color: unset; } a:hover { text-decoration: unset; color: unset; } /* Override Blueprint's _accessibility.scss styles */ :focus { outline: unset; outline-offset: unset; -moz-outline-radius: unset; } /* Styles for ui-components */ .jp-Button { border-radius: var(--jp-border-radius); padding: 0px 12px; font-size: var(--jp-ui-font-size1); } /* Use our own theme for hover styles */ button.jp-Button.bp3-button.bp3-minimal:hover { background-color: var(--jp-layout-color2); } .jp-Button.minimal { color: unset !important; } .jp-Button.jp-ToolbarButtonComponent { text-transform: none; } .jp-InputGroup input { box-sizing: border-box; border-radius: 0; background-color: transparent; color: var(--jp-ui-font-color0); box-shadow: inset 0 0 0 var(--jp-border-width) var(--jp-input-border-color); } .jp-InputGroup input:focus { box-shadow: inset 0 0 0 var(--jp-border-width) var(--jp-input-active-box-shadow-color), inset 0 0 0 3px var(--jp-input-active-box-shadow-color); } .jp-InputGroup input::placeholder, input::placeholder { color: var(--jp-ui-font-color3); } .jp-BPIcon { display: inline-block; vertical-align: middle; margin: auto; } /* Stop blueprint futzing with our icon fills */ .bp3-icon.jp-BPIcon > svg:not([fill]) { fill: var(--jp-inverse-layout-color3); } .jp-InputGroupAction { padding: 6px; } .jp-HTMLSelect.jp-DefaultStyle select { background-color: initial; border: none; border-radius: 0; box-shadow: none; color: var(--jp-ui-font-color0); display: block; font-size: var(--jp-ui-font-size1); height: 24px; line-height: 14px; padding: 0 25px 0 10px; text-align: left; -moz-appearance: none; -webkit-appearance: none; } /* Use our own theme for hover and option styles */ .jp-HTMLSelect.jp-DefaultStyle select:hover, .jp-HTMLSelect.jp-DefaultStyle select > option { background-color: var(--jp-layout-color2); color: var(--jp-ui-font-color0); } select { box-sizing: border-box; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-Collapse { display: flex; flex-direction: column; align-items: stretch; border-top: 1px solid var(--jp-border-color2); border-bottom: 1px solid var(--jp-border-color2); } .jp-Collapse-header { padding: 1px 12px; color: var(--jp-ui-font-color1); background-color: var(--jp-layout-color1); font-size: var(--jp-ui-font-size2); } .jp-Collapse-header:hover { background-color: var(--jp-layout-color2); } .jp-Collapse-contents { padding: 0px 12px 0px 12px; background-color: var(--jp-layout-color1); color: var(--jp-ui-font-color1); overflow: auto; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Variables |----------------------------------------------------------------------------*/ :root { --jp-private-commandpalette-search-height: 28px; } /*----------------------------------------------------------------------------- | Overall styles |----------------------------------------------------------------------------*/ .lm-CommandPalette { padding-bottom: 0px; color: var(--jp-ui-font-color1); background: var(--jp-layout-color1); /* This is needed so that all font sizing of children done in ems is * relative to this base size */ font-size: var(--jp-ui-font-size1); } /*----------------------------------------------------------------------------- | Modal variant |----------------------------------------------------------------------------*/ .jp-ModalCommandPalette { position: absolute; z-index: 10000; top: 38px; left: 30%; margin: 0; padding: 4px; width: 40%; box-shadow: var(--jp-elevation-z4); border-radius: 4px; background: var(--jp-layout-color0); } .jp-ModalCommandPalette .lm-CommandPalette { max-height: 40vh; } .jp-ModalCommandPalette .lm-CommandPalette .lm-close-icon::after { display: none; } .jp-ModalCommandPalette .lm-CommandPalette .lm-CommandPalette-header { display: none; } .jp-ModalCommandPalette .lm-CommandPalette .lm-CommandPalette-item { margin-left: 4px; margin-right: 4px; } .jp-ModalCommandPalette .lm-CommandPalette .lm-CommandPalette-item.lm-mod-disabled { display: none; } /*----------------------------------------------------------------------------- | Search |----------------------------------------------------------------------------*/ .lm-CommandPalette-search { padding: 4px; background-color: var(--jp-layout-color1); z-index: 2; } .lm-CommandPalette-wrapper { overflow: overlay; padding: 0px 9px; background-color: var(--jp-input-active-background); height: 30px; box-shadow: inset 0 0 0 var(--jp-border-width) var(--jp-input-border-color); } .lm-CommandPalette.lm-mod-focused .lm-CommandPalette-wrapper { box-shadow: inset 0 0 0 1px var(--jp-input-active-box-shadow-color), inset 0 0 0 3px var(--jp-input-active-box-shadow-color); } .jp-SearchIconGroup { color: white; background-color: var(--jp-brand-color1); position: absolute; top: 4px; right: 4px; padding: 5px 5px 1px 5px; } .jp-SearchIconGroup svg { height: 20px; width: 20px; } .jp-SearchIconGroup .jp-icon3[fill] { fill: var(--jp-layout-color0); } .lm-CommandPalette-input { background: transparent; width: calc(100% - 18px); float: left; border: none; outline: none; font-size: var(--jp-ui-font-size1); color: var(--jp-ui-font-color0); line-height: var(--jp-private-commandpalette-search-height); } .lm-CommandPalette-input::-webkit-input-placeholder, .lm-CommandPalette-input::-moz-placeholder, .lm-CommandPalette-input:-ms-input-placeholder { color: var(--jp-ui-font-color2); font-size: var(--jp-ui-font-size1); } /*----------------------------------------------------------------------------- | Results |----------------------------------------------------------------------------*/ .lm-CommandPalette-header:first-child { margin-top: 0px; } .lm-CommandPalette-header { border-bottom: solid var(--jp-border-width) var(--jp-border-color2); color: var(--jp-ui-font-color1); cursor: pointer; display: flex; font-size: var(--jp-ui-font-size0); font-weight: 600; letter-spacing: 1px; margin-top: 8px; padding: 8px 0 8px 12px; text-transform: uppercase; } .lm-CommandPalette-header.lm-mod-active { background: var(--jp-layout-color2); } .lm-CommandPalette-header > mark { background-color: transparent; font-weight: bold; color: var(--jp-ui-font-color1); } .lm-CommandPalette-item { padding: 4px 12px 4px 4px; color: var(--jp-ui-font-color1); font-size: var(--jp-ui-font-size1); font-weight: 400; display: flex; } .lm-CommandPalette-item.lm-mod-disabled { color: var(--jp-ui-font-color2); } .lm-CommandPalette-item.lm-mod-active { color: var(--jp-ui-inverse-font-color1); background: var(--jp-brand-color1); } .lm-CommandPalette-item.lm-mod-active .lm-CommandPalette-itemLabel > mark { color: var(--jp-ui-inverse-font-color0); } .lm-CommandPalette-item.lm-mod-active .jp-icon-selectable[fill] { fill: var(--jp-layout-color0); } .lm-CommandPalette-item.lm-mod-active .lm-CommandPalette-itemLabel > mark { color: var(--jp-ui-inverse-font-color0); } .lm-CommandPalette-item.lm-mod-active:hover:not(.lm-mod-disabled) { color: var(--jp-ui-inverse-font-color1); background: var(--jp-brand-color1); } .lm-CommandPalette-item:hover:not(.lm-mod-active):not(.lm-mod-disabled) { background: var(--jp-layout-color2); } .lm-CommandPalette-itemContent { overflow: hidden; } .lm-CommandPalette-itemLabel > mark { color: var(--jp-ui-font-color0); background-color: transparent; font-weight: bold; } .lm-CommandPalette-item.lm-mod-disabled mark { color: var(--jp-ui-font-color2); } .lm-CommandPalette-item .lm-CommandPalette-itemIcon { margin: 0 4px 0 0; position: relative; width: 16px; top: 2px; flex: 0 0 auto; } .lm-CommandPalette-item.lm-mod-disabled .lm-CommandPalette-itemIcon { opacity: 0.6; } .lm-CommandPalette-item .lm-CommandPalette-itemShortcut { flex: 0 0 auto; } .lm-CommandPalette-itemCaption { display: none; } .lm-CommandPalette-content { background-color: var(--jp-layout-color1); } .lm-CommandPalette-content:empty:after { content: 'No results'; margin: auto; margin-top: 20px; width: 100px; display: block; font-size: var(--jp-ui-font-size2); font-family: var(--jp-ui-font-family); font-weight: lighter; } .lm-CommandPalette-emptyMessage { text-align: center; margin-top: 24px; line-height: 1.32; padding: 0px 8px; color: var(--jp-content-font-color3); } /*----------------------------------------------------------------------------- | Copyright (c) 2014-2017, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-Dialog { position: absolute; z-index: 10000; display: flex; flex-direction: column; align-items: center; justify-content: center; top: 0px; left: 0px; margin: 0; padding: 0; width: 100%; height: 100%; background: var(--jp-dialog-background); } .jp-Dialog-content { display: flex; flex-direction: column; margin-left: auto; margin-right: auto; background: var(--jp-layout-color1); padding: 24px; padding-bottom: 12px; min-width: 300px; min-height: 150px; max-width: 1000px; max-height: 500px; box-sizing: border-box; box-shadow: var(--jp-elevation-z20); word-wrap: break-word; border-radius: var(--jp-border-radius); /* This is needed so that all font sizing of children done in ems is * relative to this base size */ font-size: var(--jp-ui-font-size1); color: var(--jp-ui-font-color1); resize: both; } .jp-Dialog-button { overflow: visible; } button.jp-Dialog-button:focus { outline: 1px solid var(--jp-brand-color1); outline-offset: 4px; -moz-outline-radius: 0px; } button.jp-Dialog-button:focus::-moz-focus-inner { border: 0; } button.jp-Dialog-close-button { padding: 0; height: 100%; min-width: unset; min-height: unset; } .jp-Dialog-header { display: flex; justify-content: space-between; flex: 0 0 auto; padding-bottom: 12px; font-size: var(--jp-ui-font-size3); font-weight: 400; color: var(--jp-ui-font-color0); } .jp-Dialog-body { display: flex; flex-direction: column; flex: 1 1 auto; font-size: var(--jp-ui-font-size1); background: var(--jp-layout-color1); overflow: auto; } .jp-Dialog-footer { display: flex; flex-direction: row; justify-content: flex-end; flex: 0 0 auto; margin-left: -12px; margin-right: -12px; padding: 12px; } .jp-Dialog-title { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .jp-Dialog-body > .jp-select-wrapper { width: 100%; } .jp-Dialog-body > button { padding: 0px 16px; } .jp-Dialog-body > label { line-height: 1.4; color: var(--jp-ui-font-color0); } .jp-Dialog-button.jp-mod-styled:not(:last-child) { margin-right: 12px; } /*----------------------------------------------------------------------------- | Copyright (c) 2014-2016, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-HoverBox { position: fixed; } .jp-HoverBox.jp-mod-outofview { display: none; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-IFrame { width: 100%; height: 100%; } .jp-IFrame > iframe { border: none; } /* When drag events occur, `p-mod-override-cursor` is added to the body. Because iframes steal all cursor events, the following two rules are necessary to suppress pointer events while resize drags are occurring. There may be a better solution to this problem. */ body.lm-mod-override-cursor .jp-IFrame { position: relative; } body.lm-mod-override-cursor .jp-IFrame:before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: transparent; } .jp-Input-Boolean-Dialog { flex-direction: row-reverse; align-items: end; width: 100%; } .jp-Input-Boolean-Dialog > label { flex: 1 1 auto; } /*----------------------------------------------------------------------------- | Copyright (c) 2014-2016, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-MainAreaWidget > :focus { outline: none; } /** * google-material-color v1.2.6 * https://github.com/danlevan/google-material-color */ :root { --md-red-50: #ffebee; --md-red-100: #ffcdd2; --md-red-200: #ef9a9a; --md-red-300: #e57373; --md-red-400: #ef5350; --md-red-500: #f44336; --md-red-600: #e53935; --md-red-700: #d32f2f; --md-red-800: #c62828; --md-red-900: #b71c1c; --md-red-A100: #ff8a80; --md-red-A200: #ff5252; --md-red-A400: #ff1744; --md-red-A700: #d50000; --md-pink-50: #fce4ec; --md-pink-100: #f8bbd0; --md-pink-200: #f48fb1; --md-pink-300: #f06292; --md-pink-400: #ec407a; --md-pink-500: #e91e63; --md-pink-600: #d81b60; --md-pink-700: #c2185b; --md-pink-800: #ad1457; --md-pink-900: #880e4f; --md-pink-A100: #ff80ab; --md-pink-A200: #ff4081; --md-pink-A400: #f50057; --md-pink-A700: #c51162; --md-purple-50: #f3e5f5; --md-purple-100: #e1bee7; --md-purple-200: #ce93d8; --md-purple-300: #ba68c8; --md-purple-400: #ab47bc; --md-purple-500: #9c27b0; --md-purple-600: #8e24aa; --md-purple-700: #7b1fa2; --md-purple-800: #6a1b9a; --md-purple-900: #4a148c; --md-purple-A100: #ea80fc; --md-purple-A200: #e040fb; --md-purple-A400: #d500f9; --md-purple-A700: #aa00ff; --md-deep-purple-50: #ede7f6; --md-deep-purple-100: #d1c4e9; --md-deep-purple-200: #b39ddb; --md-deep-purple-300: #9575cd; --md-deep-purple-400: #7e57c2; --md-deep-purple-500: #673ab7; --md-deep-purple-600: #5e35b1; --md-deep-purple-700: #512da8; --md-deep-purple-800: #4527a0; --md-deep-purple-900: #311b92; --md-deep-purple-A100: #b388ff; --md-deep-purple-A200: #7c4dff; --md-deep-purple-A400: #651fff; --md-deep-purple-A700: #6200ea; --md-indigo-50: #e8eaf6; --md-indigo-100: #c5cae9; --md-indigo-200: #9fa8da; --md-indigo-300: #7986cb; --md-indigo-400: #5c6bc0; --md-indigo-500: #3f51b5; --md-indigo-600: #3949ab; --md-indigo-700: #303f9f; --md-indigo-800: #283593; --md-indigo-900: #1a237e; --md-indigo-A100: #8c9eff; --md-indigo-A200: #536dfe; --md-indigo-A400: #3d5afe; --md-indigo-A700: #304ffe; --md-blue-50: #e3f2fd; --md-blue-100: #bbdefb; --md-blue-200: #90caf9; --md-blue-300: #64b5f6; --md-blue-400: #42a5f5; --md-blue-500: #2196f3; --md-blue-600: #1e88e5; --md-blue-700: #1976d2; --md-blue-800: #1565c0; --md-blue-900: #0d47a1; --md-blue-A100: #82b1ff; --md-blue-A200: #448aff; --md-blue-A400: #2979ff; --md-blue-A700: #2962ff; --md-light-blue-50: #e1f5fe; --md-light-blue-100: #b3e5fc; --md-light-blue-200: #81d4fa; --md-light-blue-300: #4fc3f7; --md-light-blue-400: #29b6f6; --md-light-blue-500: #03a9f4; --md-light-blue-600: #039be5; --md-light-blue-700: #0288d1; --md-light-blue-800: #0277bd; --md-light-blue-900: #01579b; --md-light-blue-A100: #80d8ff; --md-light-blue-A200: #40c4ff; --md-light-blue-A400: #00b0ff; --md-light-blue-A700: #0091ea; --md-cyan-50: #e0f7fa; --md-cyan-100: #b2ebf2; --md-cyan-200: #80deea; --md-cyan-300: #4dd0e1; --md-cyan-400: #26c6da; --md-cyan-500: #00bcd4; --md-cyan-600: #00acc1; --md-cyan-700: #0097a7; --md-cyan-800: #00838f; --md-cyan-900: #006064; --md-cyan-A100: #84ffff; --md-cyan-A200: #18ffff; --md-cyan-A400: #00e5ff; --md-cyan-A700: #00b8d4; --md-teal-50: #e0f2f1; --md-teal-100: #b2dfdb; --md-teal-200: #80cbc4; --md-teal-300: #4db6ac; --md-teal-400: #26a69a; --md-teal-500: #009688; --md-teal-600: #00897b; --md-teal-700: #00796b; --md-teal-800: #00695c; --md-teal-900: #004d40; --md-teal-A100: #a7ffeb; --md-teal-A200: #64ffda; --md-teal-A400: #1de9b6; --md-teal-A700: #00bfa5; --md-green-50: #e8f5e9; --md-green-100: #c8e6c9; --md-green-200: #a5d6a7; --md-green-300: #81c784; --md-green-400: #66bb6a; --md-green-500: #4caf50; --md-green-600: #43a047; --md-green-700: #388e3c; --md-green-800: #2e7d32; --md-green-900: #1b5e20; --md-green-A100: #b9f6ca; --md-green-A200: #69f0ae; --md-green-A400: #00e676; --md-green-A700: #00c853; --md-light-green-50: #f1f8e9; --md-light-green-100: #dcedc8; --md-light-green-200: #c5e1a5; --md-light-green-300: #aed581; --md-light-green-400: #9ccc65; --md-light-green-500: #8bc34a; --md-light-green-600: #7cb342; --md-light-green-700: #689f38; --md-light-green-800: #558b2f; --md-light-green-900: #33691e; --md-light-green-A100: #ccff90; --md-light-green-A200: #b2ff59; --md-light-green-A400: #76ff03; --md-light-green-A700: #64dd17; --md-lime-50: #f9fbe7; --md-lime-100: #f0f4c3; --md-lime-200: #e6ee9c; --md-lime-300: #dce775; --md-lime-400: #d4e157; --md-lime-500: #cddc39; --md-lime-600: #c0ca33; --md-lime-700: #afb42b; --md-lime-800: #9e9d24; --md-lime-900: #827717; --md-lime-A100: #f4ff81; --md-lime-A200: #eeff41; --md-lime-A400: #c6ff00; --md-lime-A700: #aeea00; --md-yellow-50: #fffde7; --md-yellow-100: #fff9c4; --md-yellow-200: #fff59d; --md-yellow-300: #fff176; --md-yellow-400: #ffee58; --md-yellow-500: #ffeb3b; --md-yellow-600: #fdd835; --md-yellow-700: #fbc02d; --md-yellow-800: #f9a825; --md-yellow-900: #f57f17; --md-yellow-A100: #ffff8d; --md-yellow-A200: #ffff00; --md-yellow-A400: #ffea00; --md-yellow-A700: #ffd600; --md-amber-50: #fff8e1; --md-amber-100: #ffecb3; --md-amber-200: #ffe082; --md-amber-300: #ffd54f; --md-amber-400: #ffca28; --md-amber-500: #ffc107; --md-amber-600: #ffb300; --md-amber-700: #ffa000; --md-amber-800: #ff8f00; --md-amber-900: #ff6f00; --md-amber-A100: #ffe57f; --md-amber-A200: #ffd740; --md-amber-A400: #ffc400; --md-amber-A700: #ffab00; --md-orange-50: #fff3e0; --md-orange-100: #ffe0b2; --md-orange-200: #ffcc80; --md-orange-300: #ffb74d; --md-orange-400: #ffa726; --md-orange-500: #ff9800; --md-orange-600: #fb8c00; --md-orange-700: #f57c00; --md-orange-800: #ef6c00; --md-orange-900: #e65100; --md-orange-A100: #ffd180; --md-orange-A200: #ffab40; --md-orange-A400: #ff9100; --md-orange-A700: #ff6d00; --md-deep-orange-50: #fbe9e7; --md-deep-orange-100: #ffccbc; --md-deep-orange-200: #ffab91; --md-deep-orange-300: #ff8a65; --md-deep-orange-400: #ff7043; --md-deep-orange-500: #ff5722; --md-deep-orange-600: #f4511e; --md-deep-orange-700: #e64a19; --md-deep-orange-800: #d84315; --md-deep-orange-900: #bf360c; --md-deep-orange-A100: #ff9e80; --md-deep-orange-A200: #ff6e40; --md-deep-orange-A400: #ff3d00; --md-deep-orange-A700: #dd2c00; --md-brown-50: #efebe9; --md-brown-100: #d7ccc8; --md-brown-200: #bcaaa4; --md-brown-300: #a1887f; --md-brown-400: #8d6e63; --md-brown-500: #795548; --md-brown-600: #6d4c41; --md-brown-700: #5d4037; --md-brown-800: #4e342e; --md-brown-900: #3e2723; --md-grey-50: #fafafa; --md-grey-100: #f5f5f5; --md-grey-200: #eeeeee; --md-grey-300: #e0e0e0; --md-grey-400: #bdbdbd; --md-grey-500: #9e9e9e; --md-grey-600: #757575; --md-grey-700: #616161; --md-grey-800: #424242; --md-grey-900: #212121; --md-blue-grey-50: #eceff1; --md-blue-grey-100: #cfd8dc; --md-blue-grey-200: #b0bec5; --md-blue-grey-300: #90a4ae; --md-blue-grey-400: #78909c; --md-blue-grey-500: #607d8b; --md-blue-grey-600: #546e7a; --md-blue-grey-700: #455a64; --md-blue-grey-800: #37474f; --md-blue-grey-900: #263238; } /*----------------------------------------------------------------------------- | Copyright (c) 2017, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-Spinner { position: absolute; display: flex; justify-content: center; align-items: center; z-index: 10; left: 0; top: 0; width: 100%; height: 100%; background: var(--jp-layout-color0); outline: none; } .jp-SpinnerContent { font-size: 10px; margin: 50px auto; text-indent: -9999em; width: 3em; height: 3em; border-radius: 50%; background: var(--jp-brand-color3); background: linear-gradient( to right, #f37626 10%, rgba(255, 255, 255, 0) 42% ); position: relative; animation: load3 1s infinite linear, fadeIn 1s; } .jp-SpinnerContent:before { width: 50%; height: 50%; background: #f37626; border-radius: 100% 0 0 0; position: absolute; top: 0; left: 0; content: ''; } .jp-SpinnerContent:after { background: var(--jp-layout-color0); width: 75%; height: 75%; border-radius: 50%; content: ''; margin: auto; position: absolute; top: 0; left: 0; bottom: 0; right: 0; } @keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes load3 { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /*----------------------------------------------------------------------------- | Copyright (c) 2014-2017, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ button.jp-mod-styled { font-size: var(--jp-ui-font-size1); color: var(--jp-ui-font-color0); border: none; box-sizing: border-box; text-align: center; line-height: 32px; height: 32px; padding: 0px 12px; letter-spacing: 0.8px; outline: none; appearance: none; -webkit-appearance: none; -moz-appearance: none; } input.jp-mod-styled { background: var(--jp-input-background); height: 28px; box-sizing: border-box; border: var(--jp-border-width) solid var(--jp-border-color1); padding-left: 7px; padding-right: 7px; font-size: var(--jp-ui-font-size2); color: var(--jp-ui-font-color0); outline: none; appearance: none; -webkit-appearance: none; -moz-appearance: none; } input[type='checkbox'].jp-mod-styled { appearance: checkbox; -webkit-appearance: checkbox; -moz-appearance: checkbox; height: auto; } input.jp-mod-styled:focus { border: var(--jp-border-width) solid var(--md-blue-500); box-shadow: inset 0 0 4px var(--md-blue-300); } .jp-FileDialog-Checkbox { margin-top: 35px; display: flex; flex-direction: row; align-items: end; width: 100%; } .jp-FileDialog-Checkbox > label { flex: 1 1 auto; } .jp-select-wrapper { display: flex; position: relative; flex-direction: column; padding: 1px; background-color: var(--jp-layout-color1); height: 28px; box-sizing: border-box; margin-bottom: 12px; } .jp-select-wrapper.jp-mod-focused select.jp-mod-styled { border: var(--jp-border-width) solid var(--jp-input-active-border-color); box-shadow: var(--jp-input-box-shadow); background-color: var(--jp-input-active-background); } select.jp-mod-styled:hover { background-color: var(--jp-layout-color1); cursor: pointer; color: var(--jp-ui-font-color0); background-color: var(--jp-input-hover-background); box-shadow: inset 0 0px 1px rgba(0, 0, 0, 0.5); } select.jp-mod-styled { flex: 1 1 auto; height: 32px; width: 100%; font-size: var(--jp-ui-font-size2); background: var(--jp-input-background); color: var(--jp-ui-font-color0); padding: 0 25px 0 8px; border: var(--jp-border-width) solid var(--jp-input-border-color); border-radius: 0px; outline: none; appearance: none; -webkit-appearance: none; -moz-appearance: none; } /*----------------------------------------------------------------------------- | Copyright (c) 2014-2016, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ :root { --jp-private-toolbar-height: calc( 28px + var(--jp-border-width) ); /* leave 28px for content */ } .jp-Toolbar { color: var(--jp-ui-font-color1); flex: 0 0 auto; display: flex; flex-direction: row; border-bottom: var(--jp-border-width) solid var(--jp-toolbar-border-color); box-shadow: var(--jp-toolbar-box-shadow); background: var(--jp-toolbar-background); min-height: var(--jp-toolbar-micro-height); padding: 2px; z-index: 1; overflow-x: auto; } /* Toolbar items */ .jp-Toolbar > .jp-Toolbar-item.jp-Toolbar-spacer { flex-grow: 1; flex-shrink: 1; } .jp-Toolbar-item.jp-Toolbar-kernelStatus { display: inline-block; width: 32px; background-repeat: no-repeat; background-position: center; background-size: 16px; } .jp-Toolbar > .jp-Toolbar-item { flex: 0 0 auto; display: flex; padding-left: 1px; padding-right: 1px; font-size: var(--jp-ui-font-size1); line-height: var(--jp-private-toolbar-height); height: 100%; } /* Toolbar buttons */ /* This is the div we use to wrap the react component into a Widget */ div.jp-ToolbarButton { color: transparent; border: none; box-sizing: border-box; outline: none; appearance: none; -webkit-appearance: none; -moz-appearance: none; padding: 0px; margin: 0px; } button.jp-ToolbarButtonComponent { background: var(--jp-layout-color1); border: none; box-sizing: border-box; outline: none; appearance: none; -webkit-appearance: none; -moz-appearance: none; padding: 0px 6px; margin: 0px; height: 24px; border-radius: var(--jp-border-radius); display: flex; align-items: center; text-align: center; font-size: 14px; min-width: unset; min-height: unset; } button.jp-ToolbarButtonComponent:disabled { opacity: 0.4; } button.jp-ToolbarButtonComponent span { padding: 0px; flex: 0 0 auto; } button.jp-ToolbarButtonComponent .jp-ToolbarButtonComponent-label { font-size: var(--jp-ui-font-size1); line-height: 100%; padding-left: 2px; color: var(--jp-ui-font-color1); } #jp-main-dock-panel[data-mode='single-document'] .jp-MainAreaWidget > .jp-Toolbar.jp-Toolbar-micro { padding: 0; min-height: 0; } #jp-main-dock-panel[data-mode='single-document'] .jp-MainAreaWidget > .jp-Toolbar { border: none; box-shadow: none; } /*----------------------------------------------------------------------------- | Copyright (c) 2014-2017, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ /* */ body.p-mod-override-cursor *, /* */ body.lm-mod-override-cursor * { cursor: inherit !important; } /*----------------------------------------------------------------------------- | Copyright (c) 2014-2016, Jupyter Development Team. | | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-JSONEditor { display: flex; flex-direction: column; width: 100%; } .jp-JSONEditor-host { flex: 1 1 auto; border: var(--jp-border-width) solid var(--jp-input-border-color); border-radius: 0px; background: var(--jp-layout-color0); min-height: 50px; padding: 1px; } .jp-JSONEditor.jp-mod-error .jp-JSONEditor-host { border-color: red; outline-color: red; } .jp-JSONEditor-header { display: flex; flex: 1 0 auto; padding: 0 0 0 12px; } .jp-JSONEditor-header label { flex: 0 0 auto; } .jp-JSONEditor-commitButton { height: 16px; width: 16px; background-size: 18px; background-repeat: no-repeat; background-position: center; } .jp-JSONEditor-host.jp-mod-focused { background-color: var(--jp-input-active-background); border: 1px solid var(--jp-input-active-border-color); box-shadow: var(--jp-input-box-shadow); } .jp-Editor.jp-mod-dropTarget { border: var(--jp-border-width) solid var(--jp-input-active-border-color); box-shadow: var(--jp-input-box-shadow); } /* BASICS */ .CodeMirror { /* Set height, width, borders, and global font properties here */ font-family: monospace; height: 300px; color: black; direction: ltr; } /* PADDING */ .CodeMirror-lines { padding: 4px 0; /* Vertical padding around content */ } .CodeMirror pre.CodeMirror-line, .CodeMirror pre.CodeMirror-line-like { padding: 0 4px; /* Horizontal padding of content */ } .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { background-color: white; /* The little square between H and V scrollbars */ } /* GUTTER */ .CodeMirror-gutters { border-right: 1px solid #ddd; background-color: #f7f7f7; white-space: nowrap; } .CodeMirror-linenumbers {} .CodeMirror-linenumber { padding: 0 3px 0 5px; min-width: 20px; text-align: right; color: #999; white-space: nowrap; } .CodeMirror-guttermarker { color: black; } .CodeMirror-guttermarker-subtle { color: #999; } /* CURSOR */ .CodeMirror-cursor { border-left: 1px solid black; border-right: none; width: 0; } /* Shown when moving in bi-directional text */ .CodeMirror div.CodeMirror-secondarycursor { border-left: 1px solid silver; } .cm-fat-cursor .CodeMirror-cursor { width: auto; border: 0 !important; background: #7e7; } .cm-fat-cursor div.CodeMirror-cursors { z-index: 1; } .cm-fat-cursor-mark { background-color: rgba(20, 255, 20, 0.5); -webkit-animation: blink 1.06s steps(1) infinite; -moz-animation: blink 1.06s steps(1) infinite; animation: blink 1.06s steps(1) infinite; } .cm-animate-fat-cursor { width: auto; border: 0; -webkit-animation: blink 1.06s steps(1) infinite; -moz-animation: blink 1.06s steps(1) infinite; animation: blink 1.06s steps(1) infinite; background-color: #7e7; } @-moz-keyframes blink { 0% {} 50% { background-color: transparent; } 100% {} } @-webkit-keyframes blink { 0% {} 50% { background-color: transparent; } 100% {} } @keyframes blink { 0% {} 50% { background-color: transparent; } 100% {} } /* Can style cursor different in overwrite (non-insert) mode */ .CodeMirror-overwrite .CodeMirror-cursor {} .cm-tab { display: inline-block; text-decoration: inherit; } .CodeMirror-rulers { position: absolute; left: 0; right: 0; top: -50px; bottom: 0; overflow: hidden; } .CodeMirror-ruler { border-left: 1px solid #ccc; top: 0; bottom: 0; position: absolute; } /* DEFAULT THEME */ .cm-s-default .cm-header {color: blue;} .cm-s-default .cm-quote {color: #090;} .cm-negative {color: #d44;} .cm-positive {color: #292;} .cm-header, .cm-strong {font-weight: bold;} .cm-em {font-style: italic;} .cm-link {text-decoration: underline;} .cm-strikethrough {text-decoration: line-through;} .cm-s-default .cm-keyword {color: #708;} .cm-s-default .cm-atom {color: #219;} .cm-s-default .cm-number {color: #164;} .cm-s-default .cm-def {color: #00f;} .cm-s-default .cm-variable, .cm-s-default .cm-punctuation, .cm-s-default .cm-property, .cm-s-default .cm-operator {} .cm-s-default .cm-variable-2 {color: #05a;} .cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;} .cm-s-default .cm-comment {color: #a50;} .cm-s-default .cm-string {color: #a11;} .cm-s-default .cm-string-2 {color: #f50;} .cm-s-default .cm-meta {color: #555;} .cm-s-default .cm-qualifier {color: #555;} .cm-s-default .cm-builtin {color: #30a;} .cm-s-default .cm-bracket {color: #997;} .cm-s-default .cm-tag {color: #170;} .cm-s-default .cm-attribute {color: #00c;} .cm-s-default .cm-hr {color: #999;} .cm-s-default .cm-link {color: #00c;} .cm-s-default .cm-error {color: #f00;} .cm-invalidchar {color: #f00;} .CodeMirror-composing { border-bottom: 2px solid; } /* Default styles for common addons */ div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;} div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;} .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } .CodeMirror-activeline-background {background: #e8f2ff;} /* STOP */ /* The rest of this file contains styles related to the mechanics of the editor. You probably shouldn't touch them. */ .CodeMirror { position: relative; overflow: hidden; background: white; } .CodeMirror-scroll { overflow: scroll !important; /* Things will break if this is overridden */ /* 50px is the magic margin used to hide the element's real scrollbars */ /* See overflow: hidden in .CodeMirror */ margin-bottom: -50px; margin-right: -50px; padding-bottom: 50px; height: 100%; outline: none; /* Prevent dragging from highlighting the element */ position: relative; } .CodeMirror-sizer { position: relative; border-right: 50px solid transparent; } /* The fake, visible scrollbars. Used to force redraw during scrolling before actual scrolling happens, thus preventing shaking and flickering artifacts. */ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { position: absolute; z-index: 6; display: none; outline: none; } .CodeMirror-vscrollbar { right: 0; top: 0; overflow-x: hidden; overflow-y: scroll; } .CodeMirror-hscrollbar { bottom: 0; left: 0; overflow-y: hidden; overflow-x: scroll; } .CodeMirror-scrollbar-filler { right: 0; bottom: 0; } .CodeMirror-gutter-filler { left: 0; bottom: 0; } .CodeMirror-gutters { position: absolute; left: 0; top: 0; min-height: 100%; z-index: 3; } .CodeMirror-gutter { white-space: normal; height: 100%; display: inline-block; vertical-align: top; margin-bottom: -50px; } .CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: none !important; border: none !important; } .CodeMirror-gutter-background { position: absolute; top: 0; bottom: 0; z-index: 4; } .CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; } .CodeMirror-gutter-wrapper ::selection { background-color: transparent } .CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent } .CodeMirror-lines { cursor: text; min-height: 1px; /* prevents collapsing before first draw */ } .CodeMirror pre.CodeMirror-line, .CodeMirror pre.CodeMirror-line-like { /* Reset some styles that the rest of the page might have set */ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; border-width: 0; background: transparent; font-family: inherit; font-size: inherit; margin: 0; white-space: pre; word-wrap: normal; line-height: inherit; color: inherit; z-index: 2; position: relative; overflow: visible; -webkit-tap-highlight-color: transparent; -webkit-font-variant-ligatures: contextual; font-variant-ligatures: contextual; } .CodeMirror-wrap pre.CodeMirror-line, .CodeMirror-wrap pre.CodeMirror-line-like { word-wrap: break-word; white-space: pre-wrap; word-break: normal; } .CodeMirror-linebackground { position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 0; } .CodeMirror-linewidget { position: relative; z-index: 2; padding: 0.1px; /* Force widget margins to stay inside of the container */ } .CodeMirror-widget {} .CodeMirror-rtl pre { direction: rtl; } .CodeMirror-code { outline: none; } /* Force content-box sizing for the elements where we expect it */ .CodeMirror-scroll, .CodeMirror-sizer, .CodeMirror-gutter, .CodeMirror-gutters, .CodeMirror-linenumber { -moz-box-sizing: content-box; box-sizing: content-box; } .CodeMirror-measure { position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden; } .CodeMirror-cursor { position: absolute; pointer-events: none; } .CodeMirror-measure pre { position: static; } div.CodeMirror-cursors { visibility: hidden; position: relative; z-index: 3; } div.CodeMirror-dragcursors { visibility: visible; } .CodeMirror-focused div.CodeMirror-cursors { visibility: visible; } .CodeMirror-selected { background: #d9d9d9; } .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } .CodeMirror-crosshair { cursor: crosshair; } .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } .cm-searching { background-color: #ffa; background-color: rgba(255, 255, 0, .4); } /* Used to force a border model for a node */ .cm-force-border { padding-right: .1px; } @media print { /* Hide the cursor when printing */ .CodeMirror div.CodeMirror-cursors { visibility: hidden; } } /* See issue #2901 */ .cm-tab-wrap-hack:after { content: ''; } /* Help users use markselection to safely style text background */ span.CodeMirror-selectedtext { background: none; } .CodeMirror-dialog { position: absolute; left: 0; right: 0; background: inherit; z-index: 15; padding: .1em .8em; overflow: hidden; color: inherit; } .CodeMirror-dialog-top { border-bottom: 1px solid #eee; top: 0; } .CodeMirror-dialog-bottom { border-top: 1px solid #eee; bottom: 0; } .CodeMirror-dialog input { border: none; outline: none; background: transparent; width: 20em; color: inherit; font-family: monospace; } .CodeMirror-dialog button { font-size: 70%; } .CodeMirror-foldmarker { color: blue; text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; font-family: arial; line-height: .3; cursor: pointer; } .CodeMirror-foldgutter { width: .7em; } .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { cursor: pointer; } .CodeMirror-foldgutter-open:after { content: "\25BE"; } .CodeMirror-foldgutter-folded:after { content: "\25B8"; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .CodeMirror { line-height: var(--jp-code-line-height); font-size: var(--jp-code-font-size); font-family: var(--jp-code-font-family); border: 0; border-radius: 0; height: auto; /* Changed to auto to autogrow */ } .CodeMirror pre { padding: 0 var(--jp-code-padding); } .jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-dialog { background-color: var(--jp-layout-color0); color: var(--jp-content-font-color1); } /* This causes https://github.com/jupyter/jupyterlab/issues/522 */ /* May not cause it not because we changed it! */ .CodeMirror-lines { padding: var(--jp-code-padding) 0; } .CodeMirror-linenumber { padding: 0 8px; } .jp-CodeMirrorEditor { cursor: text; } .jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-cursor { border-left: var(--jp-code-cursor-width0) solid var(--jp-editor-cursor-color); } /* When zoomed out 67% and 33% on a screen of 1440 width x 900 height */ @media screen and (min-width: 2138px) and (max-width: 4319px) { .jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-cursor { border-left: var(--jp-code-cursor-width1) solid var(--jp-editor-cursor-color); } } /* When zoomed out less than 33% */ @media screen and (min-width: 4320px) { .jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-cursor { border-left: var(--jp-code-cursor-width2) solid var(--jp-editor-cursor-color); } } .CodeMirror.jp-mod-readOnly .CodeMirror-cursor { display: none; } .CodeMirror-gutters { border-right: 1px solid var(--jp-border-color2); background-color: var(--jp-layout-color0); } .jp-CollaboratorCursor { border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: none; border-bottom: 3px solid; background-clip: content-box; margin-left: -5px; margin-right: -5px; } .CodeMirror-selectedtext.cm-searching { background-color: var(--jp-search-selected-match-background-color) !important; color: var(--jp-search-selected-match-color) !important; } .cm-searching { background-color: var( --jp-search-unselected-match-background-color ) !important; color: var(--jp-search-unselected-match-color) !important; } .CodeMirror-focused .CodeMirror-selected { background-color: var(--jp-editor-selected-focused-background); } .CodeMirror-selected { background-color: var(--jp-editor-selected-background); } .jp-CollaboratorCursor-hover { position: absolute; z-index: 1; transform: translateX(-50%); color: white; border-radius: 3px; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; text-align: center; font-size: var(--jp-ui-font-size1); white-space: nowrap; } .jp-CodeMirror-ruler { border-left: 1px dashed var(--jp-border-color2); } /** * Here is our jupyter theme for CodeMirror syntax highlighting * This is used in our marked.js syntax highlighting and CodeMirror itself * The string "jupyter" is set in ../codemirror/widget.DEFAULT_CODEMIRROR_THEME * This came from the classic notebook, which came form highlight.js/GitHub */ /** * CodeMirror themes are handling the background/color in this way. This works * fine for CodeMirror editors outside the notebook, but the notebook styles * these things differently. */ .CodeMirror.cm-s-jupyter { background: var(--jp-layout-color0); color: var(--jp-content-font-color1); } /* In the notebook, we want this styling to be handled by its container */ .jp-CodeConsole .CodeMirror.cm-s-jupyter, .jp-Notebook .CodeMirror.cm-s-jupyter { background: transparent; } .cm-s-jupyter .CodeMirror-cursor { border-left: var(--jp-code-cursor-width0) solid var(--jp-editor-cursor-color); } .cm-s-jupyter span.cm-keyword { color: var(--jp-mirror-editor-keyword-color); font-weight: bold; } .cm-s-jupyter span.cm-atom { color: var(--jp-mirror-editor-atom-color); } .cm-s-jupyter span.cm-number { color: var(--jp-mirror-editor-number-color); } .cm-s-jupyter span.cm-def { color: var(--jp-mirror-editor-def-color); } .cm-s-jupyter span.cm-variable { color: var(--jp-mirror-editor-variable-color); } .cm-s-jupyter span.cm-variable-2 { color: var(--jp-mirror-editor-variable-2-color); } .cm-s-jupyter span.cm-variable-3 { color: var(--jp-mirror-editor-variable-3-color); } .cm-s-jupyter span.cm-punctuation { color: var(--jp-mirror-editor-punctuation-color); } .cm-s-jupyter span.cm-property { color: var(--jp-mirror-editor-property-color); } .cm-s-jupyter span.cm-operator { color: var(--jp-mirror-editor-operator-color); font-weight: bold; } .cm-s-jupyter span.cm-comment { color: var(--jp-mirror-editor-comment-color); font-style: italic; } .cm-s-jupyter span.cm-string { color: var(--jp-mirror-editor-string-color); } .cm-s-jupyter span.cm-string-2 { color: var(--jp-mirror-editor-string-2-color); } .cm-s-jupyter span.cm-meta { color: var(--jp-mirror-editor-meta-color); } .cm-s-jupyter span.cm-qualifier { color: var(--jp-mirror-editor-qualifier-color); } .cm-s-jupyter span.cm-builtin { color: var(--jp-mirror-editor-builtin-color); } .cm-s-jupyter span.cm-bracket { color: var(--jp-mirror-editor-bracket-color); } .cm-s-jupyter span.cm-tag { color: var(--jp-mirror-editor-tag-color); } .cm-s-jupyter span.cm-attribute { color: var(--jp-mirror-editor-attribute-color); } .cm-s-jupyter span.cm-header { color: var(--jp-mirror-editor-header-color); } .cm-s-jupyter span.cm-quote { color: var(--jp-mirror-editor-quote-color); } .cm-s-jupyter span.cm-link { color: var(--jp-mirror-editor-link-color); } .cm-s-jupyter span.cm-error { color: var(--jp-mirror-editor-error-color); } .cm-s-jupyter span.cm-hr { color: #999; } .cm-s-jupyter span.cm-tab { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=); background-position: right; background-repeat: no-repeat; } .cm-s-jupyter .CodeMirror-activeline-background, .cm-s-jupyter .CodeMirror-gutter { background-color: var(--jp-layout-color2); } /* Styles for shared cursors (remote cursor locations and selected ranges) */ .jp-CodeMirrorEditor .remote-caret { position: relative; border-left: 2px solid black; margin-left: -1px; margin-right: -1px; box-sizing: border-box; } .jp-CodeMirrorEditor .remote-caret > div { white-space: nowrap; position: absolute; top: -1.15em; padding-bottom: 0.05em; left: -2px; font-size: 0.95em; background-color: rgb(250, 129, 0); font-family: var(--jp-ui-font-family); font-weight: bold; line-height: normal; user-select: none; color: white; padding-left: 2px; padding-right: 2px; z-index: 3; transition: opacity 0.3s ease-in-out; } .jp-CodeMirrorEditor .remote-caret.hide-name > div { transition-delay: 0.7s; opacity: 0; } .jp-CodeMirrorEditor .remote-caret:hover > div { opacity: 1; transition-delay: 0s; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | RenderedText |----------------------------------------------------------------------------*/ :root { /* This is the padding value to fill the gaps between lines containing spans with background color. */ --jp-private-code-span-padding: calc( (var(--jp-code-line-height) - 1) * var(--jp-code-font-size) / 2 ); } .jp-RenderedText { text-align: left; padding-left: var(--jp-code-padding); line-height: var(--jp-code-line-height); font-family: var(--jp-code-font-family); } .jp-RenderedText pre, .jp-RenderedJavaScript pre, .jp-RenderedHTMLCommon pre { color: var(--jp-content-font-color1); font-size: var(--jp-code-font-size); border: none; margin: 0px; padding: 0px; } .jp-RenderedText pre a:link { text-decoration: none; color: var(--jp-content-link-color); } .jp-RenderedText pre a:hover { text-decoration: underline; color: var(--jp-content-link-color); } .jp-RenderedText pre a:visited { text-decoration: none; color: var(--jp-content-link-color); } /* console foregrounds and backgrounds */ .jp-RenderedText pre .ansi-black-fg { color: #3e424d; } .jp-RenderedText pre .ansi-red-fg { color: #e75c58; } .jp-RenderedText pre .ansi-green-fg { color: #00a250; } .jp-RenderedText pre .ansi-yellow-fg { color: #ddb62b; } .jp-RenderedText pre .ansi-blue-fg { color: #208ffb; } .jp-RenderedText pre .ansi-magenta-fg { color: #d160c4; } .jp-RenderedText pre .ansi-cyan-fg { color: #60c6c8; } .jp-RenderedText pre .ansi-white-fg { color: #c5c1b4; } .jp-RenderedText pre .ansi-black-bg { background-color: #3e424d; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-red-bg { background-color: #e75c58; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-green-bg { background-color: #00a250; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-yellow-bg { background-color: #ddb62b; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-blue-bg { background-color: #208ffb; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-magenta-bg { background-color: #d160c4; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-cyan-bg { background-color: #60c6c8; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-white-bg { background-color: #c5c1b4; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-black-intense-fg { color: #282c36; } .jp-RenderedText pre .ansi-red-intense-fg { color: #b22b31; } .jp-RenderedText pre .ansi-green-intense-fg { color: #007427; } .jp-RenderedText pre .ansi-yellow-intense-fg { color: #b27d12; } .jp-RenderedText pre .ansi-blue-intense-fg { color: #0065ca; } .jp-RenderedText pre .ansi-magenta-intense-fg { color: #a03196; } .jp-RenderedText pre .ansi-cyan-intense-fg { color: #258f8f; } .jp-RenderedText pre .ansi-white-intense-fg { color: #a1a6b2; } .jp-RenderedText pre .ansi-black-intense-bg { background-color: #282c36; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-red-intense-bg { background-color: #b22b31; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-green-intense-bg { background-color: #007427; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-yellow-intense-bg { background-color: #b27d12; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-blue-intense-bg { background-color: #0065ca; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-magenta-intense-bg { background-color: #a03196; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-cyan-intense-bg { background-color: #258f8f; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-white-intense-bg { background-color: #a1a6b2; padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-default-inverse-fg { color: var(--jp-ui-inverse-font-color0); } .jp-RenderedText pre .ansi-default-inverse-bg { background-color: var(--jp-inverse-layout-color0); padding: var(--jp-private-code-span-padding) 0; } .jp-RenderedText pre .ansi-bold { font-weight: bold; } .jp-RenderedText pre .ansi-underline { text-decoration: underline; } .jp-RenderedText[data-mime-type='application/vnd.jupyter.stderr'] { background: var(--jp-rendermime-error-background); padding-top: var(--jp-code-padding); } /*----------------------------------------------------------------------------- | RenderedLatex |----------------------------------------------------------------------------*/ .jp-RenderedLatex { color: var(--jp-content-font-color1); font-size: var(--jp-content-font-size1); line-height: var(--jp-content-line-height); } /* Left-justify outputs.*/ .jp-OutputArea-output.jp-RenderedLatex { padding: var(--jp-code-padding); text-align: left; } /*----------------------------------------------------------------------------- | RenderedHTML |----------------------------------------------------------------------------*/ .jp-RenderedHTMLCommon { color: var(--jp-content-font-color1); font-family: var(--jp-content-font-family); font-size: var(--jp-content-font-size1); line-height: var(--jp-content-line-height); /* Give a bit more R padding on Markdown text to keep line lengths reasonable */ padding-right: 20px; } .jp-RenderedHTMLCommon em { font-style: italic; } .jp-RenderedHTMLCommon strong { font-weight: bold; } .jp-RenderedHTMLCommon u { text-decoration: underline; } .jp-RenderedHTMLCommon a:link { text-decoration: none; color: var(--jp-content-link-color); } .jp-RenderedHTMLCommon a:hover { text-decoration: underline; color: var(--jp-content-link-color); } .jp-RenderedHTMLCommon a:visited { text-decoration: none; color: var(--jp-content-link-color); } /* Headings */ .jp-RenderedHTMLCommon h1, .jp-RenderedHTMLCommon h2, .jp-RenderedHTMLCommon h3, .jp-RenderedHTMLCommon h4, .jp-RenderedHTMLCommon h5, .jp-RenderedHTMLCommon h6 { line-height: var(--jp-content-heading-line-height); font-weight: var(--jp-content-heading-font-weight); font-style: normal; margin: var(--jp-content-heading-margin-top) 0 var(--jp-content-heading-margin-bottom) 0; } .jp-RenderedHTMLCommon h1:first-child, .jp-RenderedHTMLCommon h2:first-child, .jp-RenderedHTMLCommon h3:first-child, .jp-RenderedHTMLCommon h4:first-child, .jp-RenderedHTMLCommon h5:first-child, .jp-RenderedHTMLCommon h6:first-child { margin-top: calc(0.5 * var(--jp-content-heading-margin-top)); } .jp-RenderedHTMLCommon h1:last-child, .jp-RenderedHTMLCommon h2:last-child, .jp-RenderedHTMLCommon h3:last-child, .jp-RenderedHTMLCommon h4:last-child, .jp-RenderedHTMLCommon h5:last-child, .jp-RenderedHTMLCommon h6:last-child { margin-bottom: calc(0.5 * var(--jp-content-heading-margin-bottom)); } .jp-RenderedHTMLCommon h1 { font-size: var(--jp-content-font-size5); } .jp-RenderedHTMLCommon h2 { font-size: var(--jp-content-font-size4); } .jp-RenderedHTMLCommon h3 { font-size: var(--jp-content-font-size3); } .jp-RenderedHTMLCommon h4 { font-size: var(--jp-content-font-size2); } .jp-RenderedHTMLCommon h5 { font-size: var(--jp-content-font-size1); } .jp-RenderedHTMLCommon h6 { font-size: var(--jp-content-font-size0); } /* Lists */ .jp-RenderedHTMLCommon ul:not(.list-inline), .jp-RenderedHTMLCommon ol:not(.list-inline) { padding-left: 2em; } .jp-RenderedHTMLCommon ul { list-style: disc; } .jp-RenderedHTMLCommon ul ul { list-style: square; } .jp-RenderedHTMLCommon ul ul ul { list-style: circle; } .jp-RenderedHTMLCommon ol { list-style: decimal; } .jp-RenderedHTMLCommon ol ol { list-style: upper-alpha; } .jp-RenderedHTMLCommon ol ol ol { list-style: lower-alpha; } .jp-RenderedHTMLCommon ol ol ol ol { list-style: lower-roman; } .jp-RenderedHTMLCommon ol ol ol ol ol { list-style: decimal; } .jp-RenderedHTMLCommon ol, .jp-RenderedHTMLCommon ul { margin-bottom: 1em; } .jp-RenderedHTMLCommon ul ul, .jp-RenderedHTMLCommon ul ol, .jp-RenderedHTMLCommon ol ul, .jp-RenderedHTMLCommon ol ol { margin-bottom: 0em; } .jp-RenderedHTMLCommon hr { color: var(--jp-border-color2); background-color: var(--jp-border-color1); margin-top: 1em; margin-bottom: 1em; } .jp-RenderedHTMLCommon > pre { margin: 1.5em 2em; } .jp-RenderedHTMLCommon pre, .jp-RenderedHTMLCommon code { border: 0; background-color: var(--jp-layout-color0); color: var(--jp-content-font-color1); font-family: var(--jp-code-font-family); font-size: inherit; line-height: var(--jp-code-line-height); padding: 0; white-space: pre-wrap; } .jp-RenderedHTMLCommon :not(pre) > code { background-color: var(--jp-layout-color2); padding: 1px 5px; } /* Tables */ .jp-RenderedHTMLCommon table { border-collapse: collapse; border-spacing: 0; border: none; color: var(--jp-ui-font-color1); font-size: 12px; table-layout: fixed; margin-left: auto; margin-right: auto; } .jp-RenderedHTMLCommon thead { border-bottom: var(--jp-border-width) solid var(--jp-border-color1); vertical-align: bottom; } .jp-RenderedHTMLCommon td, .jp-RenderedHTMLCommon th, .jp-RenderedHTMLCommon tr { vertical-align: middle; padding: 0.5em 0.5em; line-height: normal; white-space: normal; max-width: none; border: none; } .jp-RenderedMarkdown.jp-RenderedHTMLCommon td, .jp-RenderedMarkdown.jp-RenderedHTMLCommon th { max-width: none; } :not(.jp-RenderedMarkdown).jp-RenderedHTMLCommon td, :not(.jp-RenderedMarkdown).jp-RenderedHTMLCommon th, :not(.jp-RenderedMarkdown).jp-RenderedHTMLCommon tr { text-align: right; } .jp-RenderedHTMLCommon th { font-weight: bold; } .jp-RenderedHTMLCommon tbody tr:nth-child(odd) { background: var(--jp-layout-color0); } .jp-RenderedHTMLCommon tbody tr:nth-child(even) { background: var(--jp-rendermime-table-row-background); } .jp-RenderedHTMLCommon tbody tr:hover { background: var(--jp-rendermime-table-row-hover-background); } .jp-RenderedHTMLCommon table { margin-bottom: 1em; } .jp-RenderedHTMLCommon p { text-align: left; margin: 0px; } .jp-RenderedHTMLCommon p { margin-bottom: 1em; } .jp-RenderedHTMLCommon img { -moz-force-broken-image-icon: 1; } /* Restrict to direct children as other images could be nested in other content. */ .jp-RenderedHTMLCommon > img { display: block; margin-left: 0; margin-right: 0; margin-bottom: 1em; } /* Change color behind transparent images if they need it... */ [data-jp-theme-light='false'] .jp-RenderedImage img.jp-needs-light-background { background-color: var(--jp-inverse-layout-color1); } [data-jp-theme-light='true'] .jp-RenderedImage img.jp-needs-dark-background { background-color: var(--jp-inverse-layout-color1); } /* ...or leave it untouched if they don't */ [data-jp-theme-light='false'] .jp-RenderedImage img.jp-needs-dark-background { } [data-jp-theme-light='true'] .jp-RenderedImage img.jp-needs-light-background { } .jp-RenderedHTMLCommon img, .jp-RenderedImage img, .jp-RenderedHTMLCommon svg, .jp-RenderedSVG svg { max-width: 100%; height: auto; } .jp-RenderedHTMLCommon img.jp-mod-unconfined, .jp-RenderedImage img.jp-mod-unconfined, .jp-RenderedHTMLCommon svg.jp-mod-unconfined, .jp-RenderedSVG svg.jp-mod-unconfined { max-width: none; } .jp-RenderedHTMLCommon .alert { padding: var(--jp-notebook-padding); border: var(--jp-border-width) solid transparent; border-radius: var(--jp-border-radius); margin-bottom: 1em; } .jp-RenderedHTMLCommon .alert-info { color: var(--jp-info-color0); background-color: var(--jp-info-color3); border-color: var(--jp-info-color2); } .jp-RenderedHTMLCommon .alert-info hr { border-color: var(--jp-info-color3); } .jp-RenderedHTMLCommon .alert-info > p:last-child, .jp-RenderedHTMLCommon .alert-info > ul:last-child { margin-bottom: 0; } .jp-RenderedHTMLCommon .alert-warning { color: var(--jp-warn-color0); background-color: var(--jp-warn-color3); border-color: var(--jp-warn-color2); } .jp-RenderedHTMLCommon .alert-warning hr { border-color: var(--jp-warn-color3); } .jp-RenderedHTMLCommon .alert-warning > p:last-child, .jp-RenderedHTMLCommon .alert-warning > ul:last-child { margin-bottom: 0; } .jp-RenderedHTMLCommon .alert-success { color: var(--jp-success-color0); background-color: var(--jp-success-color3); border-color: var(--jp-success-color2); } .jp-RenderedHTMLCommon .alert-success hr { border-color: var(--jp-success-color3); } .jp-RenderedHTMLCommon .alert-success > p:last-child, .jp-RenderedHTMLCommon .alert-success > ul:last-child { margin-bottom: 0; } .jp-RenderedHTMLCommon .alert-danger { color: var(--jp-error-color0); background-color: var(--jp-error-color3); border-color: var(--jp-error-color2); } .jp-RenderedHTMLCommon .alert-danger hr { border-color: var(--jp-error-color3); } .jp-RenderedHTMLCommon .alert-danger > p:last-child, .jp-RenderedHTMLCommon .alert-danger > ul:last-child { margin-bottom: 0; } .jp-RenderedHTMLCommon blockquote { margin: 1em 2em; padding: 0 1em; border-left: 5px solid var(--jp-border-color2); } a.jp-InternalAnchorLink { visibility: hidden; margin-left: 8px; color: var(--md-blue-800); } h1:hover .jp-InternalAnchorLink, h2:hover .jp-InternalAnchorLink, h3:hover .jp-InternalAnchorLink, h4:hover .jp-InternalAnchorLink, h5:hover .jp-InternalAnchorLink, h6:hover .jp-InternalAnchorLink { visibility: visible; } .jp-RenderedHTMLCommon kbd { background-color: var(--jp-rendermime-table-row-background); border: 1px solid var(--jp-border-color0); border-bottom-color: var(--jp-border-color2); border-radius: 3px; box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); display: inline-block; font-size: 0.8em; line-height: 1em; padding: 0.2em 0.5em; } /* Most direct children of .jp-RenderedHTMLCommon have a margin-bottom of 1.0. * At the bottom of cells this is a bit too much as there is also spacing * between cells. Going all the way to 0 gets too tight between markdown and * code cells. */ .jp-RenderedHTMLCommon > *:last-child { margin-bottom: 0.5em; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-MimeDocument { outline: none; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Variables |----------------------------------------------------------------------------*/ :root { --jp-private-filebrowser-button-height: 28px; --jp-private-filebrowser-button-width: 48px; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-FileBrowser { display: flex; flex-direction: column; color: var(--jp-ui-font-color1); background: var(--jp-layout-color1); /* This is needed so that all font sizing of children done in ems is * relative to this base size */ font-size: var(--jp-ui-font-size1); } .jp-FileBrowser-toolbar.jp-Toolbar { border-bottom: none; height: auto; margin: var(--jp-toolbar-header-margin); box-shadow: none; } .jp-BreadCrumbs { flex: 0 0 auto; margin: 8px 12px 8px 12px; } .jp-BreadCrumbs-item { margin: 0px 2px; padding: 0px 2px; border-radius: var(--jp-border-radius); cursor: pointer; } .jp-BreadCrumbs-item:hover { background-color: var(--jp-layout-color2); } .jp-BreadCrumbs-item:first-child { margin-left: 0px; } .jp-BreadCrumbs-item.jp-mod-dropTarget { background-color: var(--jp-brand-color2); opacity: 0.7; } /*----------------------------------------------------------------------------- | Buttons |----------------------------------------------------------------------------*/ .jp-FileBrowser-toolbar.jp-Toolbar { padding: 0px; margin: 8px 12px 0px 12px; } .jp-FileBrowser-toolbar.jp-Toolbar { justify-content: flex-start; } .jp-FileBrowser-toolbar.jp-Toolbar .jp-Toolbar-item { flex: 0 0 auto; padding-left: 0px; padding-right: 2px; } .jp-FileBrowser-toolbar.jp-Toolbar .jp-ToolbarButtonComponent { width: 40px; } .jp-FileBrowser-toolbar.jp-Toolbar .jp-Toolbar-item:first-child .jp-ToolbarButtonComponent { width: 72px; background: var(--jp-brand-color1); } .jp-FileBrowser-toolbar.jp-Toolbar .jp-Toolbar-item:first-child .jp-ToolbarButtonComponent:focus-visible { background-color: var(--jp-brand-color0); } .jp-FileBrowser-toolbar.jp-Toolbar .jp-Toolbar-item:first-child .jp-ToolbarButtonComponent .jp-icon3 { fill: white; } /*----------------------------------------------------------------------------- | Other styles |----------------------------------------------------------------------------*/ .jp-FileDialog.jp-mod-conflict input { color: var(--jp-error-color1); } .jp-FileDialog .jp-new-name-title { margin-top: 12px; } .jp-LastModified-hidden { display: none; } .jp-FileBrowser-filterBox { padding: 0px; flex: 0 0 auto; margin: 8px 12px 0px 12px; } /*----------------------------------------------------------------------------- | DirListing |----------------------------------------------------------------------------*/ .jp-DirListing { flex: 1 1 auto; display: flex; flex-direction: column; outline: 0; } .jp-DirListing:focus-visible { border: 1px solid var(--jp-brand-color1); } .jp-DirListing-header { flex: 0 0 auto; display: flex; flex-direction: row; overflow: hidden; border-top: var(--jp-border-width) solid var(--jp-border-color2); border-bottom: var(--jp-border-width) solid var(--jp-border-color1); box-shadow: var(--jp-toolbar-box-shadow); z-index: 2; } .jp-DirListing-headerItem { padding: 4px 12px 2px 12px; font-weight: 500; } .jp-DirListing-headerItem:hover { background: var(--jp-layout-color2); } .jp-DirListing-headerItem.jp-id-name { flex: 1 0 84px; } .jp-DirListing-headerItem.jp-id-modified { flex: 0 0 112px; border-left: var(--jp-border-width) solid var(--jp-border-color2); text-align: right; } .jp-id-narrow { display: none; flex: 0 0 5px; padding: 4px 4px; border-left: var(--jp-border-width) solid var(--jp-border-color2); text-align: right; color: var(--jp-border-color2); } .jp-DirListing-narrow .jp-id-narrow { display: block; } .jp-DirListing-narrow .jp-id-modified, .jp-DirListing-narrow .jp-DirListing-itemModified { display: none; } .jp-DirListing-headerItem.jp-mod-selected { font-weight: 600; } /* increase specificity to override bundled default */ .jp-DirListing-content { flex: 1 1 auto; margin: 0; padding: 0; list-style-type: none; overflow: auto; background-color: var(--jp-layout-color1); } .jp-DirListing-content mark { color: var(--jp-ui-font-color0); background-color: transparent; font-weight: bold; } .jp-DirListing-content .jp-DirListing-item.jp-mod-selected mark { color: var(--jp-ui-inverse-font-color0); } /* Style the directory listing content when a user drops a file to upload */ .jp-DirListing.jp-mod-native-drop .jp-DirListing-content { outline: 5px dashed rgba(128, 128, 128, 0.5); outline-offset: -10px; cursor: copy; } .jp-DirListing-item { display: flex; flex-direction: row; padding: 4px 12px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .jp-DirListing-item[data-is-dot] { opacity: 75%; } .jp-DirListing-item.jp-mod-selected { color: var(--jp-ui-inverse-font-color1); background: var(--jp-brand-color1); } .jp-DirListing-item.jp-mod-dropTarget { background: var(--jp-brand-color3); } .jp-DirListing-item:hover:not(.jp-mod-selected) { background: var(--jp-layout-color2); } .jp-DirListing-itemIcon { flex: 0 0 20px; margin-right: 4px; } .jp-DirListing-itemText { flex: 1 0 64px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; user-select: none; } .jp-DirListing-itemModified { flex: 0 0 125px; text-align: right; } .jp-DirListing-editor { flex: 1 0 64px; outline: none; border: none; } .jp-DirListing-item.jp-mod-running .jp-DirListing-itemIcon:before { color: var(--jp-success-color1); content: '\25CF'; font-size: 8px; position: absolute; left: -8px; } .jp-DirListing-item.jp-mod-running.jp-mod-selected .jp-DirListing-itemIcon:before { color: var(--jp-ui-inverse-font-color1); } .jp-DirListing-item.lm-mod-drag-image, .jp-DirListing-item.jp-mod-selected.lm-mod-drag-image { font-size: var(--jp-ui-font-size1); padding-left: 4px; margin-left: 4px; width: 160px; background-color: var(--jp-ui-inverse-font-color2); box-shadow: var(--jp-elevation-z2); border-radius: 0px; color: var(--jp-ui-font-color1); transform: translateX(-40%) translateY(-58%); } .jp-DirListing-deadSpace { flex: 1 1 auto; margin: 0; padding: 0; list-style-type: none; overflow: auto; background-color: var(--jp-layout-color1); } .jp-Document { min-width: 120px; min-height: 120px; outline: none; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Private CSS variables |----------------------------------------------------------------------------*/ :root { } /*----------------------------------------------------------------------------- | Main OutputArea | OutputArea has a list of Outputs |----------------------------------------------------------------------------*/ .jp-OutputArea { overflow-y: auto; } .jp-OutputArea-child { display: flex; flex-direction: row; } body[data-format='mobile'] .jp-OutputArea-child { flex-direction: column; } .jp-OutputPrompt { flex: 0 0 var(--jp-cell-prompt-width); color: var(--jp-cell-outprompt-font-color); font-family: var(--jp-cell-prompt-font-family); padding: var(--jp-code-padding); letter-spacing: var(--jp-cell-prompt-letter-spacing); line-height: var(--jp-code-line-height); font-size: var(--jp-code-font-size); border: var(--jp-border-width) solid transparent; opacity: var(--jp-cell-prompt-opacity); /* Right align prompt text, don't wrap to handle large prompt numbers */ text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; /* Disable text selection */ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } body[data-format='mobile'] .jp-OutputPrompt { flex: 0 0 auto; text-align: left; } .jp-OutputArea-output { height: auto; overflow: auto; user-select: text; -moz-user-select: text; -webkit-user-select: text; -ms-user-select: text; } .jp-OutputArea-child .jp-OutputArea-output { flex-grow: 1; flex-shrink: 1; } body[data-format='mobile'] .jp-OutputArea-child .jp-OutputArea-output { margin-left: var(--jp-notebook-padding); } /** * Isolated output. */ .jp-OutputArea-output.jp-mod-isolated { width: 100%; display: block; } /* When drag events occur, `p-mod-override-cursor` is added to the body. Because iframes steal all cursor events, the following two rules are necessary to suppress pointer events while resize drags are occurring. There may be a better solution to this problem. */ body.lm-mod-override-cursor .jp-OutputArea-output.jp-mod-isolated { position: relative; } body.lm-mod-override-cursor .jp-OutputArea-output.jp-mod-isolated:before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: transparent; } /* pre */ .jp-OutputArea-output pre { border: none; margin: 0px; padding: 0px; overflow-x: auto; overflow-y: auto; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; } /* tables */ .jp-OutputArea-output.jp-RenderedHTMLCommon table { margin-left: 0; margin-right: 0; } /* description lists */ .jp-OutputArea-output dl, .jp-OutputArea-output dt, .jp-OutputArea-output dd { display: block; } .jp-OutputArea-output dl { width: 100%; overflow: hidden; padding: 0; margin: 0; } .jp-OutputArea-output dt { font-weight: bold; float: left; width: 20%; padding: 0; margin: 0; } .jp-OutputArea-output dd { float: left; width: 80%; padding: 0; margin: 0; } /* Hide the gutter in case of * - nested output areas (e.g. in the case of output widgets) * - mirrored output areas */ .jp-OutputArea .jp-OutputArea .jp-OutputArea-prompt { display: none; } /*----------------------------------------------------------------------------- | executeResult is added to any Output-result for the display of the object | returned by a cell |----------------------------------------------------------------------------*/ .jp-OutputArea-output.jp-OutputArea-executeResult { margin-left: 0px; flex: 1 1 auto; } /* Text output with the Out[] prompt needs a top padding to match the * alignment of the Out[] prompt itself. */ .jp-OutputArea-executeResult .jp-RenderedText.jp-OutputArea-output { padding-top: var(--jp-code-padding); border-top: var(--jp-border-width) solid transparent; } /*----------------------------------------------------------------------------- | The Stdin output |----------------------------------------------------------------------------*/ .jp-OutputArea-stdin { line-height: var(--jp-code-line-height); padding-top: var(--jp-code-padding); display: flex; } .jp-Stdin-prompt { color: var(--jp-content-font-color0); padding-right: var(--jp-code-padding); vertical-align: baseline; flex: 0 0 auto; } .jp-Stdin-input { font-family: var(--jp-code-font-family); font-size: inherit; color: inherit; background-color: inherit; width: 42%; min-width: 200px; /* make sure input baseline aligns with prompt */ vertical-align: baseline; /* padding + margin = 0.5em between prompt and cursor */ padding: 0em 0.25em; margin: 0em 0.25em; flex: 0 0 70%; } .jp-Stdin-input:focus { box-shadow: none; } /*----------------------------------------------------------------------------- | Output Area View |----------------------------------------------------------------------------*/ .jp-LinkedOutputView .jp-OutputArea { height: 100%; display: block; } .jp-LinkedOutputView .jp-OutputArea-output:only-child { height: 100%; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ .jp-Collapser { flex: 0 0 var(--jp-cell-collapser-width); padding: 0px; margin: 0px; border: none; outline: none; background: transparent; border-radius: var(--jp-border-radius); opacity: 1; } .jp-Collapser-child { display: block; width: 100%; box-sizing: border-box; /* height: 100% doesn't work because the height of its parent is computed from content */ position: absolute; top: 0px; bottom: 0px; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Header/Footer |----------------------------------------------------------------------------*/ /* Hidden by zero height by default */ .jp-CellHeader, .jp-CellFooter { height: 0px; width: 100%; padding: 0px; margin: 0px; border: none; outline: none; background: transparent; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Input |----------------------------------------------------------------------------*/ /* All input areas */ .jp-InputArea { display: flex; flex-direction: row; overflow: hidden; } body[data-format='mobile'] .jp-InputArea { flex-direction: column; } .jp-InputArea-editor { flex: 1 1 auto; overflow: hidden; } .jp-InputArea-editor { /* This is the non-active, default styling */ border: var(--jp-border-width) solid var(--jp-cell-editor-border-color); border-radius: 0px; background: var(--jp-cell-editor-background); } body[data-format='mobile'] .jp-InputArea-editor { margin-left: var(--jp-notebook-padding); } .jp-InputPrompt { flex: 0 0 var(--jp-cell-prompt-width); color: var(--jp-cell-inprompt-font-color); font-family: var(--jp-cell-prompt-font-family); padding: var(--jp-code-padding); letter-spacing: var(--jp-cell-prompt-letter-spacing); opacity: var(--jp-cell-prompt-opacity); line-height: var(--jp-code-line-height); font-size: var(--jp-code-font-size); border: var(--jp-border-width) solid transparent; opacity: var(--jp-cell-prompt-opacity); /* Right align prompt text, don't wrap to handle large prompt numbers */ text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; /* Disable text selection */ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } body[data-format='mobile'] .jp-InputPrompt { flex: 0 0 auto; text-align: left; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Placeholder |----------------------------------------------------------------------------*/ .jp-Placeholder { display: flex; flex-direction: row; flex: 1 1 auto; } .jp-Placeholder-prompt { box-sizing: border-box; } .jp-Placeholder-content { flex: 1 1 auto; border: none; background: transparent; height: 20px; box-sizing: border-box; } .jp-Placeholder-content .jp-MoreHorizIcon { width: 32px; height: 16px; border: 1px solid transparent; border-radius: var(--jp-border-radius); } .jp-Placeholder-content .jp-MoreHorizIcon:hover { border: 1px solid var(--jp-border-color1); box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.25); background-color: var(--jp-layout-color0); } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Private CSS variables |----------------------------------------------------------------------------*/ :root { --jp-private-cell-scrolling-output-offset: 5px; } /*----------------------------------------------------------------------------- | Cell |----------------------------------------------------------------------------*/ .jp-Cell { padding: var(--jp-cell-padding); margin: 0px; border: none; outline: none; background: transparent; } /*----------------------------------------------------------------------------- | Common input/output |----------------------------------------------------------------------------*/ .jp-Cell-inputWrapper, .jp-Cell-outputWrapper { display: flex; flex-direction: row; padding: 0px; margin: 0px; /* Added to reveal the box-shadow on the input and output collapsers. */ overflow: visible; } /* Only input/output areas inside cells */ .jp-Cell-inputArea, .jp-Cell-outputArea { flex: 1 1 auto; } /*----------------------------------------------------------------------------- | Collapser |----------------------------------------------------------------------------*/ /* Make the output collapser disappear when there is not output, but do so * in a manner that leaves it in the layout and preserves its width. */ .jp-Cell.jp-mod-noOutputs .jp-Cell-outputCollapser { border: none !important; background: transparent !important; } .jp-Cell:not(.jp-mod-noOutputs) .jp-Cell-outputCollapser { min-height: var(--jp-cell-collapser-min-height); } /*----------------------------------------------------------------------------- | Output |----------------------------------------------------------------------------*/ /* Put a space between input and output when there IS output */ .jp-Cell:not(.jp-mod-noOutputs) .jp-Cell-outputWrapper { margin-top: 5px; } .jp-CodeCell.jp-mod-outputsScrolled .jp-Cell-outputArea { overflow-y: auto; max-height: 200px; box-shadow: inset 0 0 6px 2px rgba(0, 0, 0, 0.3); margin-left: var(--jp-private-cell-scrolling-output-offset); } .jp-CodeCell.jp-mod-outputsScrolled .jp-OutputArea-prompt { flex: 0 0 calc( var(--jp-cell-prompt-width) - var(--jp-private-cell-scrolling-output-offset) ); } /*----------------------------------------------------------------------------- | CodeCell |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | MarkdownCell |----------------------------------------------------------------------------*/ .jp-MarkdownOutput { flex: 1 1 auto; margin-top: 0; margin-bottom: 0; padding-left: var(--jp-code-padding); } .jp-MarkdownOutput.jp-RenderedHTMLCommon { overflow: auto; } .jp-showHiddenCellsButton { margin-left: calc(var(--jp-cell-prompt-width) + 2 * var(--jp-code-padding)); margin-top: var(--jp-code-padding); border: 1px solid var(--jp-border-color2); background-color: var(--jp-border-color3) !important; color: var(--jp-content-font-color0) !important; } .jp-showHiddenCellsButton:hover { background-color: var(--jp-border-color2) !important; } .jp-collapseHeadingButton { display: none; } .jp-MarkdownCell:hover .jp-collapseHeadingButton { display: flex; min-height: var(--jp-cell-collapser-min-height); position: absolute; right: 0; top: 0; bottom: 0; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Variables |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- /*----------------------------------------------------------------------------- | Styles |----------------------------------------------------------------------------*/ .jp-NotebookPanel-toolbar { padding: 2px; } .jp-Toolbar-item.jp-Notebook-toolbarCellType .jp-select-wrapper.jp-mod-focused { border: none; box-shadow: none; } .jp-Notebook-toolbarCellTypeDropdown select { height: 24px; font-size: var(--jp-ui-font-size1); line-height: 14px; border-radius: 0; display: block; } .jp-Notebook-toolbarCellTypeDropdown span { top: 5px !important; } /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Private CSS variables |----------------------------------------------------------------------------*/ :root { --jp-private-notebook-dragImage-width: 304px; --jp-private-notebook-dragImage-height: 36px; --jp-private-notebook-selected-color: var(--md-blue-400); --jp-private-notebook-active-color: var(--md-green-400); } /*----------------------------------------------------------------------------- | Imports |----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------- | Notebook |----------------------------------------------------------------------------*/ .jp-NotebookPanel { display: block; height: 100%; } .jp-NotebookPanel.jp-Document { min-width: 240px; min-height: 120px; } .jp-Notebook { padding: var(--jp-notebook-padding); outline: none; overflow: auto; background: var(--jp-layout-color0); } .jp-Notebook.jp-mod-scrollPastEnd::after { display: block; content: ''; min-height: var(--jp-notebook-scroll-padding); } .jp-MainAreaWidget-ContainStrict .jp-Notebook * { contain: strict; } .jp-Notebook-render * { contain: none !important; } .jp-Notebook .jp-Cell { overflow: visible; } .jp-Notebook .jp-Cell .jp-InputPrompt { cursor: move; float: left; } /*----------------------------------------------------------------------------- | Notebook state related styling | | The notebook and cells each have states, here are the possibilities: | | - Notebook | - Command | - Edit | - Cell | - None | - Active (only one can be active) | - Selected (the cells actions are applied to) | - Multiselected (when multiple selected, the cursor) | - No outputs |----------------------------------------------------------------------------*/ /* Command or edit modes */ .jp-Notebook .jp-Cell:not(.jp-mod-active) .jp-InputPrompt { opacity: var(--jp-cell-prompt-not-active-opacity); color: var(--jp-cell-prompt-not-active-font-color); } .jp-Notebook .jp-Cell:not(.jp-mod-active) .jp-OutputPrompt { opacity: var(--jp-cell-prompt-not-active-opacity); color: var(--jp-cell-prompt-not-active-font-color); } /* cell is active */ .jp-Notebook .jp-Cell.jp-mod-active .jp-Collapser { background: var(--jp-brand-color1); } /* cell is dirty */ .jp-Notebook .jp-Cell.jp-mod-dirty .jp-InputPrompt { color: var(--jp-warn-color1); } .jp-Notebook .jp-Cell.jp-mod-dirty .jp-InputPrompt:before { color: var(--jp-warn-color1); content: '•'; } .jp-Notebook .jp-Cell.jp-mod-active.jp-mod-dirty .jp-Collapser { background: var(--jp-warn-color1); } /* collapser is hovered */ .jp-Notebook .jp-Cell .jp-Collapser:hover { box-shadow: var(--jp-elevation-z2); background: var(--jp-brand-color1); opacity: var(--jp-cell-collapser-not-active-hover-opacity); } /* cell is active and collapser is hovered */ .jp-Notebook .jp-Cell.jp-mod-active .jp-Collapser:hover { background: var(--jp-brand-color0); opacity: 1; } /* Command mode */ .jp-Notebook.jp-mod-commandMode .jp-Cell.jp-mod-selected { background: var(--jp-notebook-multiselected-color); } .jp-Notebook.jp-mod-commandMode .jp-Cell.jp-mod-active.jp-mod-selected:not(.jp-mod-multiSelected) { background: transparent; } /* Edit mode */ .jp-Notebook.jp-mod-editMode .jp-Cell.jp-mod-active .jp-InputArea-editor { border: var(--jp-border-width) solid var(--jp-cell-editor-active-border-color); box-shadow: var(--jp-input-box-shadow); background-color: var(--jp-cell-editor-active-background); } /*----------------------------------------------------------------------------- | Notebook drag and drop |----------------------------------------------------------------------------*/ .jp-Notebook-cell.jp-mod-dropSource { opacity: 0.5; } .jp-Notebook-cell.jp-mod-dropTarget, .jp-Notebook.jp-mod-commandMode .jp-Notebook-cell.jp-mod-active.jp-mod-selected.jp-mod-dropTarget { border-top-color: var(--jp-private-notebook-selected-color); border-top-style: solid; border-top-width: 2px; } .jp-dragImage { display: block; flex-direction: row; width: var(--jp-private-notebook-dragImage-width); height: var(--jp-private-notebook-dragImage-height); border: var(--jp-border-width) solid var(--jp-cell-editor-border-color); background: var(--jp-cell-editor-background); overflow: visible; } .jp-dragImage-singlePrompt { box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.12); } .jp-dragImage .jp-dragImage-content { flex: 1 1 auto; z-index: 2; font-size: var(--jp-code-font-size); font-family: var(--jp-code-font-family); line-height: var(--jp-code-line-height); padding: var(--jp-code-padding); border: var(--jp-border-width) solid var(--jp-cell-editor-border-color); background: var(--jp-cell-editor-background-color); color: var(--jp-content-font-color3); text-align: left; margin: 4px 4px 4px 0px; } .jp-dragImage .jp-dragImage-prompt { flex: 0 0 auto; min-width: 36px; color: var(--jp-cell-inprompt-font-color); padding: var(--jp-code-padding); padding-left: 12px; font-family: var(--jp-cell-prompt-font-family); letter-spacing: var(--jp-cell-prompt-letter-spacing); line-height: 1.9; font-size: var(--jp-code-font-size); border: var(--jp-border-width) solid transparent; } .jp-dragImage-multipleBack { z-index: -1; position: absolute; height: 32px; width: 300px; top: 8px; left: 8px; background: var(--jp-layout-color2); border: var(--jp-border-width) solid var(--jp-input-border-color); box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.12); } /*----------------------------------------------------------------------------- | Cell toolbar |----------------------------------------------------------------------------*/ .jp-NotebookTools { display: block; min-width: var(--jp-sidebar-min-width); color: var(--jp-ui-font-color1); background: var(--jp-layout-color1); /* This is needed so that all font sizing of children done in ems is * relative to this base size */ font-size: var(--jp-ui-font-size1); overflow: auto; } .jp-NotebookTools-tool { padding: 0px 12px 0 12px; } .jp-ActiveCellTool { padding: 12px; background-color: var(--jp-layout-color1); border-top: none !important; } .jp-ActiveCellTool .jp-InputArea-prompt { flex: 0 0 auto; padding-left: 0px; } .jp-ActiveCellTool .jp-InputArea-editor { flex: 1 1 auto; background: var(--jp-cell-editor-background); border-color: var(--jp-cell-editor-border-color); } .jp-ActiveCellTool .jp-InputArea-editor .CodeMirror { background: transparent; } .jp-MetadataEditorTool { flex-direction: column; padding: 12px 0px 12px 0px; } .jp-RankedPanel > :not(:first-child) { margin-top: 12px; } .jp-KeySelector select.jp-mod-styled { font-size: var(--jp-ui-font-size1); color: var(--jp-ui-font-color0); border: var(--jp-border-width) solid var(--jp-border-color1); } .jp-KeySelector label, .jp-MetadataEditorTool label { line-height: 1.4; } .jp-NotebookTools .jp-select-wrapper { margin-top: 4px; margin-bottom: 0px; } .jp-NotebookTools .jp-Collapse { margin-top: 16px; } /*----------------------------------------------------------------------------- | Presentation Mode (.jp-mod-presentationMode) |----------------------------------------------------------------------------*/ .jp-mod-presentationMode .jp-Notebook { --jp-content-font-size1: var(--jp-content-presentation-font-size1); --jp-code-font-size: var(--jp-code-presentation-font-size); } .jp-mod-presentationMode .jp-Notebook .jp-Cell .jp-InputPrompt, .jp-mod-presentationMode .jp-Notebook .jp-Cell .jp-OutputPrompt { flex: 0 0 110px; } /*----------------------------------------------------------------------------- | Placeholder |----------------------------------------------------------------------------*/ .jp-Cell-Placeholder { padding-left: 55px; } .jp-Cell-Placeholder-wrapper { background: #fff; border: 1px solid; border-color: #e5e6e9 #dfe0e4 #d0d1d5; border-radius: 4px; -webkit-border-radius: 4px; margin: 10px 15px; } .jp-Cell-Placeholder-wrapper-inner { padding: 15px; position: relative; } .jp-Cell-Placeholder-wrapper-body { background-repeat: repeat; background-size: 50% auto; } .jp-Cell-Placeholder-wrapper-body div { background: #f6f7f8; background-image: -webkit-linear-gradient( left, #f6f7f8 0%, #edeef1 20%, #f6f7f8 40%, #f6f7f8 100% ); background-repeat: no-repeat; background-size: 800px 104px; height: 104px; position: relative; } .jp-Cell-Placeholder-wrapper-body div { position: absolute; right: 15px; left: 15px; top: 15px; } div.jp-Cell-Placeholder-h1 { top: 20px; height: 20px; left: 15px; width: 150px; } div.jp-Cell-Placeholder-h2 { left: 15px; top: 50px; height: 10px; width: 100px; } div.jp-Cell-Placeholder-content-1, div.jp-Cell-Placeholder-content-2, div.jp-Cell-Placeholder-content-3 { left: 15px; right: 15px; height: 10px; } div.jp-Cell-Placeholder-content-1 { top: 100px; } div.jp-Cell-Placeholder-content-2 { top: 120px; } div.jp-Cell-Placeholder-content-3 { top: 140px; } ================================================ FILE: src/sos_notebook/templates/sos-lab-full/static/theme-dark.css ================================================ /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /* The following CSS variables define the main, public API for styling JupyterLab. These variables should be used by all plugins wherever possible. In other words, plugins should not define custom colors, sizes, etc unless absolutely necessary. This enables users to change the visual theme of JupyterLab by changing these variables. Many variables appear in an ordered sequence (0,1,2,3). These sequences are designed to work well together, so for example, `--jp-border-color1` should be used with `--jp-layout-color1`. The numbers have the following meanings: * 0: super-primary, reserved for special emphasis * 1: primary, most important under normal situations * 2: secondary, next most important under normal situations * 3: tertiary, next most important under normal situations Throughout JupyterLab, we are mostly following principles from Google's Material Design when selecting colors. We are not, however, following all of MD as it is not optimized for dense, information rich UIs. */ :root { /* Elevation * * We style box-shadows using Material Design's idea of elevation. These particular numbers are taken from here: * * https://github.com/material-components/material-components-web * https://material-components-web.appspot.com/elevation.html */ /* The dark theme shadows need a bit of work, but this will probably also require work on the core layout * colors used in the theme as well. */ --jp-shadow-base-lightness: 32; --jp-shadow-umbra-color: rgba( var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), 0.2 ); --jp-shadow-penumbra-color: rgba( var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), 0.14 ); --jp-shadow-ambient-color: rgba( var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), 0.12 ); --jp-elevation-z0: none; --jp-elevation-z1: 0px 2px 1px -1px var(--jp-shadow-umbra-color), 0px 1px 1px 0px var(--jp-shadow-penumbra-color), 0px 1px 3px 0px var(--jp-shadow-ambient-color); --jp-elevation-z2: 0px 3px 1px -2px var(--jp-shadow-umbra-color), 0px 2px 2px 0px var(--jp-shadow-penumbra-color), 0px 1px 5px 0px var(--jp-shadow-ambient-color); --jp-elevation-z4: 0px 2px 4px -1px var(--jp-shadow-umbra-color), 0px 4px 5px 0px var(--jp-shadow-penumbra-color), 0px 1px 10px 0px var(--jp-shadow-ambient-color); --jp-elevation-z6: 0px 3px 5px -1px var(--jp-shadow-umbra-color), 0px 6px 10px 0px var(--jp-shadow-penumbra-color), 0px 1px 18px 0px var(--jp-shadow-ambient-color); --jp-elevation-z8: 0px 5px 5px -3px var(--jp-shadow-umbra-color), 0px 8px 10px 1px var(--jp-shadow-penumbra-color), 0px 3px 14px 2px var(--jp-shadow-ambient-color); --jp-elevation-z12: 0px 7px 8px -4px var(--jp-shadow-umbra-color), 0px 12px 17px 2px var(--jp-shadow-penumbra-color), 0px 5px 22px 4px var(--jp-shadow-ambient-color); --jp-elevation-z16: 0px 8px 10px -5px var(--jp-shadow-umbra-color), 0px 16px 24px 2px var(--jp-shadow-penumbra-color), 0px 6px 30px 5px var(--jp-shadow-ambient-color); --jp-elevation-z20: 0px 10px 13px -6px var(--jp-shadow-umbra-color), 0px 20px 31px 3px var(--jp-shadow-penumbra-color), 0px 8px 38px 7px var(--jp-shadow-ambient-color); --jp-elevation-z24: 0px 11px 15px -7px var(--jp-shadow-umbra-color), 0px 24px 38px 3px var(--jp-shadow-penumbra-color), 0px 9px 46px 8px var(--jp-shadow-ambient-color); /* Borders * * The following variables, specify the visual styling of borders in JupyterLab. */ --jp-border-width: 1px; --jp-border-color0: var(--md-grey-700); --jp-border-color1: var(--md-grey-700); --jp-border-color2: var(--md-grey-800); --jp-border-color3: var(--md-grey-900); --jp-border-radius: 2px; /* UI Fonts * * The UI font CSS variables are used for the typography all of the JupyterLab * user interface elements that are not directly user generated content. * * The font sizing here is done assuming that the body font size of --jp-ui-font-size1 * is applied to a parent element. When children elements, such as headings, are sized * in em all things will be computed relative to that body size. */ --jp-ui-font-scale-factor: 1.2; --jp-ui-font-size0: 0.83333em; --jp-ui-font-size1: 13px; /* Base font size */ --jp-ui-font-size2: 1.2em; --jp-ui-font-size3: 1.44em; --jp-ui-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; /* * Use these font colors against the corresponding main layout colors. * In a light theme, these go from dark to light. */ /* Defaults use Material Design specification */ --jp-ui-font-color0: rgba(255, 255, 255, 1); --jp-ui-font-color1: rgba(255, 255, 255, 0.87); --jp-ui-font-color2: rgba(255, 255, 255, 0.54); --jp-ui-font-color3: rgba(255, 255, 255, 0.38); /* * Use these against the brand/accent/warn/error colors. * These will typically go from light to darker, in both a dark and light theme. */ --jp-ui-inverse-font-color0: rgba(0, 0, 0, 1); --jp-ui-inverse-font-color1: rgba(0, 0, 0, 0.8); --jp-ui-inverse-font-color2: rgba(0, 0, 0, 0.5); --jp-ui-inverse-font-color3: rgba(0, 0, 0, 0.3); /* Content Fonts * * Content font variables are used for typography of user generated content. * * The font sizing here is done assuming that the body font size of --jp-content-font-size1 * is applied to a parent element. When children elements, such as headings, are sized * in em all things will be computed relative to that body size. */ --jp-content-line-height: 1.6; --jp-content-font-scale-factor: 1.2; --jp-content-font-size0: 0.83333em; --jp-content-font-size1: 14px; /* Base font size */ --jp-content-font-size2: 1.2em; --jp-content-font-size3: 1.44em; --jp-content-font-size4: 1.728em; --jp-content-font-size5: 2.0736em; /* This gives a magnification of about 125% in presentation mode over normal. */ --jp-content-presentation-font-size1: 17px; --jp-content-heading-line-height: 1; --jp-content-heading-margin-top: 1.2em; --jp-content-heading-margin-bottom: 0.8em; --jp-content-heading-font-weight: 500; /* Defaults use Material Design specification */ --jp-content-font-color0: rgba(255, 255, 255, 1); --jp-content-font-color1: rgba(255, 255, 255, 1); --jp-content-font-color2: rgba(255, 255, 255, 0.7); --jp-content-font-color3: rgba(255, 255, 255, 0.5); --jp-content-link-color: var(--md-blue-300); --jp-content-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; /* * Code Fonts * * Code font variables are used for typography of code and other monospaces content. */ --jp-code-font-size: 13px; --jp-code-line-height: 1.3077; /* 17px for 13px base */ --jp-code-padding: 5px; /* 5px for 13px base, codemirror highlighting needs integer px value */ --jp-code-font-family-default: Menlo, Consolas, 'DejaVu Sans Mono', monospace; --jp-code-font-family: var(--jp-code-font-family-default); /* This gives a magnification of about 125% in presentation mode over normal. */ --jp-code-presentation-font-size: 16px; /* may need to tweak cursor width if you change font size */ --jp-code-cursor-width0: 1.4px; --jp-code-cursor-width1: 2px; --jp-code-cursor-width2: 4px; /* Layout * * The following are the main layout colors use in JupyterLab. In a light * theme these would go from light to dark. */ --jp-layout-color0: #111111; --jp-layout-color1: var(--md-grey-900); --jp-layout-color2: var(--md-grey-800); --jp-layout-color3: var(--md-grey-700); --jp-layout-color4: var(--md-grey-600); /* Inverse Layout * * The following are the inverse layout colors use in JupyterLab. In a light * theme these would go from dark to light. */ --jp-inverse-layout-color0: white; --jp-inverse-layout-color1: white; --jp-inverse-layout-color2: var(--md-grey-200); --jp-inverse-layout-color3: var(--md-grey-400); --jp-inverse-layout-color4: var(--md-grey-600); /* Brand/accent */ --jp-brand-color0: var(--md-blue-700); --jp-brand-color1: var(--md-blue-500); --jp-brand-color2: var(--md-blue-300); --jp-brand-color3: var(--md-blue-100); --jp-brand-color4: var(--md-blue-50); --jp-accent-color0: var(--md-green-700); --jp-accent-color1: var(--md-green-500); --jp-accent-color2: var(--md-green-300); --jp-accent-color3: var(--md-green-100); /* State colors (warn, error, success, info) */ --jp-warn-color0: var(--md-orange-700); --jp-warn-color1: var(--md-orange-500); --jp-warn-color2: var(--md-orange-300); --jp-warn-color3: var(--md-orange-100); --jp-error-color0: var(--md-red-700); --jp-error-color1: var(--md-red-500); --jp-error-color2: var(--md-red-300); --jp-error-color3: var(--md-red-100); --jp-success-color0: var(--md-green-700); --jp-success-color1: var(--md-green-500); --jp-success-color2: var(--md-green-300); --jp-success-color3: var(--md-green-100); --jp-info-color0: var(--md-cyan-700); --jp-info-color1: var(--md-cyan-500); --jp-info-color2: var(--md-cyan-300); --jp-info-color3: var(--md-cyan-100); /* Cell specific styles */ --jp-cell-padding: 5px; --jp-cell-collapser-width: 8px; --jp-cell-collapser-min-height: 20px; --jp-cell-collapser-not-active-hover-opacity: 0.6; --jp-cell-editor-background: var(--jp-layout-color1); --jp-cell-editor-border-color: var(--md-grey-700); --jp-cell-editor-box-shadow: inset 0 0 2px var(--md-blue-300); --jp-cell-editor-active-background: var(--jp-layout-color0); --jp-cell-editor-active-border-color: var(--jp-brand-color1); --jp-cell-prompt-width: 64px; --jp-cell-prompt-font-family: var(--jp-code-font-family-default); --jp-cell-prompt-letter-spacing: 0px; --jp-cell-prompt-opacity: 1; --jp-cell-prompt-not-active-opacity: 1; --jp-cell-prompt-not-active-font-color: var(--md-grey-300); /* A custom blend of MD grey and blue 600 * See https://meyerweb.com/eric/tools/color-blend/#546E7A:1E88E5:5:hex */ --jp-cell-inprompt-font-color: #307fc1; /* A custom blend of MD grey and orange 600 * https://meyerweb.com/eric/tools/color-blend/#546E7A:F4511E:5:hex */ --jp-cell-outprompt-font-color: #bf5b3d; /* Notebook specific styles */ --jp-notebook-padding: 10px; --jp-notebook-select-background: var(--jp-layout-color1); --jp-notebook-multiselected-color: rgba(33, 150, 243, 0.24); /* The scroll padding is calculated to fill enough space at the bottom of the notebook to show one single-line cell (with appropriate padding) at the top when the notebook is scrolled all the way to the bottom. We also subtract one pixel so that no scrollbar appears if we have just one single-line cell in the notebook. This padding is to enable a 'scroll past end' feature in a notebook. */ --jp-notebook-scroll-padding: calc( 100% - var(--jp-code-font-size) * var(--jp-code-line-height) - var(--jp-code-padding) - var(--jp-cell-padding) - 1px ); /* Rendermime styles */ --jp-rendermime-error-background: rgba(244, 67, 54, 0.28); --jp-rendermime-table-row-background: var(--md-grey-900); --jp-rendermime-table-row-hover-background: rgba(3, 169, 244, 0.2); /* Dialog specific styles */ --jp-dialog-background: rgba(0, 0, 0, 0.6); /* Console specific styles */ --jp-console-padding: 10px; /* Toolbar specific styles */ --jp-toolbar-border-color: var(--jp-border-color2); --jp-toolbar-micro-height: 8px; --jp-toolbar-background: var(--jp-layout-color1); --jp-toolbar-box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.8); --jp-toolbar-header-margin: 4px 4px 0px 4px; --jp-toolbar-active-background: var(--jp-layout-color0); /* Statusbar specific styles */ --jp-statusbar-height: 24px; /* Input field styles */ --jp-input-box-shadow: inset 0 0 2px var(--md-blue-300); --jp-input-active-background: var(--jp-layout-color0); --jp-input-hover-background: var(--jp-layout-color2); --jp-input-background: var(--md-grey-800); --jp-input-border-color: var(--jp-border-color1); --jp-input-active-border-color: var(--jp-brand-color1); --jp-input-active-box-shadow-color: rgba(19, 124, 189, 0.3); /* General editor styles */ --jp-editor-selected-background: var(--jp-layout-color2); --jp-editor-selected-focused-background: rgba(33, 150, 243, 0.24); --jp-editor-cursor-color: var(--jp-ui-font-color0); /* Code mirror specific styles */ --jp-mirror-editor-keyword-color: var(--md-green-500); --jp-mirror-editor-atom-color: var(--md-blue-300); --jp-mirror-editor-number-color: var(--md-green-400); --jp-mirror-editor-def-color: var(--md-blue-600); --jp-mirror-editor-variable-color: var(--md-grey-300); --jp-mirror-editor-variable-2-color: var(--md-blue-400); --jp-mirror-editor-variable-3-color: var(--md-green-600); --jp-mirror-editor-punctuation-color: var(--md-blue-400); --jp-mirror-editor-property-color: var(--md-blue-400); --jp-mirror-editor-operator-color: #aa22ff; --jp-mirror-editor-comment-color: #408080; --jp-mirror-editor-string-color: #ff7070; --jp-mirror-editor-string-2-color: var(--md-purple-300); --jp-mirror-editor-meta-color: #aa22ff; --jp-mirror-editor-qualifier-color: #555; --jp-mirror-editor-builtin-color: var(--md-green-600); --jp-mirror-editor-bracket-color: #997; --jp-mirror-editor-tag-color: var(--md-green-700); --jp-mirror-editor-attribute-color: var(--md-blue-700); --jp-mirror-editor-header-color: var(--md-blue-500); --jp-mirror-editor-quote-color: var(--md-green-300); --jp-mirror-editor-link-color: var(--md-blue-700); --jp-mirror-editor-error-color: #f00; --jp-mirror-editor-hr-color: #999; /* Vega extension styles */ --jp-vega-background: var(--md-grey-400); /* Sidebar-related styles */ --jp-sidebar-min-width: 250px; /* Search-related styles */ --jp-search-toggle-off-opacity: 0.6; --jp-search-toggle-hover-opacity: 0.8; --jp-search-toggle-on-opacity: 1; --jp-search-selected-match-background-color: rgb(255, 225, 0); --jp-search-selected-match-color: black; --jp-search-unselected-match-background-color: var( --jp-inverse-layout-color0 ); --jp-search-unselected-match-color: var(--jp-ui-inverse-font-color0); /* scrollbar related styles. Supports every browser except Edge. */ /* colors based on JetBrain's Darcula theme */ --jp-scrollbar-background-color: #3f4244; --jp-scrollbar-thumb-color: 88, 96, 97; /* need to specify thumb color as an RGB triplet */ --jp-scrollbar-endpad: 3px; /* the minimum gap between the thumb and the ends of a scrollbar */ /* hacks for setting the thumb shape. These do nothing in Firefox */ --jp-scrollbar-thumb-margin: 3.5px; /* the space in between the sides of the thumb and the track */ --jp-scrollbar-thumb-radius: 9px; /* set to a large-ish value for rounded endcaps on the thumb */ /* Icon colors that work well with light or dark backgrounds */ --jp-icon-contrast-color0: var(--md-purple-600); --jp-icon-contrast-color1: var(--md-green-600); --jp-icon-contrast-color2: var(--md-pink-600); --jp-icon-contrast-color3: var(--md-blue-600); } ================================================ FILE: src/sos_notebook/templates/sos-lab-full/static/theme-light.css ================================================ /*----------------------------------------------------------------------------- | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ /* The following CSS variables define the main, public API for styling JupyterLab. These variables should be used by all plugins wherever possible. In other words, plugins should not define custom colors, sizes, etc unless absolutely necessary. This enables users to change the visual theme of JupyterLab by changing these variables. Many variables appear in an ordered sequence (0,1,2,3). These sequences are designed to work well together, so for example, `--jp-border-color1` should be used with `--jp-layout-color1`. The numbers have the following meanings: * 0: super-primary, reserved for special emphasis * 1: primary, most important under normal situations * 2: secondary, next most important under normal situations * 3: tertiary, next most important under normal situations Throughout JupyterLab, we are mostly following principles from Google's Material Design when selecting colors. We are not, however, following all of MD as it is not optimized for dense, information rich UIs. */ :root { /* Elevation * * We style box-shadows using Material Design's idea of elevation. These particular numbers are taken from here: * * https://github.com/material-components/material-components-web * https://material-components-web.appspot.com/elevation.html */ --jp-shadow-base-lightness: 0; --jp-shadow-umbra-color: rgba( var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), 0.2 ); --jp-shadow-penumbra-color: rgba( var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), 0.14 ); --jp-shadow-ambient-color: rgba( var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), var(--jp-shadow-base-lightness), 0.12 ); --jp-elevation-z0: none; --jp-elevation-z1: 0px 2px 1px -1px var(--jp-shadow-umbra-color), 0px 1px 1px 0px var(--jp-shadow-penumbra-color), 0px 1px 3px 0px var(--jp-shadow-ambient-color); --jp-elevation-z2: 0px 3px 1px -2px var(--jp-shadow-umbra-color), 0px 2px 2px 0px var(--jp-shadow-penumbra-color), 0px 1px 5px 0px var(--jp-shadow-ambient-color); --jp-elevation-z4: 0px 2px 4px -1px var(--jp-shadow-umbra-color), 0px 4px 5px 0px var(--jp-shadow-penumbra-color), 0px 1px 10px 0px var(--jp-shadow-ambient-color); --jp-elevation-z6: 0px 3px 5px -1px var(--jp-shadow-umbra-color), 0px 6px 10px 0px var(--jp-shadow-penumbra-color), 0px 1px 18px 0px var(--jp-shadow-ambient-color); --jp-elevation-z8: 0px 5px 5px -3px var(--jp-shadow-umbra-color), 0px 8px 10px 1px var(--jp-shadow-penumbra-color), 0px 3px 14px 2px var(--jp-shadow-ambient-color); --jp-elevation-z12: 0px 7px 8px -4px var(--jp-shadow-umbra-color), 0px 12px 17px 2px var(--jp-shadow-penumbra-color), 0px 5px 22px 4px var(--jp-shadow-ambient-color); --jp-elevation-z16: 0px 8px 10px -5px var(--jp-shadow-umbra-color), 0px 16px 24px 2px var(--jp-shadow-penumbra-color), 0px 6px 30px 5px var(--jp-shadow-ambient-color); --jp-elevation-z20: 0px 10px 13px -6px var(--jp-shadow-umbra-color), 0px 20px 31px 3px var(--jp-shadow-penumbra-color), 0px 8px 38px 7px var(--jp-shadow-ambient-color); --jp-elevation-z24: 0px 11px 15px -7px var(--jp-shadow-umbra-color), 0px 24px 38px 3px var(--jp-shadow-penumbra-color), 0px 9px 46px 8px var(--jp-shadow-ambient-color); /* Borders * * The following variables, specify the visual styling of borders in JupyterLab. */ --jp-border-width: 1px; --jp-border-color0: var(--md-grey-400); --jp-border-color1: var(--md-grey-400); --jp-border-color2: var(--md-grey-300); --jp-border-color3: var(--md-grey-200); --jp-border-radius: 2px; /* UI Fonts * * The UI font CSS variables are used for the typography all of the JupyterLab * user interface elements that are not directly user generated content. * * The font sizing here is done assuming that the body font size of --jp-ui-font-size1 * is applied to a parent element. When children elements, such as headings, are sized * in em all things will be computed relative to that body size. */ --jp-ui-font-scale-factor: 1.2; --jp-ui-font-size0: 0.83333em; --jp-ui-font-size1: 13px; /* Base font size */ --jp-ui-font-size2: 1.2em; --jp-ui-font-size3: 1.44em; --jp-ui-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; /* * Use these font colors against the corresponding main layout colors. * In a light theme, these go from dark to light. */ /* Defaults use Material Design specification */ --jp-ui-font-color0: rgba(0, 0, 0, 1); --jp-ui-font-color1: rgba(0, 0, 0, 0.87); --jp-ui-font-color2: rgba(0, 0, 0, 0.54); --jp-ui-font-color3: rgba(0, 0, 0, 0.38); /* * Use these against the brand/accent/warn/error colors. * These will typically go from light to darker, in both a dark and light theme. */ --jp-ui-inverse-font-color0: rgba(255, 255, 255, 1); --jp-ui-inverse-font-color1: rgba(255, 255, 255, 1); --jp-ui-inverse-font-color2: rgba(255, 255, 255, 0.7); --jp-ui-inverse-font-color3: rgba(255, 255, 255, 0.5); /* Content Fonts * * Content font variables are used for typography of user generated content. * * The font sizing here is done assuming that the body font size of --jp-content-font-size1 * is applied to a parent element. When children elements, such as headings, are sized * in em all things will be computed relative to that body size. */ --jp-content-line-height: 1.6; --jp-content-font-scale-factor: 1.2; --jp-content-font-size0: 0.83333em; --jp-content-font-size1: 14px; /* Base font size */ --jp-content-font-size2: 1.2em; --jp-content-font-size3: 1.44em; --jp-content-font-size4: 1.728em; --jp-content-font-size5: 2.0736em; /* This gives a magnification of about 125% in presentation mode over normal. */ --jp-content-presentation-font-size1: 17px; --jp-content-heading-line-height: 1; --jp-content-heading-margin-top: 1.2em; --jp-content-heading-margin-bottom: 0.8em; --jp-content-heading-font-weight: 500; /* Defaults use Material Design specification */ --jp-content-font-color0: rgba(0, 0, 0, 1); --jp-content-font-color1: rgba(0, 0, 0, 0.87); --jp-content-font-color2: rgba(0, 0, 0, 0.54); --jp-content-font-color3: rgba(0, 0, 0, 0.38); --jp-content-link-color: var(--md-blue-700); --jp-content-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; /* * Code Fonts * * Code font variables are used for typography of code and other monospaces content. */ --jp-code-font-size: 13px; --jp-code-line-height: 1.3077; /* 17px for 13px base */ --jp-code-padding: 5px; /* 5px for 13px base, codemirror highlighting needs integer px value */ --jp-code-font-family-default: Menlo, Consolas, 'DejaVu Sans Mono', monospace; --jp-code-font-family: var(--jp-code-font-family-default); /* This gives a magnification of about 125% in presentation mode over normal. */ --jp-code-presentation-font-size: 16px; /* may need to tweak cursor width if you change font size */ --jp-code-cursor-width0: 1.4px; --jp-code-cursor-width1: 2px; --jp-code-cursor-width2: 4px; /* Layout * * The following are the main layout colors use in JupyterLab. In a light * theme these would go from light to dark. */ --jp-layout-color0: white; --jp-layout-color1: white; --jp-layout-color2: var(--md-grey-200); --jp-layout-color3: var(--md-grey-400); --jp-layout-color4: var(--md-grey-600); /* Inverse Layout * * The following are the inverse layout colors use in JupyterLab. In a light * theme these would go from dark to light. */ --jp-inverse-layout-color0: #111111; --jp-inverse-layout-color1: var(--md-grey-900); --jp-inverse-layout-color2: var(--md-grey-800); --jp-inverse-layout-color3: var(--md-grey-700); --jp-inverse-layout-color4: var(--md-grey-600); /* Brand/accent */ --jp-brand-color0: var(--md-blue-900); --jp-brand-color1: var(--md-blue-700); --jp-brand-color2: var(--md-blue-300); --jp-brand-color3: var(--md-blue-100); --jp-brand-color4: var(--md-blue-50); --jp-accent-color0: var(--md-green-900); --jp-accent-color1: var(--md-green-700); --jp-accent-color2: var(--md-green-300); --jp-accent-color3: var(--md-green-100); /* State colors (warn, error, success, info) */ --jp-warn-color0: var(--md-orange-900); --jp-warn-color1: var(--md-orange-700); --jp-warn-color2: var(--md-orange-300); --jp-warn-color3: var(--md-orange-100); --jp-error-color0: var(--md-red-900); --jp-error-color1: var(--md-red-700); --jp-error-color2: var(--md-red-300); --jp-error-color3: var(--md-red-100); --jp-success-color0: var(--md-green-900); --jp-success-color1: var(--md-green-700); --jp-success-color2: var(--md-green-300); --jp-success-color3: var(--md-green-100); --jp-info-color0: var(--md-cyan-900); --jp-info-color1: var(--md-cyan-700); --jp-info-color2: var(--md-cyan-300); --jp-info-color3: var(--md-cyan-100); /* Cell specific styles */ --jp-cell-padding: 5px; --jp-cell-collapser-width: 8px; --jp-cell-collapser-min-height: 20px; --jp-cell-collapser-not-active-hover-opacity: 0.6; --jp-cell-editor-background: var(--md-grey-100); --jp-cell-editor-border-color: var(--md-grey-300); --jp-cell-editor-box-shadow: inset 0 0 2px var(--md-blue-300); --jp-cell-editor-active-background: var(--jp-layout-color0); --jp-cell-editor-active-border-color: var(--jp-brand-color1); --jp-cell-prompt-width: 64px; --jp-cell-prompt-font-family: var(--jp-code-font-family-default); --jp-cell-prompt-letter-spacing: 0px; --jp-cell-prompt-opacity: 1; --jp-cell-prompt-not-active-opacity: 0.5; --jp-cell-prompt-not-active-font-color: var(--md-grey-700); /* A custom blend of MD grey and blue 600 * See https://meyerweb.com/eric/tools/color-blend/#546E7A:1E88E5:5:hex */ --jp-cell-inprompt-font-color: #307fc1; /* A custom blend of MD grey and orange 600 * https://meyerweb.com/eric/tools/color-blend/#546E7A:F4511E:5:hex */ --jp-cell-outprompt-font-color: #bf5b3d; /* Notebook specific styles */ --jp-notebook-padding: 10px; --jp-notebook-select-background: var(--jp-layout-color1); --jp-notebook-multiselected-color: var(--md-blue-50); /* The scroll padding is calculated to fill enough space at the bottom of the notebook to show one single-line cell (with appropriate padding) at the top when the notebook is scrolled all the way to the bottom. We also subtract one pixel so that no scrollbar appears if we have just one single-line cell in the notebook. This padding is to enable a 'scroll past end' feature in a notebook. */ --jp-notebook-scroll-padding: calc( 100% - var(--jp-code-font-size) * var(--jp-code-line-height) - var(--jp-code-padding) - var(--jp-cell-padding) - 1px ); /* Rendermime styles */ --jp-rendermime-error-background: #fdd; --jp-rendermime-table-row-background: var(--md-grey-100); --jp-rendermime-table-row-hover-background: var(--md-light-blue-50); /* Dialog specific styles */ --jp-dialog-background: rgba(0, 0, 0, 0.25); /* Console specific styles */ --jp-console-padding: 10px; /* Toolbar specific styles */ --jp-toolbar-border-color: var(--jp-border-color1); --jp-toolbar-micro-height: 8px; --jp-toolbar-background: var(--jp-layout-color1); --jp-toolbar-box-shadow: 0px 0px 2px 0px rgba(0, 0, 0, 0.24); --jp-toolbar-header-margin: 4px 4px 0px 4px; --jp-toolbar-active-background: var(--md-grey-300); /* Statusbar specific styles */ --jp-statusbar-height: 24px; /* Input field styles */ --jp-input-box-shadow: inset 0 0 2px var(--md-blue-300); --jp-input-active-background: var(--jp-layout-color1); --jp-input-hover-background: var(--jp-layout-color1); --jp-input-background: var(--md-grey-100); --jp-input-border-color: var(--jp-border-color1); --jp-input-active-border-color: var(--jp-brand-color1); --jp-input-active-box-shadow-color: rgba(19, 124, 189, 0.3); /* General editor styles */ --jp-editor-selected-background: #d9d9d9; --jp-editor-selected-focused-background: #d7d4f0; --jp-editor-cursor-color: var(--jp-ui-font-color0); /* Code mirror specific styles */ --jp-mirror-editor-keyword-color: #008000; --jp-mirror-editor-atom-color: #88f; --jp-mirror-editor-number-color: #080; --jp-mirror-editor-def-color: #00f; --jp-mirror-editor-variable-color: var(--md-grey-900); --jp-mirror-editor-variable-2-color: #05a; --jp-mirror-editor-variable-3-color: #085; --jp-mirror-editor-punctuation-color: #05a; --jp-mirror-editor-property-color: #05a; --jp-mirror-editor-operator-color: #aa22ff; --jp-mirror-editor-comment-color: #408080; --jp-mirror-editor-string-color: #ba2121; --jp-mirror-editor-string-2-color: #708; --jp-mirror-editor-meta-color: #aa22ff; --jp-mirror-editor-qualifier-color: #555; --jp-mirror-editor-builtin-color: #008000; --jp-mirror-editor-bracket-color: #997; --jp-mirror-editor-tag-color: #170; --jp-mirror-editor-attribute-color: #00c; --jp-mirror-editor-header-color: blue; --jp-mirror-editor-quote-color: #090; --jp-mirror-editor-link-color: #00c; --jp-mirror-editor-error-color: #f00; --jp-mirror-editor-hr-color: #999; /* Vega extension styles */ --jp-vega-background: white; /* Sidebar-related styles */ --jp-sidebar-min-width: 250px; /* Search-related styles */ --jp-search-toggle-off-opacity: 0.5; --jp-search-toggle-hover-opacity: 0.8; --jp-search-toggle-on-opacity: 1; --jp-search-selected-match-background-color: rgb(245, 200, 0); --jp-search-selected-match-color: black; --jp-search-unselected-match-background-color: var( --jp-inverse-layout-color0 ); --jp-search-unselected-match-color: var(--jp-ui-inverse-font-color0); /* Icon colors that work well with light or dark backgrounds */ --jp-icon-contrast-color0: var(--md-purple-600); --jp-icon-contrast-color1: var(--md-green-600); --jp-icon-contrast-color2: var(--md-pink-600); --jp-icon-contrast-color3: var(--md-blue-600); } ================================================ FILE: src/sos_notebook/templates/sos-lab-report-only/conf.json ================================================ { "base_template": "sos-lab-cm", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-lab-report-only/index.html.j2 ================================================ {% extends 'sos-lab-report-only.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-lab-report-only/sos-lab-report-only.html.j2 ================================================ {% extends 'sos-lab-cm.html.j2' %} {%- block codecell -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden and (not cell.outputs or cell.metadata.jupyter.outputs_hidden) -%} {%- else -%} {{ super() }} {%- endif -%} {%- endblock codecell -%} {%- block in_prompt -%} {%- endblock in_prompt -%} {%- block input -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden and (not cell.outputs or cell.metadata.jupyter.source_hidden) -%} {%- else -%} {{ super() }} {%- endif -%} {%- endblock input -%} {# output_prompt doesn't do anything in HTML, because there is a prompt div in each output area (see output block) #} {% block output_area_prompt %} {% endblock output_area_prompt %} {% block output %} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.outputs_hidden -%} {%- else -%} {{ super() }} {%- endif -%} {% endblock output %} {# remove stderr #} {% block stream_stderr -%} {%- endblock stream_stderr %} {% block markdowncell %} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden -%} {%- else -%}
{{ cell.source | markdown2html | strip_files_prefix }}
{%- endif -%} {%- endblock markdowncell -%} {% block notebook_css %} {{ super() }} {% endblock %} ================================================ FILE: src/sos_notebook/templates/sos-markdown/conf.json ================================================ { "base_template": "markdown", "mimetypes": { "text/markdown": true } } ================================================ FILE: src/sos_notebook/templates/sos-markdown/index.md.j2 ================================================ {% extends 'sos-markdown.md.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-markdown/sos-markdown.md.j2 ================================================ {% extends 'markdown/index.md.j2' %} {% block input %} ``` {%- if 'kernel' in cell.metadata -%} {{ cell.metadata.kernel.replace('SoS', 'Python3') }} {%- elif 'magics_language' in cell.metadata -%} {{ cell.metadata.magics_language}} {%- elif 'name' in nb.metadata.get('language_info', {}) -%} {{ nb.metadata.language_info.name }} {%- endif %} {{ cell.source}} ``` {% endblock input %} ================================================ FILE: src/sos_notebook/templates/sos-report/conf.json ================================================ { "base_template": "sos-full", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-report/index.html.j2 ================================================ {% extends 'sos-report.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-report/parts/control_panel.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %}
{% endmacro %} {% macro js() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-report/sos-report.html.j2 ================================================ {% extends 'sos-full.html.j2' %} {% import 'parts/control_panel.tpl' as control_panel %} {% block header %} {{ super() }} {{ control_panel.css() }} {% endblock header %} {%- block input -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'report_cell' in cell.metadata.get('tags', []) -%} {{ super() }} {%- else -%}
{{ super() }}
{%- endif -%} {%- endblock input -%} {% block output %} {%- if 'report_output' in cell.metadata.get('tags', []) -%} {{ super() }} {%- elif 'report_cell' in cell.metadata.get('tags', []) -%} {{ super() }} {%- elif 'scratch' in cell.metadata.get('tags', []) -%} {%- else -%}
{{ super() }}
{%- endif -%} {% endblock output %} {% block markdowncell %} {%- if 'hide_output' in cell.metadata.get('tags', []) -%}
{{ super() }}
{%- elif 'scratch' in cell.metadata.get('tags', []) -%} {%- else -%} {{ super() }} {%- endif -%} {%- endblock markdowncell -%} {% block body %} {{ control_panel.html() }} {{ super() }} {% endblock body %} {% block footer %} {{ control_panel.js() }} {{ super() }} {% endblock footer %} ================================================ FILE: src/sos_notebook/templates/sos-report-only/conf.json ================================================ { "base_template": "sos-cm", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-report-only/index.html.j2 ================================================ {% extends 'sos-report-only.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-report-only/sos-report-only.html.j2 ================================================ {% extends 'sos-cm.html.j2' %} {%- block codecell -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden and (not cell.outputs or cell.metadata.jupyter.outputs_hidden) -%} {%- else -%} {{ super() }} {%- endif -%} {%- endblock codecell -%} {%- block in_prompt -%} {%- endblock in_prompt -%} {%- block input -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden and (not cell.outputs or cell.metadata.jupyter.source_hidden) -%} {%- else -%} {{ super() }} {%- endif -%} {%- endblock input -%} {# output_prompt doesn't do anything in HTML, because there is a prompt div in each output area (see output block) #} {% block output_area_prompt %} {% endblock output_area_prompt %} {% block output %} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.outputs_hidden -%} {%- else -%} {{ super() }} {%- endif -%} {% endblock output %} {# remove stderr #} {% block stream_stderr -%} {%- endblock stream_stderr %} {% block markdowncell %} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden -%} {%- else -%}
{{ cell.source | markdown2html | strip_files_prefix }}
{%- endif -%} {%- endblock markdowncell -%} {% block notebook_css %} {{ super() }} {% endblock %} ================================================ FILE: src/sos_notebook/templates/sos-report-only-toc/conf.json ================================================ { "base_template": "sos-report-only", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-report-only-toc/index.html.j2 ================================================ {% extends 'sos-report-only-toc.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-report-only-toc/parts/toc.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %} {% endmacro %} {% macro js(headers='h1, h2, h3, h4', remove_only_top_header='true') %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-report-only-toc/sos-report-only-toc.html.j2 ================================================ {% extends 'sos-report-only.html.j2' %} {% import 'parts/toc.tpl' as toc %} {% block html_head %} {{ super() | replace('', '') | replace('', '')}} {{ toc.css() }} {% endblock html_head %} {% block body %}
{{ super() | replace('', '') | replace('', '') | replace('class="container"', 'class="notebook-container"')}}
{% endblock body %} {% block footer_js %} {{ super() }} {{ toc.js() }} {% endblock footer_js %} {% block markdowncell %} {{ super() | replace('¶', '')}} {%- endblock markdowncell -%} ================================================ FILE: src/sos_notebook/templates/sos-report-toc/conf.json ================================================ { "base_template": "sos-report", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-report-toc/index.html.j2 ================================================ {% extends 'sos-report-toc.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-report-toc/parts/toc.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %} {% endmacro %} {% macro js(headers='h1, h2, h3, h4', remove_only_top_header='true') %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-report-toc/sos-report-toc.html.j2 ================================================ {% extends 'sos-report.html.j2' %} {% import 'parts/toc.tpl' as toc %} {% block html_head %} {{ super() | replace('', '') | replace('', '')}} {{ toc.css() }} {% endblock html_head %} {% block body %}
{{ super() | replace('', '') | replace('', '') | replace('class="container"', 'class="notebook-container"')}}
{% endblock body %} {% block footer_js %} {{ super() }} {{ toc.js() }} {% endblock footer_js %} {% block markdowncell %} {{ super() | replace('¶', '')}} {%- endblock markdowncell -%} ================================================ FILE: src/sos_notebook/templates/sos-report-toc-v2/conf.json ================================================ { "base_template": "sos-report-v2", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-report-toc-v2/index.html.j2 ================================================ {% extends 'sos-report-toc-v2.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-report-toc-v2/parts/toc.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %} {% endmacro %} {% macro js(headers='h1, h2, h3, h4', remove_only_top_header='true') %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-report-toc-v2/sos-report-toc-v2.html.j2 ================================================ {% extends 'sos-report-v2.html.j2' %} {% import 'parts/toc.tpl' as toc %} {% block html_head %} {{ super() | replace('', '') | replace('', '')}} {{ toc.css() }} {% endblock html_head %} {% block body %}
{{ super() | replace('', '') | replace('', '') | replace('class="container"', 'class="notebook-container"')}}
{% endblock body %} {% block footer_js %} {{ super() }} {{ toc.js() }} {% endblock footer_js %} {% block markdowncell %} {{ super() | replace('¶', '')}} {%- endblock markdowncell -%} ================================================ FILE: src/sos_notebook/templates/sos-report-v1/conf.json ================================================ { "base_template": "sos-full", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-report-v1/index.html.j2 ================================================ {% extends 'sos-report-v1.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-report-v1/parts/control_panel_v1.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %}
Display content:


{% endmacro %} {% macro js() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-report-v1/sos-report-v1.html.j2 ================================================ {% extends 'sos-full.html.j2' %} {% import 'parts/control_panel_v1.tpl' as control_panel %} {% block header %} {{ super() }} {{ control_panel.css() }} {% endblock header %} {%- block input -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'report_cell' in cell.metadata.get('tags', []) -%} {{ super() }} {%- else -%}
{{ super() }}
{%- endif -%} {%- endblock input -%} {% block output %} {%- if 'report_output' in cell.metadata.get('tags', []) -%} {{ super() }} {%- elif 'report_cell' in cell.metadata.get('tags', []) -%} {{ super() }} {%- elif 'scratch' in cell.metadata.get('tags', []) -%} {%- else -%}
{{ super() }}
{%- endif -%} {% endblock output %} {% block markdowncell %} {%- if 'hide_output' in cell.metadata.get('tags', []) -%}
{{ super() }}
{%- elif 'scratch' in cell.metadata.get('tags', []) -%} {%- else -%} {{ super() }} {%- endif -%} {%- endblock markdowncell -%} {% block body %} {{ control_panel.html() }} {{ super() }} {% endblock body %} {% block footer %} {{ control_panel.js() }} {{ super() }} {% endblock footer %} ================================================ FILE: src/sos_notebook/templates/sos-report-v2/conf.json ================================================ { "base_template": "sos-cm", "mimetypes": { "text/html": true } } ================================================ FILE: src/sos_notebook/templates/sos-report-v2/index.html.j2 ================================================ {% extends 'sos-report-v2.html.j2' %} ================================================ FILE: src/sos_notebook/templates/sos-report-v2/parts/control_panel.tpl ================================================ {% macro css() %} {% endmacro %} {% macro html() %}
{% endmacro %} {% macro js() %} {% endmacro %} ================================================ FILE: src/sos_notebook/templates/sos-report-v2/sos-report-v2.html.j2 ================================================ {% extends 'sos-cm' %} {% import 'parts/control_panel.tpl' as control_panel %} {% block header %} {{ super() }} {{ control_panel.css() }} {% endblock header %} {%- block codecell -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden and (not cell.outputs or cell.metadata.jupyter.outputs_hidden) %}
{{ super() }}
{%- else -%} {{ super() }} {%- endif -%} {%- endblock codecell -%} {%- block input -%} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden -%}
{{ super() }}
{%- else -%} {{ super() }} {%- endif -%} {%- endblock input -%} {% block output %} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.outputs_hidden -%}
{{ super() }}
{%- else -%} {{ super() }} {%- endif -%} {% endblock output %} {% block markdowncell %} {%- if 'scratch' in cell.metadata.get('tags', []) -%} {%- elif 'jupyter' in cell.metadata and cell.metadata.jupyter.source_hidden -%}
{{ super() }}
{%- else -%} {{ super() }} {%- endif -%} {%- endblock markdowncell -%} {% block body %} {{ control_panel.html() }} {{ super() }} {% endblock body %} {% block footer %} {{ control_panel.js() }} {{ super() }} {% endblock footer %} ================================================ FILE: src/sos_notebook/test_utils.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import asyncio import atexit import os import re import time from contextlib import contextmanager from queue import Empty from textwrap import dedent import pytest from jupyter_client import KernelManager pjoin = os.path.join TIMEOUT = 60 KM = None KC = None def start_new_kernel(kernel_name="python3"): """Start a new kernel and return the manager and client.""" km = KernelManager(kernel_name=kernel_name) km.start_kernel() kc = km.client() kc.start_channels() try: kc.wait_for_ready(timeout=TIMEOUT) except RuntimeError: kc.stop_channels() km.shutdown_kernel() raise return km, kc @contextmanager def sos_kernel(): """Context manager for the global kernel instance Returns ------- kernel_client: connected KernelClient instance """ yield start_sos_kernel() def flush_channels(kc=None): """flush any messages waiting on the queue""" if kc is None: kc = KC for channel in (kc.shell_channel, kc.iopub_channel): while True: try: channel.get_msg(timeout=0.1) except Empty: break def start_sos_kernel(): """start the global kernel (if it isn't running) and return its client""" global KM, KC if KM is None: KM, KC = start_new_kernel(kernel_name="sos") atexit.register(stop_sos_kernel) else: flush_channels(KC) return KC def stop_sos_kernel(): """Stop the global shared kernel instance, if it exists""" global KM, KC KC.stop_channels() KC = None if KM is None: return KM.shutdown_kernel(now=False) KM = None def get_result(iopub): """retrieve result from an execution""" return asyncio.run(_async_get_result(iopub)) async def _async_get_result(iopub): result = None while True: msg = await iopub.get_msg(timeout=1) msg_type = msg["msg_type"] content = msg["content"] if msg_type == "status" and content["execution_state"] == "idle": break if msg["msg_type"] == "execute_result": result = content["data"] elif msg["msg_type"] == "display_data": result = content["data"] from numpy import array, matrix, uint8 _ = array _ = matrix _ = uint8 def dict_keys(args): return args if result is None: return None return eval(result["text/plain"]) def get_display_data(iopub, data_type="text/plain"): """retrieve display_data from an execution from subkernel""" return asyncio.run(_async_get_display_data(iopub, data_type)) async def _async_get_display_data(iopub, data_type): result = None while True: msg = await iopub.get_msg(timeout=1) msg_type = msg["msg_type"] content = msg["content"] if msg_type == "status" and content["execution_state"] == "idle": break if msg["msg_type"] == "display_data": if isinstance(data_type, str): if data_type in content["data"]: result = content["data"][data_type] else: for dt in data_type: if dt in content["data"]: result = content["data"][dt] elif msg["msg_type"] == "execute_result": result = content["data"]["text/plain"] return result def clear_channels(iopub): """assemble stdout/err from an execution""" return asyncio.run(_async_clear_channels(iopub)) async def _async_clear_channels(iopub): while True: msg = await iopub.get_msg(timeout=1) msg_type = msg["msg_type"] content = msg["content"] if msg_type == "status" and content["execution_state"] == "idle": break def get_std_output(iopub): """Obtain stderr and remove some unnecessary warning from https://github.com/jupyter/jupyter_client/pull/201#issuecomment-314269710""" stdout = [] stderr = [] while True: try: msg = iopub.get_msg(timeout=1) except Empty: break msg_type = msg["msg_type"] content = msg["content"] if msg_type == "status" and content["execution_state"] == "idle": break if msg_type == "stream": if content["name"] == "stdout": stdout.append(content["text"]) elif content["name"] == "stderr": stderr.append(content["text"]) elif msg_type == "error": stderr.append("\n".join(content["traceback"])) return "".join(stdout), "\n".join( x for x in "".join(stderr).splitlines() if "sticky" not in x and "RuntimeWarning" not in x and "communicator" not in x ) class NotebookTest: """Base test class for kernel tests""" class Notebook: """Notebook interface for kernel testing. Executes code in the SoS kernel and supports switching between subkernels (R, Python3, etc.) using the %use magic. """ def __init__(self, kernel_client=None): self.kc = kernel_client or start_sos_kernel() self.current_kernel = "SoS" def _execute_and_collect(self, code): """Execute code and collect all iopub messages until idle. Returns (stdout, stderr, result, all_messages) where result is the text/plain from execute_result or display_data if any. """ self.kc.execute(code) self.kc.get_shell_msg(timeout=TIMEOUT) stdout = [] stderr = [] result = None messages = [] while True: try: msg = self.kc.get_iopub_msg(timeout=5) except Empty: break messages.append(msg) msg_type = msg["msg_type"] content = msg["content"] if msg_type == "status" and content["execution_state"] == "idle": break if msg_type == "stream": if content["name"] == "stdout": stdout.append(content["text"]) elif content["name"] == "stderr": stderr.append(content["text"]) elif msg_type == "execute_result": if "text/plain" in content.get("data", {}): result = content["data"]["text/plain"] elif msg_type == "display_data": if "text/plain" in content.get("data", {}): result = content["data"]["text/plain"] elif msg_type == "error": stderr.append("\n".join(content["traceback"])) return "".join(stdout), "".join(stderr), result, messages def _switch_kernel(self, kernel): """Switch to a different kernel using %use magic.""" if kernel != self.current_kernel: self._execute_and_collect(f"%use {kernel}") self.current_kernel = kernel def check_output(self, code, kernel="SoS"): """Execute code in the specified kernel and return output as string.""" self._switch_kernel(kernel) code = dedent(code).strip() stdout, stderr, result, _ = self._execute_and_collect(code) if result is not None: return result return stdout def call(self, code, kernel="SoS"): """Execute code in the specified kernel without returning output.""" self._switch_kernel(kernel) code = dedent(code).strip() self._execute_and_collect(code) def save(self): """No-op: save is a frontend concept, not applicable in kernel testing.""" def get_input_backgroundColor(self, idx=0): """Not available without frontend. Returns None.""" return None def get_cell_output(self, idx=0): """Drain any pending iopub messages and return accumulated output. This is used to poll for output from background tasks (%run &). """ output = [] while True: try: msg = self.kc.get_iopub_msg(timeout=1) if msg["msg_type"] == "stream": output.append(msg["content"]["text"]) elif msg["msg_type"] == "status" and msg["content"]["execution_state"] == "idle": break except Empty: break return "".join(output) ================================================ FILE: src/sos_notebook/workflow_executor.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import copy import logging import multiprocessing as mp import os import re import shlex import subprocess import sys import tempfile from threading import Event import psutil import zmq from sos.__main__ import get_run_parser from sos.controller import Controller, connect_controllers, disconnect_controllers from sos.parser import SoS_Script from sos.section_analyzer import analyze_section from sos.syntax import SOS_SECTION_HEADER from sos.targets import RemovedTarget, UnknownTarget, sos_targets, textMD5 from sos.utils import TerminateExecution, _parse_error, env, get_traceback, pexpect_run from .step_executor import Interactive_Step_Executor class NotebookLoggingHandler(logging.Handler): def __init__(self, level, kernel=None, title="Log Messages"): super().__init__(level) self.kernel = kernel self.title = title def setTitle(self, title): self.title = title def emit(self, record): msg = re.sub( r"``([^`]*)``", r'\1', record.msg ) self.kernel.send_frontend_msg( "display_data", { "metadata": {}, "data": { "text/html": f'
{record.levelname}: {msg}
' }, }, ) # self.kernel.send_response(self.kernel.iopub_socket, 'stream', # {'name': 'stdout', 'text': record.msg}) def start_controller(kernel): env.zmq_context = zmq.Context() # ready to monitor other workflows env.config["exec_mode"] = "master" ready = Event() controller = Controller(ready, kernel) controller.start() # wait for the thread to start with a signature_req saved to env.config ready.wait() connect_controllers(env.zmq_context) return controller def stop_controller(controller): if not controller: return env.master_request_socket.send_pyobj(["done"]) env.master_request_socket.recv() disconnect_controllers() controller.join() last_cell_id = None def execute_scratch_cell(code, raw_args, kernel): # we then have to change the parse to disable args.workflow when # there is no workflow option. raw_args = shlex.split(raw_args) if isinstance(raw_args, str) else raw_args if code is None or "-h" in raw_args: parser = get_run_parser(interactive=True, with_workflow=True) parser.print_help() return if raw_args and raw_args[0].lstrip().startswith("-"): parser = get_run_parser(interactive=True, with_workflow=False) parser.error = _parse_error args, workflow_args = parser.parse_known_args(raw_args) args.workflow = None else: parser = get_run_parser(interactive=True, with_workflow=True) parser.error = _parse_error args, workflow_args = parser.parse_known_args(raw_args) if not code.strip(): return # for reporting purpose sys.argv = ["%run"] + raw_args env.verbosity = args.verbosity if not any(isinstance(x, NotebookLoggingHandler) for x in env.logger.handlers): env.logger.handlers = [ x for x in env.logger.handlers if not isinstance(x, logging.StreamHandler) ] levels = { 0: logging.ERROR, 1: logging.WARNING, 2: logging.INFO, 3: logging.DEBUG, 4: logging.DEBUG, None: logging.INFO, } env.logger.addHandler( NotebookLoggingHandler( levels[env.verbosity], kernel, title=" ".join(sys.argv) ) ) else: env.logger.handers[0].setTitle(" ".join(sys.argv)) global last_cell_id # we retain step_input etc only when we step through a cell #256 if kernel and kernel.cell_id != last_cell_id: # clear __step_input__, __step_output__ etc because there is # no concept of passing input/outputs across cells. env.sos_dict.set("__step_output__", sos_targets([])) for k in [ "__step_input__", "__default_output__", "step_input", "step_output", "step_depends", "_input", "_output", "_depends", ]: env.sos_dict.pop(k, None) last_cell_id = kernel.cell_id config = { "config_file": args.__config__, "default_queue": args.__queue__, "run_mode": "dryrun" if args.dryrun else "interactive", # issue 230, ignore sig mode in interactive mode "sig_mode": "ignore", "verbosity": args.verbosity, # for backward compatibility, we try both args.__worker_procs__ and args.__max_procs__ "worker_procs": args.__worker_procs__ if hasattr(args, "__worker_procs__") else args.__max_procs__, "max_running_jobs": args.__max_running_jobs__, # for infomration and resume only "workdir": os.getcwd(), "workflow": args.workflow, "targets": args.__targets__, "workflow_args": workflow_args, "workflow_id": textMD5(code), # interactive work is also a slave of the controller "slave_id": kernel.cell_id, } env.sos_dict.set("workflow_id", config["workflow_id"]) env.config.update(config) try: if not any( SOS_SECTION_HEADER.match(line) or line.startswith("%from") or line.startswith("%include") for line in code.splitlines() ): code = ( f"[cell{str(kernel.cell_id)[:8] if kernel and kernel.cell_id else '0'}]\n" + code ) script = SoS_Script(content=code) else: return workflow = script.workflow(args.workflow) section = workflow.sections[0] res = analyze_section(section) env.sos_dict.quick_update( { "__signature_vars__": res["signature_vars"], "__environ_vars__": res["environ_vars"], "__changed_vars__": res["changed_vars"], } ) executor = Interactive_Step_Executor(section, mode="interactive") ret = executor.run() try: return ret["__last_res__"] except Exception as e: raise RuntimeError( f"Unknown result returned from executor {ret}: {e}" ) from e except (UnknownTarget, RemovedTarget) as e: raise RuntimeError(f"Unavailable target {e.target}") from e except TerminateExecution: return except SystemExit: # this happens because the executor is in resume mode but nothing # needs to be resumed, we simply pass return except Exception: env.log_to_file("PROCESS", get_traceback()) raise class Tapped_Executor(mp.Process): def __init__(self, code, args, config): # the worker process knows configuration file, command line argument etc super().__init__() self.code = code self.args = args self.config = config def run(self): env.config.update(self.config) # start a socket? context = zmq.Context() stdout_socket = context.socket(zmq.PUSH) stdout_socket.connect(self.config["sockets"]["tapping_logging"]) informer_socket = context.socket(zmq.PUSH) informer_socket.connect(self.config["sockets"]["tapping_listener"]) try: filename = tempfile.NamedTemporaryFile( prefix=".tmp_script_", dir=os.path.expanduser("~/.sos"), suffix=".sos", delete=False, ).name with open(filename, "w") as script_file: script_file.write(self.code) cmd = ( ["sos", "run", filename] + shlex.split(self.args) + [ "-m", "tapping", "slave", self.config["slave_id"], self.config["sockets"]["tapping_logging"], self.config["sockets"]["tapping_listener"], self.config["sockets"]["tapping_controller"], ] ) ret_code = pexpect_run( subprocess.list2cmdline(cmd), shell=True, stdout_socket=stdout_socket ) # status will not trigger frontend update if it was not # started with a pending status informer_socket.send_pyobj( { "msg_type": "workflow_status", "data": { "cell_id": env.config["slave_id"], "status": "completed" if ret_code == 0 else "failed", }, } ) sys.exit(ret_code) except Exception as e: stdout_socket.send_multipart([b"ERROR", str(e).encode()]) informer_socket.send_pyobj( { "msg_type": "workflow_status", "data": { "cell_id": env.config["slave_id"], "status": "failed", "exception": str(e), }, } ) sys.exit(1) finally: # when the script is execute on a remote host, we do not know when the # remote job is started or ended and if they still need access to the script file. if "-r" not in self.args: try: os.remove(filename) except Exception as e: env.logger.warning(f"Failed to remove temp script {filename}: {e}") stdout_socket.LINGER = 0 stdout_socket.close() informer_socket.LINGER = 0 informer_socket.close() context.term() # workflow queue that holds all workflow g_workflow_queue: list = [] def run_next_workflow_in_queue(): # execute the first available item global g_workflow_queue for idx, (_, proc) in enumerate(g_workflow_queue): if proc is None: continue # this is ordered if isinstance(proc, tuple): executor = Tapped_Executor(*proc) executor.start() g_workflow_queue[idx][1] = executor break if not (proc.is_alive() and psutil.pid_exists(proc.pid)): g_workflow_queue[idx][1] = None continue break def execute_pending_workflow(cell_ids, kernel): # we are giving a list of cell_ids because some cells might be removed # we use this list to clear workflow queue of removed cells for idx, (cid, proc) in enumerate(g_workflow_queue): # if proc is a process if cid not in cell_ids: if not isinstance(proc, tuple): proc.join() g_workflow_queue[idx][1] = None run_next_workflow_in_queue() def run_sos_workflow( code, raw_args="", kernel=None, workflow_mode=False, run_in_queue=False ): # when user asks to execute a cell as workflow. We either # execute the workflow or put it in queue global g_workflow_queue # if a cell already exist, remove previous pending job (a tuple) # completed job (dead process), or running job. if kernel.cell_id in [cid for cid, proc in g_workflow_queue if proc is not None]: cancel_workflow(kernel.cell_id, kernel) if run_in_queue: # put to the back cfg = copy.deepcopy(env.config) cfg["slave_id"] = kernel.cell_id g_workflow_queue.append([kernel.cell_id, (code, raw_args, cfg)]) # in any case, we start with a pending status kernel.send_frontend_msg( "workflow_status", { "cell_id": kernel.cell_id, "status": "pending", "index": len(g_workflow_queue), }, ) run_next_workflow_in_queue() else: env.config["slave_id"] = kernel.cell_id executor = Tapped_Executor(code, raw_args, env.config) executor.start() executor.join() if executor.exitcode != 0: if executor.exitcode < 0: raise RuntimeError( f"Workflow terminated by sigmal {-executor.exitcode}" ) raise RuntimeError(f"Workflow exited with code {executor.exitcode}") return None def cancel_workflow(cell_id, kernel): global g_workflow_queue env.logger.info("A queued or running workflow in this cell is canceled") kernel.send_frontend_msg( "workflow_status", {"cell_id": cell_id, "status": "purged"} ) for idx, (cid, proc) in enumerate(g_workflow_queue): if cid != cell_id or proc is None: continue if not isinstance(proc, tuple) and ( proc.is_alive() and psutil.pid_exists(proc.pid) ): from sos.executor_utils import kill_all_subprocesses kill_all_subprocesses(proc.pid, include_self=True) proc.terminate() if psutil.pid_exists(proc.pid): raise RuntimeError("Failed to kill workflow") g_workflow_queue[idx][1] = None ================================================ FILE: tasks.py ================================================ """ Development tasks for sos-notebook using invoke. """ import os import sys from pathlib import Path from invoke import task def check_tool(ctx, tool_name): """Check if a tool is available.""" result = ctx.run(f"which {tool_name}", warn=True, hide=True) return result.ok # Project paths ROOT_DIR = Path(__file__).parent SRC_DIR = ROOT_DIR / "src" TEST_DIR = ROOT_DIR / "test" @task def format(ctx, check=False): """Format code with ruff.""" if not check_tool(ctx, "ruff"): print("❌ ruff not found. Install with: uv add --dev ruff") sys.exit(1) paths = [str(SRC_DIR), str(TEST_DIR), "tasks.py"] if check: print("🔍 Checking code formatting...") cmd = "ruff format --check " + " ".join(paths) else: print("🎨 Formatting code...") cmd = "ruff format " + " ".join(paths) result = ctx.run(cmd, warn=True) if check and result.ok: print("✅ Code formatting is correct!") elif check: print("⚠️ Code formatting needs changes") else: print("✅ Code formatting complete!") @task def lint(ctx, fix=False): """Run linting with ruff.""" if not check_tool(ctx, "ruff"): print("❌ ruff not found. Install with: uv add --dev ruff") sys.exit(1) paths = [str(SRC_DIR), str(TEST_DIR), "tasks.py"] if fix: print("🔧 Running ruff linting with auto-fix...") cmd = "ruff check --fix " + " ".join(paths) else: print("🔍 Running ruff linting...") cmd = "ruff check " + " ".join(paths) result = ctx.run(cmd, warn=True) if result.ok: print("✅ Linting passed!") else: print( "❌ Linting issues found. Run 'invoke lint --fix' or 'invoke format' to fix issues." ) sys.exit(1) @task def precommit(ctx, install=False): """Run pre-commit hooks.""" if install: print("📋 Installing pre-commit hooks...") ctx.run("pre-commit install") print("✅ Pre-commit hooks installed!") else: print("🔍 Running pre-commit checks...") ctx.run("pre-commit run --all-files") @task def test(ctx, path="", verbose=False, coverage=False): """Run tests with pytest.""" if not path: path = str(TEST_DIR) cmd = ["python", "-m", "pytest"] if verbose: cmd.append("-v") else: cmd.append("-q") if coverage: cmd.extend( [ "--cov=sos_notebook", "--cov-report=term-missing", "--cov-report=html:htmlcov", ] ) print("🧪 Running tests with coverage...") else: print("🧪 Running tests...") cmd.append(path) cmd.extend(["--disable-warnings"]) result = ctx.run(" ".join(cmd), warn=True) if result.ok: print("✅ All tests passed!") if coverage: print("📊 Coverage report generated in htmlcov/") else: print("❌ Some tests failed!") sys.exit(1) @task def test_docker(ctx): """Run full test suite in Docker (as done in CI).""" print("🐳 Running tests in Docker environment...") print("This requires Docker to be running and may take some time...") # Check if docker-compose is available result = ctx.run("docker-compose --version", warn=True, hide=True) if not result.ok: print( "❌ docker-compose not available. Install Docker and docker-compose first." ) sys.exit(1) # Run the Docker test setup similar to CI with ctx.cd("development"): print("🔧 Setting up Docker environment...") ctx.run("docker network create sosnet", warn=True) ctx.run("docker-compose up -d") # Copy project and run tests ctx.run("docker cp .. sosnotebook_sos-notebook_1:/home/jovyan") ctx.run( "docker exec -u root sosnotebook_sos-notebook_1 sh ./development/install_sos_notebook.sh" ) print("🧪 Running tests in container...") result = ctx.run( "docker exec sosnotebook_sos-notebook_1 bash -c 'cd test && pytest -v'", warn=True, ) # Cleanup print("🧹 Cleaning up Docker environment...") ctx.run("docker-compose down", warn=True) if result.ok: print("✅ Docker tests passed!") else: print("❌ Docker tests failed!") sys.exit(1) @task def build(ctx, clean=False): """Build source and wheel distributions.""" if clean: print("🧹 Cleaning build artifacts...") ctx.run("rm -rf build/ dist/ src/*.egg-info/") print("📦 Building distributions...") ctx.run("python -m build") print("✅ Build complete! Check dist/ directory.") @task def clean(ctx, all=False): """Clean build artifacts and caches.""" patterns = [ "build/", "dist/", "src/*.egg-info/", "**/__pycache__/", "**/*.pyc", "**/*.pyo", ".coverage", "htmlcov/", ".pytest_cache/", ] if all: patterns.extend( [ ".tox/", "**/.ipynb_checkpoints/", ] ) print("🧹 Deep cleaning all build artifacts and caches...") else: print("🧹 Cleaning build artifacts...") for pattern in patterns: ctx.run(f"find . -name '{pattern}' -exec rm -rf {{}} +", warn=True) print("✅ Cleanup complete!") @task def install(ctx, dev=True, force=False): """Install the package.""" if dev: print("📦 Installing in development mode...") cmd = "uv pip install -e ." else: print("📦 Installing package...") cmd = "uv pip install ." if force: cmd += " --force-reinstall" ctx.run(cmd) print("✅ Installation complete!") @task def check(ctx): """Run all quality checks (format, lint, test).""" print("🔍 Running comprehensive quality checks...") print("\n" + "=" * 50) print("1. Code Formatting Check") print("=" * 50) format(ctx, check=True) print("\n" + "=" * 50) print("2. Linting Check") print("=" * 50) lint(ctx) print("\n" + "=" * 50) print("3. Running Tests") print("=" * 50) test(ctx) print("\n" + "=" * 50) print("✅ All quality checks passed!") print("=" * 50) @task def release_check(ctx): """Run comprehensive checks before release.""" print("🚀 Running release checks...") # Run quality checks check(ctx) print("\n" + "=" * 50) print("4. Build Check") print("=" * 50) build(ctx, clean=True) print("\n" + "=" * 50) print("✅ All release checks passed!") print("🚀 Ready for release!") print("=" * 50) @task def uv_sync(ctx): """Sync dependencies using uv.""" print("🔄 Syncing dependencies with uv...") ctx.run("uv sync") print("✅ Dependencies synced!") @task def uv_lock(ctx): """Update uv.lock file.""" print("🔒 Updating uv.lock file...") ctx.run("uv lock") print("✅ Lock file updated!") @task def venv_create(ctx): """Create virtual environment with uv.""" print("🏗️ Creating virtual environment with uv...") ctx.run("uv venv") print("✅ Virtual environment created!") print("💡 Activate with: source .venv/bin/activate") @task def dev_setup(ctx): """Set up development environment.""" print("🛠️ Setting up development environment...") # Create virtual environment if it doesn't exist if not os.path.exists(".venv"): print("🏗️ Creating virtual environment...") ctx.run("uv venv") # Install development dependencies print("📦 Installing development dependencies...") ctx.run("uv pip install -e .") ctx.run("uv sync --dev") # Set up pre-commit print("📋 Setting up pre-commit hooks...") precommit(ctx, install=True) print("✅ Development environment setup complete!") print("\nCommon commands:") print(" invoke --list # Show all available tasks") print(" invoke check # Run all quality checks") print(" invoke format # Format code with ruff") print(" invoke lint # Run linting with ruff") print(" invoke lint --fix # Run linting with auto-fix") print(" invoke test # Run tests") print("\n💡 Don't forget to activate the virtual environment:") print(" source .venv/bin/activate") @task(default=True) def help(ctx): """Show help and available tasks.""" print("SoS Notebook Development Tasks") print("=" * 40) ctx.run("invoke --list") print("\nFor detailed help on any task:") print(" invoke --help TASKNAME") ================================================ FILE: test/__init__.py ================================================ ================================================ FILE: test/build_test_docker.sh ================================================ #!/usr/bin/bash # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. # # Make sure we have local public key # instance=$(docker ps | grep test_sos) if [ "${instance}" != "" ] then #echo "sshd is already running" #exit docker stop test_sos fi docker rm test_sos docker rmi eg_sshd # this will create ~/.ssh/id_rsa.pub and ~/.ssh/id_rsa [ -f ~/.ssh/id_rsa.pub ] || ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa # copy the public key here cp ~/.ssh/id_rsa.pub authorized_keys # create a docker file # cat > Dockerfile << 'HERE' FROM python:3.6 RUN apt-get update && apt-get install -y openssh-server rsync task-spooler RUN mkdir /var/run/sshd RUN echo 'root:screencast' | chpasswd RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config # SSH login fix. Otherwise user is kicked off after login RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd ENV NOTVISIBLE "in users profile" RUN echo "export VISIBLE=now" >> /etc/profile RUN [ -d /root/.ssh ] || mkdir -p /root/.ssh ADD authorized_keys /root/.ssh/authorized_keys # install sos on the remote host RUN pip install spyder jedi notebook nbconvert nbformat pyyaml psutil tqdm RUN pip install fasteners pygments ipython ptpython networkx pydotplus ARG SHA=LATEST RUN SHA=$SHA git clone http://github.com/vatlab/sos sos RUN cd sos && pip install . -U RUN echo "export TS_SLOTS=10" >> /root/.bash_profile EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] HERE # # # Build the docker image, but we will force docker to use latest github commit # SHA=$(curl -s 'https://api.github.com/repos/vatlab/SOS/commits' | grep sha | head -1 | cut -d\" -f4) echo "COMMIT SHA $SHA" docker build --build-arg SHA=$SHA -t eg_sshd . # # start docker image docker run -d -P --env TS_SLOTS=10 --name test_sos eg_sshd # get the port PORT22=$(docker port test_sos 22 | cut -f2 -d:) # add the docker machine to known_hosts so that sos will not be # prompt with the message "are you sure you want to connect"? ssh -o 'StrictHostKeyChecking no' -p $PORT22 root@localhost exit # write a host file cat > ~/docker.yml << HERE localhost: localhost remote_user: root limited: max_cores: 1 max_mem: 1G hosts: localhost: description: localhost address: localhost paths: home: $HOME docker: address: "{remote_user}@localhost" port: $PORT22 paths: home: "/{remote_user}" local_limited: based_on: - hosts.localhost - limited max_walltime: 10 docker_limited: based_on: - hosts.docker - limited max_walltime: 10 local_rq: based_on: hosts.localhost description: rq server with worker queue_type: rq redis_host: localhost redis_port: 6379 queue: high ts: description: task spooler on the docker machine based_on: hosts.docker HERE # this part is not interpolated cat >> ~/docker.yml << 'HERE' queue_type: pbs status_check_interval: 5 job_template: | #!/bin/bash cd {cur_dir} sos execute {task} -v {verbosity} -s {sig_mode} {'--dryrun' if run_mode == 'dryrun' else ''} max_running_jobs: 100 submit_cmd: tsp -L {task} sh {job_file} status_cmd: tsp -s {job_id} kill_cmd: tsp -r {job_id} HERE ================================================ FILE: test/conftest.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import os import tempfile import pytest from sos_notebook.test_utils import Notebook @pytest.fixture(scope="class") def notebook(): """Provide a notebook interface for kernel testing""" return Notebook() @pytest.fixture() def sample_scripts(): if not os.path.isdir("temp"): os.mkdir("temp") with open("temp/script1.sos", "w") as script: script.write(""" [0] seq = range(3) input: for_each='seq' output: 'test${_seq}.txt' print(output) """) with open("temp/script2.sos", "w") as script: # with tab after run: script.write(""" #! This is supposed to be a markdown #! cell [0] seq = range(3) input: for_each='seq' output: 'test${_seq}.txt' run:\t\t\tconcurrent=True echo 'this is test script' [10] report('this is action report') """) return ["temp/script1.sos", "temp/script2.sos"] @pytest.fixture() def sample_notebook(): with open("sample_notebook.ipynb", "w") as sn: sn.write(r"""{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this is a test workflow" ] }, { "cell_type": "markdown", "metadata": { "kernel": "SoS" }, "source": [ "This is a markdown cell" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "kernel": "R" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a cell with another kernel" ] } ], "source": [ "cat('This is a cell with another kernel')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "kernel": "SoS" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a scratch cell\n" ] } ], "source": [ "print('This is a scratch cell')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this comment will be included but not shown in help message\n", "# because it is for the global\n", "[global]\n", "a = 1\n", "# this comment will become the comment for parameter b\n", "parameter: b=2\n", "parameter: c=3 \n", "# this comment will become the comment for parameter d\n", "parameter: d='d'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this comment will not be included in exported workflow\n", "# because it is not immediately before section\n", "\n", "# this is a section comment, will be displayed\n", "[default]\n", "print(f'Hello {a}')" ] } ], "metadata": { "kernelspec": { "display_name": "SoS", "language": "sos", "name": "sos" }, "language_info": { "codemirror_mode": "sos", "file_extension": ".sos", "mimetype": "text/x-sos", "name": "sos", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", "pygments_lexer": "sos" }, "sos": { "default_kernel": "SoS", "kernels": [ [ "R", "ir", "R", "#DCDCDA" ], [ "SoS", "sos", "", "" ] ], "panel": { "displayed": true, "height": 0, "style": "side" }, "version": "0.9.14.11" } }, "nbformat": 4, "nbformat_minor": 2 } """) return "sample_notebook.ipynb" @pytest.fixture() def sample_papermill_notebook(): with open("sample_mill_notebook.ipynb", "w") as sn: sn.write(r"""{ "cells": [ { "cell_type": "markdown", "metadata": { "kernel": "SoS" }, "source": [ "## Notebook for testing papermill" ] }, { "cell_type": "markdown", "metadata": { "kernel": "SoS" }, "source": [ "## Section 1" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "kernel": "SoS", "tags": [ "parameters" ] }, "outputs": [], "source": [ "# this is the parameter cell\n", "cutoff = 1" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "kernel": "SoS" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "# use of parameter cutoff\n", "print(cutoff)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "kernel": "R" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1" ] } ], "source": [ "%expand\n", "cat(\"{cutoff}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "R" }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SoS", "language": "sos", "name": "sos" }, "language_info": { "codemirror_mode": "sos", "file_extension": ".sos", "mimetype": "text/x-sos", "name": "sos", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", "pygments_lexer": "sos" }, "sos": { "celltoolbar": true, "kernels": [ [ "R", "ir", "R", "#FDEDEC", "" ], [ "SoS", "sos", "", "", "sos" ] ], "panel": { "displayed": true, "height": 0, "style": "side" }, "version": "0.21.15" } }, "nbformat": 4, "nbformat_minor": 4 } """) return "sample_mill_notebook.ipynb" ================================================ FILE: test/sample_notebook.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this is a test workflow" ] }, { "cell_type": "markdown", "metadata": { "kernel": "SoS" }, "source": [ "This is a markdown cell" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "kernel": "R" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a cell with another kernel" ] } ], "source": [ "cat('This is a cell with another kernel')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "kernel": "SoS" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a scratch cell\n" ] } ], "source": [ "print('This is a scratch cell')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this comment will be included but not shown in help message\n", "# because it is for the global\n", "[global]\n", "a = 1\n", "# this comment will become the comment for parameter b\n", "parameter: b=2\n", "parameter: c=3 \n", "# this comment will become the comment for parameter d\n", "parameter: d='d'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this comment will not be included in exported workflow\n", "# because it is not immediately before section\n", "\n", "# this is a section comment, will be displayed\n", "[default]\n", "print(f'Hello {a}')" ] } ], "metadata": { "kernelspec": { "display_name": "SoS", "language": "sos", "name": "sos" }, "language_info": { "codemirror_mode": "sos", "file_extension": ".sos", "mimetype": "text/x-sos", "name": "sos", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", "pygments_lexer": "sos" }, "sos": { "default_kernel": "SoS", "kernels": [ [ "R", "ir", "R", "#DCDCDA" ], [ "SoS", "sos", "", "" ] ], "panel": { "displayed": true, "height": 0, "style": "side" }, "version": "0.9.14.11" } }, "nbformat": 4, "nbformat_minor": 2 } ================================================ FILE: test/sample_papermill_notebook.ipynb ================================================ { "cells": [ { "cell_type": "markdown", "metadata": { "kernel": "SoS" }, "source": [ "## Notebook for testing papermill" ] }, { "cell_type": "markdown", "metadata": { "kernel": "SoS" }, "source": [ "## Section 1" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "kernel": "SoS", "tags": [ "parameters" ] }, "outputs": [], "source": [ "# this is the parameter cell\n", "cutoff = 1" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "kernel": "SoS" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "# use of parameter cutoff\n", "print(cutoff)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "kernel": "R" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1" ] } ], "source": [ "%expand\n", "cat(\"{cutoff}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "R" }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SoS", "language": "sos", "name": "sos" }, "language_info": { "codemirror_mode": "sos", "file_extension": ".sos", "mimetype": "text/x-sos", "name": "sos", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", "pygments_lexer": "sos" }, "sos": { "celltoolbar": true, "kernels": [ [ "R", "ir", "R", "#FDEDEC", "" ], [ "SoS", "sos", "", "", "sos" ] ], "panel": { "displayed": true, "height": 0, "style": "side" }, "version": "0.21.15" } }, "nbformat": 4, "nbformat_minor": 4 } ================================================ FILE: test/sample_workflow.ipynb ================================================ { "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this is a test workflow" ] }, { "cell_type": "markdown", "metadata": { "kernel": "SoS" }, "source": [ "This is a markdown cell" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "kernel": "R" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a cell with another kernel" ] } ], "source": [ "cat('This is a cell with another kernel')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "kernel": "SoS" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a scratch cell\n" ] } ], "source": [ "print('This is a scratch cell')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this comment will be included but not shown in help message\n", "# because it is for the global\n", "[global]\n", "a = 1\n", "# this comment will become the comment for parameter b\n", "parameter: b=2\n", "parameter: c=3 \n", "# this comment will become the comment for parameter d\n", "parameter: d='d'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "kernel": "SoS" }, "outputs": [], "source": [ "# this comment will not be included in exported workflow\n", "# because it is not immediately before section\n", "\n", "# this is a section comment, will be displayed\n", "[default]\n", "print(f'Hello {a}')" ] } ], "metadata": { "kernelspec": { "display_name": "SoS", "language": "sos", "name": "sos" }, "language_info": { "codemirror_mode": "sos", "file_extension": ".sos", "mimetype": "text/x-sos", "name": "sos", "nbconvert_exporter": "sos_notebook.converter.SoS_Exporter", "pygments_lexer": "sos" }, "sos": { "default_kernel": "SoS", "kernels": [ [ "R", "ir", "R", "#DCDCDA" ], [ "SoS", "sos", "", "" ] ], "panel": { "displayed": true, "height": 0, "style": "side" }, "version": "0.9.14.11" } }, "nbformat": 4, "nbformat_minor": 2 } ================================================ FILE: test/test_convert.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import os import shutil import subprocess import pytest def test_script_to_and_from_notebook(sample_scripts): """Test sos show script --notebook""" for script_file in sample_scripts: subprocess.call( f"sos convert {script_file} {script_file[:-4]}.ipynb", shell=True ) subprocess.call( f"sos convert {script_file[:-4]}.ipynb {script_file}", shell=True ) subprocess.call( f"sos convert {script_file[:-4]}.ipynb {script_file} --all", shell=True ) def test_convert_html(sample_notebook): subprocess.call(f"sos convert {sample_notebook} test_wf.html", shell=True) assert os.path.isfile("test_wf.html") # test the use of jupyter templates subprocess.call( f"sos convert {sample_notebook} test_wf1.html --template basic", shell=True ) assert os.path.isfile("test_wf1.html") # subprocess.call( f"sos convert {sample_notebook} test_wf2.html --template sos-report", shell=True ) assert os.path.isfile("test_wf2.html") # subprocess.call( f"sos convert {sample_notebook} test_wf3.html --template sos-full", shell=True ) assert os.path.isfile("test_wf3.html") # subprocess.call( f"sos convert {sample_notebook} test_wf4.html --template sos-cm", shell=True ) assert os.path.isfile("test_wf4.html") # subprocess.call( f"sos convert {sample_notebook} test_wf5.html --template sos-full-toc", shell=True, ) assert os.path.isfile("test_wf5.html") # subprocess.call( f"sos convert {sample_notebook} test_wf6.html --template sos-report-toc", shell=True, ) assert os.path.isfile("test_wf6.html") # subprocess.call( f"sos convert {sample_notebook} test_wf7.html --template sos-cm-toc", shell=True ) assert os.path.isfile("test_wf7.html") @pytest.mark.skipif( not shutil.which("xelatex"), reason="No XeLatex under windows to compile pdf" ) def test_convert_pdf(sample_notebook, sample_papermill_notebook): subprocess.call(f"sos convert {sample_notebook} test_wf.pdf", shell=True) assert os.path.isfile("test_wf.pdf") # PDF with execute subprocess.call( f"sos convert {sample_papermill_notebook} test_notebook.pdf --execute", shell=True, ) assert os.path.isfile("test_notebook.pdf") # mark down with execute subprocess.call( f"sos convert {sample_papermill_notebook} test_notebook_with_param.pdf --execute cutoff=34587", shell=True, ) assert os.path.isfile("test_notebook_with_param.pdf") with open("test_notebook_with_param.pdf", "rb") as md: assert b"34587" in md.read() def test_convert_md(sample_notebook, sample_papermill_notebook): subprocess.call(f"sos convert {sample_notebook} test_wf.md", shell=True) assert os.path.isfile("test_wf.md") # output to stdout subprocess.call(f"sos convert {sample_notebook} --to md > test_wf1.md", shell=True) assert os.path.isfile("test_wf1.md") # mark down with execute subprocess.call( f"sos convert {sample_papermill_notebook} test_notebook.md --execute", shell=True, ) assert os.path.isfile("test_notebook.md") # mark down with execute subprocess.call( f"sos convert {sample_papermill_notebook} test_notebook_with_param.md --execute cutoff=54321", shell=True, ) assert os.path.isfile("test_notebook_with_param.md") with open("test_notebook_with_param.md") as md: assert "54321" in md.read() def test_convert_notebook(sample_notebook): assert ( subprocess.call( f"sos convert {sample_notebook} test_nonSoS.ipynb --kernel python3", shell=True, ) == 0 ) assert os.path.isfile("test_nonSoS.ipynb") # assert ( subprocess.call("sos convert test_nonSoS.ipynb test_SoS.ipynb", shell=True) == 0 ) assert os.path.isfile("test_SoS.ipynb") # cannot convert to invalid kernel assert ( subprocess.call( f"sos convert {sample_notebook} test_invalid.ipynb --kernel nonexisting", shell=True, ) != 0 ) def test_execute_notebook(sample_papermill_notebook): assert ( subprocess.call( f"sos convert {sample_papermill_notebook} test_papermill_executed.ipynb --execute", shell=True, ) == 0 ) assert os.path.isfile("test_papermill_executed.ipynb") # assert ( subprocess.call( f"sos convert {sample_papermill_notebook} test_papermill_executed_with_param.ipynb --execute cutoff=12345", shell=True, ) == 0 ) assert os.path.isfile("test_papermill_executed_with_param.ipynb") with open("test_papermill_executed_with_param.ipynb") as nb: assert "12345" in nb.read() def test_execute_and_convert(sample_papermill_notebook): assert ( subprocess.call( f"sos convert {sample_papermill_notebook} test_papermill_executed.html --execute", shell=True, ) == 0 ) assert os.path.isfile("test_papermill_executed.html") # assert ( subprocess.call( f"sos convert {sample_papermill_notebook} test_papermill_executed_with_param.html --execute cutoff=12345", shell=True, ) == 0 ) assert os.path.isfile("test_papermill_executed_with_param.html") with open("test_papermill_executed_with_param.html") as nb: assert "12345" in nb.read() def test_comments(sample_notebook): """Test if comments before section headers are correctly extracted""" subprocess.call(f"sos convert {sample_notebook} sample_workflow.sos", shell=True) with open("sample_workflow.sos") as sw: wf = sw.read() assert "this is a test workflow" not in wf assert wf.count("this comment will be included but not shown in help") == 1 assert wf.count("this comment will become the comment for parameter b") == 1 assert wf.count("this comment will become the comment for parameter d") == 1 assert "this is a cell with another kernel" not in wf assert "this comment will not be included in exported workflow" not in wf ================================================ FILE: test/test_magics.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import os import sys import tempfile import pytest from sos_notebook.test_utils import NotebookTest class TestMagics(NotebookTest): def test_magic_in_subkernel(self, notebook): """test %pwd in the python3 kernel (which is not a sos magic)""" assert len(notebook.check_output("%pwd", kernel="Python3")) > 0 def test_help_messages(self, notebook): """test help functions of magics""" for magic in ( "cd", "convert", "get", "matplotlib", "preview", "put", "render", "revisions", "run", "runfile", "save", "sandbox", "sessioninfo", "sosrun", "shutdown", "task", "use", "with", ): output = notebook.check_output(f"%{magic} -h", kernel="SoS") # output does not have error assert magic in output def test_magic_capture(self, notebook): # test %capture # capture raw (default) notebook.call( """\ %capture cat('this is to stdout') """, kernel="R", ) output = notebook.check_output("__captured", kernel="SoS") assert ( "stream" in output and "stdout" in output and "this is to stdout" in output ) # specify raw notebook.call( """\ %capture raw cat('this is to stdout') """, kernel="R", ) output = notebook.check_output("__captured", kernel="SoS") assert ( "stream" in output and "stdout" in output and "this is to stdout" in output ) # # capture SoS execute_result (#220) notebook.call( """\ %capture raw 'this is to texts' """, kernel="SoS", ) output = notebook.check_output("__captured", kernel="SoS") assert ( "execute_result" in output and "text/plain" in output and "this is to texts" in output ) # # capture to variable assert ( notebook.check_output( """\ %capture stdout --to R_out cat('this is to stdout') """, kernel="R", ) == "this is to stdout" ) # notebook.call("%capture stdout --to R_out \n ", kernel="R") assert notebook.check_output("R_out", kernel="SoS") == "''" # notebook.call( """\ %capture text --to R_out paste('this is the return value') """, kernel="R", ) output = notebook.check_output("R_out", kernel="SoS") assert "this is the return value" in output # # capture as csv notebook.call( """\ %capture stdout --as csv --to res print('a,b\\nc,d') """, kernel="SoS", ) assert "a" in notebook.check_output("res", kernel="SoS") assert "DataFrame" in notebook.check_output("type(res)", kernel="SoS") # # capture as tsv notebook.call( """\ %capture stdout --as tsv --to res print('a\\tb\\nc\\td') """, kernel="SoS", ) assert "a" in notebook.check_output("res", kernel="SoS") assert "DataFrame" in notebook.check_output("type(res)", kernel="SoS") # # capture as json notebook.call( """\ %capture stdout --as json --to res print('[1,2,3]') """, kernel="SoS", ) assert "[1, 2, 3]" in notebook.check_output("res", kernel="SoS") # # test append to str notebook.call( """\ %capture stdout --to captured_text print('from sos') """, kernel="SoS", ) notebook.call( """\ %capture stdout --append captured_text cat('from R') """, kernel="R", ) output = notebook.check_output("captured_text", kernel="SoS") assert "from sos" in output and "from R" in output assert "str" in notebook.check_output("type(captured_text)", kernel="SoS") # test append to dataframe notebook.call( """\ %capture stdout --as tsv --to table print('a\\tb\\n11\\t22') """, kernel="SoS", ) notebook.call( """\ %capture stdout --as tsv --append table print('a\\tb\\n33\\t44') """, kernel="SoS", ) output = notebook.check_output("table", kernel="SoS") assert "11" in output and "22" in output and "33" in output and "44" in output assert "DataFrame" in notebook.check_output("type(table)", kernel="SoS") def test_magic_cd(self, notebook): # magic cd that changes directory of all subfolders output1 = notebook.check_output( """\ import os print(os.getcwd()) """, kernel="Python3", ) notebook.call("%cd ..", kernel="SoS") output2 = notebook.check_output( """\ import os print(os.getcwd()) """, kernel="Python3", ) assert len(output1) > len(output2) and output1.startswith(output2) def test_magic_connectinfo(self, notebook): # test %capture assert "Connection file" in notebook.check_output("%connectinfo", kernel="SoS") def test_magic_debug(self, notebook): assert "debug" in notebook.check_output( """\ %debug on %debug off """, kernel="SoS", expect_error=True, ) def test_magic_dict(self, notebook): # test %dict notebook.call( """\ R_out = 1 ran = 5 """, kernel="SoS", ) output = notebook.check_output( """\ %dict --keys """, kernel="SoS", ) assert "R_out" in output and "ran" in output # assert "r" in notebook.check_output("%dict ran", kernel="SoS") # assert "R_out" not in notebook.check_output( """\ %dict --reset %dict --keys """, kernel="SoS", ) def test_magic_expand(self, notebook): # test %expand notebook.call("par=100", kernel="SoS") assert ( "A parameter {par} greater than 50 is specified." == notebook.check_output( """\ cat('A parameter {par} greater than 50 is specified.'); """, kernel="R", ) ) assert "A parameter 100 greater than 50 is specified." == notebook.check_output( """\ %expand if ({par} > 50) {{ cat('A parameter {par} greater than 50 is specified.'); }} """, kernel="R", ) assert "A parameter 100 greater than 50 is specified." == notebook.check_output( """\ %expand ${ } if (${par} > 50) { cat('A parameter ${par} greater than 50 is specified.'); } """, kernel="R", ) assert "A parameter 100 greater than 50 is specified." == notebook.check_output( """\ %expand [ ] if ([par] > 50) { cat('A parameter [par] greater than 50 is specified.'); } """, kernel="R", ) def test_magic_get(self, notebook): # test %get notebook.call( """\ a = [1, 2, 3] b = [1, 2, '3'] """, kernel="SoS", ) assert "[1, 2, 3]" == notebook.check_output( """\ %get a a """, kernel="Python3", ) assert "[1, 2, 3]" == notebook.check_output( """\ %get a --as aa aa """, kernel="Python3", ) assert "List of 3" in notebook.check_output( """\ %get b str(b) R_var <- 'R variable' """, kernel="R", ) assert "R variable" in notebook.check_output( """\ %get --from R R_var R_var """, kernel="Python3", ) # # get with different variable names notebook.call( """\ a = 1025 _b_a = 22 """, kernel="SoS", ) assert "1025" == notebook.check_output( """\ %get a b <- 122 c <- 555 a """, kernel="R", ) # assert "22" in notebook.check_output( """\ %get _b_a .b_a """, kernel="R", expect_error=True, ) # # get from another kernel assert "555" in notebook.check_output( """\ %get c --from R c """, kernel="R", ) def test_magic_get_between_subkernels(self, notebook): # test variable transfer between subkernels, which should not leave a trace in # SoS notebook.call( """\ subs_a = 'sos_a' """, kernel="SoS", ) notebook.call( """\ subs_a = 'python_a' subs_b = 'python_b' """, kernel="Python3", ) notebook.call( """\ %get subs_a subs_b --from Python3 """, kernel="R", ) assert "sos_a" in notebook.check_output("subs_a", kernel="SoS") assert "NameError" in notebook.check_output( "subs_b", kernel="SoS", expect_error=True ) # notebook.call( """\ %get subs_b --from Python3 --as subr """, kernel="R", ) assert "python_b" in notebook.check_output("subr", kernel="R") def test_magic_matplotlib(self, notebook): # test %capture pytest.importorskip("matplotlib") assert "data:image/png;base64" in notebook.check_output( """\ %matplotlib inline import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 10) plt.plot(x, np.sin(x), '--', linewidth=2) plt.show() """, kernel="SoS", selector="img", attribute="src", ) def test_magic_render(self, notebook): # test %put from subkernel to SoS Kernel output = notebook.check_output( '''\ %render """ # header * item1 * item2 """ ''', kernel="SoS", ) assert "header" in output and "item1" in output and "item2" in output assert ( "# header" not in output and "* item1" not in output and "* item2" not in output ) # render wrong type from subkernel output = notebook.check_output( """\ %render text cat("\\n# header\\n* item1\\n* item2\\n") """, kernel="R", ) assert ( "header" not in output and "item1" not in output and "item2" not in output ) # render correct type output = notebook.check_output( """\ %render cat("\\n# header\\n* item1\\n* item2\\n") """, kernel="R", ) assert "header" in output and "item1" in output and "item2" in output # # test render as other types output = notebook.check_output( '''\ %render --as Latex """ $$c = \\sqrt{a^2 + b^2}$$ """ ''', kernel="SoS", ) assert "c=" in output and "a2+b2" in output def test_magic_run(self, notebook): # test passing parameters and %run output = notebook.check_output( """\ %run --floatvar 1 --test_mode --INT_LIST 1 2 3 --infile a.txt VAR = 'This var is defined without global.' [global] GLOBAL_VAR='This var is defined with global.' [step_1] CELL_VAR='This var is defined in Cell.' parameter: floatvar=float parameter: stringvar='stringvar' print(VAR) print(GLOBAL_VAR) print(CELL_VAR) print(floatvar) print(stringvar) [step_2] parameter: test_mode=bool parameter: INT_LIST=[] parameter: infile = path parameter: b=1 print(test_mode) print(INT_LIST) print(infile.name) python: expand=True print({b}) """, kernel="SoS", ) lines = output.splitlines() results = [ "This var is defined without global.", "This var is defined with global.", "This var is defined in Cell.", "1.0", "stringvar", "True", "['1', '2', '3']", "a.txt", "1", ] for index, _line in enumerate(lines): assert lines[index] == results[index] def test_magic_runfile(self, notebook): # notebook.call( """\ %save check_run -f %run --var 1 parameter: var=0 python: expand=True print({var}) """, kernel="SoS", ) assert "2" == notebook.check_output("%runfile check_run --var=2", kernel="SoS") @pytest.mark.skipif( sys.platform == "win32" or "TRAVIS" in os.environ, reason="Skip test because of no internet connection or in travis test", ) def test_magic_preview_dot(self, notebook): output = notebook.check_output( ''' %preview -n a.dot with open('a.dot', 'w') as dot: dot.write("""\\ graph graphname { a -- b -- c; b -- d; } """) ''', kernel="SoS", selector="img", ) assert "a.dot" in output and "data:image/png;base64" in output def test_magic_preview_in_R(self, notebook): assert "mtcars" in notebook.check_output( """\ %preview -n mtcars %use R """, kernel="R", ) def test_magic_preview_png(self, notebook): output = notebook.check_output( """\ %preview -n a.png R: png('a.png') plot(0) dev.off() """, kernel="SoS", selector="img", ) assert "a.png" in output and "data:image/png;base64" in output def test_magic_preview_jpg(self, notebook): output = notebook.check_output( """\ %preview -n a.jp* R: jpeg('a.jpg') plot(0) dev.off() """, kernel="SoS", selector="img", ) assert "a.jpg" in output and ( "data:image/jpeg;base64" in output or "data:image/png;base64" in output ) def test_magic_preview_pdf(self, notebook): output = notebook.check_output( """\ %preview -n a.pdf R: pdf('a.pdf') plot(0) dev.off() """, kernel="SoS", selector="embed", attribute="type", ) assert "a.pdf" in output and ( "application/x-google-chrome-pdf" in output or "application/pdf" in output ) @pytest.mark.xfail( reason="Some system has imagemagick refusing to read PDF due to policy reasons." ) def test_magic_preview_pdf_as_png(self, notebook): try: from wand.image import Image _ = Image except ImportError: pytest.skip("Skip because imagemagick is not properly installed") # preview as png output = notebook.check_output( """\ %preview -n a.pdf -s png R: pdf('a.pdf') plot(0) dev.off() """, kernel="SoS", selector="img", ) assert "a.pdf" in output and "data:image/png;base64" in output def test_magic_preview_var(self, notebook): assert "> a: int" in notebook.check_output( """\ %preview -n a a=1 """, kernel="SoS", ) def test_magic_preview_var_limit(self, notebook): output = notebook.check_output( """\ %preview var -n -l 5 import numpy as np import pandas as pd var = pd.DataFrame( np.asmatrix([[i*10, i*10+1] for i in range(100)])) """, kernel="SoS", ) assert "var" in output and "41" in output and "80" not in output # def test_magic_preview_var_scatterplot(self, notebook): # output = notebook.check_output('''\ # %preview mtcars -n -s scatterplot mpg disp --by cyl # %get mtcars --from R # ''', kernel="SoS") # def test_magic_preview_var_scatterplot_tooltip(self, notebook): # output = notebook.check_output('''\ # %preview mtcars -n -s scatterplot _index disp hp mpg --tooltip wt qsec # %get mtcars --from R # ''', kernel="SoS") # def test_magic_preview_var_scatterplot_log(self, notebook): # output = notebook.check_output('''\ # %preview mtcars -n -s scatterplot disp hp --log xy --xlim 60 80 --ylim 40 300 # %get mtcars --from R # ''', kernel="SoS") def test_magic_preview_csv(self, notebook): output = notebook.check_output( '''\ %preview -n a.csv with open('a.csv', 'w') as csv: csv.write("""\ a,b,c 1,2,3 4,5,6 """) ''', kernel="SoS", ) assert "> a.csv" in output and " a b c " in output def test_magic_preview_txt(self, notebook): output = notebook.check_output( '''\ %preview -n a.txt with open('a.txt', 'w') as txt: txt.write("""\ hello world """) ''', kernel="SoS", ) assert "> a.txt" in output and "2 lines" in output def test_magic_preview_zip(self, notebook): output = notebook.check_output( """\ %preview -n a.zip import zipfile with open('a.csv', 'w') as tmp: tmp.write('blah') with zipfile.ZipFile('a.zip', 'w') as zfile: zfile.write('a.csv') """, kernel="SoS", ) import time time.sleep(20) assert "> a.zip" in output and "1 file" in output and "a.csv" in output def test_magic_preview_tar(self, notebook): output = notebook.check_output( """\ %preview -n a.tar import tarfile with open('a.csv', 'w') as tmp: tmp.write('blah') with tarfile.open('a.tar', 'w') as tar: tar.add('a.csv') """, kernel="SoS", ) assert "> a.tar" in output and "1 file" in output and "a.csv" in output def test_magic_preview_tar_gz(self, notebook): output = notebook.check_output( """\ %preview -n a.tar.gz import tarfile with open('a.csv', 'w') as tmp: tmp.write('blah') with tarfile.open('a.tar.gz', 'w:gz') as tar: tar.add('a.csv') """, kernel="SoS", ) assert "> a.tar.gz" in output and "1 file" in output and "a.csv" in output def test_magic_preview_gz(self, notebook): output = notebook.check_output( '''\ %preview -n a.gz import gzip with gzip.open('a.gz', 'w') as gz: gz.write(b""" Hello world """) ''', kernel="SoS", ) assert "> a.gz" in output and "Hello" in output and "world" in output def test_magic_preview_md(self, notebook): output = notebook.check_output( '''\ %preview -n a.md with open('a.md', 'w') as md: md.write("""\ # title * item1 * item2 """) ''', kernel="SoS", ) assert "> a.md" in output and "title" in output and "item2" in output def test_magic_preview_html(self, notebook): output = notebook.check_output( '''\ %preview -n a.html with open('a.html', 'w') as dot: dot.write("""\

My First Heading

My first paragraph.

""") ''', kernel="SoS", ) assert ( "> a.html" in output and "My First Heading" in output and "My first paragraph" in output ) def test_magic_put(self, notebook): # test %put from subkernel to SoS Kernel notebook.call( """\ %put a b c R_var a <- c(1) b <- c(1, 2, 3) R_var <- 'R variable' """, kernel="R", ) assert "1" in notebook.check_output(content="a", kernel="SoS") assert "[1, 2, 3]" in notebook.check_output(content="b", kernel="SoS") assert "R variable" in notebook.check_output(content="R_var", kernel="SoS") # test %put from SoS to other kernel # notebook.call( """\ %put a1 b1 --to R a1 = 123 b1 = 'this is python' """, kernel="SoS", ) assert "123" in notebook.check_output(content="cat(a1)", kernel="R") assert "this is python" in notebook.check_output(content="cat(b1)", kernel="R") # # test put variable with invalid names notebook.call( """\ %put .a.b .a.b <- 22""", kernel="R", expect_error=True, ) assert "22" == notebook.check_output("_a_b", kernel="SoS") # # test independence of variables notebook.call( """\ %put my_var --to R my_var = '124' """, kernel="SoS", ) assert "'124'" == notebook.check_output("my_var", kernel="R") notebook.call("my_var = 'something else'", kernel="R") assert "'124'" == notebook.check_output("my_var", kernel="SoS") def test_magic_sandbox(self, notebook): notebook.call( """\ %sandbox with open('test_blah.txt', 'w') as tb: tb.write('a') """, kernel="SoS", ) assert not os.path.isfile("test_blah.txt") def test_magic_save(self, notebook): tmp_file = os.path.join(os.path.expanduser("~"), "test_save.txt") if os.path.isfile(tmp_file): os.remove(tmp_file) notebook.call( """\ %save ~/test_save.txt a=1 """, kernel="SoS", ) with open(tmp_file) as tt: assert tt.read() == "a=1\n" os.remove(tmp_file) def test_magic_sessioninfo(self, notebook): output = notebook.check_output( """\ %use Python3 %use SoS %sessioninfo """, kernel="SoS", ) assert "SoS Version" in output and "Python3" in output # test the with option notebook.call( """ sinfo = { 'str_section': 'rsync 3.2', 'list_section': [('v1', 'v2'), ('v3', b'v4')], 'dict_section': {'d1': 'd2', 'd3': b'd4'} } """, kernel="SoS", ) output = notebook.check_output( """\ %use Python3 %use SoS %sessioninfo --with sinfo """, kernel="SoS", ) assert "SoS Version" in output and "Python3" in output assert all( x in output for x in ("rsync 3.2", "v1", "v2", "v3", "v4", "d1", "d2", "d3", "d4") ) @pytest.mark.skipif( sys.platform == "win32", reason="! magic does not support built-in command #203" ) def test_magic_shell(self, notebook): assert "haha" in notebook.check_output("!echo haha", kernel="SoS") @pytest.mark.xfail(reason="Cannot figure out why the file sometimes does not exist") def test_magic_convert(self, notebook): # notebook.save() tmp_file = os.path.join(tempfile.gettempdir(), "test_convert.html") if os.path.isfile(tmp_file): os.remove(tmp_file) assert "Workflow saved to" in notebook.check_output( f"""\ %convert {tmp_file} --force [10] print('kkk') """, kernel="SoS", ) with open(tmp_file) as tt: assert "kkk" in tt.read() @pytest.mark.xfail(reason="Cannot figure out why the file sometimes does not exist") def test_magic_convert_sos(self, notebook): # notebook.save() tmp_file = os.path.join(tempfile.gettempdir(), "test_convert.sos") if os.path.isfile(tmp_file): os.remove(tmp_file) assert "Workflow saved to" in notebook.check_output( f"""\ %convert {tmp_file} --force [10] print('kkk') """, kernel="SoS", ) with open(tmp_file) as tt: assert "kkk" in tt.read() @pytest.mark.xfail(reason="Cannot figure out why the file sometimes does not exist") def test_magic_convert_sos_all(self, notebook): # notebook.save() tmp_file = os.path.join(tempfile.gettempdir(), "test_convert.sos") if os.path.isfile(tmp_file): os.remove(tmp_file) assert "Workflow saved to" in notebook.check_output( f"""\ %convert {tmp_file} --all --force print('kkk') """, kernel="SoS", ) with open(tmp_file) as tt: assert "kkk" in tt.read() def test_magic_use(self, notebook): # Background color assertions require frontend, skip those notebook.call("%use R0 -l sos_r.kernel:sos_R -c #CCCCCC", kernel="SoS") notebook.call("%use R1 -l sos_r.kernel:sos_R -k ir -c #CCCCCC", kernel="SoS") notebook.call("%use R2 -k ir", kernel="SoS") notebook.call("a <- 1024", kernel="R2") assert "1024" == notebook.check_output("a", kernel="R2") notebook.call("%use R3 -k ir -l R", kernel="SoS") notebook.call("a <- 233", kernel="R3") assert "233" == notebook.check_output("a", kernel="R3") notebook.call("%use R2 -c red", kernel="R3") assert "1024" == notebook.check_output("a", kernel="R2") # def test_sos_vars(self, notebook): # # test automatic tranfer of sos variables # notebook.call("sosa = f'{3*8}'", kernel="Python3") # assert "24" in notebook.check_output("sosa", kernel="SoS") def test_magic_with(self, notebook): # test %with notebook.call("a = 3", kernel="SoS") notebook.call( """\ %with R -i a -o ran ran<-rnorm(a) """, kernel="SoS", ) assert len(notebook.check_output("ran", kernel="SoS")) > 0 ================================================ FILE: test/test_workflow.py ================================================ #!/usr/bin/env python3 # # Copyright (c) Bo Peng and the University of Texas MD Anderson Cancer Center # Distributed under the terms of the 3-clause BSD License. import pytest from sos_notebook.test_utils import NotebookTest class TestWorkflow(NotebookTest): def test_no_output(self, notebook): """Test no output from workflow cell""" assert not notebook.check_output( """ [1] print('hellp world') """, kernel="SoS", ) def test_no_signature(self, notebook): """Test no signature for interactive mode""" notebook.call( """ output: 'a.txt' a=2 _output.touch() """, kernel="SoS", ) assert "2" in notebook.check_output("a", kernel="SoS") # change it assert "4" in notebook.check_output( """\ a=4 a""", kernel="SoS", ) # this step will be rerun again notebook.call( """ output: 'a.txt' a=2 _output.touch() """, kernel="SoS", ) assert "2" in notebook.check_output("a", kernel="SoS") def test_task(self, notebook): """Test the execution of tasks with -s force""" output = notebook.check_output( """\ %run -s force -v1 -q localhost [10] input: for_each={'i': range(1)} task: python: expand=True import time print("this is {i}") time.sleep({i}) [20] input: for_each={'i': range(2)} task: python: expand=True import time print("this aa is {i}") time.sleep({i}) """, kernel="SoS", ) assert "Ran for < 5 seconds" in output assert "this aa is" not in output assert "start" not in output def test_identical_task(self, notebook): """Test running two identical tasks in different cells #225""" output = notebook.check_output( """\ %run -s force -q localhost task: print('hello') """, kernel="SoS", ) assert "Ran for < 5 seconds" in output # output = notebook.check_output( """\ %run -s force -q localhost task: print('hello') """, kernel="SoS", ) assert "Ran for < 5 seconds" in output @pytest.mark.skip(reason="background task output polling requires frontend") def test_background_mode(self, notebook): """test executing sos workflows in background""" idx = notebook.call( """\ %run & import time for i in range(5): print(f'output {i}') time.sleep(1) """, kernel="SoS", ) output = notebook.get_cell_output(idx) assert "output 4" not in output import time time.sleep(10) output = notebook.get_cell_output(idx) assert "output 4" in output def test_warning_from_sos(self, notebook): """Test warning message sent from sos""" notebook.call(""" sh: allow_error=True eho something wrong """)