Repository: jupytercalpoly/jupyterlab-code-snippets Branch: master Commit: 24ea8a6908c8 Files: 132 Total size: 854.0 KB Directory structure: gitextract_5ffki41f/ ├── .eslintignore ├── .eslintrc.js ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows/ │ └── build.yml ├── .gitignore ├── .husky/ │ ├── .gitignore │ └── pre-commit ├── .prettierignore ├── .prettierrc ├── .vscode/ │ ├── launch.json │ └── settings.json ├── LICENSE ├── MANIFEST.in ├── PRESSRELEASE.md ├── PROGRESS.md ├── README.md ├── babel.config.js ├── binder/ │ ├── environment.yml │ ├── postBuild │ ├── requirements.txt │ └── workspace.json ├── coverage/ │ ├── CodeSnippetContentsService.ts.html │ ├── CodeSnippetWidgetModel.ts.html │ ├── base.css │ ├── block-navigation.js │ ├── clover.xml │ ├── coverage-final.json │ ├── index.html │ ├── lcov-report/ │ │ ├── CodeSnippetContentsService.ts.html │ │ ├── CodeSnippetWidgetModel.ts.html │ │ ├── base.css │ │ ├── block-navigation.js │ │ ├── index.html │ │ ├── prettify.css │ │ ├── prettify.js │ │ └── sorter.js │ ├── lcov.info │ ├── prettify.css │ ├── prettify.js │ └── sorter.js ├── cypress/ │ ├── fixtures/ │ │ └── example.json │ ├── integration/ │ │ ├── codeSnippetService.spec.js │ │ └── examples/ │ │ ├── actions.spec.js │ │ ├── aliasing.spec.js │ │ ├── assertions.spec.js │ │ ├── connectors.spec.js │ │ ├── cookies.spec.js │ │ ├── cypress_api.spec.js │ │ ├── files.spec.js │ │ ├── local_storage.spec.js │ │ ├── location.spec.js │ │ ├── misc.spec.js │ │ ├── navigation.spec.js │ │ ├── network_requests.spec.js │ │ ├── querying.spec.js │ │ ├── spies_stubs_clocks.spec.js │ │ ├── traversal.spec.js │ │ ├── utilities.spec.js │ │ ├── viewport.spec.js │ │ ├── waiting.spec.js │ │ └── window.spec.js │ ├── plugins/ │ │ └── index.js │ └── support/ │ ├── commands.js │ └── index.js ├── cypress.json ├── docs/ │ ├── contributor/ │ │ ├── codebase.rst │ │ ├── contribute.rst │ │ └── snippet_metadata.rst │ ├── getting_started/ │ │ ├── changelog.rst │ │ ├── installation.rst │ │ └── overview.rst │ ├── index.rst │ └── user/ │ ├── features.rst │ ├── transition.rst │ └── ux.rst ├── install.json ├── jest.config.js ├── junit.xml ├── jupyterlab-code-snippets/ │ ├── _version.py │ └── labextension/ │ ├── build_log.json │ ├── package.json │ ├── schemas/ │ │ └── jupyterlab-code-snippets/ │ │ ├── package.json.orig │ │ └── snippets.json │ └── static/ │ ├── lib_index_js.be5d61b481146873348d.js │ ├── remoteEntry.0a192b189a42c6f0af60.js │ ├── style.js │ ├── style_index_js.93ff47ff4745f8384ae9.js │ └── vendors-node_modules_css-loader_dist_runtime_api_js-node_modules_css-loader_dist_runtime_cssW-7d5e6f.8245c3041950ff727f29.js ├── package.json ├── pyproject.toml ├── schema/ │ └── snippets.json ├── setup.py ├── snippets_example/ │ ├── carbon_emissions.json │ ├── filter_income.json │ ├── gdp_calculator.json │ ├── generate_hundred.json │ ├── import_cleaning.json │ ├── import_matlib.json │ ├── life_exp_eur_asia.json │ ├── lorenz_deriv.json │ ├── matplotlib_import.json │ ├── matrix_lstsqr.json │ ├── most_frequent.json │ ├── parallel_strings.json │ ├── plotting_sine.json │ ├── progress_bar.json │ ├── sum_array.json │ └── time_calculation.json ├── src/ │ ├── CodeSnippetContentsService.ts │ ├── CodeSnippetDisplay.tsx │ ├── CodeSnippetEditor.tsx │ ├── CodeSnippetEditorTags.tsx │ ├── CodeSnippetFilterTools.tsx │ ├── CodeSnippetInputDialog.ts │ ├── CodeSnippetLanguages.ts │ ├── CodeSnippetMenu.ts │ ├── CodeSnippetMessage.ts │ ├── CodeSnippetPreview.ts │ ├── CodeSnippetService.ts │ ├── CodeSnippetUtilities.ts │ ├── CodeSnippetWidget.tsx │ ├── index.ts │ └── svg.d.ts ├── style/ │ ├── base.css │ ├── index.css │ └── index.js ├── test/ │ ├── codeSnippetContentsService.test.ts │ └── sample.test.ts ├── testutils/ │ └── jest-setup-files.js ├── tsconfig.json └── tsconfig.test.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintignore ================================================ node_modules dist coverage **/*.d.ts test _temp_extension babel.config.ts jest.config.ts ================================================ FILE: .eslintrc.js ================================================ module.exports = { extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', 'plugin:react/recommended' ], settings: { react: { createClass: "createReactClass", // Regex for Component Factory to use, // default to "createReactClass" pragma: "React", // Pragma to use, default to "React" fragment: "Fragment", // Fragment to use (may be a property of ), default to "Fragment" version: "detect", // React version. "detect" automatically picks the version you have installed. // You can also use `16.0`, `16.3`, etc, if you want to override the detected value. // default to latest and warns if missing // It will default to "detect" in the future flowVersion: "0.53" // Flow version } }, parser: '@typescript-eslint/parser', parserOptions: { project: 'tsconfig.json', sourceType: 'module' }, plugins: ['@typescript-eslint', 'react'], rules: { '@typescript-eslint/camelcase': 'off', '@typescript-eslint/no-unused-vars': ['warn', { args: 'none' }], '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/no-namespace': 'off', '@typescript-eslint/no-use-before-define': 'off', '@typescript-eslint/no-control-regex': 'off', '@typescript-eslint/quotes': [ 'error', 'single', { avoidEscape: true, allowTemplateLiterals: false } ], curly: ['error', 'all'], eqeqeq: 'error', 'prefer-arrow-callback': 'error' }, ignorePatterns: ['.eslintrc.js'] }; ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: '' assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .github/workflows/build.yml ================================================ name: Build on: push: branches: master pull_request: branches: '*' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Install node uses: actions/setup-node@v2 with: node-version: '16.x' - name: Install Python uses: actions/setup-python@v2 with: python-version: '3.7' architecture: 'x64' - name: Install dependencies run: python -m pip install jupyterlab - name: Build the extension run: | jlpm jlpm run eslint:check python -m pip install . python -m jupyterlab.browser_check ================================================ FILE: .gitignore ================================================ *.bundle.* lib/ node_modules/ *.egg-info/ .ipynb_checkpoints *.tsbuildinfo *.ipynb .eslintcache snippets/ dist/ */labextension/*.tgz # Created by https://www.gitignore.io/api/python # Edit at https://www.gitignore.io/?templates=python ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # Mr Developer .mr.developer.cfg .project .pydevproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ .DS_Store # End of https://www.gitignore.io/api/python # Jupyter Stuff _temp_extension/ yarn.lock ================================================ FILE: .husky/.gitignore ================================================ _ ================================================ FILE: .husky/pre-commit ================================================ #!/bin/sh . "$(dirname "$0")/_/husky.sh" npx --no-install lint-staged jlpm lint-staged ================================================ FILE: .prettierignore ================================================ node_modules **/node_modules **/lib **/package.json ================================================ FILE: .prettierrc ================================================ { "singleQuote": true } ================================================ FILE: .vscode/launch.json ================================================ { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "chrome", "request": "launch", "name": "Launch Chrome against localhost", "url": "http://localhost:8080", "webRoot": "${workspaceFolder}" } ] } ================================================ FILE: .vscode/settings.json ================================================ { "workbench.colorCustomizations": { "activityBar.activeBackground": "#1f6fd0", "activityBar.background": "#1f6fd0", "activityBar.foreground": "#e7e7e7", "activityBar.inactiveForeground": "#e7e7e799", "activityBarBadge.background": "#ee90bb", "activityBarBadge.foreground": "#15202b", "commandCenter.border": "#e7e7e799", "sash.hoverBorder": "#1f6fd0", "statusBar.background": "#1857a4", "statusBar.foreground": "#e7e7e7", "statusBarItem.hoverBackground": "#1f6fd0", "statusBarItem.remoteBackground": "#1857a4", "statusBarItem.remoteForeground": "#e7e7e7", "titleBar.activeBackground": "#1857a4", "titleBar.activeForeground": "#e7e7e7", "titleBar.inactiveBackground": "#1857a499", "titleBar.inactiveForeground": "#e7e7e799" }, "peacock.remoteColor": "#1857a4" } ================================================ FILE: LICENSE ================================================ BSD 3-Clause License Copyright (c) 2020, jupytercalpoly All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. 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. 3. 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. ----------------------------------------------------------------------------------------------------------------- Some lines of code in this extension are from Elyra's code snippet extension (https://github.com/elyra-ai/elyra). ----------------------------------------------------------------------------------------------------------------- Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: MANIFEST.in ================================================ include LICENSE include README.md include pyproject.toml include install.json include package.json include ts*.json graft jupyterlab-code-snippets/labextension # Javascript files graft src graft style prune **/node_modules prune lib # Patterns to exclude from any directory global-exclude *~ global-exclude *.pyc global-exclude *.pyo global-exclude .git global-exclude .ipynb_checkpoints ================================================ FILE: PRESSRELEASE.md ================================================ # **JupyterLab Code Snippets** ## **JupyterLab Code Snippets empowers you to write code more rapidly** Do you find yourself typing in the same code blocks over and over again? Are you tired of clicking through tabs online for starter code or browsing old notebook files to find the right import statements? Save, reuse, and share code snippets using JupyterLab Code Snippets! In the past, you would spend more time scouring the internet than actually working. Searching old code for snippets is like searching for your lost keys; it’s frustrating! JupyterLab Code Snippets allows you to create and store code snippets that can be inserted into any JupyterLab workspace and save you from the hassle of typing repetitive code. Code snippets are pieces of code or individual cells that are frequently used. Simply browse or search snippets in the Snippets panel to use wherever you need in JupyterLab. Using JupyterLab code snippets is easy! Simply open the snippet explorer and browse through the provided predefined code snippets. Still can’t find what you need? Simply highlight code and right-click to save as a snippet or drag cells into the panel. Find snippets by utilizing the search, filter, and preview features. For a fresh start, select the plus icon in the snippet panel to construct a completely new, custom snippet. Also, edit your snippet quickly at any time by clicking the edit icon on the snippet. To use your snippets, you can drag and drop a code snippet to insert it as a cell or press the insert icon on the snippet to inject the code where your cursor is located within the JupyterLab workspace. *“I’ve grown accustomed to opening an old notebook and searching through it in order to find the necessary import statements every time I start a new project. But, with the JupyterLab Code Snippets extension, I saved a lot of time by storing them as snippets and inserting them directly into my workflow.” - amazed customer* This new extension unlocks the exciting ability to seamlessly incorporate code snippets. You can now store the frequently used code as a snippet and use it quickly. Save time, save energy, and get down to business with JupyterLab Code Snippets! ================================================ FILE: PROGRESS.md ================================================ # Log of Features and Updates ## Feature List - [x] Scrollable snippet panel displaying snippets - [x] Right click and save highlighted code (lines of code) - [x] Copy snippet - [x] Delete snippet - [x] Insert snippet - [x] Drag cell into panel to save (lines of code) - [x] Search bar for snippets - [x] Snippet preview (on the side) - [x] Drag snippet into notebook - [x] Move snippet within snippet explorer - [x] Filters on snippet panel - [x] Code snippet editor - [x] Plus button to create new snippet - [x] Multi-cell Saving ## Future development - [ ] Tab completion - [ ] Templated Fields - [ ] Color Code Tags ## Demo 3 (Aug 25) - Design review - Usability tests - Minimap preview - Removing extra icons - Filter with cell tags - Code snippet editor - ‘+’ create snippets - Design refinements ## Demo 2 (Aug 5) - Search ability - search by name/language - search bolding - Snippet preview - editing mode - snippet description - Drag and drop - drag snippet into notebook - create new cell - Undo/redo functionality ## Log of Changes/Progress ### 7/20/2020 - 7/24/2020: - Improve drag and drop cell onto snippet panel interface. - Improve code snippet preview ### 7/13/2020 - 7/17/2020: - Create preview of snippets - Add bookmark User Interface ### 7/6/2020 - 7/10/2020: - Add predefined snippets - Copy button to the clipboard - Delete Snippets - Search snippets by name - Allow user to scroll through snippets ### 6/29/2020 - 7/3/2020: - Implement right click Notebook operation to save highlighted code as snippet. - Look at/use Elyra side panel code to display snippets Preview snippets (double click or hover-scroll) ### 6/22/2020 - 6/26/2020: - Set up repos - Research JupyterLab and Elyra codebase ================================================ FILE: README.md ================================================ # JupyterLab Code Snippet ## Save, reuse, and share code snippets using JupyterLab Code Snippets ![Github Actions Status](https://github.com/jupytercalpoly/jupyterlab-code-snippets/workflows/Build/badge.svg) [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/jupytercalpoly/jupyterlab-code-snippets.git/master?urlpath=lab) [![npm version](https://badge.fury.io/js/jupyterlab-code-snippets.svg)](https://badge.fury.io/js/jupyterlab-code-snippets 'View this project on npm') [![PyPI version](https://badge.fury.io/py/jupyterlab-code-snippets.svg)](https://badge.fury.io/py/jupyterlab-code-snippets) [![Conda Version](https://img.shields.io/conda/vn/conda-forge/jupyterlab-code-snippets.svg)](https://anaconda.org/conda-forge/jupyterlab-code-snippets) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Documentation Status](https://readthedocs.org/projects/jupyterlab-code-snippets-documentation/badge/?version=latest)](https://jupyterlab-code-snippets-documentation.readthedocs.io/en/latest/?badge=latest) This extension is a derivative of [Elyra](https://github.com/elyra-ai/elyra)'s original design and further developed by Jupyter Cal Poly Team. Read [Press Release](./PRESSRELEASE.md) for more information. Check out [the Current Progress](./PROGRESS.md) to keep up with our feature updates! This extension is composed of a NPM package named `jupyterlab-code-snippets` for the frontend extension. ![Alt Text](Design/overview.gif) ## Requirements - JupyterLab >= 3.5.3 - Python >= 3.7 ## Install Install using jupyter: ```bash jupyter labextension install jupyterlab-code-snippets ``` Install using pip: ```bash pip install jupyterlab-code-snippets ``` ```bash conda install -c conda-forge jupyterlab-code-snippets ``` ## Troubleshoot If it is installed, try: ```bash jupyter lab clean jupyter lab build ``` ## Contributing ### Install The `jlpm` command is JupyterLab's pinned version of [yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use `yarn` or `npm` in lieu of `jlpm` below. ```bash # Clone the repo to your local environment # Move to jupyter-lab-code-snippets directory # Install dependencies jlpm # Build Typescript source jlpm build # Link your development version of the extension with JupyterLab jupyter labextension install . # Rebuild Typescript source after making changes jlpm build # Rebuild JupyterLab after making any changes jupyter lab build ``` You can watch the source directory and run JupyterLab in watch mode to watch for changes in the extension's source and automatically rebuild the extension and application. ```bash # Watch the source directory in another terminal tab jlpm watch # Run jupyterlab in watch mode in one terminal tab jupyter lab --watch ``` Now every change will be built locally and bundled into JupyterLab. Be sure to refresh your browser page after saving file changes to reload the extension (note: you'll need to wait for webpack to finish, which can take 10s+ at times). ### Uninstall ```bash jupyter labextension uninstall jupyterlab-code-snippets ``` OR ```bash pip uninstall jupyterlab-code-snippets ``` ================================================ FILE: babel.config.js ================================================ module.exports = require('@jupyterlab/testutils/lib/babel.config'); // module.exports = { // presets: [ // [ // '@babel/preset-env', // { // targets: { // node: 'current' // } // } // ], '@babel/preset-react' // ] // }; ================================================ FILE: binder/environment.yml ================================================ # a mybinder.org-ready environment for demoing code_snippet # this environment may also be used locally on Linux/MacOS/Windows, e.g. # # conda env update --file binder/environment.yml # conda activate code_snippet-demo # name: code_snippet-demo channels: - conda-forge dependencies: # runtime dependencies - python >=3.8,<3.9.0a0 - jupyterlab >=3,<4.0.0a0 # labextension build dependencies - nodejs >=14,<15 - pip - wheel # additional packages for demos # - ipywidgets ================================================ FILE: binder/postBuild ================================================ #!/usr/bin/env python3 """ perform a development install of code_snippet On Binder, this will run _after_ the environment has been fully created from the environment.yml in this directory. This script should also run locally on Linux/MacOS/Windows: python3 binder/postBuild """ import subprocess import sys from pathlib import Path ROOT = Path.cwd() print("Current Working dir:", ROOT) def _(*args, **kwargs): """ Run a command, echoing the args fails hard if something goes wrong """ print("\n\t", " ".join(args), "\n") return_code = subprocess.call(args, **kwargs) if return_code != 0: print("\nERROR", return_code, " ".join(args)) sys.exit(return_code) # verify the environment is self-consistent before even starting # _(sys.executable, "-m", "pip", "check") # install the labextension _(sys.executable, "-m", "pip", "install", "-e", ".") # verify the environment the extension didn't break anything # _(sys.executable, "-m", "pip", "check") # list the extensions # _("jupyter", "server", "extension", "list") # initially list installed extensions to determine if there are any surprises # _("jupyter", "labextension", "list") print("JupyterLab with code_snippet is ready to run with:\n") print("\tjupyter lab\n") # remove unnecessary directories when using the binder _('rm', '-rf', './lib') _('rm', '-rf', './src') _('rm', '-rf', './style') _('rm', '-rf', './_temp_extension') _('rm', '-rf', './Design') _('rm', '-rf', './binder') _('rm', '-rf', './docs') _('rm', '-rf', './code_snippet') _('rm', '-rf', './code_snippet.egg-info') _('rm', '-rf', './schema') _('rm', '-rf', './node_modules') _('rm', '-rf', './coverage') _('rm', '-rf', './test') _('rm', '-rf', './testutils') _('rm', './install.json') _('rm', './package.json') _('rm', './PROGRESS.md') _('rm', './setup.py') _('rm', './pyproject.toml') _('rm', './tsconfig.json') _('rm', './tsconfig.test.json') _('rm', './babel.config.js') _('rm', './jest.config.js') _('rm', './tsconfig.tsbuildinfo') _('rm', './yarn.lock') _('rm', './MANIFEST.in') ================================================ FILE: binder/requirements.txt ================================================ jupyterlab>=3.0 ================================================ FILE: binder/workspace.json ================================================ {"data":{"layout-restorer:data":{"main":{"dock":{"type":"tab-area","currentIndex":1,"widgets":["notebook:Untitled.ipynb"]},"mode":"multiple-document","current":"notebook:Untitled.ipynb"},"left":{"collapsed":false,"current":"code-snippet-extension","widgets":["filebrowser","running-sessions","command-palette","jp-property-inspector","tab-manager","code-snippet-extension","extensionmanager.main-view"]},"right":{"collapsed":true,"widgets":[]}},"file-browser-filebrowser:cwd":{"path":""},"@jupyterlab/settingeditor-extension:plugin":{"sizes":[0.09057971014492754,0.9094202898550725],"container":{"plugin":"@jupyterlab/shortcuts-extension:shortcuts","sizes":[0.48376993166287013,0.5162300683371298]}},"notebook:Untitled.ipynb":{"data":{"path":"Untitled.ipynb","factory":"Notebook"}}},"metadata":{"id":"/lab"}} ================================================ FILE: coverage/CodeSnippetContentsService.ts.html ================================================ Code coverage report for CodeSnippetContentsService.ts

All files CodeSnippetContentsService.ts

100% Statements 24/24
100% Branches 2/2
100% Functions 6/6
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 1212x                             2x         2x 2x 2x 2x       4x 2x   4x                     2x 2x         1x   1x                                         4x 4x 1x   3x                               2x 2x 1x   1x                     1x 1x   1x                        
import { ContentsManager, Drive, Contents } from '@jupyterlab/services';
 
export interface ICodeSnippet {
  name: string;
  description: string;
  language: string;
  // code separated by new line
  code: string[];
  id: number;
  tags?: string[];
}
 
/**
 * Singleton contentsService class
 */
export class CodeSnippetContentsService {
  drive: Drive;
  contentsManager: ContentsManager;
  private static instance: CodeSnippetContentsService;
  private constructor() {
    const drive = new Drive({ name: 'snippetDrive ' });
    const contentsManager = new ContentsManager({ defaultDrive: drive });
    this.drive = drive;
    this.contentsManager = contentsManager;
  }
 
  static getInstance(): CodeSnippetContentsService {
    if (!this.instance) {
      this.instance = new CodeSnippetContentsService();
    }
    return this.instance;
  }
 
  /**
   * Get the metadata information in the given path
   * @param path path to a file/directory
   */
  async getData(
    path: string,
    type: Contents.ContentType
  ): Promise<Contents.IModel> {
    try {
      const data = await this.contentsManager.get(path, {
        type: type,
        //   format: 'text',
        content: true
      });
      return data;
    } catch (error) {
      return error;
    }
    // const data = await this.contentsManager.get(path, {
    //   type: type,
    //   //   format: 'text',
    //   content: true
    // });
    // return data;
  }
 
  /**
   * Create a file/directory if it does not exist. Otherwise, save the change in a file/directory in the given path
   * @param path path to a file/directory
   * @param options options that specify if it's a file or directory and additial information
   * Usage: save('snippets', { type: 'directory' }) to create/save a directory
   *        save('snippets/test.json', {type: 'file', format: 'text', content: 'Lorem ipsum dolor sit amet'})
   */
  async save(
    path: string,
    options?: Partial<Contents.IModel>
  ): Promise<Contents.IModel> {
    try {
      const changedModel = await this.contentsManager.save(path, options);
      return changedModel;
    } catch (error) {
      return error;
    }
  }
 
  /**
   * Change the order of snippets
   * @param oldPath
   * @param newPath
   */
 
  /**
   * Rename the file or directory (not case sensitive)
   * @param oldPath change from
   * @param newPath change to
   */
  async rename(oldPath: string, newPath: string): Promise<Contents.IModel> {
    try {
      const changedModel = await this.contentsManager.rename(oldPath, newPath);
      return changedModel;
    } catch (error) {
      return error;
    }
    // const changedModel = await this.contentsManager.rename(oldPath, newPath);
    // return changedModel;
  }
 
  /**
   * Delete the file/directory in the given path
   * @param path path to a file/directory
   */
  async delete(path: string): Promise<void> {
    try {
      await this.contentsManager.delete(path);
    } catch (error) {
      return;
    }
  }
 
  // async renameAndSave(
  //   oldPath: string,
  //   newPath: string
  // ): Promise<Contents.IModel> {
  //   this.rename(oldPath, newPath);
  //   this.save(newPath);
  // }
}
 
================================================ FILE: coverage/CodeSnippetWidgetModel.ts.html ================================================ Code coverage report for CodeSnippetWidgetModel.ts

All files CodeSnippetWidgetModel.ts

100% Statements 46/46
88.89% Branches 16/18
100% Functions 14/14
100% Lines 42/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 1261x                       1x       1x       17x 17x       2x       1x 1x 2x         1x 2x 1x 1x       1x             3x 1x   3x       19x         2x 1x   2x 1x   1x 1x 1x   1x 1x               3x 3x 1x     2x 2x   2x         1x       1x 2x                         4x   4x 3x     1x 1x   1x        
import {
  ICodeSnippet,
  CodeSnippetContentsService
} from './CodeSnippetContentsService';
 
export interface ICodeSnippetWidgetModel {
  /**
   * The list of code snippets in the code snippet explorer
   */
  readonly _snippets: ICodeSnippet[];
}
 
export class CodeSnippetWidgetModel implements ICodeSnippetWidgetModel {
  _snippets: ICodeSnippet[];
 
  constructor(snippets: ICodeSnippet[]) {
    this._snippets = snippets;
  }
 
  get snippets(): ICodeSnippet[] {
    this.sortSnippets();
    return this._snippets;
  }
 
  set snippets(snippetList: ICodeSnippet[]) {
    this._snippets = snippetList;
  }
 
  reorderSnippet(): void {
    this.sortSnippets();
    for (let i = 0; i < this._snippets.length; i++) {
      this._snippets[i].id = i;
    }
  }
 
  renameSnippet(oldName: string, newName: string): void {
    for (const snippet of this._snippets) {
      if (snippet.name === oldName) {
        snippet.name = newName;
        CodeSnippetContentsService.getInstance().save(
          'snippets/' + snippet.name + '.json',
          { type: 'file', format: 'text', content: JSON.stringify(snippet) }
        );
        break;
      }
    }
  }
 
  addSnippet(newSnippet: ICodeSnippet, index: number): void {
    // append a new snippet created from input form to the end
    if (newSnippet.id === -1) {
      newSnippet.id = this._snippets.length;
    }
    this.insertSnippet(newSnippet, index);
  }
 
  sortSnippets(): void {
    this._snippets.sort((a, b) => a.id - b.id);
  }
 
  // move snippetes within explorer
  moveSnippet(fromIdx: number, toIdx: number): void {
    if (toIdx > fromIdx) {
      toIdx = toIdx - 1;
    }
    if (toIdx === fromIdx) {
      return;
    }
    const snippetToInsert = this._snippets[fromIdx];
    this.deleteSnippet(fromIdx);
    snippetToInsert.id = toIdx;
 
    this.insertSnippet(snippetToInsert, toIdx);
    this.updateSnippetContents();
  }
 
  /**
   * Delete a snippet from the list
   * @param index index to delete. If it's not given, the last one gets deleted.
   */
  deleteSnippet(index = -1): void {
    const numSnippets = this._snippets.length;
    if (index < 0 || index > numSnippets) {
      this._snippets.pop();
    } else {
      // Update list
      for (let i = index + 1; i < numSnippets; i++) {
        this._snippets[i].id = this._snippets[i].id - 1;
      }
      this._snippets.splice(index, 1);
    }
  }
 
  clearSnippets(): void {
    this._snippets = [];
  }
 
  updateSnippetContents(): void {
    this._snippets.forEach(snippet => {
      CodeSnippetContentsService.getInstance().save(
        'snippets/' + snippet.name + '.json',
        { type: 'file', format: 'text', content: JSON.stringify(snippet) }
      );
    });
  }
 
  /**
   * insert a snippet to the certain index of the snippet list
   * @param newSnippet new snippet to insert
   * @param index index to insert. If it's not given, the snippet is added at the end of the list.
   */
  private insertSnippet(newSnippet: ICodeSnippet, index = -1): void {
    const numSnippets = this._snippets.length;
    // add it at the end of the list
    if (index < 0 || index >= numSnippets) {
      this._snippets.push(newSnippet);
    } else {
      // Update list
      for (let i = index; i < numSnippets; i++) {
        this._snippets[i].id = this._snippets[i].id + 1;
      }
      this._snippets.splice(index, 0, newSnippet);
    }
  }
}
 
================================================ FILE: coverage/base.css ================================================ body, html { margin:0; padding: 0; height: 100%; } body { font-family: Helvetica Neue, Helvetica, Arial; font-size: 14px; color:#333; } .small { font-size: 12px; } *, *:after, *:before { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; } h1 { font-size: 20px; margin: 0;} h2 { font-size: 14px; } pre { font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; margin: 0; padding: 0; -moz-tab-size: 2; -o-tab-size: 2; tab-size: 2; } a { color:#0074D9; text-decoration:none; } a:hover { text-decoration:underline; } .strong { font-weight: bold; } .space-top1 { padding: 10px 0 0 0; } .pad2y { padding: 20px 0; } .pad1y { padding: 10px 0; } .pad2x { padding: 0 20px; } .pad2 { padding: 20px; } .pad1 { padding: 10px; } .space-left2 { padding-left:55px; } .space-right2 { padding-right:20px; } .center { text-align:center; } .clearfix { display:block; } .clearfix:after { content:''; display:block; height:0; clear:both; visibility:hidden; } .fl { float: left; } @media only screen and (max-width:640px) { .col3 { width:100%; max-width:100%; } .hide-mobile { display:none!important; } } .quiet { color: #7f7f7f; color: rgba(0,0,0,0.5); } .quiet a { opacity: 0.7; } .fraction { font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10px; color: #555; background: #E8E8E8; padding: 4px 5px; border-radius: 3px; vertical-align: middle; } div.path a:link, div.path a:visited { color: #333; } table.coverage { border-collapse: collapse; margin: 10px 0 0 0; padding: 0; } table.coverage td { margin: 0; padding: 0; vertical-align: top; } table.coverage td.line-count { text-align: right; padding: 0 5px 0 20px; } table.coverage td.line-coverage { text-align: right; padding-right: 10px; min-width:20px; } table.coverage td span.cline-any { display: inline-block; padding: 0 5px; width: 100%; } .missing-if-branch { display: inline-block; margin-right: 5px; border-radius: 3px; position: relative; padding: 0 4px; background: #333; color: yellow; } .skip-if-branch { display: none; margin-right: 10px; position: relative; padding: 0 4px; background: #ccc; color: white; } .missing-if-branch .typ, .skip-if-branch .typ { color: inherit !important; } .coverage-summary { border-collapse: collapse; width: 100%; } .coverage-summary tr { border-bottom: 1px solid #bbb; } .keyline-all { border: 1px solid #ddd; } .coverage-summary td, .coverage-summary th { padding: 10px; } .coverage-summary tbody { border: 1px solid #bbb; } .coverage-summary td { border-right: 1px solid #bbb; } .coverage-summary td:last-child { border-right: none; } .coverage-summary th { text-align: left; font-weight: normal; white-space: nowrap; } .coverage-summary th.file { border-right: none !important; } .coverage-summary th.pct { } .coverage-summary th.pic, .coverage-summary th.abs, .coverage-summary td.pct, .coverage-summary td.abs { text-align: right; } .coverage-summary td.file { white-space: nowrap; } .coverage-summary td.pic { min-width: 120px !important; } .coverage-summary tfoot td { } .coverage-summary .sorter { height: 10px; width: 7px; display: inline-block; margin-left: 0.5em; background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; } .coverage-summary .sorted .sorter { background-position: 0 -20px; } .coverage-summary .sorted-desc .sorter { background-position: 0 -10px; } .status-line { height: 10px; } /* yellow */ .cbranch-no { background: yellow !important; color: #111; } /* dark red */ .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } .low .chart { border:1px solid #C21F39 } .highlighted, .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ background: #C21F39 !important; } /* medium red */ .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } /* light red */ .low, .cline-no { background:#FCE1E5 } /* light green */ .high, .cline-yes { background:rgb(230,245,208) } /* medium green */ .cstat-yes { background:rgb(161,215,106) } /* dark green */ .status-line.high, .high .cover-fill { background:rgb(77,146,33) } .high .chart { border:1px solid rgb(77,146,33) } /* dark yellow (gold) */ .status-line.medium, .medium .cover-fill { background: #f9cd0b; } .medium .chart { border:1px solid #f9cd0b; } /* light yellow */ .medium { background: #fff4c2; } .cstat-skip { background: #ddd; color: #111; } .fstat-skip { background: #ddd; color: #111 !important; } .cbranch-skip { background: #ddd !important; color: #111; } span.cline-neutral { background: #eaeaea; } .coverage-summary td.empty { opacity: .5; padding-top: 4px; padding-bottom: 4px; line-height: 1; color: #888; } .cover-fill, .cover-empty { display:inline-block; height: 12px; } .chart { line-height: 0; } .cover-empty { background: white; } .cover-full { border-right: none !important; } pre.prettyprint { border: none !important; padding: 0 !important; margin: 0 !important; } .com { color: #999 !important; } .ignore-none { color: #999; font-weight: normal; } .wrapper { min-height: 100%; height: auto !important; height: 100%; margin: 0 auto -48px; } .footer, .push { height: 48px; } ================================================ FILE: coverage/block-navigation.js ================================================ /* eslint-disable */ var jumpToCode = (function init() { // Classes of code we would like to highlight in the file view var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; // Elements to highlight in the file listing view var fileListingElements = ['td.pct.low']; // We don't want to select elements that are direct descendants of another match var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` // Selecter that finds elements on the page to which we can jump var selector = fileListingElements.join(', ') + ', ' + notSelector + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` // The NodeList of matching elements var missingCoverageElements = document.querySelectorAll(selector); var currentIndex; function toggleClass(index) { missingCoverageElements .item(currentIndex) .classList.remove('highlighted'); missingCoverageElements.item(index).classList.add('highlighted'); } function makeCurrent(index) { toggleClass(index); currentIndex = index; missingCoverageElements.item(index).scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' }); } function goToPrevious() { var nextIndex = 0; if (typeof currentIndex !== 'number' || currentIndex === 0) { nextIndex = missingCoverageElements.length - 1; } else if (missingCoverageElements.length > 1) { nextIndex = currentIndex - 1; } makeCurrent(nextIndex); } function goToNext() { var nextIndex = 0; if ( typeof currentIndex === 'number' && currentIndex < missingCoverageElements.length - 1 ) { nextIndex = currentIndex + 1; } makeCurrent(nextIndex); } return function jump(event) { switch (event.which) { case 78: // n case 74: // j goToNext(); break; case 66: // b case 75: // k case 80: // p goToPrevious(); break; } }; })(); window.addEventListener('keydown', jumpToCode); ================================================ FILE: coverage/clover.xml ================================================ ================================================ FILE: coverage/coverage-final.json ================================================ {"/Users/jaewookahn/projects/code_snippet/code_snippets/src/CodeSnippetContentsService.ts": {"path":"/Users/jaewookahn/projects/code_snippet/code_snippets/src/CodeSnippetContentsService.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":72}},"1":{"start":{"line":21,"column":18},"end":{"line":21,"column":54}},"2":{"start":{"line":22,"column":28},"end":{"line":22,"column":72}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":23}},"4":{"start":{"line":24,"column":4},"end":{"line":24,"column":43}},"5":{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},"6":{"start":{"line":29,"column":6},"end":{"line":29,"column":55}},"7":{"start":{"line":31,"column":4},"end":{"line":31,"column":25}},"8":{"start":{"line":42,"column":4},"end":{"line":51,"column":null}},"9":{"start":{"line":43,"column":19},"end":{"line":47,"column":8}},"10":{"start":{"line":48,"column":6},"end":{"line":48,"column":18}},"11":{"start":{"line":50,"column":6},"end":{"line":50,"column":19}},"12":{"start":{"line":71,"column":4},"end":{"line":76,"column":null}},"13":{"start":{"line":72,"column":27},"end":{"line":72,"column":73}},"14":{"start":{"line":73,"column":6},"end":{"line":73,"column":26}},"15":{"start":{"line":75,"column":6},"end":{"line":75,"column":19}},"16":{"start":{"line":91,"column":4},"end":{"line":96,"column":null}},"17":{"start":{"line":92,"column":27},"end":{"line":92,"column":78}},"18":{"start":{"line":93,"column":6},"end":{"line":93,"column":26}},"19":{"start":{"line":95,"column":6},"end":{"line":95,"column":19}},"20":{"start":{"line":106,"column":4},"end":{"line":110,"column":null}},"21":{"start":{"line":107,"column":6},"end":{"line":107,"column":46}},"22":{"start":{"line":109,"column":6},"end":{"line":109,"column":13}},"23":{"start":{"line":16,"column":0},"end":{"line":16,"column":13}}},"fnMap":{"0":{"name":"(anonymous_7)","decl":{"start":{"line":20,"column":2},"end":{"line":20,"column":null}},"loc":{"start":{"line":20,"column":2},"end":{"line":25,"column":3}}},"1":{"name":"(anonymous_8)","decl":{"start":{"line":27,"column":2},"end":{"line":27,"column":8}},"loc":{"start":{"line":27,"column":20},"end":{"line":32,"column":3}}},"2":{"name":"(anonymous_9)","decl":{"start":{"line":38,"column":8},"end":{"line":38,"column":15}},"loc":{"start":{"line":40,"column":30},"end":{"line":58,"column":null}}},"3":{"name":"(anonymous_11)","decl":{"start":{"line":67,"column":8},"end":{"line":67,"column":12}},"loc":{"start":{"line":69,"column":38},"end":{"line":77,"column":null}}},"4":{"name":"(anonymous_13)","decl":{"start":{"line":90,"column":8},"end":{"line":90,"column":14}},"loc":{"start":{"line":90,"column":47},"end":{"line":99,"column":null}}},"5":{"name":"(anonymous_15)","decl":{"start":{"line":105,"column":8},"end":{"line":105,"column":14}},"loc":{"start":{"line":105,"column":27},"end":{"line":111,"column":null}}}},"branchMap":{"0":{"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},"type":"if","locations":[{"start":{"line":28,"column":4},"end":{"line":30,"column":null}},{"start":{"line":28,"column":4},"end":{"line":30,"column":null}}]}},"s":{"0":2,"1":2,"2":2,"3":2,"4":2,"5":4,"6":2,"7":4,"8":2,"9":2,"10":1,"11":1,"12":4,"13":4,"14":1,"15":3,"16":2,"17":2,"18":1,"19":1,"20":1,"21":1,"22":1,"23":2},"f":{"0":2,"1":4,"2":2,"3":4,"4":2,"5":1},"b":{"0":[2,2]}} ,"/Users/jaewookahn/projects/code_snippet/code_snippets/src/CodeSnippetWidgetModel.ts": {"path":"/Users/jaewookahn/projects/code_snippet/code_snippets/src/CodeSnippetWidgetModel.ts","statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":null}},"1":{"start":{"line":17,"column":4},"end":{"line":17,"column":30}},"2":{"start":{"line":21,"column":4},"end":{"line":21,"column":24}},"3":{"start":{"line":22,"column":4},"end":{"line":22,"column":26}},"4":{"start":{"line":26,"column":4},"end":{"line":26,"column":33}},"5":{"start":{"line":30,"column":4},"end":{"line":30,"column":24}},"6":{"start":{"line":31,"column":4},"end":{"line":33,"column":null}},"7":{"start":{"line":31,"column":17},"end":{"line":31,"column":18}},"8":{"start":{"line":32,"column":6},"end":{"line":32,"column":31}},"9":{"start":{"line":37,"column":4},"end":{"line":46,"column":null}},"10":{"start":{"line":38,"column":6},"end":{"line":45,"column":null}},"11":{"start":{"line":39,"column":8},"end":{"line":39,"column":31}},"12":{"start":{"line":40,"column":8},"end":{"line":43,"column":10}},"13":{"start":{"line":44,"column":8},"end":{"line":44,"column":14}},"14":{"start":{"line":51,"column":4},"end":{"line":53,"column":null}},"15":{"start":{"line":52,"column":6},"end":{"line":52,"column":44}},"16":{"start":{"line":54,"column":4},"end":{"line":54,"column":42}},"17":{"start":{"line":58,"column":4},"end":{"line":58,"column":47}},"18":{"start":{"line":58,"column":34},"end":{"line":58,"column":45}},"19":{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},"20":{"start":{"line":64,"column":6},"end":{"line":64,"column":24}},"21":{"start":{"line":66,"column":4},"end":{"line":68,"column":null}},"22":{"start":{"line":67,"column":6},"end":{"line":67,"column":13}},"23":{"start":{"line":69,"column":28},"end":{"line":69,"column":51}},"24":{"start":{"line":70,"column":4},"end":{"line":70,"column":32}},"25":{"start":{"line":71,"column":4},"end":{"line":71,"column":31}},"26":{"start":{"line":73,"column":4},"end":{"line":73,"column":47}},"27":{"start":{"line":74,"column":4},"end":{"line":74,"column":33}},"28":{"start":{"line":82,"column":24},"end":{"line":82,"column":45}},"29":{"start":{"line":83,"column":4},"end":{"line":91,"column":null}},"30":{"start":{"line":84,"column":6},"end":{"line":84,"column":27}},"31":{"start":{"line":87,"column":6},"end":{"line":89,"column":null}},"32":{"start":{"line":87,"column":19},"end":{"line":87,"column":28}},"33":{"start":{"line":88,"column":8},"end":{"line":88,"column":56}},"34":{"start":{"line":90,"column":6},"end":{"line":90,"column":38}},"35":{"start":{"line":95,"column":4},"end":{"line":95,"column":24}},"36":{"start":{"line":99,"column":4},"end":{"line":104,"column":7}},"37":{"start":{"line":100,"column":6},"end":{"line":103,"column":8}},"38":{"start":{"line":113,"column":24},"end":{"line":113,"column":45}},"39":{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},"40":{"start":{"line":116,"column":6},"end":{"line":116,"column":38}},"41":{"start":{"line":119,"column":6},"end":{"line":121,"column":null}},"42":{"start":{"line":119,"column":19},"end":{"line":119,"column":24}},"43":{"start":{"line":120,"column":8},"end":{"line":120,"column":56}},"44":{"start":{"line":122,"column":6},"end":{"line":122,"column":50}},"45":{"start":{"line":13,"column":0},"end":{"line":13,"column":13}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":16,"column":2},"end":{"line":16,"column":14}},"loc":{"start":{"line":16,"column":38},"end":{"line":18,"column":3}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":20,"column":2},"end":{"line":20,"column":6}},"loc":{"start":{"line":20,"column":14},"end":{"line":23,"column":3}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":25,"column":2},"end":{"line":25,"column":6}},"loc":{"start":{"line":25,"column":42},"end":{"line":27,"column":3}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":29,"column":2},"end":{"line":29,"column":16}},"loc":{"start":{"line":29,"column":16},"end":{"line":34,"column":3}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":36,"column":2},"end":{"line":36,"column":15}},"loc":{"start":{"line":36,"column":48},"end":{"line":47,"column":3}}},"5":{"name":"(anonymous_5)","decl":{"start":{"line":49,"column":2},"end":{"line":49,"column":12}},"loc":{"start":{"line":49,"column":52},"end":{"line":55,"column":3}}},"6":{"name":"(anonymous_6)","decl":{"start":{"line":57,"column":2},"end":{"line":57,"column":14}},"loc":{"start":{"line":57,"column":14},"end":{"line":59,"column":3}}},"7":{"name":"(anonymous_7)","decl":{"start":{"line":58,"column":24},"end":{"line":58,"column":25}},"loc":{"start":{"line":58,"column":34},"end":{"line":58,"column":45}}},"8":{"name":"(anonymous_8)","decl":{"start":{"line":62,"column":2},"end":{"line":62,"column":13}},"loc":{"start":{"line":62,"column":44},"end":{"line":75,"column":3}}},"9":{"name":"(anonymous_9)","decl":{"start":{"line":81,"column":2},"end":{"line":81,"column":15}},"loc":{"start":{"line":81,"column":26},"end":{"line":92,"column":3}}},"10":{"name":"(anonymous_10)","decl":{"start":{"line":94,"column":2},"end":{"line":94,"column":15}},"loc":{"start":{"line":94,"column":15},"end":{"line":96,"column":3}}},"11":{"name":"(anonymous_11)","decl":{"start":{"line":98,"column":2},"end":{"line":98,"column":23}},"loc":{"start":{"line":98,"column":23},"end":{"line":105,"column":3}}},"12":{"name":"(anonymous_12)","decl":{"start":{"line":99,"column":27},"end":{"line":99,"column":34}},"loc":{"start":{"line":99,"column":37},"end":{"line":104,"column":5}}},"13":{"name":"(anonymous_13)","decl":{"start":{"line":112,"column":10},"end":{"line":112,"column":23}},"loc":{"start":{"line":112,"column":60},"end":{"line":124,"column":3}}}},"branchMap":{"0":{"loc":{"start":{"line":38,"column":6},"end":{"line":45,"column":null}},"type":"if","locations":[{"start":{"line":38,"column":6},"end":{"line":45,"column":null}},{"start":{"line":38,"column":6},"end":{"line":45,"column":null}}]},"1":{"loc":{"start":{"line":51,"column":4},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":51,"column":4},"end":{"line":53,"column":null}},{"start":{"line":51,"column":4},"end":{"line":53,"column":null}}]},"2":{"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":65,"column":null}},{"start":{"line":63,"column":4},"end":{"line":65,"column":null}}]},"3":{"loc":{"start":{"line":66,"column":4},"end":{"line":68,"column":null}},"type":"if","locations":[{"start":{"line":66,"column":4},"end":{"line":68,"column":null}},{"start":{"line":66,"column":4},"end":{"line":68,"column":null}}]},"4":{"loc":{"start":{"line":81,"column":24},"end":{"line":81,"column":26}},"type":"default-arg","locations":[{"start":{"line":81,"column":24},"end":{"line":81,"column":26}}]},"5":{"loc":{"start":{"line":83,"column":4},"end":{"line":91,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":4},"end":{"line":91,"column":null}},{"start":{"line":83,"column":4},"end":{"line":91,"column":null}}]},"6":{"loc":{"start":{"line":83,"column":8},"end":{"line":83,"column":17}},"type":"binary-expr","locations":[{"start":{"line":83,"column":8},"end":{"line":83,"column":17}},{"start":{"line":83,"column":21},"end":{"line":83,"column":40}}]},"7":{"loc":{"start":{"line":112,"column":58},"end":{"line":112,"column":60}},"type":"default-arg","locations":[{"start":{"line":112,"column":58},"end":{"line":112,"column":60}}]},"8":{"loc":{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},"type":"if","locations":[{"start":{"line":115,"column":4},"end":{"line":123,"column":null}},{"start":{"line":115,"column":4},"end":{"line":123,"column":null}}]},"9":{"loc":{"start":{"line":115,"column":8},"end":{"line":115,"column":17}},"type":"binary-expr","locations":[{"start":{"line":115,"column":8},"end":{"line":115,"column":17}},{"start":{"line":115,"column":21},"end":{"line":115,"column":41}}]}},"s":{"0":1,"1":1,"2":17,"3":17,"4":2,"5":1,"6":1,"7":1,"8":2,"9":1,"10":2,"11":1,"12":1,"13":1,"14":3,"15":1,"16":3,"17":19,"18":14,"19":2,"20":1,"21":2,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":3,"29":3,"30":1,"31":2,"32":2,"33":2,"34":2,"35":1,"36":1,"37":2,"38":4,"39":4,"40":3,"41":1,"42":1,"43":1,"44":1,"45":1},"f":{"0":1,"1":17,"2":2,"3":1,"4":1,"5":3,"6":19,"7":14,"8":2,"9":3,"10":1,"11":1,"12":2,"13":4},"b":{"0":[1,1],"1":[1,2],"2":[1,1],"3":[1,1],"4":[0],"5":[1,2],"6":[3,2],"7":[0],"8":[3,1],"9":[4,3]}} } ================================================ FILE: coverage/index.html ================================================ Code coverage report for All files

All files

100% Statements 70/70
90% Branches 18/20
100% Functions 20/20
100% Lines 66/66

Press n or j to go to the next uncovered block, b, p or k for the previous block.

File Statements Branches Functions Lines
CodeSnippetContentsService.ts
100% 24/24 100% 2/2 100% 6/6 100% 24/24
CodeSnippetWidgetModel.ts
100% 46/46 88.89% 16/18 100% 14/14 100% 42/42
================================================ FILE: coverage/lcov-report/CodeSnippetContentsService.ts.html ================================================ Code coverage report for CodeSnippetContentsService.ts

All files CodeSnippetContentsService.ts

100% Statements 24/24
100% Branches 2/2
100% Functions 6/6
100% Lines 24/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 1212x                             2x         2x 2x 2x 2x       4x 2x   4x                     2x 2x         1x   1x                                         4x 4x 1x   3x                               2x 2x 1x   1x                     1x 1x   1x                        
import { ContentsManager, Drive, Contents } from '@jupyterlab/services';
 
export interface ICodeSnippet {
  name: string;
  description: string;
  language: string;
  // code separated by new line
  code: string[];
  id: number;
  tags?: string[];
}
 
/**
 * Singleton contentsService class
 */
export class CodeSnippetContentsService {
  drive: Drive;
  contentsManager: ContentsManager;
  private static instance: CodeSnippetContentsService;
  private constructor() {
    const drive = new Drive({ name: 'snippetDrive ' });
    const contentsManager = new ContentsManager({ defaultDrive: drive });
    this.drive = drive;
    this.contentsManager = contentsManager;
  }
 
  static getInstance(): CodeSnippetContentsService {
    if (!this.instance) {
      this.instance = new CodeSnippetContentsService();
    }
    return this.instance;
  }
 
  /**
   * Get the metadata information in the given path
   * @param path path to a file/directory
   */
  async getData(
    path: string,
    type: Contents.ContentType
  ): Promise<Contents.IModel> {
    try {
      const data = await this.contentsManager.get(path, {
        type: type,
        //   format: 'text',
        content: true
      });
      return data;
    } catch (error) {
      return error;
    }
    // const data = await this.contentsManager.get(path, {
    //   type: type,
    //   //   format: 'text',
    //   content: true
    // });
    // return data;
  }
 
  /**
   * Create a file/directory if it does not exist. Otherwise, save the change in a file/directory in the given path
   * @param path path to a file/directory
   * @param options options that specify if it's a file or directory and additial information
   * Usage: save('snippets', { type: 'directory' }) to create/save a directory
   *        save('snippets/test.json', {type: 'file', format: 'text', content: 'Lorem ipsum dolor sit amet'})
   */
  async save(
    path: string,
    options?: Partial<Contents.IModel>
  ): Promise<Contents.IModel> {
    try {
      const changedModel = await this.contentsManager.save(path, options);
      return changedModel;
    } catch (error) {
      return error;
    }
  }
 
  /**
   * Change the order of snippets
   * @param oldPath
   * @param newPath
   */
 
  /**
   * Rename the file or directory (not case sensitive)
   * @param oldPath change from
   * @param newPath change to
   */
  async rename(oldPath: string, newPath: string): Promise<Contents.IModel> {
    try {
      const changedModel = await this.contentsManager.rename(oldPath, newPath);
      return changedModel;
    } catch (error) {
      return error;
    }
    // const changedModel = await this.contentsManager.rename(oldPath, newPath);
    // return changedModel;
  }
 
  /**
   * Delete the file/directory in the given path
   * @param path path to a file/directory
   */
  async delete(path: string): Promise<void> {
    try {
      await this.contentsManager.delete(path);
    } catch (error) {
      return;
    }
  }
 
  // async renameAndSave(
  //   oldPath: string,
  //   newPath: string
  // ): Promise<Contents.IModel> {
  //   this.rename(oldPath, newPath);
  //   this.save(newPath);
  // }
}
 
================================================ FILE: coverage/lcov-report/CodeSnippetWidgetModel.ts.html ================================================ Code coverage report for CodeSnippetWidgetModel.ts

All files CodeSnippetWidgetModel.ts

100% Statements 46/46
88.89% Branches 16/18
100% Functions 14/14
100% Lines 42/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 1261x                       1x       1x       17x 17x       2x       1x 1x 2x         1x 2x 1x 1x       1x             3x 1x   3x       19x         2x 1x   2x 1x   1x 1x 1x   1x 1x               3x 3x 1x     2x 2x   2x         1x       1x 2x                         4x   4x 3x     1x 1x   1x        
import {
  ICodeSnippet,
  CodeSnippetContentsService
} from './CodeSnippetContentsService';
 
export interface ICodeSnippetWidgetModel {
  /**
   * The list of code snippets in the code snippet explorer
   */
  readonly _snippets: ICodeSnippet[];
}
 
export class CodeSnippetWidgetModel implements ICodeSnippetWidgetModel {
  _snippets: ICodeSnippet[];
 
  constructor(snippets: ICodeSnippet[]) {
    this._snippets = snippets;
  }
 
  get snippets(): ICodeSnippet[] {
    this.sortSnippets();
    return this._snippets;
  }
 
  set snippets(snippetList: ICodeSnippet[]) {
    this._snippets = snippetList;
  }
 
  reorderSnippet(): void {
    this.sortSnippets();
    for (let i = 0; i < this._snippets.length; i++) {
      this._snippets[i].id = i;
    }
  }
 
  renameSnippet(oldName: string, newName: string): void {
    for (const snippet of this._snippets) {
      if (snippet.name === oldName) {
        snippet.name = newName;
        CodeSnippetContentsService.getInstance().save(
          'snippets/' + snippet.name + '.json',
          { type: 'file', format: 'text', content: JSON.stringify(snippet) }
        );
        break;
      }
    }
  }
 
  addSnippet(newSnippet: ICodeSnippet, index: number): void {
    // append a new snippet created from input form to the end
    if (newSnippet.id === -1) {
      newSnippet.id = this._snippets.length;
    }
    this.insertSnippet(newSnippet, index);
  }
 
  sortSnippets(): void {
    this._snippets.sort((a, b) => a.id - b.id);
  }
 
  // move snippetes within explorer
  moveSnippet(fromIdx: number, toIdx: number): void {
    if (toIdx > fromIdx) {
      toIdx = toIdx - 1;
    }
    if (toIdx === fromIdx) {
      return;
    }
    const snippetToInsert = this._snippets[fromIdx];
    this.deleteSnippet(fromIdx);
    snippetToInsert.id = toIdx;
 
    this.insertSnippet(snippetToInsert, toIdx);
    this.updateSnippetContents();
  }
 
  /**
   * Delete a snippet from the list
   * @param index index to delete. If it's not given, the last one gets deleted.
   */
  deleteSnippet(index = -1): void {
    const numSnippets = this._snippets.length;
    if (index < 0 || index > numSnippets) {
      this._snippets.pop();
    } else {
      // Update list
      for (let i = index + 1; i < numSnippets; i++) {
        this._snippets[i].id = this._snippets[i].id - 1;
      }
      this._snippets.splice(index, 1);
    }
  }
 
  clearSnippets(): void {
    this._snippets = [];
  }
 
  updateSnippetContents(): void {
    this._snippets.forEach(snippet => {
      CodeSnippetContentsService.getInstance().save(
        'snippets/' + snippet.name + '.json',
        { type: 'file', format: 'text', content: JSON.stringify(snippet) }
      );
    });
  }
 
  /**
   * insert a snippet to the certain index of the snippet list
   * @param newSnippet new snippet to insert
   * @param index index to insert. If it's not given, the snippet is added at the end of the list.
   */
  private insertSnippet(newSnippet: ICodeSnippet, index = -1): void {
    const numSnippets = this._snippets.length;
    // add it at the end of the list
    if (index < 0 || index >= numSnippets) {
      this._snippets.push(newSnippet);
    } else {
      // Update list
      for (let i = index; i < numSnippets; i++) {
        this._snippets[i].id = this._snippets[i].id + 1;
      }
      this._snippets.splice(index, 0, newSnippet);
    }
  }
}
 
================================================ FILE: coverage/lcov-report/base.css ================================================ body, html { margin:0; padding: 0; height: 100%; } body { font-family: Helvetica Neue, Helvetica, Arial; font-size: 14px; color:#333; } .small { font-size: 12px; } *, *:after, *:before { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; } h1 { font-size: 20px; margin: 0;} h2 { font-size: 14px; } pre { font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; margin: 0; padding: 0; -moz-tab-size: 2; -o-tab-size: 2; tab-size: 2; } a { color:#0074D9; text-decoration:none; } a:hover { text-decoration:underline; } .strong { font-weight: bold; } .space-top1 { padding: 10px 0 0 0; } .pad2y { padding: 20px 0; } .pad1y { padding: 10px 0; } .pad2x { padding: 0 20px; } .pad2 { padding: 20px; } .pad1 { padding: 10px; } .space-left2 { padding-left:55px; } .space-right2 { padding-right:20px; } .center { text-align:center; } .clearfix { display:block; } .clearfix:after { content:''; display:block; height:0; clear:both; visibility:hidden; } .fl { float: left; } @media only screen and (max-width:640px) { .col3 { width:100%; max-width:100%; } .hide-mobile { display:none!important; } } .quiet { color: #7f7f7f; color: rgba(0,0,0,0.5); } .quiet a { opacity: 0.7; } .fraction { font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 10px; color: #555; background: #E8E8E8; padding: 4px 5px; border-radius: 3px; vertical-align: middle; } div.path a:link, div.path a:visited { color: #333; } table.coverage { border-collapse: collapse; margin: 10px 0 0 0; padding: 0; } table.coverage td { margin: 0; padding: 0; vertical-align: top; } table.coverage td.line-count { text-align: right; padding: 0 5px 0 20px; } table.coverage td.line-coverage { text-align: right; padding-right: 10px; min-width:20px; } table.coverage td span.cline-any { display: inline-block; padding: 0 5px; width: 100%; } .missing-if-branch { display: inline-block; margin-right: 5px; border-radius: 3px; position: relative; padding: 0 4px; background: #333; color: yellow; } .skip-if-branch { display: none; margin-right: 10px; position: relative; padding: 0 4px; background: #ccc; color: white; } .missing-if-branch .typ, .skip-if-branch .typ { color: inherit !important; } .coverage-summary { border-collapse: collapse; width: 100%; } .coverage-summary tr { border-bottom: 1px solid #bbb; } .keyline-all { border: 1px solid #ddd; } .coverage-summary td, .coverage-summary th { padding: 10px; } .coverage-summary tbody { border: 1px solid #bbb; } .coverage-summary td { border-right: 1px solid #bbb; } .coverage-summary td:last-child { border-right: none; } .coverage-summary th { text-align: left; font-weight: normal; white-space: nowrap; } .coverage-summary th.file { border-right: none !important; } .coverage-summary th.pct { } .coverage-summary th.pic, .coverage-summary th.abs, .coverage-summary td.pct, .coverage-summary td.abs { text-align: right; } .coverage-summary td.file { white-space: nowrap; } .coverage-summary td.pic { min-width: 120px !important; } .coverage-summary tfoot td { } .coverage-summary .sorter { height: 10px; width: 7px; display: inline-block; margin-left: 0.5em; background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; } .coverage-summary .sorted .sorter { background-position: 0 -20px; } .coverage-summary .sorted-desc .sorter { background-position: 0 -10px; } .status-line { height: 10px; } /* yellow */ .cbranch-no { background: yellow !important; color: #111; } /* dark red */ .red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } .low .chart { border:1px solid #C21F39 } .highlighted, .highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ background: #C21F39 !important; } /* medium red */ .cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } /* light red */ .low, .cline-no { background:#FCE1E5 } /* light green */ .high, .cline-yes { background:rgb(230,245,208) } /* medium green */ .cstat-yes { background:rgb(161,215,106) } /* dark green */ .status-line.high, .high .cover-fill { background:rgb(77,146,33) } .high .chart { border:1px solid rgb(77,146,33) } /* dark yellow (gold) */ .status-line.medium, .medium .cover-fill { background: #f9cd0b; } .medium .chart { border:1px solid #f9cd0b; } /* light yellow */ .medium { background: #fff4c2; } .cstat-skip { background: #ddd; color: #111; } .fstat-skip { background: #ddd; color: #111 !important; } .cbranch-skip { background: #ddd !important; color: #111; } span.cline-neutral { background: #eaeaea; } .coverage-summary td.empty { opacity: .5; padding-top: 4px; padding-bottom: 4px; line-height: 1; color: #888; } .cover-fill, .cover-empty { display:inline-block; height: 12px; } .chart { line-height: 0; } .cover-empty { background: white; } .cover-full { border-right: none !important; } pre.prettyprint { border: none !important; padding: 0 !important; margin: 0 !important; } .com { color: #999 !important; } .ignore-none { color: #999; font-weight: normal; } .wrapper { min-height: 100%; height: auto !important; height: 100%; margin: 0 auto -48px; } .footer, .push { height: 48px; } ================================================ FILE: coverage/lcov-report/block-navigation.js ================================================ /* eslint-disable */ var jumpToCode = (function init() { // Classes of code we would like to highlight in the file view var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; // Elements to highlight in the file listing view var fileListingElements = ['td.pct.low']; // We don't want to select elements that are direct descendants of another match var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` // Selecter that finds elements on the page to which we can jump var selector = fileListingElements.join(', ') + ', ' + notSelector + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` // The NodeList of matching elements var missingCoverageElements = document.querySelectorAll(selector); var currentIndex; function toggleClass(index) { missingCoverageElements .item(currentIndex) .classList.remove('highlighted'); missingCoverageElements.item(index).classList.add('highlighted'); } function makeCurrent(index) { toggleClass(index); currentIndex = index; missingCoverageElements.item(index).scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' }); } function goToPrevious() { var nextIndex = 0; if (typeof currentIndex !== 'number' || currentIndex === 0) { nextIndex = missingCoverageElements.length - 1; } else if (missingCoverageElements.length > 1) { nextIndex = currentIndex - 1; } makeCurrent(nextIndex); } function goToNext() { var nextIndex = 0; if ( typeof currentIndex === 'number' && currentIndex < missingCoverageElements.length - 1 ) { nextIndex = currentIndex + 1; } makeCurrent(nextIndex); } return function jump(event) { switch (event.which) { case 78: // n case 74: // j goToNext(); break; case 66: // b case 75: // k case 80: // p goToPrevious(); break; } }; })(); window.addEventListener('keydown', jumpToCode); ================================================ FILE: coverage/lcov-report/index.html ================================================ Code coverage report for All files

All files

100% Statements 70/70
90% Branches 18/20
100% Functions 20/20
100% Lines 66/66

Press n or j to go to the next uncovered block, b, p or k for the previous block.

File Statements Branches Functions Lines
CodeSnippetContentsService.ts
100% 24/24 100% 2/2 100% 6/6 100% 24/24
CodeSnippetWidgetModel.ts
100% 46/46 88.89% 16/18 100% 14/14 100% 42/42
================================================ FILE: coverage/lcov-report/prettify.css ================================================ .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} ================================================ FILE: coverage/lcov-report/prettify.js ================================================ /* eslint-disable */ window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); ================================================ FILE: coverage/lcov-report/sorter.js ================================================ /* eslint-disable */ var addSorting = (function() { 'use strict'; var cols, currentSort = { index: 0, desc: false }; // returns the summary table element function getTable() { return document.querySelector('.coverage-summary'); } // returns the thead element of the summary table function getTableHeader() { return getTable().querySelector('thead tr'); } // returns the tbody element of the summary table function getTableBody() { return getTable().querySelector('tbody'); } // returns the th element for nth column function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } // loads all columns function loadColumns() { var colNodes = getTableHeader().querySelectorAll('th'), colNode, cols = [], col, i; for (i = 0; i < colNodes.length; i += 1) { colNode = colNodes[i]; col = { key: colNode.getAttribute('data-col'), sortable: !colNode.getAttribute('data-nosort'), type: colNode.getAttribute('data-type') || 'string' }; cols.push(col); if (col.sortable) { col.defaultDescSort = col.type === 'number'; colNode.innerHTML = colNode.innerHTML + ''; } } return cols; } // attaches a data attribute to every tr element with an object // of data values keyed by column name function loadRowData(tableRow) { var tableCols = tableRow.querySelectorAll('td'), colNode, col, data = {}, i, val; for (i = 0; i < tableCols.length; i += 1) { colNode = tableCols[i]; col = cols[i]; val = colNode.getAttribute('data-value'); if (col.type === 'number') { val = Number(val); } data[col.key] = val; } return data; } // loads all row data function loadData() { var rows = getTableBody().querySelectorAll('tr'), i; for (i = 0; i < rows.length; i += 1) { rows[i].data = loadRowData(rows[i]); } } // sorts the table using the data for the ith column function sortByIndex(index, desc) { var key = cols[index].key, sorter = function(a, b) { a = a.data[key]; b = b.data[key]; return a < b ? -1 : a > b ? 1 : 0; }, finalSorter = sorter, tableBody = document.querySelector('.coverage-summary tbody'), rowNodes = tableBody.querySelectorAll('tr'), rows = [], i; if (desc) { finalSorter = function(a, b) { return -1 * sorter(a, b); }; } for (i = 0; i < rowNodes.length; i += 1) { rows.push(rowNodes[i]); tableBody.removeChild(rowNodes[i]); } rows.sort(finalSorter); for (i = 0; i < rows.length; i += 1) { tableBody.appendChild(rows[i]); } } // removes sort indicators for current column being sorted function removeSortIndicators() { var col = getNthColumn(currentSort.index), cls = col.className; cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); col.className = cls; } // adds sort indicators for current column being sorted function addSortIndicators() { getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; } // adds event listeners for all sorter widgets function enableUI() { var i, el, ithSorter = function ithSorter(i) { var col = cols[i]; return function() { var desc = col.defaultDescSort; if (currentSort.index === i) { desc = !currentSort.desc; } sortByIndex(i, desc); removeSortIndicators(); currentSort.index = i; currentSort.desc = desc; addSortIndicators(); }; }; for (i = 0; i < cols.length; i += 1) { if (cols[i].sortable) { // add the click event handler on the th so users // dont have to click on those tiny arrows el = getNthColumn(i).querySelector('.sorter').parentElement; if (el.addEventListener) { el.addEventListener('click', ithSorter(i)); } else { el.attachEvent('onclick', ithSorter(i)); } } } } // adds sorting functionality to the UI return function() { if (!getTable()) { return; } cols = loadColumns(); loadData(); addSortIndicators(); enableUI(); }; })(); window.addEventListener('load', addSorting); ================================================ FILE: coverage/lcov.info ================================================ TN: SF:src/CodeSnippetContentsService.ts FN:20,(anonymous_7) FN:27,(anonymous_8) FN:38,(anonymous_9) FN:67,(anonymous_11) FN:90,(anonymous_13) FN:105,(anonymous_15) FNF:6 FNH:6 FNDA:2,(anonymous_7) FNDA:4,(anonymous_8) FNDA:2,(anonymous_9) FNDA:4,(anonymous_11) FNDA:2,(anonymous_13) FNDA:1,(anonymous_15) DA:1,2 DA:16,2 DA:21,2 DA:22,2 DA:23,2 DA:24,2 DA:28,4 DA:29,2 DA:31,4 DA:42,2 DA:43,2 DA:48,1 DA:50,1 DA:71,4 DA:72,4 DA:73,1 DA:75,3 DA:91,2 DA:92,2 DA:93,1 DA:95,1 DA:106,1 DA:107,1 DA:109,1 LF:24 LH:24 BRDA:28,0,0,2 BRDA:28,0,1,2 BRF:2 BRH:2 end_of_record TN: SF:src/CodeSnippetWidgetModel.ts FN:16,(anonymous_0) FN:20,(anonymous_1) FN:25,(anonymous_2) FN:29,(anonymous_3) FN:36,(anonymous_4) FN:49,(anonymous_5) FN:57,(anonymous_6) FN:58,(anonymous_7) FN:62,(anonymous_8) FN:81,(anonymous_9) FN:94,(anonymous_10) FN:98,(anonymous_11) FN:99,(anonymous_12) FN:112,(anonymous_13) FNF:14 FNH:14 FNDA:1,(anonymous_0) FNDA:17,(anonymous_1) FNDA:2,(anonymous_2) FNDA:1,(anonymous_3) FNDA:1,(anonymous_4) FNDA:3,(anonymous_5) FNDA:19,(anonymous_6) FNDA:14,(anonymous_7) FNDA:2,(anonymous_8) FNDA:3,(anonymous_9) FNDA:1,(anonymous_10) FNDA:1,(anonymous_11) FNDA:2,(anonymous_12) FNDA:4,(anonymous_13) DA:1,1 DA:13,1 DA:17,1 DA:21,17 DA:22,17 DA:26,2 DA:30,1 DA:31,1 DA:32,2 DA:37,1 DA:38,2 DA:39,1 DA:40,1 DA:44,1 DA:51,3 DA:52,1 DA:54,3 DA:58,19 DA:63,2 DA:64,1 DA:66,2 DA:67,1 DA:69,1 DA:70,1 DA:71,1 DA:73,1 DA:74,1 DA:82,3 DA:83,3 DA:84,1 DA:87,2 DA:88,2 DA:90,2 DA:95,1 DA:99,1 DA:100,2 DA:113,4 DA:115,4 DA:116,3 DA:119,1 DA:120,1 DA:122,1 LF:42 LH:42 BRDA:38,0,0,1 BRDA:38,0,1,1 BRDA:51,1,0,1 BRDA:51,1,1,2 BRDA:63,2,0,1 BRDA:63,2,1,1 BRDA:66,3,0,1 BRDA:66,3,1,1 BRDA:81,4,0,0 BRDA:83,5,0,1 BRDA:83,5,1,2 BRDA:83,6,0,3 BRDA:83,6,1,2 BRDA:112,7,0,0 BRDA:115,8,0,3 BRDA:115,8,1,1 BRDA:115,9,0,4 BRDA:115,9,1,3 BRF:18 BRH:16 end_of_record ================================================ FILE: coverage/prettify.css ================================================ .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} ================================================ FILE: coverage/prettify.js ================================================ /* eslint-disable */ window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); ================================================ FILE: coverage/sorter.js ================================================ /* eslint-disable */ var addSorting = (function() { 'use strict'; var cols, currentSort = { index: 0, desc: false }; // returns the summary table element function getTable() { return document.querySelector('.coverage-summary'); } // returns the thead element of the summary table function getTableHeader() { return getTable().querySelector('thead tr'); } // returns the tbody element of the summary table function getTableBody() { return getTable().querySelector('tbody'); } // returns the th element for nth column function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } // loads all columns function loadColumns() { var colNodes = getTableHeader().querySelectorAll('th'), colNode, cols = [], col, i; for (i = 0; i < colNodes.length; i += 1) { colNode = colNodes[i]; col = { key: colNode.getAttribute('data-col'), sortable: !colNode.getAttribute('data-nosort'), type: colNode.getAttribute('data-type') || 'string' }; cols.push(col); if (col.sortable) { col.defaultDescSort = col.type === 'number'; colNode.innerHTML = colNode.innerHTML + ''; } } return cols; } // attaches a data attribute to every tr element with an object // of data values keyed by column name function loadRowData(tableRow) { var tableCols = tableRow.querySelectorAll('td'), colNode, col, data = {}, i, val; for (i = 0; i < tableCols.length; i += 1) { colNode = tableCols[i]; col = cols[i]; val = colNode.getAttribute('data-value'); if (col.type === 'number') { val = Number(val); } data[col.key] = val; } return data; } // loads all row data function loadData() { var rows = getTableBody().querySelectorAll('tr'), i; for (i = 0; i < rows.length; i += 1) { rows[i].data = loadRowData(rows[i]); } } // sorts the table using the data for the ith column function sortByIndex(index, desc) { var key = cols[index].key, sorter = function(a, b) { a = a.data[key]; b = b.data[key]; return a < b ? -1 : a > b ? 1 : 0; }, finalSorter = sorter, tableBody = document.querySelector('.coverage-summary tbody'), rowNodes = tableBody.querySelectorAll('tr'), rows = [], i; if (desc) { finalSorter = function(a, b) { return -1 * sorter(a, b); }; } for (i = 0; i < rowNodes.length; i += 1) { rows.push(rowNodes[i]); tableBody.removeChild(rowNodes[i]); } rows.sort(finalSorter); for (i = 0; i < rows.length; i += 1) { tableBody.appendChild(rows[i]); } } // removes sort indicators for current column being sorted function removeSortIndicators() { var col = getNthColumn(currentSort.index), cls = col.className; cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); col.className = cls; } // adds sort indicators for current column being sorted function addSortIndicators() { getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; } // adds event listeners for all sorter widgets function enableUI() { var i, el, ithSorter = function ithSorter(i) { var col = cols[i]; return function() { var desc = col.defaultDescSort; if (currentSort.index === i) { desc = !currentSort.desc; } sortByIndex(i, desc); removeSortIndicators(); currentSort.index = i; currentSort.desc = desc; addSortIndicators(); }; }; for (i = 0; i < cols.length; i += 1) { if (cols[i].sortable) { // add the click event handler on the th so users // dont have to click on those tiny arrows el = getNthColumn(i).querySelector('.sorter').parentElement; if (el.addEventListener) { el.addEventListener('click', ithSorter(i)); } else { el.attachEvent('onclick', ithSorter(i)); } } } } // adds sorting functionality to the UI return function() { if (!getTable()) { return; } cols = loadColumns(); loadData(); addSortIndicators(); enableUI(); }; })(); window.addEventListener('load', addSorting); ================================================ FILE: cypress/fixtures/example.json ================================================ { "name": "Using fixtures to represent data", "email": "hello@cypress.io", "body": "Fixtures are a great way to mock data for responses to routes" } ================================================ FILE: cypress/integration/codeSnippetService.spec.js ================================================ describe('Test Code Snippet Extension on load', () => { beforeEach(() => { cy.visit('http://localhost:8888/lab') }) // it('Create code snippet settings on load', () => { // cy.get('.jp-PluginList > ul > li').eq(1).should('have.attr', 'data-id', 'jupyterlab-code-snippets:snippets') // }) it('Create default snippets in the beginning', () => { cy.get('.jp-codeSnippetsContainer').find('.jp-codeSnippet-item').should('have.length', 3) }) }) describe('Test Code Snippet Manipulation', () => { beforeEach(() => { cy.visit('http://localhost:8888/lab') }) it('Create a new code snippet', () => { // adding a snippet cy.get('.jp-Notebook').rightclick() .get('.lm-Menu-itemLabel').eq(13).click() .wait(500) .get('.jp-codeSnippet-dialog-input').eq(0).click().type("test").should('have.value', 'test') .wait(500) .get('.jp-codeSnippet-dialog-input').eq(1).click().type("testing with cypress").should('have.value', 'testing with cypress') .wait(500) .get('.jp-codeSnippet-dialog-input').eq(2).click().type("Python").should('have.value', 'Python') .get('.jp-mod-accept').click(); cy.get('.lm-Widget').eq(0).click({force: true}); // checking the snippet cy.get('.jp-codeSnippetsContainer').find('.jp-codeSnippet-item').should('have.length', 4); }) it('Delete a new code snippet', () => { // delete snippet cy.get('.jp-codeSnippet-item #0 > .jp-codeSnippetsContainer-button').click() .get('.jp-codeSnippet-more-options-delete').click() .get('.jp-mod-accept').click() // checking the snippet cy.get('.jp-codeSnippetsContainer').find('.jp-codeSnippet-item').should('have.length', 3); }) it('Renaming a snippet', () => { cy.wait(500) // rename snippet cy.get('.jp-codeSnippet-item #0 > .jp-codeSnippetsContainer-name > span').eq(1).dblclick() .get('#jp-codeSnippet-rename').type('new_test') cy.wait(500) // rename with duplicate name cy.get('.jp-codeSnippet-item #1 > .jp-codeSnippetsContainer-name > span').eq(1).dblclick() .get('#jp-codeSnippet-rename').type('new_test') .get('.lm-StackedPanel').eq(0).click({force:true}) .get('.jp-mod-accept').click() }) it('Create a new code snippet from scratch', () => { cy.get('.jp-createSnippetBtn').click().get('.jp-codeSnippet-editor-name').type('create_test').should('have.value', 'create_test') .get('.jp-codeSnippet-editor-description').type('testing').should('have.value', 'testing') .get('.saveBtn').click() }) it.only('Edit a snippet', () => { cy.get('.jp-codeSnippet-item #0 > .jp-codeSnippetsContainer-button').click() .get('.jp-codeSnippet-more-options-edit').click() .wait(500) .get('.jp-codeSnippet-editor-name').clear().type('test_editing').should('have.value', 'test_editing') .wait(500) .get('.jp-codeSnippet-editor-name').clear().type('test_editing').should('have.value', 'test_editing') .get('.saveBtn').click() cy.get('.jp-codeSnippet-item #0 > .jp-codeSnippetsContainer-name > span').eq(1).contains('test_editing') }) // it.only('moving a snippet', () => { // cy.visit('http://localhost:8888/lab') // cy.wait(500) // cy.get('.jp-codeSnippet-drag-hover').eq(0) // .dragTo(':nth-child(3) > .jp-codeSnippet-metadata') // .get('.jp-codeSnippet-item #1 > .jp-codeSnippetsContainer-name > span').eq(1).contains('test') // }) }) ================================================ FILE: cypress/integration/examples/actions.spec.js ================================================ /// context('Actions', () => { beforeEach(() => { cy.visit('https://example.cypress.io/commands/actions') }) // https://on.cypress.io/interacting-with-elements it('.type() - type into a DOM element', () => { // https://on.cypress.io/type cy.get('.action-email') .type('fake@email.com').should('have.value', 'fake@email.com') // .type() with special character sequences .type('{leftarrow}{rightarrow}{uparrow}{downarrow}') .type('{del}{selectall}{backspace}') // .type() with key modifiers .type('{alt}{option}') //these are equivalent .type('{ctrl}{control}') //these are equivalent .type('{meta}{command}{cmd}') //these are equivalent .type('{shift}') // Delay each keypress by 0.1 sec .type('slow.typing@email.com', { delay: 100 }) .should('have.value', 'slow.typing@email.com') cy.get('.action-disabled') // Ignore error checking prior to type // like whether the input is visible or disabled .type('disabled error checking', { force: true }) .should('have.value', 'disabled error checking') }) it('.focus() - focus on a DOM element', () => { // https://on.cypress.io/focus cy.get('.action-focus').focus() .should('have.class', 'focus') .prev().should('have.attr', 'style', 'color: orange;') }) it('.blur() - blur off a DOM element', () => { // https://on.cypress.io/blur cy.get('.action-blur').type('About to blur').blur() .should('have.class', 'error') .prev().should('have.attr', 'style', 'color: red;') }) it('.clear() - clears an input or textarea element', () => { // https://on.cypress.io/clear cy.get('.action-clear').type('Clear this text') .should('have.value', 'Clear this text') .clear() .should('have.value', '') }) it('.submit() - submit a form', () => { // https://on.cypress.io/submit cy.get('.action-form') .find('[type="text"]').type('HALFOFF') cy.get('.action-form').submit() .next().should('contain', 'Your form has been submitted!') }) it('.click() - click on a DOM element', () => { // https://on.cypress.io/click cy.get('.action-btn').click() // You can click on 9 specific positions of an element: // ----------------------------------- // | topLeft top topRight | // | | // | | // | | // | left center right | // | | // | | // | | // | bottomLeft bottom bottomRight | // ----------------------------------- // clicking in the center of the element is the default cy.get('#action-canvas').click() cy.get('#action-canvas').click('topLeft') cy.get('#action-canvas').click('top') cy.get('#action-canvas').click('topRight') cy.get('#action-canvas').click('left') cy.get('#action-canvas').click('right') cy.get('#action-canvas').click('bottomLeft') cy.get('#action-canvas').click('bottom') cy.get('#action-canvas').click('bottomRight') // .click() accepts an x and y coordinate // that controls where the click occurs :) cy.get('#action-canvas') .click(80, 75) // click 80px on x coord and 75px on y coord .click(170, 75) .click(80, 165) .click(100, 185) .click(125, 190) .click(150, 185) .click(170, 165) // click multiple elements by passing multiple: true cy.get('.action-labels>.label').click({ multiple: true }) // Ignore error checking prior to clicking cy.get('.action-opacity>.btn').click({ force: true }) }) it('.dblclick() - double click on a DOM element', () => { // https://on.cypress.io/dblclick // Our app has a listener on 'dblclick' event in our 'scripts.js' // that hides the div and shows an input on double click cy.get('.action-div').dblclick().should('not.be.visible') cy.get('.action-input-hidden').should('be.visible') }) it('.rightclick() - right click on a DOM element', () => { // https://on.cypress.io/rightclick // Our app has a listener on 'contextmenu' event in our 'scripts.js' // that hides the div and shows an input on right click cy.get('.rightclick-action-div').rightclick().should('not.be.visible') cy.get('.rightclick-action-input-hidden').should('be.visible') }) it('.check() - check a checkbox or radio element', () => { // https://on.cypress.io/check // By default, .check() will check all // matching checkbox or radio elements in succession, one after another cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]') .check().should('be.checked') cy.get('.action-radios [type="radio"]').not('[disabled]') .check().should('be.checked') // .check() accepts a value argument cy.get('.action-radios [type="radio"]') .check('radio1').should('be.checked') // .check() accepts an array of values cy.get('.action-multiple-checkboxes [type="checkbox"]') .check(['checkbox1', 'checkbox2']).should('be.checked') // Ignore error checking prior to checking cy.get('.action-checkboxes [disabled]') .check({ force: true }).should('be.checked') cy.get('.action-radios [type="radio"]') .check('radio3', { force: true }).should('be.checked') }) it('.uncheck() - uncheck a checkbox element', () => { // https://on.cypress.io/uncheck // By default, .uncheck() will uncheck all matching // checkbox elements in succession, one after another cy.get('.action-check [type="checkbox"]') .not('[disabled]') .uncheck().should('not.be.checked') // .uncheck() accepts a value argument cy.get('.action-check [type="checkbox"]') .check('checkbox1') .uncheck('checkbox1').should('not.be.checked') // .uncheck() accepts an array of values cy.get('.action-check [type="checkbox"]') .check(['checkbox1', 'checkbox3']) .uncheck(['checkbox1', 'checkbox3']).should('not.be.checked') // Ignore error checking prior to unchecking cy.get('.action-check [disabled]') .uncheck({ force: true }).should('not.be.checked') }) it('.select() - select an option in a {SUPPORTED_LANGUAGES.map((lang) => this.renderLanguageOptions(lang))} ); } renderLanguageOptions(option: string): JSX.Element { return